// --- 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_FocusWindow(tWindow *Destination);
+extern void WM_RaiseWindow(tWindow *Window);
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);
#include <ipcmessages.h>
#include <stdio.h>
#include <wm.h>
+#include <wm_internals.h>
#define AXWIN_PORT 4101
tWindow **Windows;
};
+// === IMPORTS ===
+extern tWindow *gpWM_FocusedWindow; // Needed for _FocusWindow
// === PROTOTYPES ===
void IPC_Init(void);
return 0;
}
+int IPC_Msg_FocusWindow(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
+{
+ tWindow *win;
+
+ // Don't allow the focus to be changed unless the client has the focus
+ if(!gpWM_FocusedWindow) return 1;
+ if(gpWM_FocusedWindow->Client != Client) return 1;
+
+ win = IPC_int_GetWindow(Client, Msg->Window);
+ if(!win) return 1;
+
+ WM_FocusWindow(win);
+
+ return 0;
+}
+
int IPC_Msg_CreateWin(tIPC_Client *Client, tAxWin_IPCMessage *Msg)
{
tIPCMsg_CreateWin *info = (void*)Msg->Data;
_SysDebug(" IPC_Handle: IPCMSG_CREATEWIN");
rv = IPC_Msg_CreateWin(client, Msg);
break;
+ // --- Give a window focus
+ case IPCMSG_FOCUSWINDOW:
+ _SysDebug(" IPC_Handle: IPCMSG_FOCUSWINDOW");
+ rv = IPC_Msg_FocusWindow(client, Msg);
+ break;
// --- Show/Hide a window
case IPCMSG_SHOWWINDOW:
_SysDebug(" IPC_Handle: IPCMSG_SHOWWINDOW");
if(item->UnderlineW)
{
WM_Render_FillRect(Window,
- ciMenu_LeftPadding + item->UnderlineX, y + ciMenu_FontHeight + 1,
+ ciMenu_LeftPadding + item->UnderlineX, y + ciMenu_FontHeight,
item->UnderlineW, 1,
cMenu_LabelColour
);
+ 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);
}
if( !Info->Items[i]->Label )
{
- // Spacer - doesn't hilight
+ // Spacer - not selectable
if(Y < ciMenu_SpacerHeight) {
return -1;
}
}
else
{
- // Normal item, set the hilight
+ // Normal item, can be selected/hilighted
if(Y < ciMenu_ItemHeight) {
return i;
}
case WNDMSG_SHOW: {
struct sWndMsg_Bool *msg = Data;
if(Length < sizeof(*msg)) return -1;
- if(msg->Val) {
- // Take focus?
- _SysDebug(" - Shown, take focus");
- WM_GiveFocus(Window);
+ if(msg->Val)
+ {
+// _SysDebug(" - Shown, take focus");
+ // TODO: This shouldn't really be done, instead focus should be given
+ // when the menu is shown.
+// WM_FocusWindow(Window);
}
else
{
// === GLOBALS ===
tWMRenderer *gpWM_Renderers;
tWindow *gpWM_RootWindow;
+//! Window which will recieve the next keyboard event
+tWindow *gpWM_FocusedWindow;
// === CODE ===
void WM_Initialise(void)
parent->LastChild = Window;
}
+void WM_FocusWindow(tWindow *Destination)
+{
+ struct sWndMsg_Bool _msg;
+
+ if( gpWM_FocusedWindow == Destination )
+ return ;
+ if( Destination && !(Destination->Flags & WINFLAG_SHOW) )
+ 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;
+}
+
+
void WM_ShowWindow(tWindow *Window, int bShow)
{
// Message window
struct sWndMsg_Bool _msg;
+ if( !!(Window->Flags & WINFLAG_SHOW) == bShow )
+ return ;
+
_msg.Val = !!bShow;
WM_SendMessage(NULL, Window, WNDMSG_SHOW, sizeof(_msg), &_msg);
if(bShow)
Window->Flags |= WINFLAG_SHOW;
- else
+ else {
Window->Flags &= ~WINFLAG_SHOW;
+ if( Window == gpWM_FocusedWindow )
+ WM_FocusWindow(Window->Parent);
+ }
WM_Invalidate(Window);
}
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];
if( ButtonIndex == 0 && Pressed == 1 )
{
_SysDebug("Gave focus to %p", win);
- WM_GiveFocus(win);
+ WM_FocusWindow(win);
WM_RaiseWindow(win);
}
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;
-}
-
IPCMSG_CREATEWIN, //!< Create a window
IPCMSG_DESTROYWIN, //!< Destroy a window
IPCMSG_SHOWWINDOW, //!< Show/Hide a window
+ IPCMSG_FOCUSWINDOW, //!< Give a window focus (no data)
IPCMSG_SETWINPOS, //!< Set a window position
};
{
AxWin3_MoveWindow(Menu, X, Y);
AxWin3_ShowWindow(Menu, 1);
+ AxWin3_FocusWindow(Menu);
}
tAxWin3_MenuItem *AxWin3_Menu_AddItem(
tWindow *AxWin3_int_AllocateWindowInfo(int DataBytes, int *WinID)
{
int idx, newWinID;
- tWindowBlock *block, *prev;
+ tWindowBlock *block, *prev = NULL;
tWindow *ret;
block = &gAxWin3_WindowList;
free(msg);
}
+void AxWin3_FocusWindow(tHWND Window)
+{
+ tAxWin_IPCMessage *msg;
+
+ msg = AxWin3_int_AllocateIPCMessage(Window, IPCMSG_FOCUSWINDOW, 0, 0);
+
+ AxWin3_int_SendIPCMessage(msg);
+ free(msg);
+}
+
void AxWin3_ShowWindow(tHWND Window, int bShow)
{
tAxWin_IPCMessage *msg;
// --- Core window management functions
extern void AxWin3_SendMessage(tHWND Window, tHWND Dest, int Message, int Length, void *Data);
+extern void AxWin3_FocusWindow(tHWND Window);
extern void AxWin3_ShowWindow(tHWND Window, int bShow);
extern void AxWin3_SetWindowPos(tHWND Window, short X, short Y, short W, short H);
extern void AxWin3_MoveWindow(tHWND Window, short X, short Y);