diff options
Diffstat (limited to 'src/FbTk/Menu.cc')
-rw-r--r-- | src/FbTk/Menu.cc | 125 |
1 files changed, 98 insertions, 27 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 |