Usermode/AxWin3 - Added decorator support
authorJohn Hodge <[email protected]>
Sun, 13 Nov 2011 14:08:52 +0000 (22:08 +0800)
committerJohn Hodge <[email protected]>
Sun, 13 Nov 2011 14:08:52 +0000 (22:08 +0800)
- Alongside comes window titles :)

18 files changed:
Usermode/Applications/axwin3_src/Interface/main.c
Usermode/Applications/axwin3_src/WM/Makefile
Usermode/Applications/axwin3_src/WM/decorator.c [new file with mode: 0644]
Usermode/Applications/axwin3_src/WM/include/decorator.h [new file with mode: 0644]
Usermode/Applications/axwin3_src/WM/include/wm.h
Usermode/Applications/axwin3_src/WM/include/wm_internals.h
Usermode/Applications/axwin3_src/WM/ipc.c
Usermode/Applications/axwin3_src/WM/renderer_menu.c
Usermode/Applications/axwin3_src/WM/renderer_widget.c
Usermode/Applications/axwin3_src/WM/renderer_widget_decorator.c
Usermode/Applications/axwin3_src/WM/wm.c
Usermode/Applications/axwin3_src/WM/wm_render.c
Usermode/Applications/axwin3_src/WM/wm_render_text.c
Usermode/Applications/axwin3_src/include/ipcmessages.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/include/internal.h
Usermode/Applications/axwin3_src/libaxwin3.so_src/wm.c
Usermode/include/axwin3/axwin.h
Usermode/include/axwin3/widget.h

index b4f0199..f8e3527 100644 (file)
 #include <axwin3/menu.h>
 
 #define SIDEBAR_WIDTH  36
+#define RUN_WIDTH      200
+#define RUN_HEIGHT     70
 
 // === PROTOTYPES ===
 void   create_sidebar(void);
 void   create_mainmenu(void);
+void   create_run_dialog(void);
 
 // === GLOBALS ===
 tHWND  gSidebar;
-tHWND  gSystemMenu;
 tAxWin3_Widget *gSidebarRoot;
+tHWND  gSystemMenu;
+tHWND  gRunDialog;
+tAxWin3_Widget *gRunInput;
  int   giScreenWidth;
  int   giScreenHeight;
 
