X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Frenderers%2Fwidget.c;h=fd757af7a0fe2167b88bb018ae8c463df02d5f3c;hb=5f8480455a9e2172b15dfc7fb96480a68506c30d;hp=88529543c92d18e16cc1481f74351b4449ad2603;hpb=507f19941f45bca7c1de783a394f56b15f10be4d;p=tpg%2Facess2.git diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget.c b/Usermode/Applications/axwin3_src/WM/renderers/widget.c index 88529543..fd757af7 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget.c @@ -16,6 +16,14 @@ #define DEFAULT_ELETABLE_SIZE 64 #define BORDER_EVERYTHING 0 +// === IMPORTS === +extern tWidgetDef _widget_typedef_ELETYPE_IMAGE; +extern tWidgetDef _widget_typedef_ELETYPE_BUTTON; +extern tWidgetDef _widget_typedef_ELETYPE_TEXT; +extern tWidgetDef _widget_typedef_ELETYPE_TEXTINPUT; +extern tWidgetDef _widget_typedef_ELETYPE_SPACER; +extern tWidgetDef _widget_typedef_ELETYPE_SUBWIN; + // === PROTOTYPES === int Renderer_Widget_Init(void); tWindow *Renderer_Widget_Create(int Flags); @@ -26,10 +34,15 @@ void Widget_UpdateDimensions(tElement *Element); void Widget_UpdatePosition(tElement *Element); // --- Messages tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID); -void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg); -void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg); -void Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg); -void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg); + int Widget_IPC_Create(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_NewWidgetSubwin(tWindow *Win, size_t Len, const void *Data); +// int Widget_IPC_Delete(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_SetFocus(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_SetFlags(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_SetSize(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_SetText(tWindow *Win, size_t Len, const void *Data); + int Widget_IPC_GetText(tWindow *Win, size_t Len, const void *Data); +// int Widget_IPC_SetColour(tWindow *Win, size_t Len, const void *Data); int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); // === GLOBALS === @@ -37,21 +50,37 @@ tWMRenderer gRenderer_Widget = { .Name = "Widget", .CreateWindow = Renderer_Widget_Create, .Redraw = Renderer_Widget_Redraw, - .HandleMessage = Renderer_Widget_HandleMessage + .HandleMessage = Renderer_Widget_HandleMessage, + .nIPCHandlers = N_IPC_WIDGET, + .IPCHandlers = { + [IPC_WIDGET_CREATE] = Widget_IPC_Create, + [IPC_WIDGET_CREATESUBWIN] = Widget_IPC_NewWidgetSubwin, + [IPC_WIDGET_SETFOCUS] = Widget_IPC_SetFocus, + [IPC_WIDGET_SETFLAGS] = Widget_IPC_SetFlags, + [IPC_WIDGET_SETSIZE] = Widget_IPC_SetSize, + [IPC_WIDGET_SETTEXT] = Widget_IPC_SetText, + [IPC_WIDGET_GETTEXT] = Widget_IPC_GetText, + } }; // --- Element callbacks -tWidgetDef *gaWM_WidgetTypes[NUM_ELETYPES]; +tWidgetDef *gaWM_WidgetTypes[NUM_ELETYPES] = { + [ELETYPE_IMAGE] = &_widget_typedef_ELETYPE_IMAGE, + [ELETYPE_BUTTON] = &_widget_typedef_ELETYPE_BUTTON, + [ELETYPE_TEXT] = &_widget_typedef_ELETYPE_TEXT, + [ELETYPE_TEXTINPUT] = &_widget_typedef_ELETYPE_TEXTINPUT, + [ELETYPE_SPACER] = &_widget_typedef_ELETYPE_SPACER, + [ELETYPE_SUBWIN] = &_widget_typedef_ELETYPE_SUBWIN, + }; const int ciWM_NumWidgetTypes = sizeof(gaWM_WidgetTypes)/sizeof(gaWM_WidgetTypes[0]); tWidgetDef gWidget_NullWidgetDef; // === CODE === int Renderer_Widget_Init(void) { - int i; WM_RegisterRenderer(&gRenderer_Widget); - for(i = 0; i < ciWM_NumWidgetTypes; i ++) + for(int i = 0; i < ciWM_NumWidgetTypes; i ++) { if(gaWM_WidgetTypes[i] != NULL) continue; @@ -79,6 +108,7 @@ void Widget_int_SetTypeDef(int Type, tWidgetDef *Ptr) } gaWM_WidgetTypes[Type] = Ptr; + _SysDebug("Registered widget type %i '%s'", Type, Ptr->Name); } tWindow *Renderer_Widget_Create(int Flags) @@ -87,7 +117,7 @@ tWindow *Renderer_Widget_Create(int Flags) tWidgetWin *info; int eletable_size = DEFAULT_ELETABLE_SIZE; - _SysDebug("Renderer_Widget_Create: (Flags = 0x%x)", Flags); + //_SysDebug("Renderer_Widget_Create: (Flags = 0x%x)", Flags); // TODO: Use `Flags` as default element count? // - Actaully, it's taken by the root ele flags @@ -214,14 +244,14 @@ void Widget_UpdateDimensions(tElement *Element) else fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB; - _SysDebug("%i (p=%i) - WxH=%ix%i", - Element->ID, (Element->Parent ? Element->Parent->ID : -1), - Element->CachedW, Element->CachedH - ); - _SysDebug(" %s dynWith = %i, fullCross = %i", - (Element->Flags & ELEFLAG_VERTICAL ? "Vert" : "Horiz"), - dynWith, fullCross - ); + //_SysDebug("%i (p=%i) - WxH=%ix%i", + // Element->ID, (Element->Parent ? Element->Parent->ID : -1), + // Element->CachedW, Element->CachedH + // ); + //_SysDebug(" %s dynWith = %i, fullCross = %i", + // (Element->Flags & ELEFLAG_VERTICAL ? "Vert" : "Horiz"), + // dynWith, fullCross + // ); // Pass 2 - Set sizes and recurse for( child = Element->FirstChild; child; child = child->NextSibling ) @@ -234,7 +264,7 @@ void Widget_UpdateDimensions(tElement *Element) if( child->Flags & ELEFLAG_ABSOLUTEPOS ) continue ; // --- Width --- - if( child->Flags & ELEFLAG_NOEXPAND ) + if( child->Flags & (bVertical ? ELEFLAG_NOEXPAND : ELEFLAG_NOSTRETCH) ) w = child->MinW; else if( bVertical ) w = child->FixedCross ? child->FixedCross : fullCross; @@ -242,7 +272,7 @@ void Widget_UpdateDimensions(tElement *Element) w = child->FixedWith ? child->FixedWith : dynWith; // --- Height --- - if( child->Flags & ELEFLAG_NOSTRETCH ) + if( child->Flags & (bVertical ? ELEFLAG_NOSTRETCH : ELEFLAG_NOEXPAND) ) h = child->MinH; else if( bVertical ) h = child->FixedWith ? child->FixedWith : dynWith; @@ -274,7 +304,6 @@ void Widget_UpdateDimensions(tElement *Element) */ void Widget_UpdatePosition(tElement *Element) { - tElement *child; int x, y; if( Element->Flags & ELEFLAG_NORENDER ) return ; @@ -291,7 +320,7 @@ void Widget_UpdatePosition(tElement *Element) y = Element->CachedY + Element->PaddingT; // Update each child - for(child = Element->FirstChild; child; child = child->NextSibling) + for(tElement *child = Element->FirstChild; child; child = child->NextSibling) { int newX, newY; // Ignore elements that will not be rendered @@ -342,7 +371,6 @@ void Widget_UpdatePosition(tElement *Element) */ void Widget_UpdateMinDims(tElement *Element) { - tElement *child; int minW, minH; int nChildren; @@ -352,7 +380,7 @@ void Widget_UpdateMinDims(tElement *Element) minH = 0; nChildren = 0; - for(child = Element->FirstChild; child; child = child->NextSibling) + for( tElement *child = Element->FirstChild; child; child = child->NextSibling ) { int cross; @@ -389,14 +417,13 @@ void Widget_UpdateMinDims(tElement *Element) tElement *Widget_GetElementByPos(tWidgetWin *Info, int X, int Y) { - tElement *ret, *next, *ele; - - next = &Info->RootElement; - do - { + tElement *ret; + tElement *next = &Info->RootElement; + // Scan down tree + do { ret = next; next = NULL; - for(ele = ret->FirstChild; ele; ele = ele->NextSibling) + for(tElement *ele = ret->FirstChild; ele; ele = ele->NextSibling) { if(ele->Flags & ELEFLAG_NORENDER) continue; if(X < ele->CachedX) continue; @@ -427,6 +454,12 @@ tElement *Widget_int_Create(tWidgetWin *Info, tElement *Parent, int ID, int Type { if( Widget_GetElementById(Info, ID) ) return NULL; + if( Type >= NUM_ELETYPES ) { + return NULL; + } + + _SysDebug("Widget Create #%i '%s' 0x%x", + ID, gaWM_WidgetTypes[Type]->Name, Flags); // Create new element tElement *new = calloc(sizeof(tElement), 1); @@ -440,7 +473,7 @@ tElement *Widget_int_Create(tWidgetWin *Info, tElement *Parent, int ID, int Type new->PaddingL = 2; new->PaddingR = 2; new->CachedX = -1; - + if( gaWM_WidgetTypes[Type]->Init ) gaWM_WidgetTypes[Type]->Init(new); @@ -464,17 +497,27 @@ tElement *Widget_int_Create(tWidgetWin *Info, tElement *Parent, int ID, int Type return new; } +void Widget_SetFocus(tWidgetWin *Info, tElement *Ele) +{ + // TODO: Callbacks + + Info->FocusedElement = Ele; +} + + // --- Message Handlers --- -void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg) +int Widget_IPC_Create(tWindow *Win, size_t Len, const void *Data) { - const int max_debugname_len = Len - sizeof(tWidgetMsg_Create); + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_Create *Msg = Data; + const int max_debugname_len = Len - sizeof(*Msg); tElement *parent; // Sanity check if( Len < sizeof(*Msg) ) - return ; + return -1; if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len ) - return ; + return -1; _SysDebug("Widget_NewWidget (%i %i Type %i Flags 0x%x)", Msg->Parent, Msg->NewID, Msg->Type, Msg->Flags); @@ -482,7 +525,7 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg if(Msg->Type >= ciWM_NumWidgetTypes) { _SysDebug("Widget_NewWidget - Bad widget type %i", Msg->Type); - return ; + return 1; } // Create @@ -490,85 +533,113 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg if(!parent) { _SysDebug("Widget_NewWidget - Bad parent ID %i", Msg->Parent); - return ; + return 1; } Widget_int_Create(Info, parent, Msg->NewID, Msg->Type, Msg->Flags); Widget_UpdateMinDims(parent); + return 0; } -void Widget_NewWidgetSubwin(tWidgetWin *Info, size_t Len, const tWidgetMsg_CreateSubWin *Msg) +int Widget_IPC_NewWidgetSubwin(tWindow *Win, size_t Len, const void *Data) { - const int max_debugname_len = Len - sizeof(tWidgetMsg_CreateSubWin); + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_CreateSubWin *Msg = Data; + const int max_debugname_len = Len - sizeof(*Msg); tElement *parent, *new; // Sanity check if( Len < sizeof(*Msg) ) - return ; + return -1; if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len ) - return ; + return -1; + + _SysDebug("Widget_NewWidgetSubwin(%i %i Type %i Flags 0x%x Subwin %i)", + Msg->Parent, Msg->NewID, Msg->Type, Msg->Flags, Msg->WindowHandle); parent = Widget_GetElementById(Info, Msg->Parent); - if(!parent) return; - if( Widget_GetElementById(Info, Msg->NewID) ) return ; + if(!parent) return 1; + if( Widget_GetElementById(Info, Msg->NewID) ) return 1; new = Widget_int_Create(Info, parent, Msg->NewID, Msg->Type, Msg->Flags); new->Data = WM_GetWindowByID(parent->Window, Msg->WindowHandle); Widget_UpdateMinDims(parent); + return 0; } -void Widget_SetFocus(tWidgetWin *Info, tElement *Ele) +// TODO: Widget_IPC_Delete + +int Widget_IPC_SetFocus(tWindow *Win, size_t Len, const void *Data) { - // TODO: Callbacks + tWidgetWin *info = Win->RendererInfo; + tElement *ele; + const tWidgetIPC_SetFocus *msg = Data; + if(Len < sizeof(*msg)) return -1; - Info->FocusedElement = Ele; + _SysDebug("Widget_SetFocus(%i)", msg->WidgetID); + + ele = Widget_GetElementById(info, msg->WidgetID); + Widget_SetFocus(info, ele); + return 0; } -void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg) +int Widget_IPC_SetFlags(tWindow *Win, size_t Len, const void *Data) { + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_SetFlags *Msg = Data; tElement *ele; if( Len < sizeof(*Msg) ) - return ; + return -1; _SysDebug("Widget_SetFlags: (%i 0x%x 0x%x)", Msg->WidgetID, Msg->Value, Msg->Mask); ele = Widget_GetElementById(Info, Msg->WidgetID); - if(!ele) return; + if(!ele) return 1; ele->Flags &= ~Msg->Mask; ele->Flags |= Msg->Value & Msg->Mask; + + return 0; } -void Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg) +int Widget_IPC_SetSize(tWindow *Win, size_t Len, const void *Data) { + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_SetSize *Msg = Data; tElement *ele; if( Len < sizeof(*Msg) ) - return ; + return -1; + + _SysDebug("Widget_SetSize(%i, %i)", Msg->WidgetID, Msg->Value); ele = Widget_GetElementById(Info, Msg->WidgetID); - if(!ele) return ; + if(!ele) return 1; ele->FixedWith = Msg->Value; + return 0; } -void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) +int Widget_IPC_SetText(tWindow *Win, size_t Len, const void *Data) { + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_SetText *Msg = Data; tElement *ele; if( Len < sizeof(*Msg) + 1 ) - return ; + return -1; if( Msg->Text[Len - sizeof(*Msg) - 1] != '\0' ) - return ; + return -1; + _SysDebug("Widget_SetText(%i, '%.30s')", Msg->WidgetID, Msg->Text); ele = Widget_GetElementById(Info, Msg->WidgetID); - if(!ele) return ; - + if(!ele) return 1; if( gaWM_WidgetTypes[ele->Type]->UpdateText ) { + _SysDebug(" - calling handler"); gaWM_WidgetTypes[ele->Type]->UpdateText( ele, Msg->Text ); } // else @@ -576,22 +647,23 @@ void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) // if(ele->Text) free(ele->Text); // ele->Text = strdup(Msg->Text); // } + return 0; } -int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) +int Widget_IPC_GetText(tWindow *Win, size_t Len, const void *Data) { + tWidgetWin *Info = Win->RendererInfo; + const tWidgetIPC_SetText *Msg = Data; if( Len < sizeof(*Msg) ) - return 0; - if( Len > sizeof(*Msg) ) - return 1; // Pass to user + return -1; const char *text = NULL; tElement *ele = Widget_GetElementById(Info, Msg->WidgetID); if(ele) text = ele->Text; - char buf[sizeof(tWidgetMsg_SetText) + strlen(text?text:"") + 1]; - tWidgetMsg_SetText *omsg = (void*)buf; + char buf[sizeof(tWidgetIPC_SetText) + strlen(text?text:"") + 1]; + tWidgetIPC_SetText *omsg = (void*)buf; if( text ) { omsg->WidgetID = Msg->WidgetID; @@ -602,7 +674,7 @@ int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) omsg->Text[0] = 0; } - WM_SendMessage(Info->RootElement.Window, Info->RootElement.Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf); + WM_SendIPCReply(Win, IPC_WIDGET_GETTEXT, sizeof(buf), buf); return 0; } @@ -711,46 +783,6 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void } return 0; } - // New Widget - case MSG_WIDGET_CREATE: - Widget_NewWidget(info, Len, Data); - return 0; - case MSG_WIDGET_CREATESUBWIN: - Widget_NewWidgetSubwin(info, Len, Data); - return 0; - - // Delete a widget - case MSG_WIDGET_DELETE: - _SysDebug("TODO: Implement MSG_WIDGET_DELETE"); - return 0; - - // Set focused widget - case MSG_WIDGET_SETFOCUS: { - tElement *ele; - const tWidgetMsg_SetFocus *msg = Data; - if(Len < sizeof(*msg)) return -1; - - ele = Widget_GetElementById(info, msg->WidgetID); - Widget_SetFocus(info, ele); - return 0; } - - // Set Flags - case MSG_WIDGET_SETFLAGS: - Widget_SetFlags(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; - case MSG_WIDGET_GETTEXT: - return Widget_GetText(info, Len, Data); - // default: return 1; // Unhandled, pass to user @@ -761,6 +793,7 @@ void Widget_Fire(tElement *Element) { tWidgetMsg_Fire msg; msg.WidgetID = Element->ID; + _SysDebug("Widget_Fire: Fire on %p %i", Element->Window, Element->ID); WM_SendMessage(Element->Window, Element->Window, MSG_WIDGET_FIRE, sizeof(msg), &msg); }