X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Faxwin3_src%2FWM%2Frenderers%2Fwidget.c;h=46b3198ae030be49afa9a7817d0db49a185fc6c8;hb=fb3abbad5dfd71ea2b190d0b33d9c57e879fb15a;hp=68f81cbfd42371ad5ecb22da502dc907ad791a28;hpb=dd2491a82880ed9b01b5d66b1814d271921797a4;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 68f81cbf..46b3198a 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget.c @@ -14,7 +14,7 @@ #include "widget/common.h" #define DEFAULT_ELETABLE_SIZE 64 -#define BORDER_EVERYTHING 1 +#define BORDER_EVERYTHING 0 // === PROTOTYPES === int Renderer_Widget_Init(void); @@ -79,7 +79,6 @@ void Widget_int_SetTypeDef(int Type, tWidgetDef *Ptr) } gaWM_WidgetTypes[Type] = Ptr; - _SysDebug("Registered type %i to %p", Type, Ptr); } tWindow *Renderer_Widget_Create(int Flags) @@ -98,6 +97,7 @@ tWindow *Renderer_Widget_Create(int Flags) info = ret->RendererInfo; info->TableSize = eletable_size; + info->FocusedElement = &info->RootElement; info->RootElement.Window = ret; info->RootElement.ID = -1; info->RootElement.BackgroundColour = 0xCCCCCC; @@ -113,7 +113,7 @@ tWindow *Renderer_Widget_Create(int Flags) void Renderer_Widget_Redraw(tWindow *Window) { tWidgetWin *info = Window->RendererInfo; - WM_Render_FillRect(Window, 0, 0, 0xFFF, 0xFFF, info->RootElement.BackgroundColour); + WM_Render_FillRect(Window, 0, 0, Window->W, Window->H, info->RootElement.BackgroundColour); Widget_UpdateDimensions(&info->RootElement); Widget_UpdatePosition(&info->RootElement); @@ -142,10 +142,6 @@ void Widget_RenderWidget(tWindow *Window, tElement *Element) { gaWM_WidgetTypes[Element->Type]->Render(Window, Element); } - else - { - Widget_Decorator_RenderWidget(Window, Element); - } for(child = Element->FirstChild; child; child = child->NextSibling) { @@ -161,6 +157,7 @@ void Widget_UpdateDimensions(tElement *Element) int maxCross = 0; int fixedSize = 0; int fullCross, dynWith = 0; + int bVertical = Element->Flags & ELEFLAG_VERTICAL; // Check if this element can have children if( (gaWM_WidgetTypes[Element->Type]->Flags & WIDGETTYPE_FLAG_NOCHILDREN) ) @@ -170,6 +167,9 @@ void Widget_UpdateDimensions(tElement *Element) // - Get the fixed and minimum sizes of the element for( child = Element->FirstChild; child; child = child->NextSibling ) { + int minWith = bVertical ? child->MinH : child->MinW; + int minCross = bVertical ? child->MinW : child->MinH; + // Ignore elements that will not be rendered if( child->Flags & ELEFLAG_NORENDER ) continue ; @@ -185,19 +185,17 @@ void Widget_UpdateDimensions(tElement *Element) else if( child->Flags & ELEFLAG_NOSTRETCH ) { nFixed ++; - fixedSize += child->MinWith; + fixedSize += minWith; } - if( child->FixedCross && maxCross < child->FixedCross ) - maxCross = child->FixedCross; - if( child->MinCross && maxCross < child->MinCross ) - maxCross = child->MinCross; + if( maxCross < child->FixedCross ) maxCross = child->FixedCross; + if( maxCross < minCross ) maxCross = minCross; nChildren ++; } // Get the dynamic with size from the unused space in the element if( nChildren > nFixed ) { - if( Element->Flags & ELEFLAG_VERTICAL ) + if( bVertical ) dynWith = Element->CachedH - Element->PaddingT - Element->PaddingB; else dynWith = Element->CachedW - Element->PaddingL - Element->PaddingR; @@ -211,7 +209,7 @@ void Widget_UpdateDimensions(tElement *Element) } // Get the cross size - if( Element->Flags & ELEFLAG_VERTICAL ) + if( bVertical ) fullCross = Element->CachedW - Element->PaddingL - Element->PaddingR; else fullCross = Element->CachedH - Element->PaddingT - Element->PaddingB; @@ -228,52 +226,39 @@ void Widget_UpdateDimensions(tElement *Element) // Pass 2 - Set sizes and recurse for( child = Element->FirstChild; child; child = child->NextSibling ) { - int cross, with; + int w, h; // 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? - // TODO: Extra flag so options are (Expand, Equal, Wrap) - if( child->FixedCross ) - cross = child->FixedCross; - else if( child->Flags & ELEFLAG_NOEXPAND ) - cross = child->MinCross; + // --- Width --- + if( child->Flags & ELEFLAG_NOEXPAND ) + w = child->MinW; + else if( bVertical ) + w = child->FixedCross ? child->FixedCross : fullCross; else - cross = fullCross; - - // --- With Size --- - if( child->FixedWith ) - with = child->FixedWith; - else if( child->Flags & ELEFLAG_NOSTRETCH ) - with = child->MinWith; - else - with = dynWith; + w = child->FixedWith ? child->FixedWith : dynWith; + // --- Height --- + if( child->Flags & ELEFLAG_NOSTRETCH ) + h = child->MinH; + else if( bVertical ) + h = child->FixedWith ? child->FixedWith : dynWith; + else + h = child->FixedCross ? child->FixedCross : fullCross; - if(with < child->MinWith) with = child->MinWith; - if(cross < child->MinCross) cross = child->MinCross; + if(w < child->MinW) w = child->MinW; + if(h < child->MinH) h = child->MinH; - _SysDebug("with = %i", with); +// _SysDebug("Child %ix%i (min %ix%i)", w, h, child->MinW, child->MinH); // Update the dimensions if they have changed - if( Element->Flags & ELEFLAG_VERTICAL ) { - // If no change, don't recurse - if( child->CachedW == cross && child->CachedH == with ) - continue ; - child->CachedW = cross; - child->CachedH = with; - } - else { - // If no change, don't recurse - if( child->CachedW == with && child->CachedH == cross ) - continue ; - child->CachedW = with; - child->CachedH = cross; - } + if( child->CachedW == w && child->CachedH == h ) + continue ; + child->CachedW = w; + child->CachedH = h; // Force the positions of child elements to be recalculated child->CachedX = -1; @@ -359,48 +344,44 @@ void Widget_UpdateMinDims(tElement *Element) { tElement *child; int minW, minH; + int nChildren; if(!Element) return; minW = 0; minH = 0; + nChildren = 0; for(child = Element->FirstChild; child; child = child->NextSibling) { + int cross; + + if(Element->Flags & ELEFLAG_NORENDER) continue ; + if( (Element->Flags & ELEFLAG_VERTICAL) ) { - if(child->FixedCross) - minW += child->FixedCross; - else - minW += child->MinCross; - if(child->FixedWith) - minH += child->FixedWith; - else - minH += child->MinWith; + cross = child->FixedCross ? child->FixedCross : child->MinW; + if(minW < cross) minW = cross; + minH += child->FixedWith ? child->FixedWith : child->MinH; } else { - if(child->FixedCross) - minH += child->FixedCross; - else - minH += child->MinCross; - if(child->FixedWith) - minW += child->FixedWith; - else - minW += child->MinWith; + cross = child->FixedCross ? child->FixedCross : child->MinH; + minW += child->FixedWith ? child->FixedWith : child->MinW; + if(minH < cross) minH = cross; } - } +// _SysDebug("%i/%i cross = %i", Element->ID, child->ID, cross); - if( Element->Parent && (Element->Parent->Flags & ELEFLAG_VERTICAL) ) - { - Element->MinCross = Element->PaddingL + minW + Element->PaddingR; - Element->MinWith = Element->PaddingT + minH + Element->PaddingB; + nChildren ++; } + + if( Element->Flags & ELEFLAG_VERTICAL ) + minH += (nChildren - 1) * Element->GapSize; else - { - Element->MinWith = Element->PaddingL + minW + Element->PaddingR; - Element->MinCross = Element->PaddingL + minH + Element->PaddingR; - } + minW += (nChildren - 1) * Element->GapSize; + + Element->MinW = Element->PaddingL + minW + Element->PaddingR; + Element->MinH = Element->PaddingT + minH + Element->PaddingB; // Recurse upwards Widget_UpdateMinDims(Element->Parent); @@ -411,7 +392,7 @@ tElement *Widget_GetElementByPos(tWidgetWin *Info, int X, int Y) tElement *ret, *next, *ele; next = &Info->RootElement; - while(next) + do { ret = next; next = NULL; @@ -424,7 +405,7 @@ tElement *Widget_GetElementByPos(tWidgetWin *Info, int X, int Y) if(Y >= ele->CachedY + ele->CachedH) continue; next = ele; } - } + } while(next); return ret; } @@ -511,6 +492,13 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg Widget_UpdateMinDims(parent); } +void Widget_SetFocus(tWidgetWin *Info, tElement *Ele) +{ + // TODO: Callbacks + + Info->FocusedElement = Ele; +} + void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg) { tElement *ele; @@ -564,9 +552,38 @@ void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) // } } +int Widget_GetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) +{ + if( Len < sizeof(*Msg) ) + return 0; + if( Len > sizeof(*Msg) ) + return 1; // Pass to user + + 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; + + if( text ) { + omsg->WidgetID = Msg->WidgetID; + strcpy(omsg->Text, text); + } + else { + omsg->WidgetID = -1; + omsg->Text[0] = 0; + } + + WM_SendMessage(Info->RootElement.Window, Info->RootElement.Window, MSG_WIDGET_GETTEXT, sizeof(buf), buf); + return 0; +} + int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) { tWidgetWin *info = Target->RendererInfo; + tElement *ele; switch(Msg) { case WNDMSG_RESIZE: { @@ -587,7 +604,6 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void case WNDMSG_MOUSEBTN: { const struct sWndMsg_MouseButton *msg = Data; tWidgetMsg_MouseBtn client_msg; - tElement *ele; int x, y; int rv; @@ -598,6 +614,7 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void client_msg.bPressed = msg->bPressed; ele = Widget_GetElementByPos(info, x, y); + Widget_SetFocus(info, ele); // Send event to all elements from `ele` upwards for( ; ele; ele = ele->Parent ) { @@ -622,15 +639,72 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void } return 0; } + case WNDMSG_KEYDOWN: { + const struct sWndMsg_KeyAction *msg = Data; + if(Len < sizeof(*msg)) return -1; + + if(!info->FocusedElement) return 0; + ele = info->FocusedElement; + + if(gaWM_WidgetTypes[ele->Type]->KeyDown) + gaWM_WidgetTypes[ele->Type]->KeyDown(ele, msg->KeySym, msg->UCS32); + else + { + // TODO: Pass to user + } + + return 0; } + + case WNDMSG_KEYFIRE: { + const struct sWndMsg_KeyAction *msg = Data; + if(Len < sizeof(*msg)) return -1; + + if(!info->FocusedElement) return 0; + ele = info->FocusedElement; + + if(gaWM_WidgetTypes[ele->Type]->KeyFire) + gaWM_WidgetTypes[ele->Type]->KeyFire(ele, msg->KeySym, msg->UCS32); + else + { + // TODO: Pass the buck + } + return 0; } + + case WNDMSG_KEYUP: { + const struct sWndMsg_KeyAction *msg = Data; + if(Len < sizeof(*msg)) return -1; + + if(!info->FocusedElement) return 0; + ele = info->FocusedElement; + + if(gaWM_WidgetTypes[ele->Type]->KeyUp) + gaWM_WidgetTypes[ele->Type]->KeyUp(ele, msg->KeySym); + else + { + // TODO: Pass the buck + } + return 0; } + // New Widget case MSG_WIDGET_CREATE: Widget_NewWidget(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); @@ -645,6 +719,8 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void case MSG_WIDGET_SETTEXT: Widget_SetText(info, Len, Data); return 0; + case MSG_WIDGET_GETTEXT: + return Widget_GetText(info, Len, Data); // default: