#include <stdlib.h>
#include <axwin3/axwin.h>
#include <axwin3/widget.h>
+#include <axwin3/menu.h>
#define SIDEBAR_WIDTH 36
// === PROTOTYPES ===
void create_sidebar(void);
+void create_mainmenu(void);
// === GLOBALS ===
tHWND gSidebar;
+tHWND gSystemMenu;
tAxWin3_Widget *gSidebarRoot;
int giScreenWidth;
int giScreenHeight;
int systembutton_fire(tAxWin3_Widget *Widget)
{
_SysDebug("SystemButton pressed");
+ AxWin3_Menu_ShowAt(gSystemMenu, SIDEBAR_WIDTH, 0);
return 0;
}
AxWin3_Connect(NULL);
create_sidebar();
+ create_mainmenu();
// Idle loop
AxWin3_MainLoop();
}
+void mainmenu_app_textedit(void *unused)
+{
+ _SysDebug("TODO: Launch text editor");
+}
+
+void mainmenu_run_dialog(void *unused)
+{
+ _SysDebug("TODO: Show run dialog");
+}
+
void create_mainmenu(void)
{
+ gSystemMenu = AxWin3_Menu_Create(gSidebar);
+
+ AxWin3_Menu_AddItem(gSystemMenu, "Text &Editor\tWin+E", mainmenu_app_textedit, NULL, 0, NULL);
+ AxWin3_Menu_AddItem(gSystemMenu, NULL, NULL, NULL, 0, NULL);
+ AxWin3_Menu_AddItem(gSystemMenu, "Run\tWin+R", mainmenu_run_dialog, NULL, 0, NULL);
}
--- /dev/null
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ *
+ * render_menu.c
+ * - Pop-up menu window class/renderer
+ */
+#include <common.h>
+#include <menu_messages.h>
+
+// === STRUCTURES ===
+typedef struct sMenuItem
+{
+ // Settings
+ char *Label;
+ char *Shortcut;
+ int KeyOffset;
+ int Flags;
+
+ // Cached values
+ int LabelWidth;
+ int ShortcutWidth;
+ int UnderlineX;
+ int UnderlineW;
+
+ char Data[];
+} tMenuItem;
+
+typedef struct sMenuWindowInfo
+{
+ int MaxLabelWidth;
+ int MinLabelWidth;
+
+ int MaxItems;
+ int nItems;
+ tMenuItem *Items[];
+} tMenuWindowInfo;
+
+// === GLOBALS ===
+tWMRenderer gRenderer_Menu = {
+ .Name = "Menu",
+ .CreateWindow = Renderer_Menu_Create,
+ .Redraw = Renderer_Menu_Redraw,
+ .HandleMessage = Renderer_Menu_HandleMessage
+};
+
+// === CODE ===
+void Renderer_Menu_Init(void)
+{
+ WM_RegisterRenderer(&gRenderer_Menu);
+}
+
+tWindow *Renderer_Menu_Create(int Argument)
+{
+ tWindow *ret;
+ tMenuWindowInfo *info;
+
+ if(Argument < 5) Argument = 5;
+ if(Argument > 200) Argument = 200;
+
+ ret = WM_CreateWindowStruct(sizeof(*info) + Argument*sizeof(info->Items[0]));
+ info = ret->RendererInfo;
+ info->MaxItems = Argument;
+
+ return ret;
+}
+
+void Renderer_Menu_Redraw(tWindow *Window)
+{
+ // TODO: Implement Renderer_Menu_Redraw
+
+ // - Resize window to contain all items
+
+ // - Move the window such that it is on screen
+ // > Make sure to catch if the menu can't fit fully onscreen
+
+ // - Render each item
+}
+
+int Renderer_Menu_HandleMessage(tWindow *Window, int Msg, int Length, void *Data)
+{
+ switch(Msg)
+ {
+ case MSG_MENU_ADDITEM: {
+ tMenuMsg_AddItem *req = Data;
+ tMenuItem *item;
+ if(Length < sizeof(*req) + 1) return -1;
+ if(req->Label[Length-sizeof(*req)] != '\0') return -1;
+
+ if(info->Items[req->ID]) break;
+ item = malloc(sizeof(tMenuItem)+strlen(req->Label));
+ info->Items[req->ID] = item;
+
+ if(req->Label[0] == '\0')
+ {
+ // Spacer
+ item->Label = NULL;
+ }
+ else
+ {
+ // Actual item
+ char *dest = item->Data;
+ char *src = req->Label;
+ int ofs = 0;
+ // - Main label
+ item->KeyOffset = -1;
+ item->Label = dest;
+ for(ofs = 0; *src && *src != '\t'; ofs ++)
+ {
+ if(*src == '&') {
+ *dest = '\0';
+ item->KeyOffset = ofs;
+ src ++;
+ }
+ else {
+ *dest++ = *src++;
+ }
+ }
+ *dest = '\0';
+ // - Key combo / Shortcut
+ if(*src)
+ {
+ src ++;
+ item->Shortcut = dest;
+ strcpy(item->Shortcut, src);
+ }
+ else
+ {
+ item->Shortcut = NULL;
+ }
+
+ // Get dimensions
+ // - Underline (hotkey)
+ if(item->KeyOffset == -1)
+ {
+ item->UnderlineX = 0;
+ item->UnderlineW = 0;
+ }
+ else
+ {
+ char tmp = item->Label[item->KeyOffset];
+ item->Label[item->KeyOffset] = '\0';
+ WM_Render_GetTextDims(NULL, item->Label, &item->UnderlineX, NULL);
+ item->Label[item->KeyOffset] = tmp;
+ tmp = item->Label[item->KeyOffset+1];
+ item->Label[item->KeyOffset+1] = '\0';
+ WM_Render_GetTextDims(NULL, item->Label+item->KeyOffset, &item->UnderlineW, NULL);
+ item->Label[item->KeyOffset+1] = tmp;
+ }
+ // - Labels
+ WM_Render_GetTextDims(NULL, item->Label, &item->LabelWidth, NULL);
+ if(item->Shortcut)
+ WM_Render_GetTextDims(NULL, item->Shortcut, &item->ShortcutWidth, NULL);
+ else
+ item->ShortcutWidth = 0;
+ }
+
+ break; }
+
+ // Only message to pass to client
+ case MSG_MENU_SELECT:
+ return 1;
+ }
+ return 0;
+}
+
--- /dev/null
+/*
+ * Acess2 Window Manager v3
+ * - By John Hodge (thePowersGang)
+ *
+ * menu_messages.h
+ * - AxWin3 Menu IPC Messages
+ */
+#ifndef _MENU_MESSAGES_H_
+#define _MENU_MESSAGES_H_
+
+#include "ipcmessages.h"
+
+enum eMenuMessages
+{
+ MSG_MENU_ADDITEM = 0x1000,
+ MSG_MENU_SETFLAGS,
+
+ MSG_MENU_SELECT
+};
+
+typedef struct
+{
+ uint16_t ID;
+ uint16_t Flags;
+ uint32_t SubMenuID;
+ char Label[];
+} tMenuMsg_AddItem;
+
+typedef struct
+{
+ uint16_t ID;
+ uint16_t Value;
+ uint16_t Mask;
+} tMenuMsg_SetFlags;
+
+typedef struct
+{
+ uint16_t ID;
+} tMenuMsg_Select;
+
+#endif
+
CFLAGS += -Wall
LDFLAGS += -lc -soname libaxwin3.so
-OBJ = main.o msg.o wm.o r_widget.o
+OBJ = main.o msg.o wm.o r_widget.o r_menu.o
BIN = libaxwin3.so
include ../../../Libraries/Makefile.tpl
--- /dev/null
+/*
+ * AxWin3 Interface Library
+ * - By John Hodge (thePowersGang)
+ *
+ * r_menu.c
+ * - Menu renderer interface
+ */
+#include <stdlib.h>
+#include <axwin3/axwin.h>
+#include <axwin3/menu.h>
+#include <menu_messages.h>
+#include "include/internal.h"
+#include "include/ipc.h"
+#include <string.h>
+
+// === TYPES ===
+typedef struct sMenuWindowInfo tMenuWindowInfo;
+
+struct sAxWin3_MenuItem
+{
+ tHWND Window;
+ int ID;
+ tAxWin3_Menu_Callback Callback;
+ void *CbPtr;
+ tHWND SubMenu;
+};
+
+struct sMenuWindowInfo
+{
+ int nItems;
+ tAxWin3_MenuItem *Items;
+};
+
+// === CODE ===
+int AxWin3_Menu_int_Callback(tHWND Window, int Message, int Length, void *Data)
+{
+ tMenuWindowInfo *info = AxWin3_int_GetDataPtr(Window);
+ switch(Message)
+ {
+ case MSG_MENU_SELECT: {
+ tMenuMsg_Select *msg = Data;
+ tAxWin3_MenuItem *item;
+ if(Length < sizeof(tMenuMsg_Select)) return -1;
+ if(msg->ID >= info->nItems) return -1;
+ item = &info->Items[msg->ID];
+ if(item->Callback) item->Callback(item->CbPtr);
+ return 0; }
+ }
+ return 1;
+}
+
+tHWND AxWin3_Menu_Create(tHWND Parent)
+{
+ tHWND ret;
+ tMenuWindowInfo *info;
+
+ ret = AxWin3_CreateWindow(Parent, "Menu", 0, sizeof(*info), AxWin3_Menu_int_Callback);
+ if(!ret) return ret;
+
+ info = AxWin3_int_GetDataPtr(ret);
+ info->nItems = 0;
+ info->Items = NULL;
+
+ return ret;
+}
+
+void AxWin3_Menu_ShowAt(tHWND Menu, int X, int Y)
+{
+ AxWin3_MoveWindow(Menu, X, Y);
+ AxWin3_ShowWindow(Menu, 1);
+}
+
+tAxWin3_MenuItem *AxWin3_Menu_AddItem(
+ tHWND Menu, const char *Label,
+ tAxWin3_Menu_Callback Cb, void *Ptr,
+ int Flags, tHWND SubMenu
+ )
+{
+ tMenuWindowInfo *info;
+ tAxWin3_MenuItem *ret;
+
+ info = AxWin3_int_GetDataPtr(Menu);
+
+ info->nItems ++;
+ info->Items = realloc(info->Items, sizeof(*info->Items)*info->nItems);
+ if(!info->Items) {
+ _SysDebug("ERROR: Realloc Failed");
+ return NULL;
+ }
+
+ ret = &info->Items[info->nItems-1];
+ ret->ID = info->nItems - 1;
+ ret->Window = Menu;
+ ret->Callback = Cb;
+ ret->CbPtr = Ptr;
+ ret->SubMenu = SubMenu;
+
+ {
+ tAxWin_IPCMessage *msg;
+ tMenuMsg_AddItem *req;
+ msg = AxWin3_int_AllocateIPCMessage(Menu, MSG_MENU_ADDITEM, 0, sizeof(*req)+strlen(Label));
+ req = (void*)msg->Data;
+ req->ID = ret->ID;
+ req->Flags = Flags;
+ req->SubMenuID = AxWin3_int_GetWindowID(SubMenu);
+ strcpy(req->Label, Label);
+ AxWin3_int_SendIPCMessage(msg);
+ free(msg);
+ }
+
+ return ret;
+}
* AxWin3 Interface Library
* - By John Hodge (thePowersGang)
*
- * main.c
- * - Entrypoint and setup
+ * r_widget.c
+ * - Widget window type interface
*/
#include <axwin3/axwin.h>
#include <axwin3/widget.h>
--- /dev/null
+/*
+ * Acess2 GUI Version 3 (AxWin3)
+ * - By John Hodge (thePowersGang)
+ *
+ * menu.h
+ * - Menu window type
+ */
+#ifndef _AXWIN3_MENU_H_
+#define _AXWIN3_MENU_H_
+
+typedef void (*tAxWin3_Menu_Callback)(void *Ptr);
+typedef struct sAxWin3_MenuItem tAxWin3_MenuItem;
+
+extern tHWND AxWin3_Menu_Create(tHWND Parent);
+extern void AxWin3_Menu_ShowAt(tHWND Menu, int X, int Y);
+
+extern tAxWin3_MenuItem *AxWin3_Menu_AddItem(
+ tHWND Menu, const char *Label,
+ tAxWin3_Menu_Callback Cb, void *Ptr,
+ int Flags, tHWND SubMenu
+ );
+extern tAxWin3_MenuItem *AxWin3_Menu_GetItem(tHWND Menu, int Index);
+extern void AxWin3_Menu_SetFlags(tAxWin3_MenuItem *Item, int Flags, int Mask);
+
+#endif
+