Reduce number of allocations for menu creation Every time either the Slit menu or the Toolbar menu were added to the root menu, the whole root menu was (re)created from scratch. Now we create and remove only the menus needed. Side effect: the position of these menus is now at the end of the root menu and not somewhere in between. If users complaint, I' ll think about it.
Mathias Gumz akira@fluxbox.org
4 files changed,
44 insertions(+),
23 deletions(-)
M
src/FbTk/Menu.cc
→
src/FbTk/Menu.cc
@@ -91,6 +91,12 @@
Menu* Menu::shownMenu() { return s_shown; } Menu* Menu::focused() { return s_focused; } +void Menu::hideShownMenu() { + if (s_shown) + s_shown->hide(); +} + + Menu::Menu(FbTk::ThemeProxy<MenuTheme> &tm, ImageControl &imgctrl): m_theme(tm), m_parent(0),@@ -239,6 +245,18 @@ }
m_need_update = true; // we need to redraw the menu return m_items.size(); } + + +int Menu::findSubmenuIndex(const FbTk::Menu* submenu) const { + size_t i; + for (i = 0; i < m_items.size(); i++) { + if (m_items[i]->submenu() == submenu) { + return i; + } + } + return -1; +} + void Menu::fixMenuItemIndices() { for (size_t i = 0; i < m_items.size(); i++)@@ -1391,9 +1409,5 @@ FbTk::MenuItem *item = find(index);
item->drawLine(m_frame, theme(), size, item_x, item_y, m_item_w); } -void Menu::hideShownMenu() { - if (s_shown) - s_shown->hide(); -} } // end namespace FbTk
M
src/FbTk/Menu.hh
→
src/FbTk/Menu.hh
@@ -45,6 +45,12 @@
/// Base class for menus class Menu: public FbTk::EventHandler, FbTk::FbWindowRenderer { public: + + static Menu* shownMenu(); + static Menu* focused(); + static void hideShownMenu(); + + enum Alignment{ ALIGNDONTCARE = 1, ALIGNTOP, ALIGNBOTTOM }; enum { RIGHT = 1, LEFT };@@ -134,11 +140,13 @@ bool isItemSelectable(unsigned int index) const;
FbTk::ThemeProxy<MenuTheme> &theme() { return m_theme; } const FbTk::ThemeProxy<MenuTheme> &theme() const { return m_theme; } unsigned char alpha() const { return theme()->alpha(); } - static Menu* shownMenu(); - static Menu* focused(); - static void hideShownMenu(); const MenuItem *find(size_t i) const { return m_items[i]; } MenuItem *find(size_t i) { return m_items[i]; } + + // returns index of 'submenu', it it is in the top most list of + // menu items. -1 if no match is found + int findSubmenuIndex(const Menu* submenu) const; + //@} /// @return true if index is valid bool validIndex(int index) const { return (index < static_cast<int>(numberOfItems()) && index >= 0); }
M
src/Screen.cc
→
src/Screen.cc
@@ -1362,22 +1362,25 @@
} void BScreen::addConfigMenu(const FbTk::FbString &label, FbTk::Menu &menu) { - m_configmenu_list.push_back(make_pair(label, &menu)); - if (m_configmenu.get()) - setupConfigmenu(*m_configmenu.get()); + + FbTk::Menu* cm = m_configmenu.get(); + if (cm) { + int pos = cm->findSubmenuIndex(&menu); + if (pos == -1) { // not found? add + cm->insertSubmenu(label, &menu, pos); + } + } } void BScreen::removeConfigMenu(FbTk::Menu &menu) { - Configmenus::iterator erase_it = find_if(m_configmenu_list.begin(), - m_configmenu_list.end(), - FbTk::Compose(bind2nd(equal_to<FbTk::Menu *>(), &menu), - FbTk::Select2nd<Configmenus::value_type>())); - if (erase_it != m_configmenu_list.end()) - m_configmenu_list.erase(erase_it); - if (!isShuttingdown() && m_configmenu.get()) - setupConfigmenu(*m_configmenu.get()); - + FbTk::Menu* cm = m_configmenu.get(); + if (cm) { + int pos = cm->findSubmenuIndex(&menu); + if (pos > -1) { + cm->remove(pos); + } + } }
M
src/Screen.hh
→
src/Screen.hh
@@ -501,10 +501,6 @@ std::auto_ptr<FbMenu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu;
ExtraMenus m_extramenus; - typedef std::list<std::pair<FbTk::FbString, FbTk::Menu *> > Configmenus; - - - Configmenus m_configmenu_list; Icons m_icon_list; std::auto_ptr<Slit> m_slit;