From bf75608df0025d49ea0f52326a402825fcc55d06 Mon Sep 17 00:00:00 2001 From: fluxgen Date: Fri, 12 Dec 2003 18:18:49 +0000 Subject: menu delay and mode --- src/FbTk/Menu.cc | 125 +++++++++++++++++++++++++++++++++++++++----------- src/FbTk/Menu.hh | 10 +++- src/FbTk/MenuTheme.cc | 5 +- src/FbTk/MenuTheme.hh | 22 ++++++++- src/Screen.cc | 38 ++++++++++++++- src/Screen.hh | 5 +- 6 files changed, 170 insertions(+), 35 deletions(-) diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc index cb0d7bb..77ddd5d 100644 --- a/src/FbTk/Menu.cc +++ b/src/FbTk/Menu.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Menu.cc,v 1.45 2003/12/10 23:33:15 fluxgen Exp $ +// $Id: Menu.cc,v 1.46 2003/12/12 18:18:49 fluxgen Exp $ //use GNU extensions #ifndef _GNU_SOURCE @@ -37,6 +37,7 @@ #include "App.hh" #include "EventManager.hh" #include "Transparent.hh" +#include "SimpleCommand.hh" #include #include @@ -65,6 +66,17 @@ Menu::Menu(MenuTheme &tm, ImageControl &imgctrl): m_themeobserver(*this), m_need_update(true) { + // setup timers + + RefCount show_cmd(new SimpleCommand(*this, &Menu::openSubmenu)); + m_submenu_timer.setCommand(show_cmd); + m_submenu_timer.fireOnce(true); + + + RefCount hide_cmd(new SimpleCommand(*this, &Menu::closeMenu)); + m_hide_timer.setCommand(hide_cmd); + m_hide_timer.fireOnce(true); + // make sure we get updated when the theme is reloaded tm.addListener(m_themeobserver); @@ -673,7 +685,7 @@ void Menu::drawSubmenu(unsigned int index) { if (m_alignment == ALIGNBOTTOM && (y + item->submenu()->height()) > ((shifted) ? menu.y_shift : - menu.y) + height()) { + menu.y) + height()) { y = (((shifted) ? menu.y_shift : menu.y) + height() - item->submenu()->height()); } @@ -864,23 +876,23 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_ } } else if (item->isToggleItem() && m_theme.unselectedPixmap().pixmap().drawable() != 0) { - // enable clip mask - XSetClipMask(FbTk::App::instance()->display(), - gc, - m_theme.unselectedPixmap().mask().drawable()); - XSetClipOrigin(FbTk::App::instance()->display(), - gc, sel_x, item_y); - // copy bullet pixmap to frame - m_frame_pm.copyArea(m_theme.unselectedPixmap().pixmap().drawable(), - gc, - 0, 0, - sel_x, item_y, - m_theme.unselectedPixmap().width(), - m_theme.unselectedPixmap().height()); - // disable clip mask - XSetClipMask(FbTk::App::instance()->display(), - gc, - None); + // enable clip mask + XSetClipMask(FbTk::App::instance()->display(), + gc, + m_theme.unselectedPixmap().mask().drawable()); + XSetClipOrigin(FbTk::App::instance()->display(), + gc, sel_x, item_y); + // copy bullet pixmap to frame + m_frame_pm.copyArea(m_theme.unselectedPixmap().pixmap().drawable(), + gc, + 0, 0, + sel_x, item_y, + m_theme.unselectedPixmap().width(), + m_theme.unselectedPixmap().height()); + // disable clip mask + XSetClipMask(FbTk::App::instance()->display(), + gc, + None); } if (dotext && text) { @@ -1109,6 +1121,7 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) { void Menu::motionNotifyEvent(XMotionEvent &me) { + m_hide_timer.stop(); if (me.window == menu.title && (me.state & Button1Mask)) { if (movable) { if (! moving) { @@ -1128,7 +1141,7 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { menu.window.move(menu.x, menu.y); // if (which_sub >= 0) - // drawSubmenu(which_sub); + // drawSubmenu(which_sub); } } } else if ((! (me.state & Button1Mask)) && me.window == menu.frame && @@ -1139,21 +1152,28 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { if ((i != which_press || sbl != which_sbl) && (w < static_cast(menuitems.size()) && w >= 0)) { + if (which_press != -1 && which_sbl != -1) { + int p = which_sbl * menu.persub + which_press; MenuItem *item = menuitems[p]; - // don't redraw disabled items on enter/leave - if (item->isEnabled()) { + if (item != 0 && item->isEnabled()) { + drawItem(p, false, true, true); + if (item->submenu()) { + if (item->submenu()->isVisible() && - (! item->submenu()->isTorn())) { - item->submenu()->internal_hide(); + !item->submenu()->isTorn()) { which_sub = -1; + // setup hide timer for submenu + item->submenu()->startHide(); } } + } + } which_press = i; @@ -1162,11 +1182,27 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { MenuItem *itmp = menuitems[w]; if (itmp->submenu()) { - if (!itmp->submenu()->isVisible()) - drawSubmenu(w); - } else + + drawItem(w, true); + + if (theme().menuMode() == MenuTheme::DELAY_OPEN) { + cerr<<"menuMode DELAY_OPEN"<isEnabled()) drawItem(w, true, true, true); + } } } } @@ -1347,4 +1383,39 @@ void Menu::renderTransFrame() { menu.frame.updateTransparent(); } +void Menu::openSubmenu() { + if (!isVisible() || which_press < 0 || which_press >= menuitems.size() || + which_sbl < 0 || which_sbl >= menuitems.size()) + return; + + int item = which_sbl * menu.persub + which_press; + if (item < 0 || item >= menuitems.size()) + return; + + stopHide(); + + if (menuitems[item]->submenu() != 0 && !menuitems[item]->submenu()->isVisible()) + drawSubmenu(item); + +} + +void Menu::closeMenu() { + if (isVisible() && + !isTorn()) { + internal_hide(); + } +} + +void Menu::startHide() { + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = theme().delayClose(); + m_hide_timer.setTimeout(timeout); + m_hide_timer.start(); +} + +void Menu::stopHide() { + m_hide_timer.stop(); +} + }; // end namespace FbTk diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh index 9a3f425..ec75477 100644 --- a/src/FbTk/Menu.hh +++ b/src/FbTk/Menu.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Menu.hh,v 1.25 2003/12/10 23:08:06 fluxgen Exp $ +// $Id: Menu.hh,v 1.26 2003/12/12 18:18:49 fluxgen Exp $ #ifndef FBTK_MENU_HH #define FBTK_MENU_HH @@ -39,6 +39,7 @@ #include "Observer.hh" #include "FbPixmap.hh" #include "MenuTheme.hh" +#include "Timer.hh" namespace FbTk { @@ -174,6 +175,11 @@ protected: inline const Menu *parent() const { return m_parent; } private: + void openSubmenu(); + void closeMenu(); + void startHide(); + void stopHide(); + void renderTransFrame(); typedef std::vector Menuitems; @@ -215,6 +221,8 @@ private: static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused FbPixmap m_frame_pm; bool m_need_update; + Timer m_submenu_timer; + Timer m_hide_timer; }; }; // end namespace FbTk diff --git a/src/FbTk/MenuTheme.cc b/src/FbTk/MenuTheme.cc index 6159138..aea922f 100644 --- a/src/FbTk/MenuTheme.cc +++ b/src/FbTk/MenuTheme.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: MenuTheme.cc,v 1.11 2003/09/12 23:32:02 fluxgen Exp $ +// $Id: MenuTheme.cc,v 1.12 2003/12/12 18:18:49 fluxgen Exp $ #include "MenuTheme.hh" @@ -60,6 +60,9 @@ MenuTheme::MenuTheme(int screen_num): h_text_gc(RootWindow(m_display, screen_num)), d_text_gc(RootWindow(m_display, screen_num)), hilite_gc(RootWindow(m_display, screen_num)), + m_menumode(DELAY_OPEN), + m_delayopen(0), // no delay as default + m_delayclose(0), // no delay as default m_alpha(255) { // set default values diff --git a/src/FbTk/MenuTheme.hh b/src/FbTk/MenuTheme.hh index 4e9deb3..07c29ad 100644 --- a/src/FbTk/MenuTheme.hh +++ b/src/FbTk/MenuTheme.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: MenuTheme.hh,v 1.10 2003/11/28 22:53:10 fluxgen Exp $ +// $Id: MenuTheme.hh,v 1.11 2003/12/12 18:18:49 fluxgen Exp $ #ifndef FBTK_MENUTHEME_HH #define FBTK_MENUTHEME_HH @@ -37,6 +37,11 @@ namespace FbTk { class MenuTheme:public FbTk::Theme { public: + //!! TODO + // this isn't actually used with a theme item + // see setMenuMode() for more info + enum MenuMode {CLICK_OPEN, DELAY_OPEN}; + enum BulletType { EMPTY, SQUARE, TRIANGLE, DIAMOND}; MenuTheme(int screen_num); virtual ~MenuTheme(); @@ -102,7 +107,16 @@ public: inline unsigned char alpha() const { return m_alpha; } void setAlpha(unsigned char alpha) { m_alpha = alpha; } - + // this isn't actually a theme item + // but we'll let it be here for now, until there's a better way to + // get resources into menu + void setMenuMode(MenuMode mode) { m_menumode = mode; } + MenuMode menuMode() const { return m_menumode; } + void setDelayOpen(int usec) { m_delayopen = usec; } + void setDelayClose(int usec) { m_delayclose = usec; } + int delayOpen() const { return m_delayopen; } + int delayClose() const { return m_delayclose; } + const FbTk::Color &borderColor() const { return *m_border_color; } FbTk::Subject &themeChangeSig() { return m_theme_change_sig; } /// attach observer @@ -126,6 +140,10 @@ private: FbTk::Subject m_theme_change_sig; unsigned char m_alpha; + MenuMode m_menumode; + unsigned int m_delayopen; ///< in usec + unsigned int m_delayclose; ///< in usec + }; }; // end namespace FbTk diff --git a/src/Screen.cc b/src/Screen.cc index c95b96b..ba5e0d5 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.247 2003/12/10 23:08:03 fluxgen Exp $ +// $Id: Screen.cc,v 1.248 2003/12/12 18:18:12 fluxgen Exp $ #include "Screen.hh" @@ -154,7 +154,31 @@ private: }; // End anonymous namespace +template <> +void FbTk::Resource::setDefaultValue() { + *(*this) = FbTk::MenuTheme::DELAY_OPEN; +} + +template <> +string FbTk::Resource::getString() { + switch (*(*this)) { + case FbTk::MenuTheme::DELAY_OPEN: + return string("Delay"); + case FbTk::MenuTheme::CLICK_OPEN: + return string("Click"); + } + return string("Delay"); +} +template <> +void FbTk::Resource::setFromString(const char *str) { + if (strcasecmp(str, "Delay") == 0) + *(*this) = FbTk::MenuTheme::DELAY_OPEN; + else if (strcasecmp(str, "Click") == 0) + *(*this) = FbTk::MenuTheme::CLICK_OPEN; + else + setDefaultValue(); +} namespace { @@ -222,7 +246,10 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm, focus_model(rm, Fluxbox::CLICKTOFOCUS, scrname+".focusModel", altscrname+".FocusModel"), workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"), edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"), - menu_alpha(rm, 255, scrname+".menuAlpha", altscrname+".MenuAlpha") { + menu_alpha(rm, 255, scrname+".menuAlpha", altscrname+".MenuAlpha"), + menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"), + menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"), + menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode") { }; @@ -307,6 +334,9 @@ BScreen::BScreen(FbTk::ResourceManager &rm, m_menutheme->setAlpha(*resource.menu_alpha); + m_menutheme->setMenuMode(*resource.menu_mode); + m_menutheme->setDelayOpen(*resource.menu_delay); + m_menutheme->setDelayClose(*resource.menu_delay_close); imageControl().setDither(*resource.image_dither); @@ -570,6 +600,10 @@ FbTk::Menu *BScreen::createMenu(const std::string &label) { void BScreen::reconfigure() { m_menutheme->setAlpha(*resource.menu_alpha); + m_menutheme->setMenuMode(*resource.menu_mode); + m_menutheme->setDelayOpen(*resource.menu_delay); + m_menutheme->setDelayClose(*resource.menu_delay_close); + Fluxbox::instance()->loadRootCommand(*this); // setup windowtheme, toolbartheme for antialias diff --git a/src/Screen.hh b/src/Screen.hh index df836db..c73dead 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.hh,v 1.126 2003/12/10 23:08:03 fluxgen Exp $ +// $Id: Screen.hh,v 1.127 2003/12/12 18:18:12 fluxgen Exp $ #ifndef SCREEN_HH #define SCREEN_HH @@ -430,7 +430,8 @@ private: FbTk::Resource resizemode; FbTk::Resource focus_model; bool ordered_dither; - FbTk::Resource workspaces, edge_snap_threshold, menu_alpha; + FbTk::Resource workspaces, edge_snap_threshold, menu_alpha, menu_delay, menu_delay_close; + FbTk::Resource menu_mode; int placement_policy, row_direction, col_direction; -- cgit v0.11.2