From 9bf83176e50b61185f11e0742f89464d870381df Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 28 Nov 2010 15:41:54 +0800 Subject: [PATCH] GUI Fixes - bugfixing behavior of size/position determining code - Improved layout of interface --- .../Applications/axwin2_src/WM/interface.c | 72 ++++++++------ .../Applications/axwin2_src/WM/video_text.c | 31 +++++- Usermode/Applications/axwin2_src/WM/wm.c | 95 ++++++++++++++----- Usermode/Applications/axwin2_src/WM/wm.h | 9 +- 4 files changed, 148 insertions(+), 59 deletions(-) diff --git a/Usermode/Applications/axwin2_src/WM/interface.c b/Usermode/Applications/axwin2_src/WM/interface.c index af02429a..d4ad424f 100644 --- a/Usermode/Applications/axwin2_src/WM/interface.c +++ b/Usermode/Applications/axwin2_src/WM/interface.c @@ -9,7 +9,10 @@ // === GLOBALS == int giInterface_Width = 0; + int giInterface_HeaderBarSize = 20; + int giInterface_TabBarSize = 20; tElement *gpInterface_Sidebar; +tElement *gpInterface_ProgramList; tElement *gpInterface_MainArea; tElement *gpInterface_HeaderBar; tElement *gpInterface_TabBar; @@ -21,9 +24,9 @@ tElement *gpInterface_TabContent; */ void Interface_Init(void) { - tElement *area; tElement *btn, *text; - + tElement *ele; + // Calculate sizes giInterface_Width = giScreenWidth/16; @@ -31,39 +34,48 @@ void Interface_Init(void) WM_SetFlags(NULL, 0); // -- Create Sidebar -- - gpInterface_Sidebar = WM_CreateElement(NULL, ELETYPE_TOOLBAR, ELEFLAG_VERTICAL); + gpInterface_Sidebar = WM_CreateElement(NULL, ELETYPE_TOOLBAR, ELEFLAG_VERTICAL, "Sidebar"); WM_SetSize( gpInterface_Sidebar, giInterface_Width ); - // --- Top segment --- - area = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL); - // ---- Menu Button ---- - btn = WM_CreateElement(area, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH); - WM_SetSize(btn, giInterface_Width); - //text = WM_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE); - //WM_SetText(text, "asset://LogoSmall.sif"); - text = WM_CreateElement(btn, ELETYPE_TEXT, 0); + // > System Menu Button + btn = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, "SystemMenu"); + WM_SetSize(btn, giInterface_Width-4); + // TODO: Once image loading is implemented, switch to a logo + #if 0 + text = WM_CreateElement(btn, ELETYPE_IMAGE, ELEFLAG_SCALE); + WM_SetText(text, "asset://LogoSmall.sif"); + #else + text = WM_CreateElement(btn, ELETYPE_TEXT, 0, NULL); WM_SetText(text, "Acess"); + #endif + // > Plain
style spacer + ele = WM_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Top"); + WM_SetSize(ele, 4); + // > Application List + gpInterface_ProgramList = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL, "ProgramList"); + // > Plain
style spacer + ele = WM_CreateElement(gpInterface_Sidebar, ELETYPE_SPACER, ELEFLAG_NOSTRETCH, "SideBar Spacer Bottom"); + WM_SetSize(ele, 4); + // > Version/Time + text = WM_CreateElement(gpInterface_Sidebar, ELETYPE_TEXT, ELEFLAG_NOSTRETCH, "Version String"); + WM_SetSize(text, 20); + WM_SetText(text, "2.0"); - // ---- Plain
style spacer ---- - WM_CreateElement(area, ELETYPE_SPACER, 0); - - // Open Windows Go Here - - // --- Bottom Segment --- - area = WM_CreateElement(gpInterface_Sidebar, ELETYPE_BOX, ELEFLAG_VERTICAL|ELEFLAG_ALIGN_END); - - // ---- Plain
style spacer ---- - WM_CreateElement(area, ELETYPE_SPACER, 0); - - // ---- Version String ---- - text = WM_CreateElement(area, ELETYPE_TEXT, ELEFLAG_WRAP); - WM_SetText(text, "AxWin 1.0"); - + // -- // -- Create Main Area and regions within -- - gpInterface_MainArea = WM_CreateElement(NULL, ELETYPE_BOX, ELEFLAG_VERTICAL); - gpInterface_HeaderBar = WM_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0); - gpInterface_TabBar = WM_CreateElement(gpInterface_MainArea, ELETYPE_TABBAR, 0); - gpInterface_TabContent = WM_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0); + // -- + // > Righthand Area + gpInterface_MainArea = WM_CreateElement(NULL, ELETYPE_BOX, ELEFLAG_VERTICAL, "MainArea"); + // > Header Bar (Title) + gpInterface_HeaderBar = WM_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0, "HeaderBar"); + WM_SetSize(gpInterface_HeaderBar, giInterface_HeaderBarSize); + text = WM_CreateElement(gpInterface_HeaderBar, ELETYPE_TEXT, 0, NULL); + WM_SetText(text, "Acess2 GUI - By thePowersGang (John Hodge)"); + // > Tab Bar (Current windows) + gpInterface_TabBar = WM_CreateElement(gpInterface_MainArea, ELETYPE_TABBAR, 0, "TabBar"); + WM_SetSize(gpInterface_TabBar, giInterface_TabBarSize); + // > Application Space + gpInterface_TabContent = WM_CreateElement(gpInterface_MainArea, ELETYPE_BOX, 0, "TabContent"); } void Interface_Update(void) diff --git a/Usermode/Applications/axwin2_src/WM/video_text.c b/Usermode/Applications/axwin2_src/WM/video_text.c index 5dc462f2..7cf10493 100644 --- a/Usermode/Applications/axwin2_src/WM/video_text.c +++ b/Usermode/Applications/axwin2_src/WM/video_text.c @@ -46,7 +46,7 @@ struct sFont { tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint); void _RenderGlyph(short X, short Y, tGlyph *Glyph, uint32_t Color); tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint); - int ReadUTF8(char *Input, uint32_t *Output); + int ReadUTF8(const char *Input, uint32_t *Output); // === GLOBALS === tFont gSystemFont = { @@ -96,6 +96,27 @@ int Video_DrawText(short X, short Y, short W, short H, tFont *Font, uint32_t Col return xOfs; } +void Video_GetTextDims(tFont *Font, const char *Text, int *W, int *H) +{ + int w=0, h=0; + uint32_t ch; + tGlyph *glyph; + if( !Font ) Font = &gSystemFont; + + while( *Text ) + { + Text += ReadUTF8(Text, &ch); + glyph = _GetGlyph(Font, ch); + if( !glyph ) continue; + + w += glyph->Width; + if( h < glyph->Height ) h = glyph->Height; + } + + if(W) *W = w; + if(H) *H = h; +} + tGlyph *_GetGlyph(tFont *Font, uint32_t Codepoint) { tGlyph *next = NULL, *prev = NULL; @@ -245,6 +266,10 @@ tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint) _SysDebug(" index = %i", index); ret = malloc( sizeof(tGlyph) + FONT_WIDTH*FONT_HEIGHT ); + if( !ret ) { + _SysDebug("ERROR: malloc(%i) failed", sizeof(tGlyph) + FONT_WIDTH*FONT_HEIGHT); + return NULL; + } ret->Codepoint = Codepoint; @@ -279,9 +304,9 @@ tGlyph *_SystemFont_CacheGlyph(tFont *Font, uint32_t Codepoint) * \fn int ReadUTF8(char *Input, uint32_t *Val) * \brief Read a UTF-8 character from a string */ -int ReadUTF8(char *Input, uint32_t *Val) +int ReadUTF8(const char *Input, uint32_t *Val) { - uint8_t *str = (uint8_t *)Input; + const uint8_t *str = (const uint8_t *)Input; *Val = 0xFFFD; // Assume invalid character // ASCII diff --git a/Usermode/Applications/axwin2_src/WM/wm.c b/Usermode/Applications/axwin2_src/WM/wm.c index 9bd5aa43..ad441b39 100644 --- a/Usermode/Applications/axwin2_src/WM/wm.c +++ b/Usermode/Applications/axwin2_src/WM/wm.c @@ -11,9 +11,10 @@ // === IMPORTS === extern void Decorator_RenderWidget(tElement *Element); +extern void Video_GetTextDims(tFont *Font, const char *Text, int *W, int *H); // === PROTOTYPES === -tElement *WM_CreateElement(tElement *Parent, int Type, int Flags); +tElement *WM_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName); void WM_UpdateMinDims(tElement *Element); void WM_SetFlags(tElement *Element, int Flags); void WM_SetSize(tElement *Element, int Size); @@ -24,7 +25,9 @@ void WM_RenderWidget(tElement *Element); void WM_Update(void); // === GLOBALS === -tElement gWM_RootElement; +tElement gWM_RootElement = { + DebugName: "ROOT" +}; struct { void (*Init)(tElement *This); void (*UpdateFlags)(tElement *This); @@ -37,21 +40,24 @@ struct { // === CODE === // --- Widget Creation and Control --- -tElement *WM_CreateElement(tElement *Parent, int Type, int Flags) +tElement *WM_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName) { tElement *ret; + const char *dbgName = DebugName ? DebugName : ""; - ret = calloc(sizeof(tElement), 1); + ret = calloc(sizeof(tElement)+strlen(dbgName)+1, 1); if(!ret) return NULL; // Prepare ret->Type = Type; + strcpy(ret->DebugName, dbgName); if(Parent == NULL) Parent = &gWM_RootElement; ret->Parent = Parent; ret->Flags = Flags; // Append to parent's list - ret->NextSibling = Parent->LastChild; + if(Parent->LastChild) + Parent->LastChild->NextSibling = ret; Parent->LastChild = ret; if(!Parent->FirstChild) Parent->FirstChild = ret; @@ -123,6 +129,21 @@ void WM_SetText(tElement *Element, char *Text) Element->MinCross = ((tImage*)Element->Data)->Height; } break; + + case ELETYPE_TEXT: + { + int w=0, h=0; + Video_GetTextDims(NULL, Element->Text, &w, &h); + if(Element->Parent && Element->Parent->Flags & ELEFLAG_VERTICAL) { + Element->MinCross = w; + Element->MinWith = h; + } + else { + Element->MinWith = w; + Element->MinCross = h; + } + } + break; } return ; @@ -150,12 +171,13 @@ void WM_UpdateDimensions(tElement *Element, int Pass) int fixedSize = 0; int fullCross, dynWith; - _SysDebug("%p -> Flags = 0x%x", Element, Element->Flags); - _SysDebug("%p ->CachedH = %i, ->PaddingT = %i, ->PaddingB = %i", - Element, Element->CachedH, Element->PaddingT, Element->PaddingB + _SysDebug("WM_UpdateDimensions %p'%s'", Element, Element->DebugName); + _SysDebug(" -> Flags = 0x%x", Element->Flags); + _SysDebug(" ->CachedH = %i, ->PaddingT = %i, ->PaddingB = %i", + Element->CachedH, Element->PaddingT, Element->PaddingB ); - _SysDebug("%p ->CachedW = %i, ->PaddingL = %i, ->PaddingR = %i", - Element, Element->CachedW, Element->PaddingL, Element->PaddingR + _SysDebug(" ->CachedW = %i, ->PaddingL = %i, ->PaddingR = %i", + Element->CachedW, Element->PaddingL, Element->PaddingR ); // Pass 1 @@ -164,7 +186,7 @@ void WM_UpdateDimensions(tElement *Element, int Pass) if( child->Flags & ELEFLAG_ABSOLUTEPOS ) continue ; - _SysDebug("%p,%p ->FixedWith = %i", Element, child, child->FixedWith); + _SysDebug(" > %p'%s' ->FixedWith = %i", child, child->DebugName, child->FixedWith); if( child->FixedWith ) { nFixed ++; @@ -178,7 +200,7 @@ void WM_UpdateDimensions(tElement *Element, int Pass) nChildren ++; } - _SysDebug("%p - nChildren = %i, nFixed = %i", Element, nChildren, nFixed); + _SysDebug(" - nChildren = %i, nFixed = %i", Element, nChildren, nFixed); if( nChildren > nFixed ) { if( Element->Flags & ELEFLAG_VERTICAL ) dynWith = Element->CachedH - Element->PaddingT @@ -189,7 +211,7 @@ void WM_UpdateDimensions(tElement *Element, int Pass) dynWith -= fixedSize; if( dynWith < 0 ) return ; dynWith /= nChildren - nFixed; - _SysDebug("%p - dynWith = %i", Element, dynWith); + _SysDebug(" - dynWith = %i", dynWith); } if( Element->Flags & ELEFLAG_VERTICAL ) @@ -197,14 +219,14 @@ void WM_UpdateDimensions(tElement *Element, int Pass) else fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB; - _SysDebug("%p - fullCross = %i", Element, fullCross); + _SysDebug(" - fullCross = %i", Element, fullCross); // Pass 2 - Set sizes and recurse for( child = Element->FirstChild; child; child = child->NextSibling ) { int cross, with; - _SysDebug("%p,%p ->MinCross = %i", Element, child, child->MinCross); + _SysDebug(" > %p'%s' ->MinCross = %i", child, child->DebugName, child->MinCross); // --- Cross Size --- @@ -216,7 +238,7 @@ void WM_UpdateDimensions(tElement *Element, int Pass) cross = child->MinCross; else cross = fullCross; - _SysDebug("%p,%p - cross = %i", Element, child, cross); + _SysDebug(" > %p'%s' - cross = %i", child, child->DebugName, cross); if( Element->Flags & ELEFLAG_VERTICAL ) child->CachedW = cross; else @@ -229,7 +251,7 @@ void WM_UpdateDimensions(tElement *Element, int Pass) with = child->MinWith; else with = dynWith; - _SysDebug("%p,%p - with = %i", Element, child, with); + _SysDebug(" > %p'%s' - with = %i", child, child->DebugName, with); if( Element->Flags & ELEFLAG_VERTICAL ) child->CachedH = with; else @@ -237,6 +259,8 @@ void WM_UpdateDimensions(tElement *Element, int Pass) WM_UpdateDimensions(child, 0); } + + _SysDebug("%p'%s' Done", Element, Element->DebugName); } /** @@ -248,36 +272,56 @@ void WM_UpdatePosition(tElement *Element) { tElement *child; int x, y; + static int depth = 0; + char indent[depth+1]; if( Element->Flags & ELEFLAG_NORENDER ) return ; - _SysDebug("Element=%p{PaddingL:%i, PaddingT:%i}", - Element, Element->PaddingL, Element->PaddingT); + memset(indent, ' ', depth); + indent[depth] = '\0'; + depth ++; + + _SysDebug("%sWM_UpdatePosition %p'%s'{PaddingL:%i, PaddingT:%i}", + indent, Element, Element->DebugName, Element->PaddingL, Element->PaddingT); // Initialise x = Element->CachedX + Element->PaddingL; y = Element->CachedY + Element->PaddingT; + _SysDebug("%s- Alignment = %s", indent, + (Element->Flags & ELEFLAG_VERTICAL) ? "vertical" : "horizontal"); + // Update each child for(child = Element->FirstChild; child; child = child->NextSibling) { + _SysDebug("%s- x = %i, y = %i", indent, x, y); child->CachedX = x; child->CachedY = y; // Set Alignment if( Element->Flags & ELEFLAG_ALIGN_CENTER ) { - if(Element->Flags & ELEFLAG_VERTICAL ) + _SysDebug("%sChild being aligned to center", indent); + if(Element->Flags & ELEFLAG_VERTICAL) child->CachedX += Element->CachedW/2 - child->CachedW/2; else child->CachedY += Element->CachedH/2 - child->CachedH/2; } - else if( Element->Flags & ELEFLAG_ALIGN_END ) { + else if( Element->Flags & ELEFLAG_ALIGN_END) { + _SysDebug("%sChild being aligned to end", indent); if(Element->Flags & ELEFLAG_VERTICAL ) - child->CachedX += Element->CachedW - child->CachedW; + child->CachedX += Element->CachedW + - Element->PaddingL - Element->PaddingR + - child->CachedW; else - child->CachedY += Element->CachedH - child->CachedH; + child->CachedY += Element->CachedH + - Element->PaddingT + - Element->PaddingB + - child->CachedH; } + _SysDebug("%s> %p'%s' at (%i,%i)", indent, child, child->DebugName, + child->CachedX, child->CachedY); + // Update child's children positions WM_UpdatePosition(child); @@ -290,9 +334,10 @@ void WM_UpdatePosition(tElement *Element) } } - _SysDebug("Element %p (%i,%i)", - Element, Element->CachedX, Element->CachedY + _SysDebug("%sElement %p'%s' (%i,%i)", + indent, Element, Element->DebugName, Element->CachedX, Element->CachedY ); + depth --; } /** diff --git a/Usermode/Applications/axwin2_src/WM/wm.h b/Usermode/Applications/axwin2_src/WM/wm.h index 96d488d5..0f5edf2f 100644 --- a/Usermode/Applications/axwin2_src/WM/wm.h +++ b/Usermode/Applications/axwin2_src/WM/wm.h @@ -31,6 +31,8 @@ typedef struct sElement // -- Render Cache short CachedX, CachedY; short CachedW, CachedH; + + char DebugName[]; } tElement; typedef struct sTab @@ -100,6 +102,11 @@ enum eElementFlags */ ELEFLAG_NOEXPAND = 0x040, + /** + * \brief With (length) size action + * If this flag is set, the element will only be as large as + * is required + */ ELEFLAG_NOSTRETCH = 0x080, /** @@ -135,7 +142,7 @@ enum eElementTypes /** * \brief Create a new element as a child of \a Parent */ -extern tElement *WM_CreateElement(tElement *Parent, int Type, int Flags); +extern tElement *WM_CreateElement(tElement *Parent, int Type, int Flags, const char *DebugName); extern void WM_SetFlags(tElement *Element, int Flags); extern void WM_SetSize(tElement *Element, int Size); extern void WM_SetText(tElement *Element, char *Text); -- 2.20.1