@@ -36,9 +41,13 @@ int main(int argc, char *argv[])
 {
        // Connect to AxWin3 Server
        AxWin3_Connect(NULL);
+
+       // TODO: Register to be told when the display layout changes
+       AxWin3_GetDisplayDims(0, NULL, NULL, &giScreenWidth, &giScreenHeight);
        
        create_sidebar();
        create_mainmenu();
+       create_run_dialog();
        
        // Idle loop
        AxWin3_MainLoop();
@@ -50,9 +59,6 @@ void create_sidebar(void)
 {
        tAxWin3_Widget  *btn, *txt, *ele;
 
-       // TODO: Register to be told when the display layout changes
-       AxWin3_GetDisplayDims(0, NULL, NULL, &giScreenWidth, &giScreenHeight);
-
        // Create sidebar
        gSidebar = AxWin3_Widget_CreateWindow(NULL, SIDEBAR_WIDTH, giScreenHeight, ELEFLAG_VERTICAL);
        AxWin3_MoveWindow(gSidebar, 0, 0);
@@ -82,6 +88,9 @@ void create_sidebar(void)
        AxWin3_Widget_SetSize(txt, 20);
        AxWin3_Widget_SetText(txt, "3.0");
 
+       // Turn off decorations
+       AxWin3_DecorateWindow(gSidebar, 0);
+
        // Show!
        AxWin3_ShowWindow(gSidebar, 1); 
        
@@ -95,6 +104,7 @@ void mainmenu_app_textedit(void *unused)
 void mainmenu_run_dialog(void *unused)
 {
        _SysDebug("TODO: Show run dialog");
+       AxWin3_ShowWindow(gRunDialog, 1);
 }
 
 void create_mainmenu(void)
@@ -106,3 +116,44 @@ void create_mainmenu(void)
        AxWin3_Menu_AddItem(gSystemMenu, "Run\tWin+R", mainmenu_run_dialog, NULL, 0, NULL);
 }
 
+int run_dorun(tAxWin3_Widget *unused)
+{
+//     char *cmd = AxWin3_Widget_GetText(gRunInput);
+       AxWin3_ShowWindow(gRunDialog, 0);
+       return 0;
+}
+
+int run_close(tAxWin3_Widget *unused)
+{
+       AxWin3_ShowWindow(gRunDialog, 0);
+       return 0;
+}
+
+tAxWin3_Widget *make_textbutton(tAxWin3_Widget *Parent, const char *Label, tAxWin3_Widget_FireCb handler)
+{
+       tAxWin3_Widget  *ret, *txt;
+       ret = AxWin3_Widget_AddWidget(Parent, ELETYPE_BUTTON, ELEFLAG_NOSTRETCH, "_btn");
+       AxWin3_Widget_SetFireHandler(ret, handler);
+       txt = AxWin3_Widget_AddWidget(ret, ELETYPE_TEXT, 0, "_txt");
+       AxWin3_Widget_SetText(ret, Label);
+       return ret;
+}
+
+void create_run_dialog(void)
+{
+       tAxWin3_Widget  *root, *box, *ele;
+       
+       gRunDialog = AxWin3_Widget_CreateWindow(NULL, RUN_WIDTH, RUN_HEIGHT, ELEFLAG_VERTICAL);
+       AxWin3_SetWindowTitle(gRunDialog, "Run Program...");
+
+       AxWin3_MoveWindow(gRunDialog, giScreenWidth/2-RUN_WIDTH/2, giScreenHeight/2-RUN_HEIGHT/2);
+       root = AxWin3_Widget_GetRoot(gRunDialog);
+
+       gRunInput = AxWin3_Widget_AddWidget(root, ELETYPE_TEXTINPUT, 0, "Input");
+       AxWin3_Widget_SetFireHandler(gRunInput, run_dorun);
+       
+       box = AxWin3_Widget_AddWidget(root, ELETYPE_BOX, ELEFLAG_ALIGN_CENTER|ELEFLAG_NOSTRETCH, "Button Area");
+       ele = make_textbutton(box, "Ok", run_dorun);
+       ele = make_textbutton(box, "Cancel", run_close);
+}
+
index 986ed6d..0e501e0 100644 (file)
@@ -8,7 +8,9 @@ DIR := Apps/AxWin/3.0
 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 += renderer_classes.o renderer_passthru.o renderer_background.o
+OBJ += decorator.o
+OBJ += renderer_passthru.o
+OBJ += renderer_background.o
 OBJ += renderer_widget.o renderer_widget_decorator.o
 OBJ += renderer_menu.o
 
diff --git a/Usermode/Applications/axwin3_src/WM/decorator.c b/Usermode/Applications/axwin3_src/WM/decorator.c
new file mode 100644 (file)
index 0000000..52ffbfb
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Acess2 Window Manager v3 (axwin3)
+ * - By John Hodge (thePowersGang)
+ *
+ * decorator.c
+ * - Window Decorator
+ */
+#include <common.h>
+#include <wm.h>
+#include <decorator.h>
+
+// === PROTOTYPES ===
+void   Decorator_UpdateBorderSize(tWindow *Window);
+void   Decorator_Redraw(tWindow *Window);
+ int   Decorator_HandleMessage(tWindow *Window, int Message, int Length, void *Data);
+
+// === CONSTANTS ===
+tColour        cColourActive_Titlebar   = 0xFF8800;
+tColour        cColourActive_TitleText  = 0x000000;
+tColour        cColourInactive_Titlebar = 0xD0D0D0;
+tColour        cColourInactive_TitleText= 0x000000;
+tColour        cColour_SideBorder       = 0xD0D0D0;
+tColour        cColour_BottomBorder     = 0xD0D0D0;
+ int   ciTitlebarHeight        = 18;
+ int   ciSideBorderWidth       = 2;
+ int   ciBottomBorderWidth     = 4;
+
+// === CODE ===
+void Decorator_UpdateBorderSize(tWindow *Window)
+{
+       Window->BorderT = 0;
+       Window->BorderB = 0;
+       Window->BorderL = 0;
+       Window->BorderR = 0;
+       
+       Window->BorderT = ciTitlebarHeight;
+       if( Window->Flags & WINFLAG_MAXIMIZED )
+               return ;
+       
+       Window->BorderB = ciBottomBorderWidth;
+       Window->BorderR = ciSideBorderWidth;
+       Window->BorderL = ciSideBorderWidth;
+}
+
+void Decorator_Redraw(tWindow *Window)
+{
+        int    bActive = 1;
+        int    text_width, text_height;
+       
+       // TODO: Detect if window has focus
+       
+       // Draw title bar
+       WM_Render_FillRect(Window,
+               0, -ciTitlebarHeight, Window->W, ciTitlebarHeight,
+               (bActive ? cColourActive_Titlebar : cColourInactive_Titlebar)
+               );
+
+       WM_Render_GetTextDims(
+               NULL,   // TODO: Select font
+               Window->Title ? Window->Title : "jI",
+               &text_width, &text_height
+               );
+       WM_Render_DrawText(Window,
+               ciTitlebarHeight + 4, -(ciTitlebarHeight - (ciTitlebarHeight/2 - text_height/2)),
+               Window->W - ciTitlebarHeight - 4, text_height,
+               NULL,   // TODO: Select font
+               (bActive ? cColourActive_TitleText : cColourInactive_TitleText),
+               Window->Title ? Window->Title : "--"
+               );
+       
+       // Maximized windows don't have any other borders
+       if( Window->Flags & WINFLAG_MAXIMIZED )
+               return ;
+       
+       // Left
+       WM_Render_FillRect(Window,
+               -ciSideBorderWidth, -ciTitlebarHeight,
+               ciSideBorderWidth, Window->H + ciTitlebarHeight + ciBottomBorderWidth,
+               cColour_SideBorder
+               );
+       // Right
+       WM_Render_FillRect(Window,
+               Window->W, -ciTitlebarHeight,
+               ciSideBorderWidth, Window->H + ciTitlebarHeight + ciBottomBorderWidth,
+               cColour_SideBorder
+               );
+       // Bottom
+       WM_Render_FillRect(Window,
+               -ciSideBorderWidth, Window->H,
+               ciSideBorderWidth*2+Window->W, ciBottomBorderWidth,
+               cColour_BottomBorder
+               );
+}
+
+int Decorator_HandleMessage(tWindow *Window, int Message, int Length, void *Data)
+{
+       switch(Message)
+       {
+       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
new file mode 100644 (file)
index 0000000..ae84cdb
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Acess2 Window Manager v3 (axwin3)
+ * - By John Hodge (thePowersGang)
+ *
+ * include/decorator.h
+ * - Decorator definitions
+ */
+#ifndef _DECORATOR_H_
+#define _DECORATOR_H_
+
+#include <wm_internals.h>
+
+extern void    Decorator_UpdateBorderSize(tWindow *Window);
+extern void    Decorator_Redraw(tWindow *Window);
+extern int     Decorator_HandleMessage(tWindow *Window, int Message, int Length, void *Data);
+
+#endif
+
index d6fd3ad..d35a462 100644 (file)
@@ -8,6 +8,9 @@
 #ifndef _WM_H_
 #define _WM_H_
 
+#include <stdint.h>
+#include <stdlib.h>
+
 #include "image.h"
 
 // === CONSTANTS ===
  */
 //! Render the window
 #define WINFLAG_SHOW           0x00000001
-//! Window isn't contained within the parent/owner
-#define WINFLAG_NONNESTED      0x00000002
+//! Don't decoratate even if root
+#define WINFLAG_NODECORATE     0x00000002
+//! Window takes up all of screen
+#define WINFLAG_MAXIMIZED      0x00000005
 //! Window contents are valid
 #define WINFLAG_CLEAN          0x00000040
 //! All child windows are un-changed
@@ -41,9 +46,11 @@ typedef struct sIPC_Client   tIPC_Client;
 // --- Management
 extern tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int Flags, const char *Renderer);
 extern void    WM_Invalidate(tWindow *Window);
+extern void    WM_SetWindowTitle(tWindow *Window, const char *Title);
 extern void    WM_FocusWindow(tWindow *Destination);
 extern void    WM_RaiseWindow(tWindow *Window);
 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);
index 9b3c7f0..92bde4a 100644 (file)
@@ -24,12 +24,17 @@ struct sWindow
        uint32_t        ID;     //!< Client assigned ID
        tWMRenderer     *Renderer;
 
+       char    *Title;
+
         int    Flags;
-       
-        int    X;
-        int    Y;
-        int    W;
-        int    H;
+
+        int    BorderL, BorderR;
+        int    BorderT, BorderB;
+
+        int    RealW, RealH;   
+
+        int    X, Y;
+        int    W, H;
 
        void    *RendererInfo;  
 
index ffad8e5..46aff21 100644 (file)
@@ -331,9 +331,24 @@ int IPC_Msg_CreateWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
        return 0;
 }
 
