Added a framework for handling menu events on Windows.
This commit is contained in:
parent
9ef8019159
commit
dc386a599e
|
@ -7,38 +7,39 @@ static void appendSeparator(HMENU menu)
|
||||||
logLastError("error appending separator in appendSeparator()");
|
logLastError("error appending separator in appendSeparator()");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void appendTextItem(HMENU menu, const char *text)
|
static void appendTextItem(HMENU menu, const char *text, UINT_PTR *id)
|
||||||
{
|
{
|
||||||
WCHAR *wtext;
|
WCHAR *wtext;
|
||||||
|
|
||||||
wtext = toUTF16(text);
|
wtext = toUTF16(text);
|
||||||
if (AppendMenuW(menu, MF_STRING, 0, wtext) == 0)
|
if (AppendMenuW(menu, MF_STRING, *id, wtext) == 0)
|
||||||
logLastError("error appending menu item in appendTextItem()");
|
logLastError("error appending menu item in appendTextItem()");
|
||||||
uiFree(wtext);
|
uiFree(wtext);
|
||||||
|
(*id)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void appendMenuItem(HMENU menu, const uiMenuItem *item)
|
static void appendMenuItem(HMENU menu, const uiMenuItem *item, UINT_PTR *id)
|
||||||
{
|
{
|
||||||
switch (item->Type) {
|
switch (item->Type) {
|
||||||
case uiMenuItemTypeCommand:
|
case uiMenuItemTypeCommand:
|
||||||
case uiMenuItemTypeCheckbox:
|
case uiMenuItemTypeCheckbox:
|
||||||
appendTextItem(menu, item->Name);
|
appendTextItem(menu, item->Name, id);
|
||||||
return;
|
return;
|
||||||
// TODO see if there are stock items for these three
|
// TODO see if there are stock items for these three
|
||||||
case uiMenuItemTypeQuit:
|
case uiMenuItemTypeQuit:
|
||||||
// TODO verify name
|
// TODO verify name
|
||||||
appendSeparator(menu);
|
appendSeparator(menu);
|
||||||
appendTextItem(menu, "Quit");
|
appendTextItem(menu, "Quit", id);
|
||||||
return;
|
return;
|
||||||
case uiMenuItemTypePreferences:
|
case uiMenuItemTypePreferences:
|
||||||
// TODO verify name
|
// TODO verify name
|
||||||
appendSeparator(menu);
|
appendSeparator(menu);
|
||||||
appendTextItem(menu, "Preferences");
|
appendTextItem(menu, "Preferences", id);
|
||||||
return;
|
return;
|
||||||
case uiMenuItemTypeAbout:
|
case uiMenuItemTypeAbout:
|
||||||
// TODO verify name
|
// TODO verify name
|
||||||
appendSeparator(menu);
|
appendSeparator(menu);
|
||||||
appendTextItem(menu, "About");
|
appendTextItem(menu, "About", id);
|
||||||
return;
|
return;
|
||||||
case uiMenuItemTypeSeparator:
|
case uiMenuItemTypeSeparator:
|
||||||
// TODO verify name
|
// TODO verify name
|
||||||
|
@ -49,7 +50,7 @@ static void appendMenuItem(HMENU menu, const uiMenuItem *item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HMENU makeMenu(uiMenuItem *items)
|
static HMENU makeMenu(uiMenuItem *items, UINT_PTR *id)
|
||||||
{
|
{
|
||||||
HMENU menu;
|
HMENU menu;
|
||||||
const uiMenuItem *i;
|
const uiMenuItem *i;
|
||||||
|
@ -58,7 +59,7 @@ static HMENU makeMenu(uiMenuItem *items)
|
||||||
if (menu == NULL)
|
if (menu == NULL)
|
||||||
logLastError("error creating menu in makeMenu()");
|
logLastError("error creating menu in makeMenu()");
|
||||||
for (i = items; i->Type != 0; i++)
|
for (i = items; i->Type != 0; i++)
|
||||||
appendMenuItem(menu, i);
|
appendMenuItem(menu, i, id);
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +69,7 @@ HMENU makeMenubar(void)
|
||||||
const uiMenu *m;
|
const uiMenu *m;
|
||||||
WCHAR *wname;
|
WCHAR *wname;
|
||||||
HMENU menu;
|
HMENU menu;
|
||||||
|
UINT_PTR id;
|
||||||
|
|
||||||
if (options.Menu == NULL)
|
if (options.Menu == NULL)
|
||||||
complain("asked to give uiWindow a menubar but didn't specify a menu in uiInitOptions");
|
complain("asked to give uiWindow a menubar but didn't specify a menu in uiInitOptions");
|
||||||
|
@ -76,9 +78,10 @@ HMENU makeMenubar(void)
|
||||||
if (menubar == NULL)
|
if (menubar == NULL)
|
||||||
logLastError("error creating menubar in makeMenubar()");
|
logLastError("error creating menubar in makeMenubar()");
|
||||||
|
|
||||||
|
id = 100; // start at a safe number
|
||||||
for (m = options.Menu; m->Name != NULL; m++) {
|
for (m = options.Menu; m->Name != NULL; m++) {
|
||||||
wname = toUTF16(m->Name);
|
wname = toUTF16(m->Name);
|
||||||
menu = makeMenu(m->Items);
|
menu = makeMenu(m->Items, &id);
|
||||||
if (AppendMenuW(menubar, MF_POPUP | MF_STRING, (UINT_PTR) menu, wname) == 0)
|
if (AppendMenuW(menubar, MF_POPUP | MF_STRING, (UINT_PTR) menu, wname) == 0)
|
||||||
logLastError("error appending menu to menubar in makeMenubar()");
|
logLastError("error appending menu to menubar in makeMenubar()");
|
||||||
uiFree(wname);
|
uiFree(wname);
|
||||||
|
@ -86,3 +89,36 @@ HMENU makeMenubar(void)
|
||||||
|
|
||||||
return menubar;
|
return menubar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is slow, but it will do for now
|
||||||
|
// TODO investigate faster options
|
||||||
|
|
||||||
|
static const uiMenuItem *lookupID(const uiMenu *items, UINT_PTR *cur, UINT_PTR id)
|
||||||
|
{
|
||||||
|
const uiMenuItem *i;
|
||||||
|
|
||||||
|
for (i = items; i->Type != 0; i++) {
|
||||||
|
if (i->Type == uiMenuItemTypeSeparator)
|
||||||
|
continue;
|
||||||
|
if (*cur == id)
|
||||||
|
return i;
|
||||||
|
(*cur)++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uiMenuItem *menuIDToItem(UINT_PTR id)
|
||||||
|
{
|
||||||
|
UINT_PTR cur;
|
||||||
|
const uiMenu *m;
|
||||||
|
const uiMenuItem *item;
|
||||||
|
|
||||||
|
cur = 100;
|
||||||
|
for (m = options.Menu; m->Name != NULL; m++) {
|
||||||
|
item = lookupID(m, &cur, id);
|
||||||
|
if (item != NULL)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
// TODO complain
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -74,3 +74,4 @@ extern const char *initParent(HICON, HCURSOR);
|
||||||
|
|
||||||
// menu.c
|
// menu.c
|
||||||
extern HMENU makeMenubar(void);
|
extern HMENU makeMenubar(void);
|
||||||
|
extern const uiMenuItem *menuIDToItem(UINT_PTR);
|
||||||
|
|
Loading…
Reference in New Issue