diff options
Diffstat (limited to 'src/FbTk')
-rw-r--r-- | src/FbTk/Menu.cc | 125 | ||||
-rw-r--r-- | src/FbTk/Menu.hh | 10 | ||||
-rw-r--r-- | src/FbTk/MenuTheme.cc | 5 | ||||
-rw-r--r-- | src/FbTk/MenuTheme.hh | 22 |
4 files changed, 131 insertions, 31 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 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Menu.cc,v 1.45 2003/12/10 23:33:15 fluxgen Exp $ | 25 | // $Id: Menu.cc,v 1.46 2003/12/12 18:18:49 fluxgen Exp $ |
26 | 26 | ||
27 | //use GNU extensions | 27 | //use GNU extensions |
28 | #ifndef _GNU_SOURCE | 28 | #ifndef _GNU_SOURCE |
@@ -37,6 +37,7 @@ | |||
37 | #include "App.hh" | 37 | #include "App.hh" |
38 | #include "EventManager.hh" | 38 | #include "EventManager.hh" |
39 | #include "Transparent.hh" | 39 | #include "Transparent.hh" |
40 | #include "SimpleCommand.hh" | ||
40 | 41 | ||
41 | #include <X11/Xatom.h> | 42 | #include <X11/Xatom.h> |
42 | #include <X11/keysym.h> | 43 | #include <X11/keysym.h> |
@@ -65,6 +66,17 @@ Menu::Menu(MenuTheme &tm, ImageControl &imgctrl): | |||
65 | m_themeobserver(*this), | 66 | m_themeobserver(*this), |
66 | m_need_update(true) { | 67 | m_need_update(true) { |
67 | 68 | ||
69 | // setup timers | ||
70 | |||
71 | RefCount<Command> show_cmd(new SimpleCommand<Menu>(*this, &Menu::openSubmenu)); | ||
72 | m_submenu_timer.setCommand(show_cmd); | ||
73 | m_submenu_timer.fireOnce(true); | ||
74 | |||
75 | |||
76 | RefCount<Command> hide_cmd(new SimpleCommand<Menu>(*this, &Menu::closeMenu)); | ||
77 | m_hide_timer.setCommand(hide_cmd); | ||
78 | m_hide_timer.fireOnce(true); | ||
79 | |||
68 | // make sure we get updated when the theme is reloaded | 80 | // make sure we get updated when the theme is reloaded |
69 | tm.addListener(m_themeobserver); | 81 | tm.addListener(m_themeobserver); |
70 | 82 | ||
@@ -673,7 +685,7 @@ void Menu::drawSubmenu(unsigned int index) { | |||
673 | 685 | ||
674 | if (m_alignment == ALIGNBOTTOM && | 686 | if (m_alignment == ALIGNBOTTOM && |
675 | (y + item->submenu()->height()) > ((shifted) ? menu.y_shift : | 687 | (y + item->submenu()->height()) > ((shifted) ? menu.y_shift : |
676 | menu.y) + height()) { | 688 | menu.y) + height()) { |
677 | y = (((shifted) ? menu.y_shift : menu.y) + | 689 | y = (((shifted) ? menu.y_shift : menu.y) + |
678 | height() - item->submenu()->height()); | 690 | height() - item->submenu()->height()); |
679 | } | 691 | } |
@@ -864,23 +876,23 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_ | |||
864 | } | 876 | } |
865 | 877 | ||
866 | } else if (item->isToggleItem() && m_theme.unselectedPixmap().pixmap().drawable() != 0) { | 878 | } else if (item->isToggleItem() && m_theme.unselectedPixmap().pixmap().drawable() != 0) { |
867 | // enable clip mask | 879 | // enable clip mask |
868 | XSetClipMask(FbTk::App::instance()->display(), | 880 | XSetClipMask(FbTk::App::instance()->display(), |
869 | gc, | 881 | gc, |
870 | m_theme.unselectedPixmap().mask().drawable()); | 882 | m_theme.unselectedPixmap().mask().drawable()); |
871 | XSetClipOrigin(FbTk::App::instance()->display(), | 883 | XSetClipOrigin(FbTk::App::instance()->display(), |
872 | gc, sel_x, item_y); | 884 | gc, sel_x, item_y); |
873 | // copy bullet pixmap to frame | 885 | // copy bullet pixmap to frame |
874 | m_frame_pm.copyArea(m_theme.unselectedPixmap().pixmap().drawable(), | 886 | m_frame_pm.copyArea(m_theme.unselectedPixmap().pixmap().drawable(), |
875 | gc, | 887 | gc, |
876 | 0, 0, | 888 | 0, 0, |
877 | sel_x, item_y, | 889 | sel_x, item_y, |
878 | m_theme.unselectedPixmap().width(), | 890 | m_theme.unselectedPixmap().width(), |
879 | m_theme.unselectedPixmap().height()); | 891 | m_theme.unselectedPixmap().height()); |
880 | // disable clip mask | 892 | // disable clip mask |
881 | XSetClipMask(FbTk::App::instance()->display(), | 893 | XSetClipMask(FbTk::App::instance()->display(), |
882 | gc, | 894 | gc, |
883 | None); | 895 | None); |
884 | } | 896 | } |
885 | 897 | ||
886 | if (dotext && text) { | 898 | if (dotext && text) { |
@@ -1109,6 +1121,7 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) { | |||
1109 | 1121 | ||
1110 | 1122 | ||
1111 | void Menu::motionNotifyEvent(XMotionEvent &me) { | 1123 | void Menu::motionNotifyEvent(XMotionEvent &me) { |
1124 | m_hide_timer.stop(); | ||
1112 | if (me.window == menu.title && (me.state & Button1Mask)) { | 1125 | if (me.window == menu.title && (me.state & Button1Mask)) { |
1113 | if (movable) { | 1126 | if (movable) { |
1114 | if (! moving) { | 1127 | if (! moving) { |
@@ -1128,7 +1141,7 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { | |||
1128 | menu.window.move(menu.x, menu.y); | 1141 | menu.window.move(menu.x, menu.y); |
1129 | 1142 | ||
1130 | // if (which_sub >= 0) | 1143 | // if (which_sub >= 0) |
1131 | // drawSubmenu(which_sub); | 1144 | // drawSubmenu(which_sub); |
1132 | } | 1145 | } |
1133 | } | 1146 | } |
1134 | } else if ((! (me.state & Button1Mask)) && me.window == menu.frame && | 1147 | } else if ((! (me.state & Button1Mask)) && me.window == menu.frame && |
@@ -1139,21 +1152,28 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { | |||
1139 | 1152 | ||
1140 | if ((i != which_press || sbl != which_sbl) && | 1153 | if ((i != which_press || sbl != which_sbl) && |
1141 | (w < static_cast<int>(menuitems.size()) && w >= 0)) { | 1154 | (w < static_cast<int>(menuitems.size()) && w >= 0)) { |
1155 | |||
1142 | if (which_press != -1 && which_sbl != -1) { | 1156 | if (which_press != -1 && which_sbl != -1) { |
1157 | |||
1143 | int p = which_sbl * menu.persub + which_press; | 1158 | int p = which_sbl * menu.persub + which_press; |
1144 | MenuItem *item = menuitems[p]; | 1159 | MenuItem *item = menuitems[p]; |
1145 | |||
1146 | // don't redraw disabled items on enter/leave | 1160 | // don't redraw disabled items on enter/leave |
1147 | if (item->isEnabled()) { | 1161 | if (item != 0 && item->isEnabled()) { |
1162 | |||
1148 | drawItem(p, false, true, true); | 1163 | drawItem(p, false, true, true); |
1164 | |||
1149 | if (item->submenu()) { | 1165 | if (item->submenu()) { |
1166 | |||
1150 | if (item->submenu()->isVisible() && | 1167 | if (item->submenu()->isVisible() && |
1151 | (! item->submenu()->isTorn())) { | 1168 | !item->submenu()->isTorn()) { |
1152 | item->submenu()->internal_hide(); | ||
1153 | which_sub = -1; | 1169 | which_sub = -1; |
1170 | // setup hide timer for submenu | ||
1171 | item->submenu()->startHide(); | ||
1154 | } | 1172 | } |
1155 | } | 1173 | } |
1174 | |||
1156 | } | 1175 | } |
1176 | |||
1157 | } | 1177 | } |
1158 | 1178 | ||
1159 | which_press = i; | 1179 | which_press = i; |
@@ -1162,11 +1182,27 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { | |||
1162 | MenuItem *itmp = menuitems[w]; | 1182 | MenuItem *itmp = menuitems[w]; |
1163 | 1183 | ||
1164 | if (itmp->submenu()) { | 1184 | if (itmp->submenu()) { |
1165 | if (!itmp->submenu()->isVisible()) | 1185 | |
1166 | drawSubmenu(w); | 1186 | drawItem(w, true); |
1167 | } else | 1187 | |
1188 | if (theme().menuMode() == MenuTheme::DELAY_OPEN) { | ||
1189 | cerr<<"menuMode DELAY_OPEN"<<endl; | ||
1190 | // setup show menu timer | ||
1191 | stopHide(); | ||
1192 | |||
1193 | timeval timeout; | ||
1194 | timeout.tv_sec = 0; | ||
1195 | timeout.tv_usec = theme().delayOpen(); | ||
1196 | m_submenu_timer.setTimeout(timeout); | ||
1197 | m_submenu_timer.start(); | ||
1198 | |||
1199 | } | ||
1200 | |||
1201 | } else { | ||
1202 | m_submenu_timer.stop(); | ||
1168 | if (itmp->isEnabled()) | 1203 | if (itmp->isEnabled()) |
1169 | drawItem(w, true, true, true); | 1204 | drawItem(w, true, true, true); |
1205 | } | ||
1170 | } | 1206 | } |
1171 | } | 1207 | } |
1172 | } | 1208 | } |
@@ -1347,4 +1383,39 @@ void Menu::renderTransFrame() { | |||
1347 | menu.frame.updateTransparent(); | 1383 | menu.frame.updateTransparent(); |
1348 | } | 1384 | } |
1349 | 1385 | ||
1386 | void Menu::openSubmenu() { | ||
1387 | if (!isVisible() || which_press < 0 || which_press >= menuitems.size() || | ||
1388 | which_sbl < 0 || which_sbl >= menuitems.size()) | ||
1389 | return; | ||
1390 | |||
1391 | int item = which_sbl * menu.persub + which_press; | ||
1392 | if (item < 0 || item >= menuitems.size()) | ||
1393 | return; | ||
1394 | |||
1395 | stopHide(); | ||
1396 | |||
1397 | if (menuitems[item]->submenu() != 0 && !menuitems[item]->submenu()->isVisible()) | ||
1398 | drawSubmenu(item); | ||
1399 | |||
1400 | } | ||
1401 | |||
1402 | void Menu::closeMenu() { | ||
1403 | if (isVisible() && | ||
1404 | !isTorn()) { | ||
1405 | internal_hide(); | ||
1406 | } | ||
1407 | } | ||
1408 | |||
1409 | void Menu::startHide() { | ||
1410 | timeval timeout; | ||
1411 | timeout.tv_sec = 0; | ||
1412 | timeout.tv_usec = theme().delayClose(); | ||
1413 | m_hide_timer.setTimeout(timeout); | ||
1414 | m_hide_timer.start(); | ||
1415 | } | ||
1416 | |||
1417 | void Menu::stopHide() { | ||
1418 | m_hide_timer.stop(); | ||
1419 | } | ||
1420 | |||
1350 | }; // end namespace FbTk | 1421 | }; // 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 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Menu.hh,v 1.25 2003/12/10 23:08:06 fluxgen Exp $ | 25 | // $Id: Menu.hh,v 1.26 2003/12/12 18:18:49 fluxgen Exp $ |
26 | 26 | ||
27 | #ifndef FBTK_MENU_HH | 27 | #ifndef FBTK_MENU_HH |
28 | #define FBTK_MENU_HH | 28 | #define FBTK_MENU_HH |
@@ -39,6 +39,7 @@ | |||
39 | #include "Observer.hh" | 39 | #include "Observer.hh" |
40 | #include "FbPixmap.hh" | 40 | #include "FbPixmap.hh" |
41 | #include "MenuTheme.hh" | 41 | #include "MenuTheme.hh" |
42 | #include "Timer.hh" | ||
42 | 43 | ||
43 | namespace FbTk { | 44 | namespace FbTk { |
44 | 45 | ||
@@ -174,6 +175,11 @@ protected: | |||
174 | inline const Menu *parent() const { return m_parent; } | 175 | inline const Menu *parent() const { return m_parent; } |
175 | 176 | ||
176 | private: | 177 | private: |
178 | void openSubmenu(); | ||
179 | void closeMenu(); | ||
180 | void startHide(); | ||
181 | void stopHide(); | ||
182 | |||
177 | void renderTransFrame(); | 183 | void renderTransFrame(); |
178 | 184 | ||
179 | typedef std::vector<MenuItem *> Menuitems; | 185 | typedef std::vector<MenuItem *> Menuitems; |
@@ -215,6 +221,8 @@ private: | |||
215 | static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused | 221 | static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused |
216 | FbPixmap m_frame_pm; | 222 | FbPixmap m_frame_pm; |
217 | bool m_need_update; | 223 | bool m_need_update; |
224 | Timer m_submenu_timer; | ||
225 | Timer m_hide_timer; | ||
218 | }; | 226 | }; |
219 | 227 | ||
220 | }; // end namespace FbTk | 228 | }; // 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 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: MenuTheme.cc,v 1.11 2003/09/12 23:32:02 fluxgen Exp $ | 22 | // $Id: MenuTheme.cc,v 1.12 2003/12/12 18:18:49 fluxgen Exp $ |
23 | 23 | ||
24 | #include "MenuTheme.hh" | 24 | #include "MenuTheme.hh" |
25 | 25 | ||
@@ -60,6 +60,9 @@ MenuTheme::MenuTheme(int screen_num): | |||
60 | h_text_gc(RootWindow(m_display, screen_num)), | 60 | h_text_gc(RootWindow(m_display, screen_num)), |
61 | d_text_gc(RootWindow(m_display, screen_num)), | 61 | d_text_gc(RootWindow(m_display, screen_num)), |
62 | hilite_gc(RootWindow(m_display, screen_num)), | 62 | hilite_gc(RootWindow(m_display, screen_num)), |
63 | m_menumode(DELAY_OPEN), | ||
64 | m_delayopen(0), // no delay as default | ||
65 | m_delayclose(0), // no delay as default | ||
63 | m_alpha(255) { | 66 | m_alpha(255) { |
64 | 67 | ||
65 | // set default values | 68 | // 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 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: MenuTheme.hh,v 1.10 2003/11/28 22:53:10 fluxgen Exp $ | 22 | // $Id: MenuTheme.hh,v 1.11 2003/12/12 18:18:49 fluxgen Exp $ |
23 | 23 | ||
24 | #ifndef FBTK_MENUTHEME_HH | 24 | #ifndef FBTK_MENUTHEME_HH |
25 | #define FBTK_MENUTHEME_HH | 25 | #define FBTK_MENUTHEME_HH |
@@ -37,6 +37,11 @@ namespace FbTk { | |||
37 | 37 | ||
38 | class MenuTheme:public FbTk::Theme { | 38 | class MenuTheme:public FbTk::Theme { |
39 | public: | 39 | public: |
40 | //!! TODO | ||
41 | // this isn't actually used with a theme item | ||
42 | // see setMenuMode() for more info | ||
43 | enum MenuMode {CLICK_OPEN, DELAY_OPEN}; | ||
44 | |||
40 | enum BulletType { EMPTY, SQUARE, TRIANGLE, DIAMOND}; | 45 | enum BulletType { EMPTY, SQUARE, TRIANGLE, DIAMOND}; |
41 | MenuTheme(int screen_num); | 46 | MenuTheme(int screen_num); |
42 | virtual ~MenuTheme(); | 47 | virtual ~MenuTheme(); |
@@ -102,7 +107,16 @@ public: | |||
102 | 107 | ||
103 | inline unsigned char alpha() const { return m_alpha; } | 108 | inline unsigned char alpha() const { return m_alpha; } |
104 | void setAlpha(unsigned char alpha) { m_alpha = alpha; } | 109 | void setAlpha(unsigned char alpha) { m_alpha = alpha; } |
105 | 110 | // this isn't actually a theme item | |
111 | // but we'll let it be here for now, until there's a better way to | ||
112 | // get resources into menu | ||
113 | void setMenuMode(MenuMode mode) { m_menumode = mode; } | ||
114 | MenuMode menuMode() const { return m_menumode; } | ||
115 | void setDelayOpen(int usec) { m_delayopen = usec; } | ||
116 | void setDelayClose(int usec) { m_delayclose = usec; } | ||
117 | int delayOpen() const { return m_delayopen; } | ||
118 | int delayClose() const { return m_delayclose; } | ||
119 | |||
106 | const FbTk::Color &borderColor() const { return *m_border_color; } | 120 | const FbTk::Color &borderColor() const { return *m_border_color; } |
107 | FbTk::Subject &themeChangeSig() { return m_theme_change_sig; } | 121 | FbTk::Subject &themeChangeSig() { return m_theme_change_sig; } |
108 | /// attach observer | 122 | /// attach observer |
@@ -126,6 +140,10 @@ private: | |||
126 | FbTk::Subject m_theme_change_sig; | 140 | FbTk::Subject m_theme_change_sig; |
127 | 141 | ||
128 | unsigned char m_alpha; | 142 | unsigned char m_alpha; |
143 | MenuMode m_menumode; | ||
144 | unsigned int m_delayopen; ///< in usec | ||
145 | unsigned int m_delayclose; ///< in usec | ||
146 | |||
129 | }; | 147 | }; |
130 | 148 | ||
131 | }; // end namespace FbTk | 149 | }; // end namespace FbTk |