Usermode/AxWin3 - Implemented Focus/Raising support
authorJohn Hodge <[email protected]>
Sat, 12 Nov 2011 14:41:42 +0000 (22:41 +0800)
committerJohn Hodge <[email protected]>
Sat, 12 Nov 2011 14:41:42 +0000 (22:41 +0800)
- Menus can now be closed :)

Usermode/Applications/axwin3_src/WM/include/wm.h
Usermode/Applications/axwin3_src/WM/include/wm_internals.h
Usermode/Applications/axwin3_src/WM/include/wm_messages.h
Usermode/Applications/axwin3_src/WM/main.c
Usermode/Applications/axwin3_src/WM/renderer_menu.c
Usermode/Applications/axwin3_src/WM/wm.c
Usermode/Applications/axwin3_src/WM/wm_input.c

index 86008be..35e7e21 100644 (file)
  */
 //! Render the window
 #define WINFLAG_SHOW           0x00000001
+//! Window isn't contained within the parent/owner
+#define WINFLAG_NONNESTED      0x00000002
 //! Window contents are valid
-#define WINFLAG_CLEAN          0x00000002
+#define WINFLAG_CLEAN          0x00000040
 //! All child windows are un-changed
-#define WINFLAG_CHILDCLEAN     0x00000004
+#define WINFLAG_CHILDCLEAN     0x00000080
 
 #define WINFLAG_RENDER_MASK    0x00FFFF00
 #define WINFLAG_USR_MASK       0xFF000000
@@ -43,6 +45,8 @@ extern void   WM_ShowWindow(tWindow *Window, int bShow);
 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 void    WM_GiveFocus(tWindow *Destination);
+extern void    WM_RaiseWindow(tWindow *Window);
 // --- 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);
index ea0826c..9b3c7f0 100644 (file)
@@ -15,8 +15,8 @@ struct sWindow
        tWindow *NextSibling;
        tWindow *PrevSibling;
 
+       // Render tree
        tWindow *Parent;
-
        tWindow *FirstChild;
        tWindow *LastChild;
 
index e4b4622..df20d77 100644 (file)
@@ -32,6 +32,11 @@ enum eWM_WindowMessages
        WNDMSG_CLASS_MAX = 0x2000,
 };
 
