X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Frenderer_widget.c;h=505c5e3a1ef511c7e1d8a4a6b6a982d7903d84b9;hb=08309c482bda11b6a86066409d08a99789ab2f5d;hp=43d39c106f88dd7204ba7827bee2407200731fed;hpb=e2eba65d40020e9f0ee28ad512ce56d74f656689;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin3_src/WM/renderer_widget.c b/Usermode/Applications/axwin3_src/WM/renderer_widget.c index 43d39c10..505c5e3a 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderer_widget.c @@ -9,65 +9,25 @@ #include #include #include +#include +#include -// === TYPES === -typedef struct sWidgetWin tWidgetWin; -typedef struct sAxWin_Element tElement; - -// === STRUCTURES === -struct sAxWin_Element -{ - enum eElementTypes Type; - - uint32_t ID; //!< Application provided ID number - tElement *ListNext; //!< Next element in bucket - - // Element Tree - tElement *Parent; - tElement *FirstChild; - tElement *LastChild; - tElement *NextSibling; - - // User modifiable attributes - short PaddingL, PaddingR; - short PaddingT, PaddingB; - short GapSize; - - uint32_t Flags; - - short FixedWith; //!< Fixed lengthways Size attribute (height) - short FixedCross; //!< Fixed Cross Size attribute (width) - - char *Text; - - // -- Attributes maitained by the element code - // Not touched by the user - short MinWith; //!< Minimum long size - short MinCross; //!< Minimum cross size - void *Data; //!< Per-type data - - // -- Render Cache - short CachedX, CachedY; - short CachedW, CachedH; - - char DebugName[]; -}; -struct sWidgetWin -{ - tElement RootElement; - - int TableSize; //!< Number of entries, anything over will wrap - tElement *ElementTable[]; //!< Hash table essentially -}; +#define DEFAULT_ELETABLE_SIZE 64 // === PROTOTYPES === -tWindow *Renderer_Widget_Create(int Width, int Height, int Flags); + int Renderer_Widget_Init(void); +tWindow *Renderer_Widget_Create(int Flags); void Renderer_Widget_Redraw(tWindow *Window); -int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data); +void Widget_RenderWidget(tWindow *Window, tElement *Element); + int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data); +void Widget_UpdateDimensions(tElement *Element); +void Widget_UpdatePosition(tElement *Element); +tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID); +void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg); // === GLOBALS === tWMRenderer gRenderer_Widget = { - .Name = "Classful", + .Name = "Widget", .CreateWindow = Renderer_Widget_Create, .Redraw = Renderer_Widget_Redraw, .HandleMessage = Renderer_Widget_HandleMessage @@ -81,17 +41,50 @@ int Renderer_Widget_Init(void) return 0; } -tWindow *Renderer_Widget_Create(int Width, int Height, int Flags) +tWindow *Renderer_Widget_Create(int Flags) { - // TODO: Add info - return WM_CreateWindowStruct( sizeof(tWidgetWin) ); + tWindow *ret; + tWidgetWin *info; + int eletable_size = DEFAULT_ELETABLE_SIZE; + + // TODO: Use `Flags` as default element count? + + ret = WM_CreateWindowStruct( sizeof(tWidgetWin) + sizeof(tElement*)*eletable_size ); + info = ret->RendererInfo; + + info->TableSize = eletable_size; + info->RootElement.BackgroundColour = 0xCCCCCC; + + return ret; } void Renderer_Widget_Redraw(tWindow *Window) { + tWidgetWin *info = Window->RendererInfo; + WM_Render_FillRect(Window, 0, 0, 0xFFF, 0xFFF, info->RootElement.BackgroundColour); + + Widget_UpdateDimensions(&info->RootElement); + Widget_UpdatePosition(&info->RootElement); + + Widget_RenderWidget(Window, &info->RootElement); } // --- Render / Resize --- +void Widget_RenderWidget(tWindow *Window, tElement *Element) +{ + tElement *child; + + if( Element->Flags & ELEFLAG_NORENDER ) return ; + if( Element->Flags & ELEFLAG_INVISIBLE ) return ; + + Widget_Decorator_RenderWidget(Window, Element); + + for(child = Element->FirstChild; child; child = child->NextSibling) + { + Widget_RenderWidget(Window, child); + } +} + void Widget_UpdateDimensions(tElement *Element) { tElement *child; @@ -257,6 +250,9 @@ void Widget_UpdatePosition(tElement *Element) tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID) { tElement *ele; + + if(ID == -1) + return &Info->RootElement; if( ID < Info->TableSize ) return Info->ElementTable[ID]; @@ -269,7 +265,7 @@ tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID) void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg) { const int max_debugname_len = Len - sizeof(tWidgetMsg_Create); - tElement *parent; + tElement *parent, *new; // Sanity check if( Len < sizeof(tWidgetMsg_Create) ) @@ -278,7 +274,62 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg) return ; // Create - parent = _GetElementById(Info, Msg->Parent); + parent = Widget_GetElementById(Info, Msg->Parent); + if(!parent) + { + _SysDebug("Widget_NewWidget - Bad parent ID %i", Msg->Parent); + return ; + } + + // Check if the ID is already in use + if( Widget_GetElementById(Info, Msg->NewID) ) + return ; + + // Create new element + new = calloc(sizeof(tElement), 1); + new->ID = Msg->NewID; + new->Type = Msg->Type; + new->Parent = parent; + new->Flags = Msg->Flags; + new->PaddingT = 2; + new->PaddingB = 2; + new->PaddingL = 2; + new->PaddingR = 2; + + // Add to parent's list + if(parent->LastChild) + parent->LastChild->NextSibling = new; + else + parent->FirstChild = new; + new->NextSibling = parent->LastChild; + parent->LastChild = new; + + // Add to info + { + tElement *ele, *prev = NULL; + for(ele = Info->ElementTable[new->ID % Info->TableSize]; ele; prev = ele, ele = ele->ListNext); + if(prev) + prev->ListNext = new; + else + Info->ElementTable[new->ID % Info->TableSize] = new; + } +} + +void Widget_SetSize(tWidgetWin *Info, int Len, tWidgetMsg_SetSize *Msg) +{ + tElement *ele; + + if( Len < sizeof(tWidgetMsg_SetSize) ) + return ; + + ele = Widget_GetElementById(Info, Msg->WidgetID); + if(!ele) return ; + + ele->FixedWith = Msg->Value; +} + +void Widget_SetText(tWidgetWin *Info, int Len, tWidgetMsg_SetText *Msg) +{ } @@ -287,16 +338,31 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) tWidgetWin *info = Target->RendererInfo; switch(Msg) { + case WNDMSG_RESIZE: { + struct sWndMsg_Resize *msg = Data; + if(Len < sizeof(*msg)) return -1; + + info->RootElement.CachedW = msg->W; + info->RootElement.CachedH = msg->H; + return 0; } + // New Widget case MSG_WIDGET_CREATE: Widget_NewWidget(info, Len, Data); return 0; + + // Set length + case MSG_WIDGET_SETSIZE: + Widget_SetSize(info, Len, Data); + return 0; + // Set text + case MSG_WIDGET_SETTEXT: + Widget_SetText(info, Len, Data); + return 0; + // default: - return 1; // Unhandled + return 1; // Unhandled, pass to user } } - - -