From 2f16fec349eabb42f5e23ea2b821f149fa6b767e Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 17 Nov 2011 22:15:27 +0800 Subject: [PATCH] Usermode/AxWin3 - Splitting widget types out into separate files --- .../Applications/axwin3_src/Interface/main.c | 2 +- Usermode/Applications/axwin3_src/WM/Makefile | 13 +- .../Applications/axwin3_src/WM/decorator.c | 30 ++- .../axwin3_src/WM/include/decorator.h | 2 +- .../Applications/axwin3_src/WM/include/wm.h | 2 +- .../axwin3_src/WM/include/wm_messages.h | 2 +- .../axwin3_src/WM/include/wm_renderer.h | 2 +- .../background.c} | 4 +- .../classes.c} | 0 .../WM/{renderer_menu.c => renderers/menu.c} | 35 ++- .../passthru.c} | 4 +- .../{renderer_widget.c => renderers/widget.c} | 204 ++++++------------ .../axwin3_src/WM/renderers/widget/button.c | 42 ++++ .../axwin3_src/WM/renderers/widget/colours.h | 21 ++ .../axwin3_src/WM/renderers/widget/common.h | 51 +++++ .../axwin3_src/WM/renderers/widget/disptext.c | 48 +++++ .../axwin3_src/WM/renderers/widget/image.c | 53 +++++ .../WM/renderers/widget/textinput.c | 55 +++++ .../widget/widget_decorator.c} | 52 +---- Usermode/Applications/axwin3_src/WM/wm.c | 10 +- .../Applications/axwin3_src/WM/wm_input.c | 14 +- 21 files changed, 416 insertions(+), 230 deletions(-) rename Usermode/Applications/axwin3_src/WM/{renderer_background.c => renderers/background.c} (95%) rename Usermode/Applications/axwin3_src/WM/{renderer_classes.c => renderers/classes.c} (100%) rename Usermode/Applications/axwin3_src/WM/{renderer_menu.c => renderers/menu.c} (92%) rename Usermode/Applications/axwin3_src/WM/{renderer_passthru.c => renderers/passthru.c} (94%) rename Usermode/Applications/axwin3_src/WM/{renderer_widget.c => renderers/widget.c} (74%) create mode 100644 Usermode/Applications/axwin3_src/WM/renderers/widget/button.c create mode 100644 Usermode/Applications/axwin3_src/WM/renderers/widget/colours.h create mode 100644 Usermode/Applications/axwin3_src/WM/renderers/widget/common.h create mode 100644 Usermode/Applications/axwin3_src/WM/renderers/widget/disptext.c create mode 100644 Usermode/Applications/axwin3_src/WM/renderers/widget/image.c create mode 100644 Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c rename Usermode/Applications/axwin3_src/WM/{renderer_widget_decorator.c => renderers/widget/widget_decorator.c} (59%) diff --git a/Usermode/Applications/axwin3_src/Interface/main.c b/Usermode/Applications/axwin3_src/Interface/main.c index 61ba4ac3..d43845b5 100644 --- a/Usermode/Applications/axwin3_src/Interface/main.c +++ b/Usermode/Applications/axwin3_src/Interface/main.c @@ -11,7 +11,7 @@ #include #include -#define SIDEBAR_WIDTH 36 +#define SIDEBAR_WIDTH 40 #define RUN_WIDTH 200 #define RUN_HEIGHT 70 diff --git a/Usermode/Applications/axwin3_src/WM/Makefile b/Usermode/Applications/axwin3_src/WM/Makefile index 0e501e03..60669b77 100644 --- a/Usermode/Applications/axwin3_src/WM/Makefile +++ b/Usermode/Applications/axwin3_src/WM/Makefile @@ -9,10 +9,15 @@ BIN := AxWinWM OBJ := main.o input.o video.o ipc.o image.o OBJ += wm.o wm_input.o wm_render.o wm_render_text.o OBJ += decorator.o -OBJ += renderer_passthru.o -OBJ += renderer_background.o -OBJ += renderer_widget.o renderer_widget_decorator.o -OBJ += renderer_menu.o +OBJ += renderers/passthru.o +OBJ += renderers/background.o +OBJ += renderers/menu.o +# TODO: Move to a lower makefile +OBJ += renderers/widget.o renderers/widget/widget_decorator.o +OBJ += renderers/widget/button.o +OBJ += renderers/widget/image.o +OBJ += renderers/widget/disptext.o +OBJ += renderers/widget/textinput.o LDFLAGS += -limage_sif -luri -lnet diff --git a/Usermode/Applications/axwin3_src/WM/decorator.c b/Usermode/Applications/axwin3_src/WM/decorator.c index 52ffbfb6..d1e24610 100644 --- a/Usermode/Applications/axwin3_src/WM/decorator.c +++ b/Usermode/Applications/axwin3_src/WM/decorator.c @@ -8,17 +8,19 @@ #include #include #include +#include // === PROTOTYPES === void Decorator_UpdateBorderSize(tWindow *Window); void Decorator_Redraw(tWindow *Window); - int Decorator_HandleMessage(tWindow *Window, int Message, int Length, void *Data); + int Decorator_HandleMessage(tWindow *Window, int Message, int Length, const void *Data); // === CONSTANTS === tColour cColourActive_Titlebar = 0xFF8800; tColour cColourActive_TitleText = 0x000000; tColour cColourInactive_Titlebar = 0xD0D0D0; tColour cColourInactive_TitleText= 0x000000; +tColour cColour_TitleTopBorder = 0xFFFFFF; tColour cColour_SideBorder = 0xD0D0D0; tColour cColour_BottomBorder = 0xD0D0D0; int ciTitlebarHeight = 18; @@ -54,6 +56,18 @@ void Decorator_Redraw(tWindow *Window) 0, -ciTitlebarHeight, Window->W, ciTitlebarHeight, (bActive ? cColourActive_Titlebar : cColourInactive_Titlebar) ); + WM_Render_FillRect(Window, + 0, -ciTitlebarHeight, Window->W, 1, + cColour_TitleTopBorder + ); + WM_Render_FillRect(Window, + 0, -ciTitlebarHeight, 1, ciTitlebarHeight, + cColour_SideBorder + ); + WM_Render_FillRect(Window, + Window->W, -ciTitlebarHeight, 1, ciTitlebarHeight, + cColour_SideBorder + ); WM_Render_GetTextDims( NULL, // TODO: Select font @@ -92,10 +106,22 @@ void Decorator_Redraw(tWindow *Window) ); } -int Decorator_HandleMessage(tWindow *Window, int Message, int Length, void *Data) +int Decorator_HandleMessage(tWindow *Window, int Message, int Length, const void *Data) { switch(Message) { + case WNDMSG_MOUSEMOVE: { + const struct sWndMsg_MouseMove *msg = Data; + if(msg->Y >= 0) return 1; // Pass + + // TODO: Handle + return 0; } + case WNDMSG_MOUSEBTN: { + const struct sWndMsg_MouseButton *msg = Data; + if(msg->Y >= 0) return 1; // Pass + + // TODO: Handle + return 0; } default: // Anything unhandled is passed on return 1; } diff --git a/Usermode/Applications/axwin3_src/WM/include/decorator.h b/Usermode/Applications/axwin3_src/WM/include/decorator.h index ae84cdb5..26505843 100644 --- a/Usermode/Applications/axwin3_src/WM/include/decorator.h +++ b/Usermode/Applications/axwin3_src/WM/include/decorator.h @@ -12,7 +12,7 @@ extern void Decorator_UpdateBorderSize(tWindow *Window); extern void Decorator_Redraw(tWindow *Window); -extern int Decorator_HandleMessage(tWindow *Window, int Message, int Length, void *Data); +extern int Decorator_HandleMessage(tWindow *Window, int Message, int Length, const void *Data); #endif diff --git a/Usermode/Applications/axwin3_src/WM/include/wm.h b/Usermode/Applications/axwin3_src/WM/include/wm.h index d35a4624..1c0671f5 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm.h @@ -53,7 +53,7 @@ extern void WM_ShowWindow(tWindow *Window, int bShow); extern void WM_DecorateWindow(tWindow *Window, int bDecorate); extern int WM_ResizeWindow(tWindow *Window, int W, int H); extern int WM_MoveWindow(tWindow *Window, int X, int Y); -extern int WM_SendMessage(tWindow *Source, tWindow *Dest, int MessageID, int Length, void *Data); +extern int WM_SendMessage(tWindow *Source, tWindow *Dest, int MessageID, int Length, const void *Data); // --- Rendering extern void WM_Render_FillRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour); extern void WM_Render_DrawRect(tWindow *Window, int X, int Y, int W, int H, tColour Colour); diff --git a/Usermode/Applications/axwin3_src/WM/include/wm_messages.h b/Usermode/Applications/axwin3_src/WM/include/wm_messages.h index df20d775..a64ac99e 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm_messages.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm_messages.h @@ -50,7 +50,7 @@ struct sWndMsg_MouseMove struct sWndMsg_MouseButton { - uint16_t X, Y; + int16_t X, Y; uint8_t Button; uint8_t bPressed; }; diff --git a/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h b/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h index b734348f..58825491 100644 --- a/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h +++ b/Usermode/Applications/axwin3_src/WM/include/wm_renderer.h @@ -51,7 +51,7 @@ struct sWMRenderer * \param Data Implementation defined data buffer * \return Boolean failure (0: Handled, 1: Unhandled) */ - int (*HandleMessage)(tWindow *Window, int MessageID, int Length, void *Data); + int (*HandleMessage)(tWindow *Window, int MessageID, int Length, const void *Data); }; extern void WM_RegisterRenderer(tWMRenderer *Renderer); diff --git a/Usermode/Applications/axwin3_src/WM/renderer_background.c b/Usermode/Applications/axwin3_src/WM/renderers/background.c similarity index 95% rename from Usermode/Applications/axwin3_src/WM/renderer_background.c rename to Usermode/Applications/axwin3_src/WM/renderers/background.c index 7772cddb..d67ca743 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_background.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/background.c @@ -19,7 +19,7 @@ struct sBgWin // === PROTOTYPES === tWindow *Renderer_Background_Create(int Flags); void Renderer_Background_Redraw(tWindow *Window); -int Renderer_Background_HandleMessage(tWindow *Target, int Msg, int Len, void *Data); +int Renderer_Background_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); // === GLOBALS === tWMRenderer gRenderer_Background = { @@ -54,7 +54,7 @@ void Renderer_Background_Redraw(tWindow *Window) WM_Render_FillRect(Window, 0, 0, 0xFFFF, 0xFFFF, info->Colour); } -int Renderer_Background_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) +int Renderer_Background_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) { switch(Msg) { diff --git a/Usermode/Applications/axwin3_src/WM/renderer_classes.c b/Usermode/Applications/axwin3_src/WM/renderers/classes.c similarity index 100% rename from Usermode/Applications/axwin3_src/WM/renderer_classes.c rename to Usermode/Applications/axwin3_src/WM/renderers/classes.c diff --git a/Usermode/Applications/axwin3_src/WM/renderer_menu.c b/Usermode/Applications/axwin3_src/WM/renderers/menu.c similarity index 92% rename from Usermode/Applications/axwin3_src/WM/renderer_menu.c rename to Usermode/Applications/axwin3_src/WM/renderers/menu.c index 45c6a241..4506ad25 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_menu.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/menu.c @@ -47,7 +47,7 @@ typedef struct sMenuWindowInfo void Renderer_Menu_Init(void); tWindow *Renderer_Menu_Create(int Argument); void Renderer_Menu_Redraw(tWindow *Window); - int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, void *Data); + int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, const void *Data); // === CONSTANTS === const int ciMenu_Gap = 10; // Gap between label and shortcut @@ -196,37 +196,36 @@ void Renderer_Menu_Redraw(tWindow *Window) } } -int Renderer_Menu_int_AddItem(tWindow *Window, int Length, void *Data) +int Renderer_Menu_int_AddItem(tWindow *Window, int Length, const tMenuMsg_AddItem *Msg) { tMenuWindowInfo *info = Window->RendererInfo; - tMenuMsg_AddItem *req = Data; tMenuItem *item; // Sanity checking // - Message length - if(Length < sizeof(*req) + 1 || req->Label[Length-sizeof(*req)-1] != '\0') { + if(Length < sizeof(*Msg) + 1 || Msg->Label[Length-sizeof(*Msg)-1] != '\0') { _SysDebug("Renderer_Menu_int_AddItem: Size checks failed"); return -1; } // - ID Number - if(req->ID >= info->MaxItems) { + if(Msg->ID >= info->MaxItems) { _SysDebug("Renderer_Menu_int_AddItem: ID (%i) >= MaxItems (%i)", - req->ID, info->MaxItems); + Msg->ID, info->MaxItems); return -1; } // Don't overwrite - if(info->Items[req->ID]) { - _SysDebug("- Caught overwrite of %i", req->ID); + if(info->Items[Msg->ID]) { + _SysDebug("- Caught overwrite of %i", Msg->ID); return 0; } // Bookkeeping - if(req->ID >= info->nItems) info->nItems = req->ID + 1; + if(Msg->ID >= info->nItems) info->nItems = Msg->ID + 1; // Allocate - item = malloc(sizeof(tMenuItem)+strlen(req->Label)); - info->Items[req->ID] = item; + item = malloc(sizeof(tMenuItem)+strlen(Msg->Label)+1); + info->Items[Msg->ID] = item; - if(req->Label[0] == '\0') + if(Msg->Label[0] == '\0') { // Spacer item->Label = NULL; @@ -237,7 +236,7 @@ int Renderer_Menu_int_AddItem(tWindow *Window, int Length, void *Data) // Actual item char *dest = item->Data; - char *src = req->Label; + const char *src = Msg->Label; int ofs = 0; // - Main label @@ -345,13 +344,13 @@ int Renderer_Menu_int_GetItemByPos(tWindow *Window, tMenuWindowInfo *Info, int X return -1; } -int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, void *Data) +int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, const void *Data) { tMenuWindowInfo *info = Window->RendererInfo; switch(Msg) { case WNDMSG_SHOW: { - struct sWndMsg_Bool *msg = Data; + const struct sWndMsg_Bool *msg = Data; if(Length < sizeof(*msg)) return -1; if(msg->Val) { @@ -367,7 +366,7 @@ int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, void *Data } return 0; } case WNDMSG_FOCUS: { - struct sWndMsg_Bool *msg = Data; + const struct sWndMsg_Bool *msg = Data; if(Length < sizeof(*msg)) return -1; if(!msg->Val) { // TODO: Catch if focus was given away to a child @@ -380,7 +379,7 @@ int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, void *Data return 0; } case WNDMSG_MOUSEBTN: { - struct sWndMsg_MouseButton *msg = Data; + const struct sWndMsg_MouseButton *msg = Data; int item; if(Length < sizeof(*msg)) return -1; @@ -402,7 +401,7 @@ int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, void *Data return 0; } case WNDMSG_MOUSEMOVE: { - struct sWndMsg_MouseMove *msg = Data; + const struct sWndMsg_MouseMove *msg = Data; int new_hilight; if(Length < sizeof(*msg)) return -1; diff --git a/Usermode/Applications/axwin3_src/WM/renderer_passthru.c b/Usermode/Applications/axwin3_src/WM/renderers/passthru.c similarity index 94% rename from Usermode/Applications/axwin3_src/WM/renderer_passthru.c rename to Usermode/Applications/axwin3_src/WM/renderers/passthru.c index 6e16e6a2..9cd112c0 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_passthru.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/passthru.c @@ -11,7 +11,7 @@ // === PROTOTYPES === tWindow *Renderer_Passthru_Create(int Flags); void Renderer_Passthru_Redraw(tWindow *Window); - int Renderer_Passthru_HandleMessage(tWindow *Target, int Msg, int Len, void *Data); + int Renderer_Passthru_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); // === GLOBALS === tWMRenderer gRenderer_Passthru = { @@ -37,7 +37,7 @@ void Renderer_Passthru_Redraw(tWindow *Window) } -int Renderer_Passthru_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) +int Renderer_Passthru_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) { return 1; } diff --git a/Usermode/Applications/axwin3_src/WM/renderer_widget.c b/Usermode/Applications/axwin3_src/WM/renderers/widget.c similarity index 74% rename from Usermode/Applications/axwin3_src/WM/renderer_widget.c rename to Usermode/Applications/axwin3_src/WM/renderers/widget.c index c4799e99..1bd437da 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_widget.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget.c @@ -11,7 +11,7 @@ #include #include #include -#include "include/image.h" +#include "widget/common.h" #define DEFAULT_ELETABLE_SIZE 64 @@ -25,16 +25,11 @@ void Widget_UpdateDimensions(tElement *Element); void Widget_UpdatePosition(tElement *Element); // --- Messages tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID); -void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg); -void Widget_SetFlags(tWidgetWin *Info, int Len, tWidgetMsg_SetFlags *Msg); -void Widget_SetSize(tWidgetWin *Info, int Len, tWidgetMsg_SetSize *Msg); -void Widget_SetText(tWidgetWin *Info, int Len, tWidgetMsg_SetText *Msg); - int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data); -// --- Type helpers -void Widget_DispText_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); -void Widget_TextInput_Init(tElement *Element); +void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg); +void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg); +void Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg); +void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg); + int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data); // === GLOBALS === tWMRenderer gRenderer_Widget = { @@ -45,36 +40,7 @@ tWMRenderer gRenderer_Widget = { }; // --- 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] = { - {0}, // NULL - {0}, // Box - {.UpdateText = Widget_DispText_UpdateText}, // Text - {.UpdateText = Widget_Image_UpdateText}, // Image - {.MouseButton = Widget_Button_MouseButton}, // Button - {0}, // Spacer - {.Init = Widget_TextInput_Init}, // Text Box (Single Line) -}; +tWidgetDef *gaWM_WidgetTypes[NUM_ELETYPES]; const int ciWM_NumWidgetTypes = sizeof(gaWM_WidgetTypes)/sizeof(gaWM_WidgetTypes[0]); // === CODE === @@ -85,6 +51,26 @@ int Renderer_Widget_Init(void) return 0; } +void Widget_int_SetTypeDef(int Type, tWidgetDef *Ptr) +{ + if( Type < 0 || Type >= ciWM_NumWidgetTypes ) { + _SysDebug("ERROR - Widget ID %i out of range (from %p)", + Type, __builtin_return_address(0) + ); + return ; + } + + if( gaWM_WidgetTypes[Type] ) { + _SysDebug("ERROR - Widget ID %i redefined by %p", + Type, __builtin_return_address(0) + ); + return ; + } + + gaWM_WidgetTypes[Type] = Ptr; + _SysDebug("Registered type %i to %p", Type, Ptr); +} + tWindow *Renderer_Widget_Create(int Flags) { tWindow *ret; @@ -105,6 +91,10 @@ tWindow *Renderer_Widget_Create(int Flags) info->RootElement.ID = -1; info->RootElement.BackgroundColour = 0xCCCCCC; info->RootElement.Flags = Flags; + info->RootElement.PaddingT = 2; + info->RootElement.PaddingB = 2; + info->RootElement.PaddingL = 2; + info->RootElement.PaddingR = 2; return ret; } @@ -127,8 +117,18 @@ void Widget_RenderWidget(tWindow *Window, tElement *Element) if( Element->Flags & ELEFLAG_NORENDER ) return ; if( Element->Flags & ELEFLAG_INVISIBLE ) return ; - - Widget_Decorator_RenderWidget(Window, Element); + + if( Element->Type < ciWM_NumWidgetTypes + && gaWM_WidgetTypes[Element->Type] + && gaWM_WidgetTypes[Element->Type]->Render + ) + { + gaWM_WidgetTypes[Element->Type]->Render(Window, Element); + } + else + { + Widget_Decorator_RenderWidget(Window, Element); + } for(child = Element->FirstChild; child; child = child->NextSibling) { @@ -394,13 +394,13 @@ tElement *Widget_GetElementById(tWidgetWin *Info, uint32_t ID) } // --- Message Handlers --- -void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg) +void Widget_NewWidget(tWidgetWin *Info, size_t Len, const tWidgetMsg_Create *Msg) { const int max_debugname_len = Len - sizeof(tWidgetMsg_Create); tElement *parent, *new; // Sanity check - if( Len < sizeof(tWidgetMsg_Create) ) + if( Len < sizeof(*Msg) ) return ; if( strnlen(Msg->DebugName, max_debugname_len) == max_debugname_len ) return ; @@ -433,8 +433,8 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg) new->PaddingR = 2; new->CachedX = -1; - if( new->Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[new->Type].Init ) - gaWM_WidgetTypes[new->Type].Init(new); + if( new->Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[new->Type] && gaWM_WidgetTypes[new->Type]->Init ) + gaWM_WidgetTypes[new->Type]->Init(new); // Add to parent's list if(parent->LastChild) @@ -456,11 +456,11 @@ void Widget_NewWidget(tWidgetWin *Info, size_t Len, tWidgetMsg_Create *Msg) Widget_UpdateMinDims(parent); } -void Widget_SetFlags(tWidgetWin *Info, int Len, tWidgetMsg_SetFlags *Msg) +void Widget_SetFlags(tWidgetWin *Info, int Len, const tWidgetMsg_SetFlags *Msg) { tElement *ele; - if( Len < sizeof(tWidgetMsg_SetFlags) ) + if( Len < sizeof(*Msg) ) return ; _SysDebug("Widget_SetFlags: (%i 0x%x 0x%x)", Msg->WidgetID, Msg->Value, Msg->Mask); @@ -468,17 +468,15 @@ void Widget_SetFlags(tWidgetWin *Info, int Len, tWidgetMsg_SetFlags *Msg) ele = Widget_GetElementById(Info, Msg->WidgetID); if(!ele) return; - Msg->Value &= Msg->Mask; - ele->Flags &= ~Msg->Mask; - ele->Flags |= Msg->Value; + ele->Flags |= Msg->Value & Msg->Mask; } -void Widget_SetSize(tWidgetWin *Info, int Len, tWidgetMsg_SetSize *Msg) +void Widget_SetSize(tWidgetWin *Info, int Len, const tWidgetMsg_SetSize *Msg) { tElement *ele; - if( Len < sizeof(tWidgetMsg_SetSize) ) + if( Len < sizeof(*Msg) ) return ; ele = Widget_GetElementById(Info, Msg->WidgetID); @@ -487,22 +485,24 @@ void Widget_SetSize(tWidgetWin *Info, int Len, tWidgetMsg_SetSize *Msg) ele->FixedWith = Msg->Value; } -void Widget_SetText(tWidgetWin *Info, int Len, tWidgetMsg_SetText *Msg) +void Widget_SetText(tWidgetWin *Info, int Len, const tWidgetMsg_SetText *Msg) { tElement *ele; - if( Len < sizeof(tWidgetMsg_SetText) + 1 ) + if( Len < sizeof(*Msg) + 1 ) return ; - if( Msg->Text[Len - sizeof(tWidgetMsg_SetText) - 1] != '\0' ) + if( Msg->Text[Len - sizeof(*Msg) - 1] != '\0' ) return ; ele = Widget_GetElementById(Info, Msg->WidgetID); if(!ele) return ; - if( ele->Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[ele->Type].UpdateText ) + if( ele->Type < ciWM_NumWidgetTypes + && gaWM_WidgetTypes[ele->Type] + && gaWM_WidgetTypes[ele->Type]->UpdateText ) { - gaWM_WidgetTypes[ele->Type].UpdateText( ele, Msg->Text ); + gaWM_WidgetTypes[ele->Type]->UpdateText( ele, Msg->Text ); } // else // { @@ -511,13 +511,13 @@ void Widget_SetText(tWidgetWin *Info, int Len, tWidgetMsg_SetText *Msg) // } } -int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) +int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, const void *Data) { tWidgetWin *info = Target->RendererInfo; switch(Msg) { case WNDMSG_RESIZE: { - struct sWndMsg_Resize *msg = Data; + const struct sWndMsg_Resize *msg = Data; if(Len < sizeof(*msg)) return -1; info->RootElement.CachedW = msg->W; @@ -528,11 +528,11 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) return 0; } case WNDMSG_MOUSEMOVE: { - _SysDebug("TODO: Support widget mouse move events"); +// _SysDebug("TODO: Support widget mouse move events"); return 0; } case WNDMSG_MOUSEBTN: { - struct sWndMsg_MouseButton *msg = Data; + const struct sWndMsg_MouseButton *msg = Data; tWidgetMsg_MouseBtn client_msg; tElement *ele; int x, y; @@ -548,9 +548,11 @@ int Renderer_Widget_HandleMessage(tWindow *Target, int Msg, int Len, void *Data) // Send event to all elements from `ele` upwards for( ; ele; ele = ele->Parent ) { - if(ele->Type < ciWM_NumWidgetTypes && gaWM_WidgetTypes[ele->Type].MouseButton) + if(ele->Type < ciWM_NumWidgetTypes + && gaWM_WidgetTypes[ele->Type] + && gaWM_WidgetTypes[ele->Type]->MouseButton) { - rv = gaWM_WidgetTypes[ele->Type].MouseButton( + rv = gaWM_WidgetTypes[ele->Type]->MouseButton( ele, x - ele->CachedX, y - ele->CachedY, msg->Button, msg->bPressed @@ -606,75 +608,3 @@ void Widget_Fire(tElement *Element) WM_SendMessage(Element->Window, Element->Window, MSG_WIDGET_FIRE, sizeof(msg), &msg); } -// --- Type Helpers -void Widget_DispText_UpdateText(tElement *Element, const char *Text) -{ - int w=0, h=0; - - if(Element->Text) free(Element->Text); - Element->Text = strdup(Text); - - WM_Render_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; - } - - Widget_UpdateMinDims(Element->Parent); -} - -void Widget_Image_UpdateText(tElement *Element, const char *Text) -{ - if(Element->Data) free(Element->Data); - Element->Data = Image_Load( Text ); - if(!Element->Data) { -// Element->Flags &= ~ELEFLAG_FIXEDSIZE; - return ; - } - - Element->CachedW = ((tImage*)Element->Data)->Width; - Element->CachedH = ((tImage*)Element->Data)->Height; - - if(Element->Parent && (Element->Parent->Flags & ELEFLAG_VERTICAL) ) { - Element->MinCross = ((tImage*)Element->Data)->Width; - Element->MinWith = ((tImage*)Element->Data)->Height; - } - else { - Element->MinWith = ((tImage*)Element->Data)->Width; - Element->MinCross = ((tImage*)Element->Data)->Height; - } - - Widget_UpdateMinDims(Element->Parent); - - // 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 -} - -void Widget_TextInput_Init(tElement *Element) -{ - int h; - - // TODO: Select font correctly - WM_Render_GetTextDims(NULL, "jJ", NULL, &h); - - if( Element->Parent && (Element->Parent->Flags & ELEFLAG_VERTICAL) ) - Element->MinWith = h; - else - Element->MinCross = h; - - // No need to explicitly update parent min dims, as the AddElement routine does that -} - diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/button.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/button.c new file mode 100644 index 00000000..e4b252c3 --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/button.c @@ -0,0 +1,42 @@ +/* + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * renderer/widget/button.c + * - Button Widget Type + */ +#include +#include "./common.h" +#include "./colours.h" + +void Widget_Button_Render(tWindow *Window, tElement *Element) +{ + WM_Render_FillRect( + Window, + Element->CachedX+1, Element->CachedY+1, + Element->CachedW-2, Element->CachedH-2, + BUTTON_BGCOLOUR + ); + WM_Render_DrawRect( + Window, + Element->CachedX, Element->CachedY, + Element->CachedW-1, Element->CachedH-1, + BUTTON_BORDER + ); +} + +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 +} + +DEFWIDGETTYPE(ELETYPE_BUTTON, + .Render = Widget_Button_Render, + .MouseButton = Widget_Button_MouseButton + ) + diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/colours.h b/Usermode/Applications/axwin3_src/WM/renderers/widget/colours.h new file mode 100644 index 00000000..75500223 --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/colours.h @@ -0,0 +1,21 @@ +/** + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * renderer/widget/colours.h + * - Widget style definitions + */ +#ifndef _RENDERER_WIDGET_COLOURS_H +#define _RENDERER_WIDGET_COLOURS_H + +#define BOX_BGCOLOUR 0xC0C0C0 +#define BOX_BORDER 0xA0A0A0 +#define BUTTON_BGCOLOUR 0xD0D0D0 +#define BUTTON_BORDER 0xF0F0F0 +#define TEXT_COLOUR 0x000000 +#define TEXTINPUT_BACKGROUND 0xFFFFFF +#define TEXTINPUT_BORDER_OUT 0x404040 +#define TEXTINPUT_BORDER_IN 0x808080 + +#endif + diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h b/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h new file mode 100644 index 00000000..b4913334 --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h @@ -0,0 +1,51 @@ +/** + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * renderer/widget/common.h + * - Widget common definitions + */ +#ifndef _RENDERER_WIDGET_COMMON_H +#define _RENDERER_WIDGET_COMMON_H + +#include // Widget types + +typedef struct sWidgetDef tWidgetDef; + +struct sWidgetDef +{ + void (*Init)(tElement *Ele); + void (*Delete)(tElement *Ele); + + void (*Render)(tWindow *Window, 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); + /** + * \} + */ +}; + +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};\ +void _widget_set_##_type(void) __attribute__((constructor));\ +void _widget_set_##_type(void) { Widget_int_SetTypeDef(_type, &_widget_typedef_##_type);} + +#endif + diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/disptext.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/disptext.c new file mode 100644 index 00000000..4a091def --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/disptext.c @@ -0,0 +1,48 @@ +/* + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * renderer/widget/button.c + * - Button Widget Type + */ +#include +#include "./common.h" +#include "./colours.h" +#include + +void Widget_DispText_Render(tWindow *Window, tElement *Element) +{ + WM_Render_DrawText( + Window, + Element->CachedX+1, Element->CachedY+1, + Element->CachedW-2, Element->CachedH-2, + NULL, TEXT_COLOUR, + Element->Text + ); +} + +void Widget_DispText_UpdateText(tElement *Element, const char *Text) +{ + int w=0, h=0; + + if(Element->Text) free(Element->Text); + Element->Text = strdup(Text); + + WM_Render_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; + } + + Widget_UpdateMinDims(Element->Parent); +} + +DEFWIDGETTYPE(ELETYPE_TEXT, + .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 new file mode 100644 index 00000000..f1f3155c --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/image.c @@ -0,0 +1,53 @@ +/* + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * renderer/widget/image.c + * - Image Widget Type + */ +#include +#include "./common.h" +#include "./colours.h" +#include "../../include/image.h" + +void Widget_Image_Render(tWindow *Window, tElement *Element) +{ + WM_Render_DrawImage( + Window, + Element->CachedX, Element->CachedY, + Element->CachedW, Element->CachedH, + Element->Data + ); +} + +void Widget_Image_UpdateText(tElement *Element, const char *Text) +{ + if(Element->Data) free(Element->Data); + Element->Data = Image_Load( Text ); + if(!Element->Data) { +// Element->Flags &= ~ELEFLAG_FIXEDSIZE; + return ; + } + + Element->CachedW = ((tImage*)Element->Data)->Width; + Element->CachedH = ((tImage*)Element->Data)->Height; + + if(Element->Parent && (Element->Parent->Flags & ELEFLAG_VERTICAL) ) { + Element->MinCross = ((tImage*)Element->Data)->Width; + Element->MinWith = ((tImage*)Element->Data)->Height; + } + else { + Element->MinWith = ((tImage*)Element->Data)->Width; + Element->MinCross = ((tImage*)Element->Data)->Height; + } + + Widget_UpdateMinDims(Element->Parent); + + // NOTE: Doesn't update Element->Text because it's useless +} + +DEFWIDGETTYPE(ELETYPE_IMAGE, + .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 new file mode 100644 index 00000000..c2eea82c --- /dev/null +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/textinput.c @@ -0,0 +1,55 @@ +/* + * Acess2 Window Manager v3 + * - By John Hodge (thePowersGang) + * + * renderer/widget/textinput.c + * - Single line text box + */ +#include +#include "./common.h" +#include "./colours.h" + +void Widget_TextInput_Render(tWindow *Window, tElement *Element) +{ + WM_Render_FillRect( + Window, + Element->CachedX, Element->CachedY, + Element->CachedW, Element->CachedH, + TEXTINPUT_BACKGROUND + ); + WM_Render_DrawRect( + Window, + Element->CachedX, Element->CachedY, + Element->CachedW, Element->CachedH, + TEXTINPUT_BORDER_OUT + ); + WM_Render_DrawRect( + Window, + Element->CachedX+1, Element->CachedY+1, + Element->CachedW-2, Element->CachedH-2, + TEXTINPUT_BORDER_IN + ); + // TODO: Cursor? +} + +void Widget_TextInput_Init(tElement *Element) +{ + int h; + + // TODO: Select font correctly + WM_Render_GetTextDims(NULL, "jJ", NULL, &h); + + if( Element->Parent && (Element->Parent->Flags & ELEFLAG_VERTICAL) ) + Element->MinWith = h; + else + Element->MinCross = h; + + // No need to explicitly update parent min dims, as the AddElement routine does that +} + +DEFWIDGETTYPE(ELETYPE_TEXTINPUT, + .Render = Widget_TextInput_Render, + .Init = Widget_TextInput_Init + ); + + diff --git a/Usermode/Applications/axwin3_src/WM/renderer_widget_decorator.c b/Usermode/Applications/axwin3_src/WM/renderers/widget/widget_decorator.c similarity index 59% rename from Usermode/Applications/axwin3_src/WM/renderer_widget_decorator.c rename to Usermode/Applications/axwin3_src/WM/renderers/widget/widget_decorator.c index 8f6309f9..442e9fcc 100644 --- a/Usermode/Applications/axwin3_src/WM/renderer_widget_decorator.c +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/widget_decorator.c @@ -11,13 +11,7 @@ #define BORDER_EVERYTHING 1 -#define BOX_BGCOLOUR 0xC0C0C0 -#define BOX_BORDER 0xA0A0A0 -#define BUTTON_BGCOLOUR 0xD0D0D0 -#define BUTTON_BORDER 0xF0F0F0 -#define TEXT_COLOUR 0x000000 -#define TEXTINPUT_BACKGROUND 0xFFFFFF -#define TEXTINPUT_BORDER_OUT 0x404040 +#include "./colours.h" // === CODE === void Widget_Decorator_RenderWidget(tWindow *Window, tElement *Element) @@ -82,61 +76,17 @@ void Widget_Decorator_RenderWidget(tWindow *Window, tElement *Element) break; case ELETYPE_BUTTON: // Button - WM_Render_FillRect( - Window, - Element->CachedX+1, Element->CachedY+1, - Element->CachedW-2, Element->CachedH-2, - BUTTON_BGCOLOUR - ); - WM_Render_DrawRect( - Window, - Element->CachedX, Element->CachedY, - Element->CachedW-1, Element->CachedH-1, - BUTTON_BORDER - ); break; // Text input field / Text Box case ELETYPE_TEXTINPUT: case ELETYPE_TEXTBOX: - WM_Render_FillRect( - Window, - Element->CachedX, Element->CachedY, - Element->CachedW, Element->CachedH, - TEXTINPUT_BACKGROUND - ); - WM_Render_DrawRect( - Window, - Element->CachedX, Element->CachedY, - Element->CachedW, Element->CachedH, - TEXTINPUT_BORDER_OUT - ); -// WM_Render_DrawRect( -// Window, -// Element->CachedX+1, Element->CachedY+1, -// Element->CachedW-2, Element->CachedH-2, -// TEXTINPUT_BORDER_IN -// ); break; case ELETYPE_TEXT: - WM_Render_DrawText( - Window, - Element->CachedX+1, Element->CachedY+1, - Element->CachedW-2, Element->CachedH-2, - NULL, - TEXT_COLOUR, - Element->Text - ); break; case ELETYPE_IMAGE: - WM_Render_DrawImage( - Window, - Element->CachedX, Element->CachedY, - Element->CachedW, Element->CachedH, - Element->Data - ); break; default: diff --git a/Usermode/Applications/axwin3_src/WM/wm.c b/Usermode/Applications/axwin3_src/WM/wm.c index a056a52b..dad3b6eb 100644 --- a/Usermode/Applications/axwin3_src/WM/wm.c +++ b/Usermode/Applications/axwin3_src/WM/wm.c @@ -14,7 +14,7 @@ #include // === IMPORTS === -extern void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int Msg, int Len, void *Data); +extern void IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int Msg, int Len, const void *Data); // === GLOBALS === tWMRenderer *gpWM_Renderers; @@ -230,10 +230,16 @@ int WM_ResizeWindow(tWindow *Window, int W, int H) return 0; } -int WM_SendMessage(tWindow *Source, tWindow *Dest, int Message, int Length, void *Data) +int WM_SendMessage(tWindow *Source, tWindow *Dest, int Message, int Length, const void *Data) { if(Dest == NULL) return -2; if(Length > 0 && Data == NULL) return -1; + + if( Decorator_HandleMessage(Dest, Message, Length, Data) != 1 ) + { + // TODO: Catch errors from ->HandleMessage + return 0; + } // ->HandleMessage returns 1 when the message was not handled if( Dest->Renderer->HandleMessage(Dest, Message, Length, Data) != 1 ) diff --git a/Usermode/Applications/axwin3_src/WM/wm_input.c b/Usermode/Applications/axwin3_src/WM/wm_input.c index 66088f92..f15d25a7 100644 --- a/Usermode/Applications/axwin3_src/WM/wm_input.c +++ b/Usermode/Applications/axwin3_src/WM/wm_input.c @@ -47,8 +47,8 @@ void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY) struct sWndMsg_MouseMove msg; win = WM_int_GetWindowAtPos(OldX, OldY); - msg.X = NewX - win->X; - msg.Y = NewY - win->Y; + msg.X = NewX - win->X - win->BorderL; + msg.Y = NewY - win->Y - win->BorderT; msg.dX = NewX - OldX; msg.dY = NewY - OldY; WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg); @@ -62,8 +62,8 @@ void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY) // TODO: Send mouseup to match mousedown if the cursor moves out of a window? win = newWin; - msg.X = NewX - win->X; - msg.Y = NewY - win->Y; + msg.X = NewX - win->X - win->BorderL; + msg.Y = NewY - win->Y - win->BorderT; msg.dX = NewX - OldX; msg.dY = NewY - OldY; WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg); @@ -73,8 +73,8 @@ inline void WM_Input_int_SendBtnMsg(tWindow *Win, int X, int Y, int Index, int P { struct sWndMsg_MouseButton msg; - msg.X = X - Win->X; - msg.Y = Y - Win->Y; + msg.X = X - Win->X - Win->BorderL; + msg.Y = Y - Win->Y - Win->BorderT; msg.Button = Index; msg.bPressed = !!Pressed; @@ -90,7 +90,7 @@ void WM_Input_MouseButton(int X, int Y, int ButtonIndex, int Pressed) // Handle press of primary button to change focus if( ButtonIndex == 0 && Pressed == 1 ) { - _SysDebug("Gave focus to %p", win); +// _SysDebug("Gave focus to %p", win); WM_FocusWindow(win); WM_RaiseWindow(win); } -- 2.20.1