+struct sWndMsg_Bool
+{
+        uint8_t        Val;
+};
+
 struct sWndMsg_Resize
 {
        uint16_t        W, H;
index a2e1fda..a9c34b7 100644 (file)
@@ -69,6 +69,7 @@ int main(int argc, char *argv[])
                char    server_info[] = "AXWIN3_SERVER=00000";
                char    *envp[] = {server_info, NULL};
                char    *argv[] = {csInterfaceApp, NULL};
+               _SysDebug("server_tid = %i, &server_tid = %p", server_tid, &server_tid);
                sprintf(server_info, "AXWIN3_SERVER=%i", server_tid);
                execve(csInterfaceApp, argv, envp);
                exit(1);
index d4e078b..b70016d 100644 (file)
@@ -102,9 +102,6 @@ void Renderer_Menu_Redraw(tWindow *Window)
 {
        tMenuWindowInfo *info = Window->RendererInfo;
         int    w, h, y, i;
-       _SysDebug("TODO: Implement Renderer_Menu_Redraw");
-
-//     _SysDebug("info->nItems = %i", info->nItems);
 
        w = info->CachedW;
        h = ciMenu_TopPadding + ciMenu_BottomPadding;
@@ -310,54 +307,103 @@ int Renderer_Menu_int_AddItem(tWindow *Window, int Length, void *Data)
        return 0;
 }
 
+int Renderer_Menu_int_GetItemByPos(tWindow *Window, tMenuWindowInfo *Info, int X, int Y)
+{
+        int    i;
+
+       if( X < 0 || X >= Window->W )
+               return -1;
+       
+       for( i = 0; i < Info->nItems; i ++ )
+       {
+               if( !Info->Items[i] )   continue;
+                       
+               if( !Info->Items[i]->Label )
+               {
+                       // Spacer - doesn't hilight
+                       if(Y < ciMenu_SpacerHeight) {
+                               return -1;
+                       }
+                       Y -= ciMenu_SpacerHeight;
+               }
+               else
+               {
+                       // Normal item, set the hilight
+                       if(Y < ciMenu_ItemHeight) {
+                               return i;
+                       }
+                       Y -= ciMenu_ItemHeight;
+               }
+       }
+       return -1;
+}
+
 int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, void *Data)
 {
+       tMenuWindowInfo *info = Window->RendererInfo;
        switch(Msg)
        {
-       case WNDMSG_MOUSEMOVE: {
-               tMenuWindowInfo *info = Window->RendererInfo;
-               struct sWndMsg_MouseMove        *msg = Data;
-                int    new_hilight;
-
+       case WNDMSG_SHOW: {
+               struct sWndMsg_Bool     *msg = Data;
                if(Length < sizeof(*msg))       return -1;
-
-               if( msg->X < 0 || msg->X >= Window->W )
-               {
-                       new_hilight = -1;
+               if(msg->Val) {
+                       // Take focus?
+                       _SysDebug(" - Shown, take focus");
+                       WM_GiveFocus(Window);
                }
                else
                {
-                        int    i, y;
-                       y = msg->Y;
-                       new_hilight = -1;
-                       for( i = 0; i < info->nItems; i ++ )
+                       // Hide Children
+                       _SysDebug("- Hidden, hide the children!");
+               }
+               return 0; }
+       case WNDMSG_FOCUS: {
+               struct sWndMsg_Bool     *msg = Data;
+               if(Length < sizeof(*msg))       return -1;
+               if(!msg->Val) {
+                       // TODO: Catch if focus was given away to a child
+                       _SysDebug("- Lost focus");
+                       WM_ShowWindow(Window, 0);       // Hide!
+               }
+               else {
+                       _SysDebug("- Focus gained, TODO: Show accel keys");
+               }
+               return 0; }
+
+       case WNDMSG_MOUSEBTN: {
+               struct sWndMsg_MouseButton      *msg = Data;
+                int    item;
+               
+               if(Length < sizeof(*msg))       return -1;
+
+               if(msg->Button == 0 && msg->bPressed == 0)
+               {
+                       item = Renderer_Menu_int_GetItemByPos(Window, info, msg->X, msg->Y);
+                       if(item != -1)
                        {
-                               if( !info->Items[i] )   continue;
-                                       
-                               if( !info->Items[i]->Label )
-                               {
-                                       // Spacer - doesn't hilight
-                                       if(y < ciMenu_SpacerHeight) {
-                                               new_hilight = -1;
-                                               break;
-                                       }
-                                       y -= ciMenu_SpacerHeight;
-                               }
-                               else
-                               {
-                                       // Normal item, set the hilight
-                                       if(y < ciMenu_ItemHeight) {
-                                               new_hilight = i;
-                                               break;
-                                       }
-                                       y -= ciMenu_ItemHeight;
-                               }
+                               tMenuMsg_Select _msg;
+                               // TODO: Ignore sub-menus too
+                               _msg.ID = item;
+                               WM_SendMessage(Window, Window, MSG_MENU_SELECT, sizeof(_msg), &_msg);
+                               WM_ShowWindow(Window, 0);
                        }
                }
+                               
+
+               return 0; }     
+
+       case WNDMSG_MOUSEMOVE: {
+               struct sWndMsg_MouseMove        *msg = Data;
+                int    new_hilight;
+
+               if(Length < sizeof(*msg))       return -1;
+
+               new_hilight = Renderer_Menu_int_GetItemByPos(Window, info, msg->X, msg->Y);
 
                if( new_hilight != info->HilightedItem )
                {
                        info->HilightedItem = new_hilight;
+                       // TODO: Change sub-menu
                        WM_Invalidate(Window);
                }
 
index 4169155..38bbbf3 100644 (file)
@@ -70,6 +70,7 @@ tWindow *WM_CreateWindow(tWindow *Parent, tIPC_Client *Client, uint32_t ID, int
                        Parent->FirstChild = ret;
                ret->PrevSibling = Parent->LastChild;
                Parent->LastChild = ret;
+               ret->NextSibling = NULL;
        }
        else
        {
@@ -90,9 +91,39 @@ tWindow *WM_CreateWindowStruct(size_t ExtraSize)
        return ret;
 }
 
+void WM_RaiseWindow(tWindow *Window)
+{
+       tWindow *parent = Window->Parent;
+       if(!Window->Parent)     return ;
+       
+       // Remove from list
+       if(Window->PrevSibling)
+               Window->PrevSibling->NextSibling = Window->NextSibling;
+       if(Window->NextSibling)
+               Window->NextSibling->PrevSibling = Window->PrevSibling;
+       if(parent->FirstChild == Window)
+               parent->FirstChild = Window->NextSibling;
+       if(parent->LastChild == Window)
+               parent->LastChild = Window->PrevSibling;
+
+       // Append to end
+       if(parent->LastChild)
+               parent->LastChild->NextSibling = Window;
+       else
+               parent->FirstChild = Window;
+       Window->PrevSibling = parent->LastChild;
+       Window->NextSibling = NULL;
+       parent->LastChild = Window;
+}
+
 void WM_ShowWindow(tWindow *Window, int bShow)
 {
-       // TODO: Message window
+       // Message window
+       struct sWndMsg_Bool     _msg;
+       
+       _msg.Val = !!bShow;
+       WM_SendMessage(NULL, Window, WNDMSG_SHOW, sizeof(_msg), &_msg);
+       
        if(bShow)
                Window->Flags |= WINFLAG_SHOW;
        else
index 991b74e..af258ff 100644 (file)
@@ -9,9 +9,17 @@
 #include <wm_internals.h>
 #include <wm_messages.h>
 
+#define MAX_BUTTONS    3
+
 // === IMPORTS ===
 extern tWindow *gpWM_RootWindow;
 
+// === GLOBALS ===
+//! Window which will recieve the next keyboard event
+tWindow        *gpWM_FocusedWindow;
+//! Window in which the mouse button was originally pressed
+tWindow        *gpWM_DownStartWindow[MAX_BUTTONS];
+
 // === CODE ===
 tWindow *WM_int_GetWindowAtPos(int X, int Y)
 {
@@ -63,17 +71,60 @@ void WM_Input_MouseMoved(int OldX, int OldY, int NewX, int NewY)
        WM_SendMessage(NULL, win, WNDMSG_MOUSEMOVE, sizeof(msg), &msg);
 }
 
-void WM_Input_MouseButton(int X, int Y, int ButtonIndex, int Pressed)
+inline void WM_Input_int_SendBtnMsg(tWindow *Win, int X, int Y, int Index, int Pressed)
 {
-       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.X = X - Win->X;
+       msg.Y = Y - Win->Y;
+       msg.Button = Index;
        msg.bPressed = !!Pressed;
        
-       WM_SendMessage(NULL, win, WNDMSG_MOUSEBTN, sizeof(msg), &msg);
+       WM_SendMessage(NULL, Win, WNDMSG_MOUSEBTN, sizeof(msg), &msg);
+}
+
+void WM_Input_MouseButton(int X, int Y, int ButtonIndex, int Pressed)
+{
+       tWindow *win;
+
+       win = WM_int_GetWindowAtPos(X, Y);
+
+       // Handle press of primary button to change focus
+       if( ButtonIndex == 0 && Pressed == 1 )
+       {
+               _SysDebug("Gave focus to %p", win);
+               WM_GiveFocus(win);
+               WM_RaiseWindow(win);
+       }
+
+       // Make sure that even if the mouse has moved out of the original window,
+       // mouse release messages reach the window.
+       if( !Pressed && ButtonIndex < MAX_BUTTONS && gpWM_DownStartWindow[ButtonIndex] != win )
+       {
+               WM_Input_int_SendBtnMsg(gpWM_DownStartWindow[ButtonIndex], X, Y, ButtonIndex, 0);
+       }
+       if( Pressed && ButtonIndex < MAX_BUTTONS )
+       {
+               gpWM_DownStartWindow[ButtonIndex] = win;
+       }
+
+       // Send Press/Release message
+       WM_Input_int_SendBtnMsg(win, X, Y, ButtonIndex, Pressed);
+}
+
+// --- Manipulation Functions ---
+void WM_GiveFocus(tWindow *Destination)
+{
+       struct sWndMsg_Bool     _msg;
+       
+       if( gpWM_FocusedWindow == Destination )
+               return ;
+       
+       _msg.Val = 0;
+       WM_SendMessage(NULL, gpWM_FocusedWindow, WNDMSG_FOCUS, sizeof(_msg), &_msg);
+       _msg.Val = 1;
+       WM_SendMessage(NULL, Destination, WNDMSG_FOCUS, sizeof(_msg), &_msg);
+       
+       gpWM_FocusedWindow = Destination;
 }
 

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