+int IPC_Msg_SetWindowTitle(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
+{
+       tWindow *win;
+
+       if( Msg->Size < 1 )     return -1;
+       if( Msg->Data[ Msg->Size-1 ] != '\0' )  return -1;      
+
+       win = IPC_int_GetWindow(Client, Msg->Window);
+       if(!win)        return 1;
+
+       WM_SetWindowTitle(win, Msg->Data);
+
+       return 0;
+}
+
 int IPC_Msg_ShowWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
 {
-       tIPCMsg_ShowWindow      *info = (void*)Msg->Data;
+       tIPCMsg_Boolean *info = (void*)Msg->Data;
        tWindow *win;
        
        if( Msg->Size < sizeof(*info) ) return -1;
@@ -341,8 +356,22 @@ int IPC_Msg_ShowWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
        win = IPC_int_GetWindow(Client, Msg->Window);
        if(!win)        return 1;
 
-       WM_ShowWindow(win, !!info->bShow);
+       WM_ShowWindow(win, !!info->Value);
+       
+       return 0;
+}
+
+int IPC_Msg_DecorateWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
+{
+       tIPCMsg_Boolean *info = (void*)Msg->Data;
+       tWindow *win;
        
+       if( Msg->Size < sizeof(*info) ) return -1;
+       
+       win = IPC_int_GetWindow(Client, Msg->Window);
+       if(!win)        return 1;
+       
+       WM_DecorateWindow(win, !!info->Value);
        return 0;
 }
 
@@ -474,6 +503,14 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW
                _SysDebug(" IPC_Handle: IPCMSG_CREATEWIN");
                rv = IPC_Msg_CreateWin(client, Msg);
                break;
+       // TODO: Destroy window
+       
+       // --- Set window title
+       case IPCMSG_SETWINTITLE:
+               _SysDebug(" IPC_Handle: IPCMSG_SETWINTITLE");
+               rv = IPC_Msg_SetWindowTitle(client, Msg);
+               break;
+
        // --- Give a window focus
        case IPCMSG_FOCUSWINDOW:
                _SysDebug(" IPC_Handle: IPCMSG_FOCUSWINDOW");
@@ -484,6 +521,10 @@ void IPC_Handle(const tIPC_Type *IPCType, const void *Ident, size_t MsgLen, tAxW
                _SysDebug(" IPC_Handle: IPCMSG_SHOWWINDOW");
                rv = IPC_Msg_ShowWindow(client, Msg);
                break;
+       case IPCMSG_DECORATEWINDOW:
+               _SysDebug(" IPC_Handle: IPCMSG_DECORATEWINDOW");
+               rv = IPC_Msg_DecorateWindow(client, Msg);
+               break;
        // --- Move/Resize a window
        case IPCMSG_SETWINPOS:
                _SysDebug(" IPC_Handle: IPCMSG_SETWINPOS");
index 7d07c93..45c6a24 100644 (file)
@@ -93,7 +93,10 @@ tWindow      *Renderer_Menu_Create(int Argument)
        info->MaxItems = Argument;
        info->HilightedItem = -1;
 
-       _SysDebug("Renderer_Menu_Create: ->MaxItems = %i", info->MaxItems);
+       ret->Flags |= WINFLAG_NODECORATE;
+       ret->H = ciMenu_TopPadding + ciMenu_BottomPadding;
+
+//     _SysDebug("Renderer_Menu_Create: ->MaxItems = %i", info->MaxItems);
        
        return ret;
 }
@@ -104,6 +107,7 @@ void Renderer_Menu_Redraw(tWindow *Window)
         int    w, h, y, i;
 
        w = info->CachedW;
+       #if 0
        h = ciMenu_TopPadding + ciMenu_BottomPadding;
        for( i = 0; i < info->nItems; i ++ )
        {
@@ -114,12 +118,12 @@ void Renderer_Menu_Redraw(tWindow *Window)
                else
                        h += ciMenu_SpacerHeight;
        }
+       #else
+       h = Window->H;
+       #endif
 
 //     _SysDebug("w = %i, h = %i", w, h);
 
-       // - Resize window to contain all items
-       WM_ResizeWindow(Window, w, h);
-
        // - Move the window such that it is on screen
        //  > Make sure to catch if the menu can't fit fully onscreen
 
@@ -212,7 +216,10 @@ int Renderer_Menu_int_AddItem(tWindow *Window, int Length, void *Data)
        }
        
        // Don't overwrite
