libui/windows: add support for submenus
This commit is contained in:
parent
3881b2615b
commit
84a842c6f3
|
@ -273,6 +273,7 @@ _UI_EXTERN uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name);
|
||||||
_UI_EXTERN uiMenuItem *uiMenuAppendQuitItem(uiMenu *m);
|
_UI_EXTERN uiMenuItem *uiMenuAppendQuitItem(uiMenu *m);
|
||||||
_UI_EXTERN uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m);
|
_UI_EXTERN uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m);
|
||||||
_UI_EXTERN uiMenuItem *uiMenuAppendAboutItem(uiMenu *m);
|
_UI_EXTERN uiMenuItem *uiMenuAppendAboutItem(uiMenu *m);
|
||||||
|
_UI_EXTERN uiMenuItem *uiMenuAppendSubmenu(uiMenu *m, const char *name, uiMenu* child);
|
||||||
_UI_EXTERN void uiMenuAppendSeparator(uiMenu *m);
|
_UI_EXTERN void uiMenuAppendSeparator(uiMenu *m);
|
||||||
_UI_EXTERN uiMenu *uiNewMenu(const char *name);
|
_UI_EXTERN uiMenu *uiNewMenu(const char *name);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ static BOOL hasAbout = FALSE;
|
||||||
struct uiMenu {
|
struct uiMenu {
|
||||||
WCHAR *name;
|
WCHAR *name;
|
||||||
uiMenuItem **items;
|
uiMenuItem **items;
|
||||||
|
BOOL ischild;
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t cap;
|
size_t cap;
|
||||||
};
|
};
|
||||||
|
@ -28,6 +29,7 @@ struct uiMenuItem {
|
||||||
BOOL disabled; // template for new instances; kept in sync with everything else
|
BOOL disabled; // template for new instances; kept in sync with everything else
|
||||||
BOOL checked;
|
BOOL checked;
|
||||||
HMENU *hmenus;
|
HMENU *hmenus;
|
||||||
|
uiMenu* popupchild;
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t cap;
|
size_t cap;
|
||||||
};
|
};
|
||||||
|
@ -39,6 +41,7 @@ enum {
|
||||||
typePreferences,
|
typePreferences,
|
||||||
typeAbout,
|
typeAbout,
|
||||||
typeSeparator,
|
typeSeparator,
|
||||||
|
typeSubmenu,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define grow 32
|
#define grow 32
|
||||||
|
@ -140,6 +143,7 @@ static uiMenuItem *newItem(uiMenu *m, int type, const char *name)
|
||||||
item->name = toUTF16(name);
|
item->name = toUTF16(name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
item->popupchild = NULL;
|
||||||
|
|
||||||
if (item->type != typeSeparator) {
|
if (item->type != typeSeparator) {
|
||||||
item->id = curID;
|
item->id = curID;
|
||||||
|
@ -156,6 +160,34 @@ static uiMenuItem *newItem(uiMenu *m, int type, const char *name)
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uiMenuItem *uiMenuAppendSubmenu(uiMenu *m, const char *name, uiMenu* child)
|
||||||
|
{
|
||||||
|
uiMenuItem *item;
|
||||||
|
|
||||||
|
if (menusFinalized)
|
||||||
|
userbug("You can not create a new menu item after menus have been finalized.");
|
||||||
|
|
||||||
|
if (m->len >= m->cap) {
|
||||||
|
m->cap += grow;
|
||||||
|
m->items = (uiMenuItem **) uiRealloc(m->items, m->cap * sizeof (uiMenuItem *), "uiMenuitem *[]");
|
||||||
|
}
|
||||||
|
|
||||||
|
item = uiNew(uiMenuItem);
|
||||||
|
|
||||||
|
m->items[m->len] = item;
|
||||||
|
m->len++;
|
||||||
|
|
||||||
|
item->type = typeSubmenu;
|
||||||
|
item->name = toUTF16(name);
|
||||||
|
|
||||||
|
item->popupchild = child;
|
||||||
|
child->ischild = TRUE;
|
||||||
|
|
||||||
|
uiMenuItemOnClicked(item, defaultOnClicked, NULL);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name)
|
uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name)
|
||||||
{
|
{
|
||||||
return newItem(m, typeRegular, name);
|
return newItem(m, typeRegular, name);
|
||||||
|
@ -216,13 +248,17 @@ uiMenu *uiNewMenu(const char *name)
|
||||||
len++;
|
len++;
|
||||||
|
|
||||||
m->name = toUTF16(name);
|
m->name = toUTF16(name);
|
||||||
|
m->ischild = FALSE;
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HMENU makeMenu(uiMenu *m);
|
||||||
|
|
||||||
static void appendMenuItem(HMENU menu, uiMenuItem *item)
|
static void appendMenuItem(HMENU menu, uiMenuItem *item)
|
||||||
{
|
{
|
||||||
UINT uFlags;
|
UINT uFlags;
|
||||||
|
UINT_PTR id = item->id;
|
||||||
|
|
||||||
uFlags = MF_SEPARATOR;
|
uFlags = MF_SEPARATOR;
|
||||||
if (item->type != typeSeparator) {
|
if (item->type != typeSeparator) {
|
||||||
|
@ -231,8 +267,13 @@ static void appendMenuItem(HMENU menu, uiMenuItem *item)
|
||||||
uFlags |= MF_DISABLED | MF_GRAYED;
|
uFlags |= MF_DISABLED | MF_GRAYED;
|
||||||
if (item->checked)
|
if (item->checked)
|
||||||
uFlags |= MF_CHECKED;
|
uFlags |= MF_CHECKED;
|
||||||
|
if (item->popupchild)
|
||||||
|
{
|
||||||
|
uFlags |= MF_POPUP;
|
||||||
|
id = (UINT_PTR)makeMenu(item->popupchild);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (AppendMenuW(menu, uFlags, item->id, item->name) == 0)
|
if (AppendMenuW(menu, uFlags, id, item->name) == 0)
|
||||||
logLastError(L"error appending menu item");
|
logLastError(L"error appending menu item");
|
||||||
|
|
||||||
if (item->len >= item->cap) {
|
if (item->len >= item->cap) {
|
||||||
|
@ -269,6 +310,7 @@ HMENU makeMenubar(void)
|
||||||
logLastError(L"error creating menubar");
|
logLastError(L"error creating menubar");
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
|
if (menus[i]->ischild) continue;
|
||||||
menu = makeMenu(menus[i]);
|
menu = makeMenu(menus[i]);
|
||||||
if (AppendMenuW(menubar, MF_POPUP | MF_STRING, (UINT_PTR) menu, menus[i]->name) == 0)
|
if (AppendMenuW(menubar, MF_POPUP | MF_STRING, (UINT_PTR) menu, menus[i]->name) == 0)
|
||||||
logLastError(L"error appending menu to menubar");
|
logLastError(L"error appending menu to menubar");
|
||||||
|
|
Loading…
Reference in New Issue