aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/Menu.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/Menu.cc')
-rw-r--r--src/FbTk/Menu.cc125
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
1111void Menu::motionNotifyEvent(XMotionEvent &me) { 1123void 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
1386void 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
1402void Menu::closeMenu() {
1403 if (isVisible() &&
1404 !isTorn()) {
1405 internal_hide();
1406 }
1407}
1408
1409void 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
1417void Menu::stopHide() {
1418 m_hide_timer.stop();
1419}
1420
1350}; // end namespace FbTk 1421}; // end namespace FbTk