-       if(info->Items[req->ID])        return 0;
+       if(info->Items[req->ID]) {
+               _SysDebug("- Caught overwrite of %i", req->ID);
+               return 0;
+       }
        // Bookkeeping
        if(req->ID >= info->nItems)     info->nItems = req->ID + 1;
        // Allocate
@@ -223,6 +230,7 @@ int Renderer_Menu_int_AddItem(tWindow *Window, int Length, void *Data)
        {
                // Spacer
                item->Label = NULL;
+               WM_ResizeWindow(Window, info->CachedW, Window->H+ciMenu_SpacerHeight);
                
                return 0;
        }
@@ -300,10 +308,8 @@ int Renderer_Menu_int_AddItem(tWindow *Window, int Length, void *Data)
                info->CachedW = ciMenu_LeftPadding + info->MaxLabelWidth
                        + ciMenu_Gap + info->MaxShortcutWidth
                        + ciMenu_RightPadding;
-               // TODO: Smarter height?
-               //  Doesn't matter a lot here really
-               WM_ResizeWindow(Window, info->CachedW, info->nItems*ciMenu_ItemHeight);
        }
+       WM_ResizeWindow(Window, info->CachedW, Window->H+ciMenu_ItemHeight);
        
        return 0;
 }
@@ -414,7 +420,7 @@ int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, void *Data
 
        // Manipulation messages
        case MSG_MENU_ADDITEM:
-               _SysDebug("MSG_MENU_ADDITEM");
+//             _SysDebug("MSG_MENU_ADDITEM");
                return Renderer_Menu_int_AddItem(Window, Length, Data);
        
        // Only message to pass to client
