diff options
author | Eugene Sandulenko | 2019-10-01 02:05:56 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2019-10-01 02:05:56 +0200 |
commit | da01e839063eac02471b5d734512bbf6e3a53f09 (patch) | |
tree | 48691ea3f53a78f17b01416adff6f7cdbb31d5ef /graphics/macgui | |
parent | 8357725bc220d36150d91e3ef14af4db371fd5ee (diff) | |
download | scummvm-rg350-da01e839063eac02471b5d734512bbf6e3a53f09.tar.gz scummvm-rg350-da01e839063eac02471b5d734512bbf6e3a53f09.tar.bz2 scummvm-rg350-da01e839063eac02471b5d734512bbf6e3a53f09.zip |
GRAPHICS: MACGUI: Further work on nested submenus
Diffstat (limited to 'graphics/macgui')
-rw-r--r-- | graphics/macgui/macmenu.cpp | 200 | ||||
-rw-r--r-- | graphics/macgui/macmenu.h | 5 |
2 files changed, 129 insertions, 76 deletions
diff --git a/graphics/macgui/macmenu.cpp b/graphics/macgui/macmenu.cpp index bbe7415819..d31ee69a53 100644 --- a/graphics/macgui/macmenu.cpp +++ b/graphics/macgui/macmenu.cpp @@ -66,7 +66,7 @@ enum { kEndMenu = 128 }; -struct MacMenuSubItem; +struct MacMenuSubMenu; typedef Common::Array<MacMenuSubItem *> SubItemArray; @@ -80,22 +80,46 @@ struct MacMenuSubItem { bool enabled; Common::Rect bbox; + MacMenuSubMenu *submenu; + + MacMenuSubItem(const Common::String &t, int a, int s = 0, char sh = 0, bool e = true) : + text(t), unicode(false), action(a), style(s), shortcut(sh), enabled(e), submenu(nullptr) {} + MacMenuSubItem(const Common::U32String &t, int a, int s = 0, char sh = 0, bool e = true) : + unicodeText(t), unicode(true), action(a), style(s), shortcut(sh), enabled(e), submenu(nullptr) {} + + ~MacMenuSubItem(); +}; + +struct MacMenuSubMenu { SubItemArray subitems; + Common::Rect bbox; - MacMenuSubItem(const Common::String &t, int a, int s = 0, char sh = 0, bool e = true) : text(t), unicode(false), action(a), style(s), shortcut(sh), enabled(e) {} - MacMenuSubItem(const Common::U32String &t, int a, int s = 0, char sh = 0, bool e = true) : unicodeText(t), unicode(true), action(a), style(s), shortcut(sh), enabled(e) {} + ~MacMenuSubMenu() { + for (uint i = 0; i < subitems.size(); i++) + delete subitems[i]; + } }; +MacMenuSubItem::~MacMenuSubItem() { + if (submenu) + delete submenu; +} + + struct MacMenuItem { Common::String name; Common::U32String unicodeName; bool unicode; - SubItemArray subitems; + MacMenuSubMenu *submenu; Common::Rect bbox; - Common::Rect subbbox; - MacMenuItem(const Common::String &n) : name(n), unicode(false) {} - MacMenuItem(const Common::U32String &n) : unicodeName(n), unicode(true) {} + MacMenuItem(const Common::String &n) : name(n), unicode(false), submenu(nullptr) {} + MacMenuItem(const Common::U32String &n) : unicodeName(n), unicode(true), submenu(nullptr) {} + + ~MacMenuItem() { + if (submenu) + delete submenu; + } }; MacMenu::MacMenu(int id, const Common::Rect &bounds, MacWindowManager *wm) @@ -127,11 +151,8 @@ MacMenu::MacMenu(int id, const Common::Rect &bounds, MacWindowManager *wm) } MacMenu::~MacMenu() { - for (uint i = 0; i < _items.size(); i++) { - for (uint j = 0; j < _items[i]->subitems.size(); j++) - delete _items[i]->subitems[j]; + for (uint i = 0; i < _items.size(); i++) delete _items[i]; - } } Common::StringArray *MacMenu::readMenuFromResource(Common::SeekableReadStream *res) { @@ -259,7 +280,10 @@ void MacMenu::addStaticMenus(const MacMenuData *data) { continue; } - _items[m->menunum]->subitems.push_back(new MacMenuSubItem(m->title, m->action, 0, m->shortcut, m->enabled)); + if (_items[m->menunum]->submenu == nullptr) + _items[m->menunum]->submenu = new MacMenuSubMenu(); + + _items[m->menunum]->submenu->subitems.push_back(new MacMenuSubItem(m->title, m->action, 0, m->shortcut, m->enabled)); } calcDimensions(); @@ -280,15 +304,21 @@ int MacMenu::addMenuItem(const Common::U32String &name) { } void MacMenu::addMenuSubItem(int id, const Common::String &text, int action, int style, char shortcut, bool enabled) { - _items[id]->subitems.push_back(new MacMenuSubItem(text, action, style, shortcut, enabled)); + if (_items[id]->submenu == nullptr) + _items[id]->submenu = new MacMenuSubMenu(); - calcMenuBounds(_items[id]); + _items[id]->submenu->subitems.push_back(new MacMenuSubItem(text, action, style, shortcut, enabled)); + + calcSubMenuBounds(_items[id]); } void MacMenu::addMenuSubItem(int id, const Common::U32String &text, int action, int style, char shortcut, bool enabled) { - _items[id]->subitems.push_back(new MacMenuSubItem(text, action, style, shortcut, enabled)); + if (_items[id]->submenu == nullptr) + _items[id]->submenu = new MacMenuSubMenu(); + + _items[id]->submenu->subitems.push_back(new MacMenuSubItem(text, action, style, shortcut, enabled)); - calcMenuBounds(_items[id]); + calcSubMenuBounds(_items[id]); } void MacMenu::calcDimensions() { @@ -306,7 +336,7 @@ void MacMenu::calcDimensions() { _items[i]->bbox.bottom = y + _font->getFontHeight() + (_wm->_fontMan->hasBuiltInFonts() ? 3 : 2); } - calcMenuBounds(_items[i]); + calcSubMenuBounds(_items[i]); x += w + kMenuSpacing; } @@ -361,10 +391,13 @@ void MacMenu::loadMenuBarResource(Common::MacResManager *resFork, uint16 id) { void MacMenu::clearSubMenu(int id) { MacMenuItem *menu = _items[id]; - for (uint j = 0; j < menu->subitems.size(); j++) - delete menu->subitems[j]; + if (menu->submenu == nullptr) + return; + + for (uint j = 0; j < menu->submenu->subitems.size(); j++) + delete menu->submenu->subitems[j]; - menu->subitems.clear(); + menu->submenu->subitems.clear(); } void MacMenu::createSubMenuFromString(int id, const char *str, int commandId) { @@ -375,12 +408,14 @@ void MacMenu::createSubMenuFromString(int id, const char *str, int commandId) { Common::String item; + menu->submenu = new MacMenuSubMenu(); + for (uint i = 0; i < string.size(); i++) { while(i < string.size() && string[i] != ';') // Read token item += string[i++]; if (item == "(-") { - menu->subitems.push_back(new MacMenuSubItem(NULL, 0)); + menu->submenu->subitems.push_back(new MacMenuSubItem(NULL, 0)); } else { bool enabled = true; int style = 0; @@ -429,13 +464,13 @@ void MacMenu::createSubMenuFromString(int id, const char *str, int commandId) { } } - menu->subitems.push_back(new MacMenuSubItem(item, commandId, style, shortcut, enabled)); + menu->submenu->subitems.push_back(new MacMenuSubItem(item, commandId, style, shortcut, enabled)); } item.clear(); } - calcMenuBounds(menu); + calcSubMenuBounds(menu); } const Font *MacMenu::getMenuFont() { @@ -451,8 +486,11 @@ const Common::String MacMenu::getAcceleratorString(MacMenuSubItem *item, const c int MacMenu::calculateMenuWidth(MacMenuItem *menu) { int maxWidth = 0; - for (uint i = 0; i < menu->subitems.size(); i++) { - MacMenuSubItem *item = menu->subitems[i]; + if (menu->submenu == nullptr) + return maxWidth; + + for (uint i = 0; i < menu->submenu->subitems.size(); i++) { + MacMenuSubItem *item = menu->submenu->subitems[i]; if (!item->text.empty()) { Common::String text(item->text); Common::String acceleratorText(getAcceleratorString(item, " ")); @@ -475,18 +513,21 @@ int MacMenu::calculateMenuWidth(MacMenuItem *menu) { return maxWidth; } -void MacMenu::calcMenuBounds(MacMenuItem *menu) { +void MacMenu::calcSubMenuBounds(MacMenuItem *menu) { + if (menu->submenu == nullptr) + return; + // TODO: cache maxWidth int maxWidth = calculateMenuWidth(menu); int x1 = menu->bbox.left - 1; int y1 = menu->bbox.bottom + 1; int x2 = x1 + maxWidth + kMenuDropdownPadding * 2 - 4; - int y2 = y1 + menu->subitems.size() * kMenuDropdownItemHeight + 2; + int y2 = y1 + menu->submenu->subitems.size() * kMenuDropdownItemHeight + 2; - menu->subbbox.left = x1; - menu->subbbox.top = y1; - menu->subbbox.right = x2; - menu->subbbox.bottom = y2; + menu->submenu->bbox.left = x1; + menu->submenu->bbox.top = y1; + menu->submenu->bbox.right = x2; + menu->submenu->bbox.bottom = y2; } static void drawPixelPlain(int x, int y, int color, void *data) { @@ -536,8 +577,8 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) { _screen.fillRect(hbox, _wm->_colorBlack); color = _wm->_colorWhite; - if (!it->subitems.empty()) - renderSubmenu(it); + if (it->submenu != nullptr) + renderSubmenu(it->submenu); } if (it->unicode) { @@ -556,8 +597,8 @@ bool MacMenu::draw(ManagedSurface *g, bool forceRedraw) { return true; } -void MacMenu::renderSubmenu(MacMenuItem *menu) { - Common::Rect *r = &menu->subbbox; +void MacMenu::renderSubmenu(MacMenuSubMenu *menu) { + Common::Rect *r = &menu->bbox; if (r->width() == 0 || r->height() == 0) return; @@ -610,7 +651,7 @@ void MacMenu::renderSubmenu(MacMenuItem *menu) { if (!acceleratorText.empty()) _font->drawString(s, acceleratorText, accelX, ty, r->width(), color); - if (menu->subitems[i]->subitems.size()) + if (menu->subitems[i]->submenu != nullptr) drawSubMenuArrow(s, arrowX, ty, color); if (!menu->subitems[i]->enabled) { @@ -691,11 +732,13 @@ bool MacMenu::mouseClick(int x, int y) { return false; if (_activeItem != -1) { // Restore background - Common::Rect r(_items[_activeItem]->subbbox); - r.right += 3; - r.bottom += 3; + if (_items[_activeItem]->submenu != nullptr) { + Common::Rect r(_items[_activeItem]->submenu->bbox); + r.right += 3; + r.bottom += 3; - _wm->setFullRefresh(true); + _wm->setFullRefresh(true); + } } _activeItem = i; @@ -706,20 +749,21 @@ bool MacMenu::mouseClick(int x, int y) { return true; } - } else if (_menuActivated && _items[_activeItem]->subbbox.contains(x, y)) { - MacMenuItem *it = _items[_activeItem]; - int numSubItem = (y - it->subbbox.top) / kMenuDropdownItemHeight; + } else if (_menuActivated && _items[_activeItem]->submenu != nullptr && + _items[_activeItem]->submenu->bbox.contains(x, y)) { + MacMenuSubMenu *it = _items[_activeItem]->submenu; + int numSubItem = (y - it->bbox.top) / kMenuDropdownItemHeight; if (numSubItem != _activeSubItem) { _activeSubItem = numSubItem; - renderSubmenu(_items[_activeItem]); + renderSubmenu(_items[_activeItem]->submenu); _contentIsDirty = true; } } else if (_menuActivated && _activeItem != -1) { _activeSubItem = -1; - renderSubmenu(_items[_activeItem]); + renderSubmenu(_items[_activeItem]->submenu); _contentIsDirty = true; } @@ -754,13 +798,13 @@ bool MacMenu::mouseRelease(int x, int y) { g_system->copyRectToScreen(_wm->_screenCopy->getBasePtr(0, 0), _wm->_screenCopy->pitch, 0, 0, _wm->_screenCopy->w, _wm->_screenCopy->h); } - if (_activeItem != -1 && _activeSubItem != -1 && _items[_activeItem]->subitems[_activeSubItem]->enabled) { - if (_items[_activeItem]->subitems[_activeSubItem]->unicode) { - (*_unicodeccallback)(_items[_activeItem]->subitems[_activeSubItem]->action, - _items[_activeItem]->subitems[_activeSubItem]->unicodeText, _cdata); + if (_activeItem != -1 && _activeSubItem != -1 && _items[_activeItem]->submenu->subitems[_activeSubItem]->enabled) { + if (_items[_activeItem]->submenu->subitems[_activeSubItem]->unicode) { + (*_unicodeccallback)(_items[_activeItem]->submenu->subitems[_activeSubItem]->action, + _items[_activeItem]->submenu->subitems[_activeSubItem]->unicodeText, _cdata); } else { - (*_ccallback)(_items[_activeItem]->subitems[_activeSubItem]->action, - _items[_activeItem]->subitems[_activeSubItem]->text, _cdata); + (*_ccallback)(_items[_activeItem]->submenu->subitems[_activeSubItem]->action, + _items[_activeItem]->submenu->subitems[_activeSubItem]->text, _cdata); } } @@ -780,24 +824,29 @@ bool MacMenu::processMenuShortCut(byte flags, uint16 ascii) { if (flags & (Common::KBD_CTRL | Common::KBD_META)) { for (uint i = 0; i < _items.size(); i++) - for (uint j = 0; j < _items[i]->subitems.size(); j++) - if (_items[i]->subitems[j]->enabled && tolower(_items[i]->subitems[j]->shortcut) == ascii) { - if (_items[i]->subitems[j]->unicode) { - (*_unicodeccallback)(_items[i]->subitems[j]->action, _items[i]->subitems[j]->unicodeText, _cdata); - } else { - (*_ccallback)(_items[i]->subitems[j]->action, _items[i]->subitems[j]->text, _cdata); + if (_items[i]->submenu != nullptr) { + for (uint j = 0; j < _items[i]->submenu->subitems.size(); j++) + if (_items[i]->submenu->subitems[j]->enabled && tolower(_items[i]->submenu->subitems[j]->shortcut) == ascii) { + if (_items[i]->submenu->subitems[j]->unicode) { + (*_unicodeccallback)(_items[i]->submenu->subitems[j]->action, _items[i]->submenu->subitems[j]->unicodeText, _cdata); + } else { + (*_ccallback)(_items[i]->submenu->subitems[j]->action, _items[i]->submenu->subitems[j]->text, _cdata); + } + return true; } - return true; - } + } } return false; } void MacMenu::enableCommand(int menunum, int action, bool state) { - for (uint i = 0; i < _items[menunum]->subitems.size(); i++) - if (_items[menunum]->subitems[i]->action == action) - _items[menunum]->subitems[i]->enabled = state; + if (!_items[menunum]->submenu) + return; + + for (uint i = 0; i < _items[menunum]->submenu->subitems.size(); i++) + if (_items[menunum]->submenu->subitems[i]->action == action) + _items[menunum]->submenu->subitems[i]->enabled = state; _contentIsDirty = true; } @@ -815,11 +864,12 @@ void MacMenu::enableCommand(const char *menuitem, const char *menuaction, bool s if (menunum == _items.size()) return; - for (uint i = 0; i < _items[menunum]->subitems.size(); i++) { - assert(!_items[menunum]->subitems[i]->unicode); - if (_items[menunum]->subitems[i]->text.equalsIgnoreCase(menuaction)) - _items[menunum]->subitems[i]->enabled = state; - } + if (_items[menunum]->submenu != nullptr) + for (uint i = 0; i < _items[menunum]->submenu->subitems.size(); i++) { + assert(!_items[menunum]->submenu->subitems[i]->unicode); + if (_items[menunum]->submenu->subitems[i]->text.equalsIgnoreCase(menuaction)) + _items[menunum]->submenu->subitems[i]->enabled = state; + } _contentIsDirty = true; } @@ -837,19 +887,21 @@ void MacMenu::enableCommand(const Common::U32String &menuitem, const Common::U32 if (menunum == _items.size()) return; - for (uint i = 0; i < _items[menunum]->subitems.size(); i++) { - assert(_items[menunum]->subitems[i]->unicode); - if (_items[menunum]->subitems[i]->unicodeText.equals(menuaction)) - _items[menunum]->subitems[i]->enabled = state; - } + if (_items[menunum]->submenu != nullptr) + for (uint i = 0; i < _items[menunum]->submenu->subitems.size(); i++) { + assert(_items[menunum]->submenu->subitems[i]->unicode); + if (_items[menunum]->submenu->subitems[i]->unicodeText.equals(menuaction)) + _items[menunum]->submenu->subitems[i]->enabled = state; + } _contentIsDirty = true; } void MacMenu::disableAllMenus() { for (uint i = 1; i < _items.size(); i++) // Leave About menu on - for (uint j = 0; j < _items[i]->subitems.size(); j++) - _items[i]->subitems[j]->enabled = false; + if (_items[i]->submenu != nullptr) + for (uint j = 0; j < _items[i]->submenu->subitems.size(); j++) + _items[i]->submenu->subitems[j]->enabled = false; _contentIsDirty = true; } diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h index 6cb1e30ad3..8d898899cb 100644 --- a/graphics/macgui/macmenu.h +++ b/graphics/macgui/macmenu.h @@ -35,6 +35,7 @@ namespace Graphics { struct MacMenuItem; struct MacMenuSubItem; +struct MacMenuSubMenu; struct MacMenuData { int menunum; @@ -91,8 +92,8 @@ private: const Font *getMenuFont(); const Common::String getAcceleratorString(MacMenuSubItem *item, const char *prefix); int calculateMenuWidth(MacMenuItem *menu); - void calcMenuBounds(MacMenuItem *menu); - void renderSubmenu(MacMenuItem *menu); + void calcSubMenuBounds(MacMenuItem *menu); + void renderSubmenu(MacMenuSubMenu *menu); bool keyEvent(Common::Event &event); bool mouseClick(int x, int y); |