Merge branch 'master' of git.mutabah.net:acess2
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / renderers / widget.c
index f3de26f..46b3198 100644 (file)
@@ -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)
        {
@@ -256,7 +252,7 @@ void Widget_UpdateDimensions(tElement *Element)
                if(w < child->MinW)     w = child->MinW;
                if(h < child->MinH)     h = child->MinH;
        
-               _SysDebug("Child %ix%i (min %ix%i)", w, h, child->MinW, child->MinH);
+//             _SysDebug("Child %ix%i (min %ix%i)", w, h, child->MinW, child->MinH);
        
                // Update the dimensions if they have changed
                if( child->CachedW == w && child->CachedH == h )
@@ -396,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;
@@ -409,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;
 }
 
@@ -496,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;
@@ -549,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: {
@@ -572,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;
                
@@ -583,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 )
                {
@@ -607,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);
@@ -630,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:

UCC git Repository :: git.ucc.asn.au