index 2c47bb7..c4799e9 100644 (file)
@@ -31,9 +31,10 @@ 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_TextBox_UpdateText(tElement *Element, const char *Text);
+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);
 
 // === GLOBALS ===
 tWMRenderer    gRenderer_Widget = {
@@ -68,9 +69,11 @@ struct {
 }      gaWM_WidgetTypes[NUM_ELETYPES] = {
        {0},    // NULL
        {0},    // Box
-       {.UpdateText = Widget_TextBox_UpdateText},      // Text
+       {.UpdateText = Widget_DispText_UpdateText},     // Text
        {.UpdateText = Widget_Image_UpdateText},        // Image
-       {.MouseButton = Widget_Button_MouseButton}      // Button
+       {.MouseButton = Widget_Button_MouseButton},     // Button
+       {0},    // Spacer
+       {.Init = Widget_TextInput_Init},        // Text Box (Single Line)
 };
 const int      ciWM_NumWidgetTypes = sizeof(gaWM_WidgetTypes)/sizeof(gaWM_WidgetTypes[0]);
 
@@ -604,7 +607,7 @@ void Widget_Fire(tElement *Element)
 }
 
 // --- Type Helpers
-void Widget_TextBox_UpdateText(tElement *Element, const char *Text)
+void Widget_DispText_UpdateText(tElement *Element, const char *Text)
 {
         int    w=0, h=0;
 
@@ -660,3 +663,18 @@ int Widget_Button_MouseButton(tElement *Element, int X, int Y, int Button, int b
        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    
+}
+
index e66da73..8f6309f 100644 (file)
@@ -16,6 +16,8 @@
 #define BUTTON_BGCOLOUR 0xD0D0D0
 #define BUTTON_BORDER   0xF0F0F0
 #define        TEXT_COLOUR     0x000000
+#define TEXTINPUT_BACKGROUND   0xFFFFFF
+#define TEXTINPUT_BORDER_OUT   0x404040
 
 // === CODE ===
 void Widget_Decorator_RenderWidget(tWindow *Window, tElement *Element)
@@ -93,6 +95,29 @@ void Widget_Decorator_RenderWidget(tWindow *Window, tElement *Element)
                        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(
index 17540a8..a056a52 100644 (file)
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <video.h>
 #include <wm_messages.h>
+#include <decorator.h>
 
 // === IMPORTS ===
 extern void    IPC_SendWMMessage(tIPC_Client *Client, uint32_t Src, uint32_t Dst, int Msg, int Len, void *Data);
@@ -27,7 +28,7 @@ void WM_Initialise(void)
        WM_CreateWindow(NULL, NULL, 0, 0x0088FF, "Background");
        gpWM_RootWindow->W = giScreenWidth;
        gpWM_RootWindow->H = giScreenHeight;
-       gpWM_RootWindow->Flags = WINFLAG_SHOW;
+       gpWM_RootWindow->Flags = WINFLAG_SHOW|WINFLAG_NODECORATE;
 }
 
 void WM_RegisterRenderer(tWMRenderer *Renderer)
@@ -61,7 +62,7 @@ tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int
        ret->ID = ID;
        ret->Parent = Parent;
        ret->Renderer = renderer;
-       ret->Flags = WINFLAG_CLEAN;     // Needed to stop invaildate early exiting
+       ret->Flags |= WINFLAG_CLEAN;    // Needed to stop invaildate early exiting
 
        // Append to parent
        if(Parent)
@@ -79,6 +80,12 @@ tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int
                gpWM_RootWindow = ret;
        }
 
+       // Don't decorate child windows by default
+       if(Parent != gpWM_RootWindow)
+       {
+               ret->Flags |= WINFLAG_NODECORATE;
+       }
+       
        // - Return!
        return ret;
 }
@@ -93,6 +100,14 @@ tWindow *WM_CreateWindowStruct(size_t ExtraSize)
        return ret;
 }
 
+void WM_SetWindowTitle(tWindow *Window, const char *Title)
+{
+       if(Window->Title)
+               free(Window->Title);
+       Window->Title = strdup(Title);
+       _SysDebug("Window %p title set to '%s'", Window, Title);
+}
+
 void WM_RaiseWindow(tWindow *Window)
 {
        tWindow *parent = Window->Parent;
@@ -154,6 +169,27 @@ void WM_ShowWindow(tWindow *Window, int bShow)
                if( Window == gpWM_FocusedWindow )
                        WM_FocusWindow(Window->Parent);
        }
