*/
//! 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
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);
tWindow *NextSibling;
tWindow *PrevSibling;
+ // Render tree
tWindow *Parent;
-
tWindow *FirstChild;
tWindow *LastChild;
WNDMSG_CLASS_MAX = 0x2000,
};
+struct sWndMsg_Bool
+{
+ uint8_t Val;
+};
+
struct sWndMsg_Resize
{
uint16_t W, H;
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);
{
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;
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);
}
Parent->FirstChild = ret;
ret->PrevSibling = Parent->LastChild;
Parent->LastChild = ret;
+ ret->NextSibling = NULL;
}
else
{
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
#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)
{
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;
}