From: John Hodge Date: Tue, 8 Nov 2011 04:12:15 +0000 (+0800) Subject: Usermode/AxWin3 - Adding widget mouse input handlers X-Git-Tag: rel0.14~137 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=036a4cd90bdc323b905d98a52c6f2ff10f0b0ebe;p=tpg%2Facess2.git Usermode/AxWin3 - Adding widget mouse input handlers --- diff --git a/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h b/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h index 9e4c144c..15bba75d 100644 --- a/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h +++ b/Usermode/Applications/axwin3_src/WM/include/renderer_widget.h @@ -22,6 +22,7 @@ struct sAxWin_Element { enum eElementTypes Type; + tWindow *Window; uint32_t ID; //!< Application provided ID number tElement *ListNext; //!< Next element in bucket diff --git a/Usermode/Applications/axwin3_src/WM/include/wm_messages.h b/Usermode/Applications/axwin3_src/WM/include/wm_messages.h index d37097ff..4b7708d0 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm_messages.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm_messages.h @@ -37,4 +37,11 @@ struct sWndMsg_Resize uint16_t W, H; }; +struct sWndMsg_MouseButton +{ + uint16_t X, Y; + uint8_t Button; + uint8_t bPressed; +}; + #endif diff --git a/Usermode/Applications/axwin3_src/WM/renderer_widget.c b/Usermode/Applications/axwin3_src/WM/renderer_widget.c index 92972d67..00768902 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderer_widget.c @@ -33,6 +33,7 @@ void Widget_SetText(tWidgetWin *Info, int Len, tWidgetMsg_SetText *Msg); // --- Type helpers void Widget_TextBox_UpdateText(tElement *Element, const char *Text); void Widget_Image_UpdateText(tElement *Element, const char *Text); + int Widget_Button_MouseButton(tElement *Element, int X, int Y, int Button, int bPress); // === GLOBALS === tWMRenderer gRenderer_Widget = { @@ -42,19 +43,34 @@ tWMRenderer gRenderer_Widget = { .HandleMessage = Renderer_Widget_HandleMessage }; -// --- Element type flags +// --- Element callbacks struct { void (*Init)(tElement *Ele); void (*Delete)(tElement *Ele); + void (*UpdateFlags)(tElement *Ele); void (*UpdateSize)(tElement *Ele); void (*UpdateText)(tElement *Ele, const char *Text); // This should update Ele->Text + + /** + * \name Input handlers + * \note Returns boolean unhandled + * \{ + */ + int (*MouseButton)(tElement *Ele, int X, int Y, int Button, int bPressed); + int (*MouseMove)(tElement *Ele, int X, int Y); + int (*KeyDown)(tElement *Ele, int KeySym, int Character); + int (*KeyUp)(tElement *Ele, int KeySym); + int (*KeyFire)(tElement *Ele, int KeySym, int Character); + /** + * \} + */ } gaWM_WidgetTypes[NUM_ELETYPES] = { - {NULL, NULL, NULL, NULL, NULL}, // NULL - {NULL, NULL, NULL, NULL, NULL}, // Box - {NULL, NULL, NULL, NULL, Widget_TextBox_UpdateText}, // Text - {NULL, NULL, NULL, NULL, Widget_Image_UpdateText}, // Image - {NULL, NULL, NULL, NULL, NULL} // Button + {0}, // NULL + {0}, // Box + {.UpdateText = Widget_TextBox_UpdateText}, // Text + {.UpdateText = Widget_Image_UpdateText}, // Image + {.MouseButton = Widget_Button_MouseButton} // Button }; const int ciWM_NumWidgetTypes = sizeof(gaWM_WidgetTypes)/sizeof(gaWM_WidgetTypes[0]); @@ -82,6 +98,7 @@ tWindow *Renderer_Widget_Create(int Flags) info = ret->RendererInfo; info->TableSize = eletable_size; + info->RootElement.Window = ret; info->RootElement.ID = -1; info->RootElement.BackgroundColour = 0xCCCCCC; info->RootElement.Flags = Flags; @@ -337,6 +354,27 @@ void Widget_UpdateMinDims(tElement *Element) Widget_UpdateMinDims(Element->Parent); } +tElement *Widget_GetElementByPos(tWidgetWin *Info, int X, int Y) +{ + tElement *ret, *next, *ele; + + next = &Info->RootElement; + while(next) + { + ret = next; + next = NULL; + for(ele = ret->FirstChild; ele; ele = ele->NextSibling) + { + if(ele->Flags & ELEFLAG_NORENDER) continue; + if(X < ele->CachedX) continue; + if(Y < ele->CachedY) continue; + if(X >= ele->CachedX + ele->CachedW) continue; + if(Y >= ele->CachedY + ele->CachedH) continue; + next = ele; + } + } + return ret; +} // --- Helpers --- tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID) @@ -381,6 +419,7 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg) // Create new element new = calloc(sizeof(tElement), 1); + new->Window = parent->Window; new->ID = Msg->NewID; new->Type = Msg->Type; new->Parent = parent; @@ -480,6 +519,47 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) info->RootElement.CachedW = msg->W; info->RootElement.CachedH = msg->H; + + // TODO: Update dimensions of all child elements? + + return 0; } + + case WNDMSG_MOUSEBTN: { + struct sWndMsg_MouseButton *msg = Data; + tWidgetMsg_MouseBtn client_msg; + tElement *ele; + int x, y; + int rv; + + if(Len < sizeof(*msg)) return -1; + + x = msg->X; y = msg->Y; + client_msg.Button = msg->Button; + client_msg.bPressed = msg->bPressed; + + ele = Widget_GetElementByPos(info, x, y); + // Send event to all elements from `ele` upwards + for( ; ele; ele = ele->Parent ) + { + if(ele->Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[ele->Type].MouseButton) + { + rv = gaWM_WidgetTypes[ele->Type].MouseButton( + ele, + x - ele->CachedX, y - ele->CachedY, + msg->Button, msg->bPressed + ); + // Allow a type to trap the input from going any higher + if(rv == 0) break; + } + else + { + // Pass to user + client_msg.X = x - ele->CachedX; + client_msg.Y = y - ele->CachedY; + client_msg.WidgetID = ele->ID; + WM_SendMessage(Target, Target, MSG_WIDGET_MOUSEBTN, sizeof(client_msg), &client_msg); + } + } return 0; } // New Widget @@ -512,6 +592,13 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) } } +void Widget_Fire(tElement *Element) +{ + tWidgetMsg_Fire msg; + msg.WidgetID = Element->ID; + WM_SendMessage(Element->Window, Element->Window, MSG_WIDGET_FIRE, sizeof(msg), &msg); +} + // --- Type Helpers void Widget_TextBox_UpdateText(tElement *Element, const char *Text) { @@ -559,3 +646,13 @@ void Widget_Image_UpdateText(tElement *Element, const char *Text) // NOTE: Doesn't update Element->Text because it's useless } +int Widget_Button_MouseButton(tElement *Element, int X, int Y, int Button, int bPress) +{ + _SysDebug("Ele %i - Button %i %s", + Element->ID, Button, + (bPress ? "pressed" : "released") + ); + if(!bPress) Widget_Fire(Element); + return 0; // Handled +} + diff --git a/Usermode/Applications/axwin3_src/WM/wm_input.c b/Usermode/Applications/axwin3_src/WM/wm_input.c index c2ebb9e6..8f51703a 100644 --- a/Usermode/Applications/axwin3_src/WM/wm_input.c +++ b/Usermode/Applications/axwin3_src/WM/wm_input.c @@ -7,6 +7,7 @@ */ #include #include +#include // === IMPORTS === extern tWindow *gpWM_RootWindow; @@ -42,8 +43,15 @@ void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY) void WM_Input_MouseButton(int X, int Y, int ButtonIndex, int Pressed) { -// tWindow *win = WM_int_GetWindowAtPos(X, Y); - + tWindow *win = WM_int_GetWindowAtPos(X, Y); + struct sWndMsg_MouseButton msg; + // Send Press/Release message + msg.X = X - win->X; + msg.Y = Y - win->Y; + msg.Button = ButtonIndex; + msg.bPressed = !!Pressed; + + WM_SendMessage(NULL, win, WNDMSG_MOUSEBTN, sizeof(msg), &msg); } diff --git a/Usermode/Applications/axwin3_src/include/widget_messages.h b/Usermode/Applications/axwin3_src/include/widget_messages.h index c6c7cdc3..1974f3f6 100644 --- a/Usermode/Applications/axwin3_src/include/widget_messages.h +++ b/Usermode/Applications/axwin3_src/include/widget_messages.h @@ -10,12 +10,18 @@ enum { + // Control (Client->Server) messages MSG_WIDGET_CREATE = 0x1000, MSG_WIDGET_DELETE, MSG_WIDGET_SETFLAGS, MSG_WIDGET_SETSIZE, MSG_WIDGET_SETTEXT, - MSG_WIDGET_SETCOLOUR + MSG_WIDGET_SETCOLOUR, + + // Event (Server->Client) messages + MSG_WIDGET_FIRE, + MSG_WIDGET_KEYPRESS, + MSG_WIDGET_MOUSEBTN, }; @@ -59,5 +65,26 @@ typedef struct uint32_t Colour; } tWidgetMsg_SetColour; +typedef struct +{ + uint32_t WidgetID; +} tWidgetMsg_Fire; + +typedef struct +{ + uint32_t WidgetID; + uint32_t KeySym; + uint32_t Character; +} tWidgetMsg_KeyEvent; + +typedef struct +{ + uint32_t WidgetID; + uint16_t X; + uint16_t Y; + uint8_t Button; + uint8_t bPressed; +} tWidgetMsg_MouseBtn; + #endif