+       // Just a little memory saving for large hidden windows
+       if(Window->RenderBuffer)
+               free(Window->RenderBuffer);
+       
+       WM_Invalidate(Window);
+}
+
+void WM_DecorateWindow(tWindow *Window, int bDecorate)
+{
+       if( !(Window->Flags & WINFLAG_NODECORATE) == !!bDecorate )
+               return ;
+       
+       if(bDecorate)
+               Window->Flags &= ~WINFLAG_NODECORATE;
+       else
+               Window->Flags |= WINFLAG_NODECORATE;
+       
+       // Needed because the window size changes
+       if(Window->RenderBuffer)
+               free(Window->RenderBuffer);
+       
        WM_Invalidate(Window);
 }
 
@@ -177,9 +213,11 @@ int WM_ResizeWindow(tWindow *Window, int W, int H)
        if(W <= 0 || H <= 0 )   return 1;
        if(Window->X + W < 0)   Window->X = -W + 1;
        if(Window->Y + H < 0)   Window->Y = -H + 1;
-       
+
        Window->W = W;  Window->H = H;
 
+       if(Window->RenderBuffer)
+               free(Window->RenderBuffer);
        WM_Invalidate(Window);
 
        {
@@ -252,6 +290,25 @@ void WM_int_UpdateWindow(tWindow *Window)
        // Render
        if( !(Window->Flags & WINFLAG_CLEAN) )
        {
+               // Calculate RealW/RealH
+               if( !(Window->Flags & WINFLAG_NODECORATE) )
+               {
+                       _SysDebug("Applying decorations to %p", Window);
+                       Decorator_UpdateBorderSize(Window);
+                       Window->RealW = Window->BorderL + Window->W + Window->BorderR;
+                       Window->RealH = Window->BorderT + Window->H + Window->BorderB;
+                       Decorator_Redraw(Window);
+               }
+               else
+               {
+                       Window->BorderL = 0;
+                       Window->BorderR = 0;
+                       Window->BorderT = 0;
+                       Window->BorderB = 0;
+                       Window->RealW = Window->W;
+                       Window->RealH = Window->H;
+               }
+               
                Window->Renderer->Redraw(Window);
                Window->Flags |= WINFLAG_CLEAN;
        }
@@ -276,8 +333,8 @@ void WM_int_BlitWindow(tWindow *Window)
        if( !(Window->Flags & WINFLAG_SHOW) )
                return ;
 
-       _SysDebug("Blit %p to (%i,%i) %ix%i", Window, Window->X, Window->Y, Window->W, Window->H);
-       Video_Blit(Window->RenderBuffer, Window->X, Window->Y, Window->W, Window->H);
+       _SysDebug("Blit %p to (%i,%i) %ix%i", Window, Window->X, Window->Y, Window->RealW, Window->RealH);
+       Video_Blit(Window->RenderBuffer, Window->X, Window->Y, Window->RealW, Window->RealH);
        
        for( child = Window->FirstChild; child; child = child->NextSibling )
        {
index 7f4a53b..84b7b41 100644 (file)
@@ -15,23 +15,26 @@ void WM_Render_FillRect(tWindow *Window, int X, int Y, int W, int H, tColour Col
 {
        uint32_t        *dest;
         int    i;
-//     _SysDebug("WM_Render_FilledRect(%p, 0x%x...", Window, Colour);
-//     _SysDebug(" (%i,%i), %ix%i)", X, Y, W, H);
+
+       X += Window->BorderL;   
+       Y += Window->BorderT;
+
        // Clip to window dimensions
        if(X < 0) { W += X; X = 0; }
        if(Y < 0) { H += Y; Y = 0; }
        if(W <= 0 || H <= 0)    return;
-       if(X >= Window->W)      return;
-       if(Y >= Window->H)      return;
-       if(X + W > Window->W)   W = Window->W - X;
-       if(Y + H > Window->H)   H = Window->H - Y;
-//     _SysDebug(" Clipped to (%i,%i), %ix%i", X, Y, W, H);
+       if(X >= Window->RealW)  return;
+       if(Y >= Window->RealH)  return;
+       if(X + W > Window->RealW)       W = Window->RealW - X;
+       if(Y + H > Window->RealH)       H = Window->RealH - Y;
+
+       // TODO: Catch overflow into decorator area
 
        if(!Window->RenderBuffer) {
-               Window->RenderBuffer = malloc(Window->W*Window->H*4);
+               Window->RenderBuffer = malloc(Window->RealW*Window->RealH*4);
        }
 
-       dest = (uint32_t*)Window->RenderBuffer + Y*Window->W + X;
+       dest = (uint32_t*)Window->RenderBuffer + Y*Window->RealW + X;
        while( H -- )
        {
                for( i = W; i --; )
@@ -65,20 +68,35 @@ void WM_Render_DrawImage(tWindow *Window, int X, int Y, int W, int H, tImage *Im
        if(!Window->RenderBuffer) {
                Window->RenderBuffer = malloc(Window->W*Window->H*4);
        }
-       
+
+       // Apply offset
+       X += Window->BorderL;
+       Y += Window->BorderT;
+
        // Bounds Check
-       if( X >= Window->W )    return ;
-       if( Y >= Window->H )    return ;
+       if( X >= Window->RealW )        return ;
+       if( Y >= Window->RealH )        return ;
        
        // Wrap to image size
        if( W > Image->Width )  W = Image->Width;
        if( H > Image->Height ) H = Image->Height;
        
        // Wrap to screen size
-       if( X + W > Window->W ) W = Window->W - X;
-       if( Y + H > Window->H ) H = Window->H - Y;
+       if( X + W > Window->RealW )     W = Window->RealW - X;
+       if( Y + H > Window->RealH )     H = Window->RealH - Y;
+
+       // TODO: Catch overflow into decorator area
+       #if 0
+       if( !Window->bDrawingDecorations )
+       {
+               if( X < Window->BorderL )       return ;
+               if( Y < Window->BorderT )       return ;
+               if( X + W > Window->BorderL + Window->W )       W = X - (Window->BorderL + Window->W);
+               if( Y + H > Window->BorderT + Window->H )       H = Y - (Window->BorderT + Window->H);
+       }
+       #endif
 
-       dest = (uint32_t*)Window->RenderBuffer + Y * Window->W + X;
+       dest = (uint32_t*)Window->RenderBuffer + Y * Window->RealW + X;
        data = Image->Data;
 
        // Do the render
@@ -116,7 +134,7 @@ void WM_Render_DrawImage(tWindow *Window, int X, int Y, int W, int H, tImage *Im
                                dest[x] = b | (g << 8) | (r << 16);
                        }
                        data += Image->Width * 4;
-                       dest += Window->W;
+                       dest += Window->RealW;
                }
                break;
        
@@ -130,7 +148,7 @@ void WM_Render_DrawImage(tWindow *Window, int X, int Y, int W, int H, tImage *Im
                                dest[x] = data[x*3+2] | (data[x*3+1] << 8) | (data[x*3+0] << 16);
                        }
                        data += W * 3;
-                       dest += Window->W;
+                       dest += Window->RealW;
                }
                break;
        default:
index 362669b..4ce35cb 100644 (file)
@@ -78,13 +78,19 @@ int WM_Render_DrawText(tWindow *Window, int X, int Y, int W, int H, tFont *Font,
        
        if(!Text)       return 0;
 
+
+       X += Window->BorderL;
+       Y += Window->BorderT;
+
        // Check the bounds
-       if(W < 0 || X < 0 || X >= Window->W)    return 0;
-       if(X + W > Window->W)   W = Window->W - X;
+       if(W < 0 || X < 0 || X >= Window->RealW)        return 0;
+       if(X + W > Window->RealW)       W = Window->RealW - X;
        
-       if(H < 0 || Y < 0 || Y >= Window->H)    return 0;
-       if(Y + H > Window->H)   H = Window->H - Y;
+       if(H < 0 || Y < 0 || Y >= Window->RealH)        return 0;
+       if(Y + H > Window->RealH)       H = Window->RealH - Y;
        
+       // TODO: Catch trampling of decorations
+
        // Handle NULL font (system default monospace)
        if( !Font )     Font = &gSystemFont;
        
@@ -239,7 +245,7 @@ void _RenderGlyph(tWindow *Window, short X, short Y, tGlyph *Glyph, uint32_t Col
        }
 
 //     _SysDebug("X = %i, Y = %i", X, Y);
-       outBuf = (uint32_t*)Window->RenderBuffer + Y*Window->W + X;
+       outBuf = (uint32_t*)Window->RenderBuffer + Y*Window->RealW + X;
        inBuf = Glyph->Bitmap + yStart*Glyph->TrueWidth;
 
        for( y = yStart; y < Glyph->TrueHeight; y ++ )
@@ -248,7 +254,7 @@ void _RenderGlyph(tWindow *Window, short X, short Y, tGlyph *Glyph, uint32_t Col
                {
                        outBuf[dst_x] = Video_AlphaBlend( outBuf[dst_x], Color, inBuf[x] );
                }
-               outBuf += Window->W;
+               outBuf += Window->RealW;
                inBuf += Glyph->TrueWidth;
        }
 }
index a3fda63..a752e36 100644 (file)
@@ -14,7 +14,7 @@
 typedef struct sAxWin_IPCMessage       tAxWin_IPCMessage;
 typedef struct sIPCMsg_ReturnInt       tIPCMsg_ReturnInt;
 typedef struct sIPCMsg_CreateWin       tIPCMsg_CreateWin;
-typedef struct sIPCMsg_ShowWindow      tIPCMsg_ShowWindow;
+typedef struct sIPCMsg_Boolean tIPCMsg_Boolean;
 typedef struct sIPCMsg_SetWindowPos    tIPCMsg_SetWindowPos;
 typedef struct sIPCMsg_SendMsg tIPCMsg_SendMsg;
 
@@ -60,9 +60,9 @@ struct sIPCMsg_SendMsg
        char    Data[];
 };
 
-struct sIPCMsg_ShowWindow
+struct sIPCMsg_Boolean
 {
-       uint32_t        bShow;
+       uint32_t        Value;
 };
 
 struct sIPCMsg_SetWindowPos
@@ -95,7 +95,9 @@ enum eAxWin_IPCMessageTypes
        IPCMSG_SENDMSG,         //!< Send a message to another window (or to self)
        IPCMSG_CREATEWIN,       //!< Create a window
        IPCMSG_DESTROYWIN,      //!< Destroy a window
+       IPCMSG_SETWINTITLE,     //!< Set window title
        IPCMSG_SHOWWINDOW,      //!< Show/Hide a window
+       IPCMSG_DECORATEWINDOW,  //!< Enable/Disable decorations
        IPCMSG_FOCUSWINDOW,     //!< Give a window focus (no data)
        IPCMSG_SETWINPOS,       //!< Set a window position
 };
index f7fd257..913cf35 100644 (file)
@@ -10,6 +10,8 @@
 
 #include <stdint.h>
 
+extern void    _SysDebug(const char *Fmt, ...);
+
 struct sAxWin3_Window
 {
        uint32_t        ServerID;
index d64bcbc..4a6242b 100644 (file)
@@ -196,6 +196,19 @@ void AxWin3_int_HandleMessage(tAxWin_IPCMessage *Msg)
        }
 }
 
+void AxWin3_SetWindowTitle(tHWND Window, const char *Title)
+{
+       tAxWin_IPCMessage       *msg;
+        int    len = strlen(Title);
+       
+       msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SETWINTITLE, 0, len+1);
+       strcpy(msg->Data, Title);
+       
+       AxWin3_int_SendIPCMessage(msg);
+       
+       free(msg);
+}
+
 void AxWin3_SendMessage(tHWND Window, tHWND Destination, int Message, int Length, void *Data)
 {
        tAxWin_IPCMessage       *msg;
@@ -225,11 +238,25 @@ void AxWin3_FocusWindow(tHWND Window)
 void AxWin3_ShowWindow(tHWND Window, int bShow)
 {
        tAxWin_IPCMessage       *msg;
-       tIPCMsg_ShowWindow      *info;
+       tIPCMsg_Boolean *info;
 
        msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_SHOWWINDOW, 0, sizeof(*info));
        info = (void*)msg->Data;
-       info->bShow = !!bShow;
+       info->Value = !!bShow;
+       
+       AxWin3_int_SendIPCMessage(msg);
+       
+       free(msg);
+}
+
+void AxWin3_DecorateWindow(tHWND Window, int bDecorate)
+{
+       tAxWin_IPCMessage       *msg;
+       tIPCMsg_Boolean *info;
+
+       msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_DECORATEWINDOW, 0, sizeof(*info));
+       info = (void*)msg->Data;
+       info->Value = !!bDecorate;
        
        AxWin3_int_SendIPCMessage(msg);
        
