void pMenu::append(Action &action) {
action.p.parentMenu = &menu;
if(parentWindow) parentWindow->p.updateMenu();
}
void pMenu::remove(Action &action) {
if(parentWindow) parentWindow->p.updateMenu();
action.p.parentMenu = 0;
}
void pMenu::setImage(const image &image) {
createBitmap();
if(parentWindow) parentWindow->p.updateMenu();
}
void pMenu::setText(const string &text) {
if(parentWindow) parentWindow->p.updateMenu();
}
void pMenu::constructor() {
hmenu = 0;
createBitmap();
}
void pMenu::destructor() {
if(hbitmap) { DeleteObject(hbitmap); hbitmap = 0; }
if(parentMenu) {
parentMenu->remove(menu);
} else if(parentWindow) {
//belongs to window's main menubar
parentWindow->remove(menu);
}
}
void pMenu::createBitmap() {
if(hbitmap) { DeleteObject(hbitmap); hbitmap = 0; }
if(menu.state.image.width && menu.state.image.height) {
nall::image nallImage = menu.state.image;
nallImage.transform(0, 32, 255u << 24, 255u << 16, 255u << 8, 255u << 0);
nallImage.alphaBlend(GetSysColor(COLOR_MENU)); //Windows does not alpha blend menu icons properly (leaves black outline)
nallImage.scale(GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK), Interpolation::Linear);
hbitmap = CreateBitmap(nallImage);
}
}
//Windows actions lack the ability to toggle visibility.
//To support this, menus must be destroyed and recreated when toggling any action's visibility.
void pMenu::update(Window &parentWindow, Menu *parentMenu) {
this->parentMenu = parentMenu;
this->parentWindow = &parentWindow;
if(hmenu) DestroyMenu(hmenu);
hmenu = CreatePopupMenu();
for(auto &action : menu.state.action) {
action.p.parentMenu = &menu;
action.p.parentWindow = &parentWindow;
unsigned enabled = action.state.enabled ? 0 : MF_GRAYED;
if(dynamic_cast