From dd2491a82880ed9b01b5d66b1814d271921797a4 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 18 Nov 2011 15:39:49 +0800 Subject: [PATCH] Usermode/AxWin3 - Bugfixing rendering/layout issues --- .../Applications/axwin3_src/Interface/main.c | 10 ++- .../axwin3_src/WM/renderers/widget.c | 77 ++++++++++++++----- .../axwin3_src/WM/renderers/widget/button.c | 1 + .../axwin3_src/WM/renderers/widget/common.h | 7 +- .../axwin3_src/WM/renderers/widget/disptext.c | 1 + .../axwin3_src/WM/renderers/widget/image.c | 1 + .../WM/renderers/widget/textinput.c | 7 +- .../WM/renderers/widget/widget_decorator.c | 11 --- 8 files changed, 79 insertions(+), 36 deletions(-) diff --git a/Usermode/Applications/axwin3_src/Interface/main.c b/Usermode/Applications/axwin3_src/Interface/main.c index b7c06ca8..a51984f8 100644 --- a/Usermode/Applications/axwin3_src/Interface/main.c +++ b/Usermode/Applications/axwin3_src/Interface/main.c @@ -13,7 +13,7 @@ #define SIDEBAR_WIDTH 40 #define RUN_WIDTH 200 -#define RUN_HEIGHT 70 +#define RUN_HEIGHT 60 // === PROTOTYPES === void create_sidebar(void); @@ -134,8 +134,10 @@ tAxWin3_Widget *make_textbutton(tAxWin3_Widget *Parent, const char *Label, tAxWi tAxWin3_Widget *ret, *txt; ret = AxWin3_Widget_AddWidget(Parent, ELETYPE_BUTTON, ELEFLAG_ALIGN_CENTER, "_btn"); AxWin3_Widget_SetFireHandler(ret, handler); + AxWin3_Widget_AddWidget(ret, ELETYPE_NONE, 0, "_spacer1"); txt = AxWin3_Widget_AddWidget(ret, ELETYPE_TEXT, ELEFLAG_NOSTRETCH|ELEFLAG_NOEXPAND, "_txt"); AxWin3_Widget_SetText(txt, Label); + AxWin3_Widget_AddWidget(ret, ELETYPE_NONE, 0, "_spacer2"); return ret; } @@ -145,14 +147,14 @@ void create_run_dialog(void) gRunDialog = AxWin3_Widget_CreateWindow(NULL, RUN_WIDTH, RUN_HEIGHT, ELEFLAG_VERTICAL); AxWin3_SetWindowTitle(gRunDialog, "Run Program..."); - AxWin3_MoveWindow(gRunDialog, giScreenWidth/2-RUN_WIDTH/2, giScreenHeight/2-RUN_HEIGHT/2); + root = AxWin3_Widget_GetRoot(gRunDialog); - gRunInput = AxWin3_Widget_AddWidget(root, ELETYPE_TEXTINPUT, 0, "Input"); + gRunInput = AxWin3_Widget_AddWidget(root, ELETYPE_TEXTINPUT, ELEFLAG_NOSTRETCH, "Input"); AxWin3_Widget_SetFireHandler(gRunInput, run_dorun); - box = AxWin3_Widget_AddWidget(root, ELETYPE_BOX, ELEFLAG_ALIGN_CENTER|ELEFLAG_NOSTRETCH, "Button Area"); + box = AxWin3_Widget_AddWidget(root, ELETYPE_BOX, ELEFLAG_ALIGN_CENTER, "Button Area"); make_textbutton(box, "Ok", run_dorun); make_textbutton(box, "Cancel", run_close); } diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget.c b/Usermode/Applications/axwin3_src/WM/renderers/widget.c index d77a67a9..68f81cbf 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget.c @@ -14,6 +14,7 @@ #include "widget/common.h" #define DEFAULT_ELETABLE_SIZE 64 +#define BORDER_EVERYTHING 1 // === PROTOTYPES === int Renderer_Widget_Init(void); @@ -42,12 +43,21 @@ tWMRenderer gRenderer_Widget = { // --- Element callbacks tWidgetDef *gaWM_WidgetTypes[NUM_ELETYPES]; 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 ++) + { + if(gaWM_WidgetTypes[i] != NULL) continue; + + gaWM_WidgetTypes[i] = &gWidget_NullWidgetDef; + } + return 0; } @@ -60,7 +70,8 @@ void Widget_int_SetTypeDef(int Type, tWidgetDef *Ptr) return ; } - if( gaWM_WidgetTypes[Type] ) { + if( gaWM_WidgetTypes[Type] && gaWM_WidgetTypes[Type] != &gWidget_NullWidgetDef ) + { _SysDebug("ERROR - Widget ID %i redefined by %p", Type, __builtin_return_address(0) ); @@ -118,10 +129,16 @@ void Widget_RenderWidget(tWindow *Window, tElement *Element) if( Element->Flags & ELEFLAG_NORENDER ) return ; if( Element->Flags & ELEFLAG_INVISIBLE ) return ; - if( Element->Type < ciWM_NumWidgetTypes - && gaWM_WidgetTypes[Element->Type] - && gaWM_WidgetTypes[Element->Type]->Render - ) + #if BORDER_EVERYTHING + WM_Render_DrawRect( + Window, + Element->CachedX, Element->CachedY, + Element->CachedW, Element->CachedH, + 0 + ); + #endif + + if(gaWM_WidgetTypes[Element->Type]->Render) { gaWM_WidgetTypes[Element->Type]->Render(Window, Element); } @@ -143,7 +160,11 @@ void Widget_UpdateDimensions(tElement *Element) int nFixed = 0; int maxCross = 0; int fixedSize = 0; - int fullCross, dynWith; + int fullCross, dynWith = 0; + + // Check if this element can have children + if( (gaWM_WidgetTypes[Element->Type]->Flags & WIDGETTYPE_FLAG_NOCHILDREN) ) + return ; // Pass 1 // - Get the fixed and minimum sizes of the element @@ -181,18 +202,28 @@ void Widget_UpdateDimensions(tElement *Element) else dynWith = Element->CachedW - Element->PaddingL - Element->PaddingR; dynWith -= fixedSize; + dynWith -= Element->GapSize * (nChildren-1); if( dynWith < 0 ) return ; dynWith /= nChildren - nFixed; } + else { + dynWith = 0; + } -// _SysDebug("%i - nChildren = %i, nFixed = %i, dynWith = %i, fixedSize = %i", -// Element->ID, nChildren, nFixed, dynWith, fixedSize); - // Get the cross size if( Element->Flags & ELEFLAG_VERTICAL ) fullCross = Element->CachedW - Element->PaddingL - Element->PaddingR; 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 + ); // Pass 2 - Set sizes and recurse for( child = Element->FirstChild; child; child = child->NextSibling ) @@ -201,6 +232,8 @@ void Widget_UpdateDimensions(tElement *Element) // Ignore elements that will not be rendered if( child->Flags & ELEFLAG_NORENDER ) continue ; + // Don't resize floating elements + if( child->Flags & ELEFLAG_ABSOLUTEPOS ) continue ; // --- Cross Size --- // TODO: Expand to fill? @@ -223,7 +256,9 @@ void Widget_UpdateDimensions(tElement *Element) if(with < child->MinWith) with = child->MinWith; if(cross < child->MinCross) cross = child->MinCross; - + + _SysDebug("with = %i", with); + // Update the dimensions if they have changed if( Element->Flags & ELEFLAG_VERTICAL ) { // If no change, don't recurse @@ -259,6 +294,10 @@ void Widget_UpdatePosition(tElement *Element) if( Element->Flags & ELEFLAG_NORENDER ) return ; + // Check if this element can have children + if( (gaWM_WidgetTypes[Element->Type]->Flags & WIDGETTYPE_FLAG_NOCHILDREN) ) + return ; + // _SysDebug("Widget_UpdatePosition: (Element=%p(%i Type=%i Flags=0x%x))", // Element, Element->ID, Element->Type, Element->Flags); @@ -275,7 +314,7 @@ void Widget_UpdatePosition(tElement *Element) newX = x; newY = y; - // Handle alignment + // Handle alignment (across parent) if( Element->Flags & ELEFLAG_ALIGN_CENTER ) { if(Element->Flags & ELEFLAG_VERTICAL) newX += Element->CachedW/2 - child->CachedW/2; @@ -418,6 +457,12 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg _SysDebug("Widget_NewWidget (%i %i Type %i Flags 0x%x)", Msg->Parent, Msg->NewID, Msg->Type, Msg->Flags); + if(Msg->Type >= ciWM_NumWidgetTypes) + { + _SysDebug("Widget_NewWidget - Bad widget type %i", Msg->Type); + return ; + } + // Create parent = Widget_GetElementById(Info, Msg->Parent); if(!parent) @@ -443,7 +488,7 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg new->PaddingR = 2; new->CachedX = -1; - if( new->Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[new->Type] && gaWM_WidgetTypes[new->Type]->Init ) + if( gaWM_WidgetTypes[new->Type]->Init ) gaWM_WidgetTypes[new->Type]->Init(new); // Add to parent's list @@ -508,9 +553,7 @@ void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) if(!ele) return ; - if( ele->Type < ciWM_NumWidgetTypes - && gaWM_WidgetTypes[ele->Type] - && gaWM_WidgetTypes[ele->Type]->UpdateText ) + if( gaWM_WidgetTypes[ele->Type]->UpdateText ) { gaWM_WidgetTypes[ele->Type]->UpdateText( ele, Msg->Text ); } @@ -558,9 +601,7 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void // Send event to all elements from `ele` upwards for( ; ele; ele = ele->Parent ) { - if(ele->Type < ciWM_NumWidgetTypes - && gaWM_WidgetTypes[ele->Type] - && gaWM_WidgetTypes[ele->Type]->MouseButton) + if(gaWM_WidgetTypes[ele->Type]->MouseButton) { rv = gaWM_WidgetTypes[ele->Type]->MouseButton( ele, diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/button.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/button.c index e4b252c3..3de65f0e 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget/button.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/button.c @@ -36,6 +36,7 @@ int Widget_Button_MouseButton(tElement *Element, int X, int Y, int Button, int b } DEFWIDGETTYPE(ELETYPE_BUTTON, + 0, .Render = Widget_Button_Render, .MouseButton = Widget_Button_MouseButton ) diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h b/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h index b4913334..172c9071 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h @@ -12,8 +12,11 @@ typedef struct sWidgetDef tWidgetDef; +#define WIDGETTYPE_FLAG_NOCHILDREN 0x001 + struct sWidgetDef { + int Flags; void (*Init)(tElement *Ele); void (*Delete)(tElement *Ele); @@ -42,8 +45,8 @@ extern void Widget_int_SetTypeDef(int Type, tWidgetDef *Def); extern void Widget_UpdateMinDims(tElement *Element); extern void Widget_Fire(tElement *Element); -#define DEFWIDGETTYPE(_type, _attribs...) \ -tWidgetDef _widget_typedef_##_type = {_attribs};\ +#define DEFWIDGETTYPE(_type, _flags, _attribs...) \ +tWidgetDef _widget_typedef_##_type = {.Flags=(_flags),_attribs};\ void _widget_set_##_type(void) __attribute__((constructor));\ void _widget_set_##_type(void) { Widget_int_SetTypeDef(_type, &_widget_typedef_##_type);} diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/disptext.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/disptext.c index 4ea48331..590945f5 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget/disptext.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/disptext.c @@ -46,6 +46,7 @@ void Widget_DispText_UpdateText(tElement *Element, const char *Text) } DEFWIDGETTYPE(ELETYPE_TEXT, + WIDGETTYPE_FLAG_NOCHILDREN, .Render = Widget_DispText_Render, .UpdateText = Widget_DispText_UpdateText ); diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/image.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/image.c index f1f3155c..8a357642 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget/image.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/image.c @@ -47,6 +47,7 @@ void Widget_Image_UpdateText(tElement *Element, const char *Text) } DEFWIDGETTYPE(ELETYPE_IMAGE, + WIDGETTYPE_FLAG_NOCHILDREN, .Render = Widget_Image_Render, .UpdateText = Widget_Image_UpdateText ); diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c index c2eea82c..b2b68e04 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c @@ -38,16 +38,21 @@ void Widget_TextInput_Init(tElement *Element) // TODO: Select font correctly WM_Render_GetTextDims(NULL, "jJ", NULL, &h); - + + h += 2+2; // Border padding + if( Element->Parent && (Element->Parent->Flags & ELEFLAG_VERTICAL) ) Element->MinWith = h; else Element->MinCross = h; + _SysDebug("h = %i", h); + // No need to explicitly update parent min dims, as the AddElement routine does that } DEFWIDGETTYPE(ELETYPE_TEXTINPUT, + WIDGETTYPE_FLAG_NOCHILDREN, .Render = Widget_TextInput_Render, .Init = Widget_TextInput_Init ); diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/widget_decorator.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/widget_decorator.c index 442e9fcc..64671a28 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget/widget_decorator.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/widget_decorator.c @@ -9,8 +9,6 @@ #include #include -#define BORDER_EVERYTHING 1 - #include "./colours.h" // === CODE === @@ -22,15 +20,6 @@ void Widget_Decorator_RenderWidget(tWindow *Window, tElement *Element) // Element->CachedW, Element->CachedH // ); - #if BORDER_EVERYTHING - WM_Render_DrawRect( - Window, - Element->CachedX, Element->CachedY, - Element->CachedW, Element->CachedH, - 0 - ); - #endif - switch(Element->Type) { case ELETYPE_NONE: -- 2.20.1