index 07bfe04..fe116e9 100644 (file)
@@ -8,6 +8,9 @@
 #ifndef _AXWIN3_AXWIN_H_
 #define _AXWIN3_AXWIN_H_
 
+// === CONSTANTS ===
+
+// === TYPES ===
 typedef struct sAxWin3_Window  *tHWND;
 typedef unsigned int   tAxWin3_Colour; // TODO: Actual 32-bit
 
@@ -49,8 +52,10 @@ extern void  AxWin3_DestroyWindow(tHWND Window);
 
 // --- Core window management functions
 extern void    AxWin3_SendMessage(tHWND Window, tHWND Dest, int Message, int Length, void *Data);
+extern void    AxWin3_SetWindowTitle(tHWND Window, const char *Title);
 extern void    AxWin3_FocusWindow(tHWND Window);
 extern void    AxWin3_ShowWindow(tHWND Window, int bShow);
+extern void    AxWin3_DecorateWindow(tHWND Window, int bDecorate);
 extern void    AxWin3_SetWindowPos(tHWND Window, short X, short Y, short W, short H);
 extern void    AxWin3_MoveWindow(tHWND Window, short X, short Y);
 extern void    AxWin3_ResizeWindow(tHWND Window, short W, short H);
index fca8f04..0329425 100644 (file)
@@ -49,6 +49,8 @@ enum eElementTypes
        ELETYPE_IMAGE,  //!< Image
        ELETYPE_BUTTON, //!< Push Button
        ELETYPE_SPACER, //!< Visual Spacer (horizontal / vertical rule)
+       ELETYPE_TEXTINPUT,      //!< Text Input Field
+       ELETYPE_TEXTBOX,        //!< Text Box Input
 
        ELETYPE_TABBAR, //!< Tab Bar
        ELETYPE_TOOLBAR,        //!< Tool Bar

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