aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk')
-rw-r--r--src/FbTk/Menu.cc254
-rw-r--r--src/FbTk/Menu.hh18
2 files changed, 163 insertions, 109 deletions
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc
index dad6159..ac8d651 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.68 2004/06/14 16:09:48 fluxgen Exp $ 25// $Id: Menu.cc,v 1.69 2004/06/27 13:50:24 fluxgen Exp $
26 26
27//use GNU extensions 27//use GNU extensions
28#ifndef _GNU_SOURCE 28#ifndef _GNU_SOURCE
@@ -89,6 +89,7 @@ Menu::Menu(MenuTheme &tm, ImageControl &imgctrl):
89 m_screen_width(DisplayWidth(FbTk::App::instance()->display(), tm.screenNum())), 89 m_screen_width(DisplayWidth(FbTk::App::instance()->display(), tm.screenNum())),
90 m_screen_height(DisplayHeight(FbTk::App::instance()->display(), tm.screenNum())), 90 m_screen_height(DisplayHeight(FbTk::App::instance()->display(), tm.screenNum())),
91 m_alignment(ALIGNDONTCARE), 91 m_alignment(ALIGNDONTCARE),
92 m_active_index(-1),
92 m_need_update(true) { 93 m_need_update(true) {
93 94
94 // setup timers 95 // setup timers
@@ -198,9 +199,7 @@ Menu::~Menu() {
198 m_image_ctrl.removeImage(menu.sel_pixmap); 199 m_image_ctrl.removeImage(menu.sel_pixmap);
199 200
200 FbTk::EventManager &evm = *FbTk::EventManager::instance(); 201 FbTk::EventManager &evm = *FbTk::EventManager::instance();
201 evm.remove(menu.title); 202
202 evm.remove(menu.frame);
203 evm.remove(menu.window);
204 if (s_focused == this) 203 if (s_focused == this)
205 s_focused = 0; 204 s_focused = 0;
206} 205}
@@ -261,7 +260,9 @@ int Menu::remove(unsigned int index) {
261 which_sub = -1; 260 which_sub = -1;
262 else if (static_cast<unsigned int>(which_sub) > index) 261 else if (static_cast<unsigned int>(which_sub) > index)
263 which_sub--; 262 which_sub--;
263
264 m_need_update = true; // we need to redraw the menu 264 m_need_update = true; // we need to redraw the menu
265
265 return menuitems.size(); 266 return menuitems.size();
266} 267}
267 268
@@ -283,30 +284,36 @@ void Menu::lower() {
283void Menu::nextItem() { 284void Menu::nextItem() {
284 int old_which_press = which_press; 285 int old_which_press = which_press;
285 286
286 if (old_which_press >= 0 && 287 if (validIndex(old_which_press) &&
287 old_which_press < static_cast<signed>(menuitems.size()) &&
288 menuitems[old_which_press] != 0) { 288 menuitems[old_which_press] != 0) {
289 if (menuitems[old_which_press]->submenu()) { 289 if (menuitems[old_which_press]->submenu()) {
290 // we need to do this explicitly on the menu.window 290 // we need to do this explicitly on the menu.window
291 // since it might hide the parent if we use Menu::hide 291 // since it might hide the parent if we use Menu::hide
292 menuitems[old_which_press]->submenu()->internal_hide(); 292 menuitems[old_which_press]->submenu()->internal_hide();
293 } 293 }
294 drawItem(old_which_press, false, true, true); 294 drawItem(old_which_press,
295 true, // clear
296 true); // transp
295 } 297 }
296 298
297 // restore old in case we changed which_press 299 // restore old in case we changed which_press
298 which_press = old_which_press; 300 which_press = old_which_press;
299 if (which_press < 0 || which_press >= static_cast<signed>(menuitems.size() - 1)) 301 if (!validIndex(which_press))
300 which_press = 0; 302 which_press = 0;
301 else 303 else
302 which_press++; 304 which_press++;
303 305
304 306
305 if (menuitems[which_press] == 0) 307 if (menuitems[which_press] == 0) {
308 m_active_index = -1;
306 return; 309 return;
310 }
307 311
312 m_active_index = which_press;
308 313
309 drawItem(which_press, true, true, true); 314 drawItem(which_press,
315 true, // clear
316 true); // transp
310 317
311} 318}
312 319
@@ -314,32 +321,39 @@ void Menu::prevItem() {
314 321
315 int old_which_press = which_press; 322 int old_which_press = which_press;
316 323
317 if (old_which_press >= 0 && old_which_press < static_cast<signed>(menuitems.size())) { 324 if (validIndex(old_which_press)) {
318 if (menuitems[old_which_press]->submenu()) { 325 if (menuitems[old_which_press]->submenu()) {
319 // we need to do this explicitly on the menu.window 326 // we need to do this explicitly on the menu.window
320 // since it might hide the parent if we use Menu::hide 327 // since it might hide the parent if we use Menu::hide
321 menuitems[old_which_press]->submenu()->internal_hide(); 328 menuitems[old_which_press]->submenu()->internal_hide();
322 } 329 }
323 drawItem(old_which_press, false, true, true); 330 drawItem(old_which_press,
331 true, // clear
332 true); // transp
324 } 333 }
325 // restore old in case we changed which_press 334 // restore old in case we changed which_press
326 which_press = old_which_press; 335 which_press = old_which_press;
327 336
328 if (which_press <= 0 || which_press >= static_cast<signed>(menuitems.size())) 337 if (!validIndex(which_press))
329 which_press = menuitems.size() - 1; 338 which_press = menuitems.size() - 1;
330 else if (which_press - 1 >= 0) 339 else if (which_press - 1 >= 0)
331 which_press--; 340 which_press--;
332 341
333 if (menuitems[which_press] == 0) 342 if (menuitems[which_press] == 0) {
343 m_active_index = -1;
334 return; 344 return;
345 }
335 346
347 m_active_index = which_press;
336 348
337 drawItem(which_press, true, true, true); 349 drawItem(which_press,
350 true, // clear
351 true); // transp
338 352
339} 353}
340 354
341void Menu::enterSubmenu() { 355void Menu::enterSubmenu() {
342 if (which_press < 0 || which_press >= static_cast<signed>(menuitems.size())) 356 if (!validIndex(which_press))
343 return; 357 return;
344 358
345 Menu *submenu = menuitems[which_press]->submenu(); 359 Menu *submenu = menuitems[which_press]->submenu();
@@ -356,14 +370,16 @@ void Menu::enterSubmenu() {
356} 370}
357 371
358void Menu::enterParent() { 372void Menu::enterParent() {
359 if (which_press < 0 || which_press >= static_cast<signed>(menuitems.size()) || parent() == 0) 373 if (!validIndex(which_press) || parent() == 0)
360 return; 374 return;
361 375
362 Menu *submenu = menuitems[which_press]->submenu(); 376 Menu *submenu = menuitems[which_press]->submenu();
363 if (submenu) 377 if (submenu)
364 submenu->internal_hide(); 378 submenu->internal_hide();
365 379
366 drawItem(which_press, false, true, true); 380 drawItem(which_press,
381 true, // clear
382 true); // transp
367 which_press = -1; // dont select any in this 383 which_press = -1; // dont select any in this
368 // hide self 384 // hide self
369 visible = false; 385 visible = false;
@@ -422,7 +438,7 @@ void Menu::update(int active_index) {
422 int new_height = menu.frame_h; 438 int new_height = menu.frame_h;
423 439
424 if (title_vis) 440 if (title_vis)
425 new_height += theme().titleHeight() + ((menu.frame_h>0)?menu.title.borderWidth():0); 441 new_height += theme().titleHeight() + ((menu.frame_h > 0)?menu.title.borderWidth():0);
426 442
427 443
428 if (new_width < 1) 444 if (new_width < 1)
@@ -588,18 +604,9 @@ void Menu::update(int active_index) {
588 renderTransp(0, 0, 604 renderTransp(0, 0,
589 m_real_frame_pm.width(), m_real_frame_pm.height()); 605 m_real_frame_pm.width(), m_real_frame_pm.height());
590 for (unsigned int i = 0; i < menuitems.size(); i++) { 606 for (unsigned int i = 0; i < menuitems.size(); i++) {
591 if (i == (unsigned int)which_sub) { 607 drawItem(i, // index
592 drawItem(i, // index 608 true, // clear
593 true, // highlight 609 false); // render_trans
594 true, // clear
595 false); // render_trans
596 } else {
597 drawItem(i, // index
598 // highlight
599 (static_cast<signed>(i) == active_index && isItemEnabled(i)),
600 true, // clear
601 false); // render transparent
602 }
603 } 610 }
604 611
605 } 612 }
@@ -609,6 +616,7 @@ void Menu::update(int active_index) {
609 616
610 617
611void Menu::show() { 618void Menu::show() {
619
612 if (m_need_update) 620 if (m_need_update)
613 update(); 621 update();
614 622
@@ -632,15 +640,18 @@ void Menu::hide() {
632 if (!isVisible()) 640 if (!isVisible())
633 return; 641 return;
634 642
635 if ((! torn) && m_parent && m_parent->isVisible()) { 643
644 // if not torn and parent is visible, go to first parent
645 // and hide it
646 if (!torn && m_parent && m_parent->isVisible()) {
636 Menu *p = m_parent; 647 Menu *p = m_parent;
637 648
638 while (p->isVisible() && (! p->torn) && p->m_parent) 649 while (p->isVisible() && (! p->torn) && p->m_parent)
639 p = p->m_parent; 650 p = p->m_parent;
640 p->internal_hide(); 651 p->internal_hide();
641 } else 652 } else // if we dont have a parent then do hide here
642 internal_hide(); 653 internal_hide();
643 654
644} 655}
645 656
646void Menu::grabInputFocus() { 657void Menu::grabInputFocus() {
@@ -666,21 +677,24 @@ void Menu::clearWindow() {
666} 677}
667 678
668void Menu::internal_hide() { 679void Menu::internal_hide() {
669 if (which_sub >= 0) { 680
681 if (validIndex(which_sub)) {
670 MenuItem *tmp = menuitems[which_sub]; 682 MenuItem *tmp = menuitems[which_sub];
671 tmp->submenu()->internal_hide(); 683 tmp->submenu()->internal_hide();
672 } 684 }
673 685
674 if (m_parent && (! torn)) { 686 if (shown && shown->menu.window == menu.window)
675 m_parent->drawItem(m_parent->which_sub, false, true);
676
677 m_parent->which_sub = -1;
678 } else if (shown && shown->menu.window == menu.window)
679 shown = (Menu *) 0; 687 shown = (Menu *) 0;
680 688
681 torn = visible = false; 689 torn = visible = false;
682 which_sub = which_press = which_sub = -1; 690 which_sub = which_press = which_sub = -1;
683 691
692 // if we have an active index we need to redraw it
693 // as non active
694 int old = m_active_index;
695 m_active_index = -1;
696 drawItem(old, true); // clear old area from highlight
697
684 menu.window.hide(); 698 menu.window.hide();
685} 699}
686 700
@@ -709,7 +723,7 @@ void Menu::move(int x, int y) {
709 renderTransp(0, 0, 723 renderTransp(0, 0,
710 m_real_frame_pm.width(), m_real_frame_pm.height()); 724 m_real_frame_pm.width(), m_real_frame_pm.height());
711 for (size_t i=0; i < menuitems.size(); ++i) { 725 for (size_t i=0; i < menuitems.size(); ++i) {
712 drawItem(i, false, // highlight 726 drawItem(i,
713 true, // clear 727 true, // clear
714 false); // transparent 728 false); // transparent
715 } 729 }
@@ -759,8 +773,7 @@ void Menu::redrawTitle() {
759 773
760 774
761void Menu::drawSubmenu(unsigned int index) { 775void Menu::drawSubmenu(unsigned int index) {
762 if (which_sub >= 0 && static_cast<unsigned int>(which_sub) != index && 776 if (validIndex(which_sub) && static_cast<unsigned int>(which_sub) != index) {
763 static_cast<unsigned int>(which_sub) < menuitems.size()) {
764 MenuItem *itmp = menuitems[which_sub]; 777 MenuItem *itmp = menuitems[which_sub];
765 778
766 if (! itmp->submenu()->isTorn()) 779 if (! itmp->submenu()->isTorn())
@@ -822,7 +835,7 @@ void Menu::drawSubmenu(unsigned int index) {
822 835
823 item->submenu()->move(new_x, new_y); 836 item->submenu()->move(new_x, new_y);
824 if (! moving) 837 if (! moving)
825 drawItem(index, true); 838 drawItem(index);
826 839
827 if (! item->submenu()->isVisible()) { 840 if (! item->submenu()->isVisible()) {
828 item->submenu()->show(); 841 item->submenu()->show();
@@ -847,7 +860,7 @@ bool Menu::hasSubmenu(unsigned int index) const {
847} 860}
848 861
849 862
850int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_trans, 863int Menu::drawItem(unsigned int index, bool clear, bool render_trans,
851 int x, int y, unsigned int w, unsigned int h) { 864 int x, int y, unsigned int w, unsigned int h) {
852 if (index >= menuitems.size() || menuitems.size() == 0 || 865 if (index >= menuitems.size() || menuitems.size() == 0 ||
853 menu.persub == 0) 866 menu.persub == 0)
@@ -862,7 +875,7 @@ int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_t
862 int sel_x = 0, sel_y = 0; 875 int sel_x = 0, sel_y = 0;
863 unsigned int hilite_w = menu.item_w, hilite_h = theme().itemHeight(); 876 unsigned int hilite_w = menu.item_w, hilite_h = theme().itemHeight();
864 unsigned int half_w = theme().itemHeight() / 2, quarter_w = theme().itemHeight() / 4; 877 unsigned int half_w = theme().itemHeight() / 2, quarter_w = theme().itemHeight() / 4;
865 878 bool highlight = (index == m_active_index);
866 GC gc = 879 GC gc =
867 ((highlight || item->isSelected()) ? theme().hiliteTextGC().gc() : 880 ((highlight || item->isSelected()) ? theme().hiliteTextGC().gc() :
868 theme().frameTextGC().gc()); 881 theme().frameTextGC().gc());
@@ -1044,7 +1057,7 @@ void Menu::buttonPressEvent(XButtonEvent &be) {
1044 int sbl = (be.x / menu.item_w), i = (be.y / theme().itemHeight()); 1057 int sbl = (be.x / menu.item_w), i = (be.y / theme().itemHeight());
1045 int w = (sbl * menu.persub) + i; 1058 int w = (sbl * menu.persub) + i;
1046 1059
1047 if (w < static_cast<int>(menuitems.size()) && w >= 0) { 1060 if (validIndex(w)) {
1048 which_press = i; 1061 which_press = i;
1049 which_sbl = sbl; 1062 which_sbl = sbl;
1050 1063
@@ -1054,7 +1067,9 @@ void Menu::buttonPressEvent(XButtonEvent &be) {
1054 if (!item->submenu()->isVisible()) 1067 if (!item->submenu()->isVisible())
1055 drawSubmenu(w); 1068 drawSubmenu(w);
1056 } else 1069 } else
1057 drawItem(w, item->isEnabled(), true, true); 1070 drawItem(w,
1071 true, // clear
1072 true); // render transparency
1058 1073
1059 } 1074 }
1060 } else { 1075 } else {
@@ -1078,7 +1093,7 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) {
1078 renderTransp(0, 0, 1093 renderTransp(0, 0,
1079 m_real_frame_pm.width(), m_real_frame_pm.height()); 1094 m_real_frame_pm.width(), m_real_frame_pm.height());
1080 for (size_t i=0; i < menuitems.size(); ++i) { 1095 for (size_t i=0; i < menuitems.size(); ++i) {
1081 drawItem(i, false, // highlight 1096 drawItem(i,
1082 true, // clear 1097 true, // clear
1083 false); // transparent 1098 false); // transparent
1084 } 1099 }
@@ -1100,20 +1115,28 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) {
1100 w = (sbl * menu.persub) + i, 1115 w = (sbl * menu.persub) + i,
1101 p = (which_sbl * menu.persub) + which_press; 1116 p = (which_sbl * menu.persub) + which_press;
1102 1117
1103 if (w < static_cast<int>(menuitems.size()) && w >= 0) { 1118 if (validIndex(w)) {
1104 if (p == w && isItemEnabled(w)) { 1119 if (p == w && isItemEnabled(w)) {
1105 if (re.x > ix && re.x < (signed) (ix + menu.item_w) && 1120 if (re.x > ix && re.x < (signed) (ix + menu.item_w) &&
1106 re.y > iy && re.y < (signed) (iy + theme().itemHeight())) { 1121 re.y > iy && re.y < (signed) (iy + theme().itemHeight())) {
1107 menuitems[w]->click(re.button, re.time); 1122 menuitems[w]->click(re.button, re.time);
1108 itemSelected(re.button, w); 1123 itemSelected(re.button, w);
1109 // just redraw this item 1124 // just redraw this item
1110 drawItem(w, true, true, true); 1125 drawItem(w,
1126 true, // clear
1127 true); // transparent
1111 } 1128 }
1112 } else { 1129 } else {
1113 drawItem(p, isItemEnabled(p) && (p == which_sub), true, true); 1130 drawItem(p,
1131 true, // clear
1132 true); // transparent
1114 } 1133 }
1115 } else 1134
1116 drawItem(p, false, true, true); 1135 } else {
1136 drawItem(p,
1137 true, // clear
1138 true); // transparent
1139 }
1117 } 1140 }
1118} 1141}
1119 1142
@@ -1126,7 +1149,9 @@ void Menu::motionNotifyEvent(XMotionEvent &me) {
1126 if (! moving) { 1149 if (! moving) {
1127 // if not moving: start moving operation 1150 // if not moving: start moving operation
1128 if (m_parent && (! torn)) { 1151 if (m_parent && (! torn)) {
1129 m_parent->drawItem(m_parent->which_sub, false, true, true); 1152 m_parent->drawItem(m_parent->which_sub,
1153 true, // clear
1154 true); // render transparency
1130 m_parent->which_sub = -1; 1155 m_parent->which_sub = -1;
1131 } 1156 }
1132 1157
@@ -1140,65 +1165,83 @@ void Menu::motionNotifyEvent(XMotionEvent &me) {
1140 menu.window.move(me.x_root - menu.x_move, me.y_root - menu.y_move); 1165 menu.window.move(me.x_root - menu.x_move, me.y_root - menu.y_move);
1141 } 1166 }
1142 1167
1143 } else if ((! (me.state & Button1Mask)) && me.window == menu.frame && 1168 } else if (!(me.state & Button1Mask) && me.window == menu.frame) {
1144 me.x >= 0 && me.x < (signed) width() &&
1145 me.y >= 0 && me.y < (signed) menu.frame_h) {
1146 stopHide(); 1169 stopHide();
1147 int sbl = (me.x / menu.item_w), i = (me.y / theme().itemHeight()), 1170 int sbl = (me.x / menu.item_w),
1171 i = (me.y / theme().itemHeight()),
1148 w = (sbl * menu.persub) + i; 1172 w = (sbl * menu.persub) + i;
1173
1174 if (validIndex(m_active_index) && w != m_active_index) {
1149 1175
1150 if ((i != which_press || sbl != which_sbl) && 1176 int old = m_active_index;
1151 (w < static_cast<int>(menuitems.size()) && w >= 0)) { 1177 m_active_index = -1;
1178 MenuItem *item = menuitems[old];
1152 1179
1153 if (which_press != -1 && which_sbl != -1) { 1180 if (item != 0) {
1154 1181
1155 int p = which_sbl * menu.persub + which_press; 1182 drawItem(old,
1156 MenuItem *item = menuitems[p]; 1183 true, // clear
1157 // don't redraw disabled items on enter/leave 1184 true); // transparent
1158 if (item != 0 && item->isEnabled()) {
1159 1185
1160 drawItem(p, false, // highlight 1186 if (item->submenu()) {
1161 true, // clear
1162 true); // transparent
1163 1187
1164 if (item->submenu()) { 1188 if (item->submenu()->isVisible() &&
1165 1189 !item->submenu()->isTorn()) {
1166 if (item->submenu()->isVisible() && 1190 // setup hide timer for submenu
1167 !item->submenu()->isTorn()) { 1191 item->submenu()->startHide();
1168 // setup hide timer for submenu
1169 item->submenu()->startHide();
1170 }
1171 } 1192 }
1172 1193 }
1173 }
1174 1194
1175 } 1195 }
1176 1196
1177 which_press = i; 1197 }
1178 which_sbl = sbl;
1179 1198
1180 MenuItem *itmp = menuitems[w];
1181 1199
1182 if (itmp->submenu()) { 1200 which_press = i;
1201 which_sbl = sbl;
1183 1202
1184 drawItem(w, true, true); 1203 m_active_index = -1;
1185 1204
1186 if (theme().menuMode() == MenuTheme::DELAY_OPEN) { 1205 if (!validIndex(w))
1187 // setup show menu timer 1206 return;
1188 timeval timeout;
1189 timeout.tv_sec = 0;
1190 timeout.tv_usec = theme().delayOpen() * 1000; // transformed to usec
1191 m_submenu_timer.setTimeout(timeout);
1192 m_submenu_timer.start();
1193 1207
1194 }
1195 1208
1196 } else { 1209 MenuItem *itmp = menuitems[w];
1197 m_submenu_timer.stop(); 1210
1198 if (itmp->isEnabled()) 1211 m_active_index = w;
1199 drawItem(w, true, true, true); 1212
1213 if (itmp == 0)
1214 return;
1215
1216 if (itmp->submenu()) {
1217 // if submenu,
1218 // draw item highlighted and
1219 // start submenu open delay
1220
1221 drawItem(w,
1222 true); // clear
1223
1224 if (theme().menuMode() == MenuTheme::DELAY_OPEN) {
1225 // setup show menu timer
1226 timeval timeout;
1227 timeout.tv_sec = 0;
1228 timeout.tv_usec = theme().delayOpen() * 1000; // transformed to usec
1229 m_submenu_timer.setTimeout(timeout);
1230 m_submenu_timer.start();
1231
1232 }
1233
1234 } else {
1235 // else normal menu item
1236 // draw highlighted
1237 m_submenu_timer.stop();
1238 if (itmp->isEnabled()) {
1239 drawItem(w,
1240 true, // clear
1241 true); // transp
1200 } 1242 }
1201 } 1243 }
1244
1202 } 1245 }
1203} 1246}
1204 1247
@@ -1238,7 +1281,7 @@ void Menu::enterNotifyEvent(XCrossingEvent &ce) {
1238 if (shifted) 1281 if (shifted)
1239 menu.window.move(menu.x_shift, menu.y_shift); 1282 menu.window.move(menu.x_shift, menu.y_shift);
1240 1283
1241 if (which_sub >= 0 && static_cast<size_t>(which_sub) < menuitems.size()) { 1284 if (validIndex(which_sub)) {
1242 MenuItem *tmp = menuitems[which_sub]; 1285 MenuItem *tmp = menuitems[which_sub];
1243 if (tmp->submenu()->isVisible()) { 1286 if (tmp->submenu()->isVisible()) {
1244 int sbl = (ce.x / menu.item_w), i = (ce.y / theme().itemHeight()), 1287 int sbl = (ce.x / menu.item_w), i = (ce.y / theme().itemHeight()),
@@ -1247,7 +1290,9 @@ void Menu::enterNotifyEvent(XCrossingEvent &ce) {
1247 if (w != which_sub && (! tmp->submenu()->isTorn())) { 1290 if (w != which_sub && (! tmp->submenu()->isTorn())) {
1248 tmp->submenu()->internal_hide(); 1291 tmp->submenu()->internal_hide();
1249 1292
1250 drawItem(which_sub, false, true, true); 1293 drawItem(which_sub,
1294 true, // clear
1295 true); // transp
1251 which_sub = -1; 1296 which_sub = -1;
1252 } 1297 }
1253 } 1298 }
@@ -1261,7 +1306,9 @@ void Menu::leaveNotifyEvent(XCrossingEvent &ce) {
1261 if (which_press != -1 && which_sbl != -1 && menuitems.size() > 0) { 1306 if (which_press != -1 && which_sbl != -1 && menuitems.size() > 0) {
1262 int p = (which_sbl * menu.persub) + which_press; 1307 int p = (which_sbl * menu.persub) + which_press;
1263 1308
1264 drawItem(p, (p == which_sub), true, true); 1309 drawItem(p,
1310 true, // clear
1311 true); // transp
1265 1312
1266 which_sbl = which_press = -1; 1313 which_sbl = which_press = -1;
1267 } 1314 }
@@ -1298,7 +1345,7 @@ void Menu::keyPressEvent(XKeyEvent &event) {
1298 break; 1345 break;
1299 case XK_Return: 1346 case XK_Return:
1300 // send fake button 1 click 1347 // send fake button 1 click
1301 if (which_press >= 0 && which_press < static_cast<signed>(menuitems.size()) && 1348 if (validIndex(which_press) &&
1302 isItemEnabled(which_press)) { 1349 isItemEnabled(which_press)) {
1303 menuitems[which_press]->click(1, event.time); 1350 menuitems[which_press]->click(1, event.time);
1304 itemSelected(1, which_press); 1351 itemSelected(1, which_press);
@@ -1345,15 +1392,16 @@ void Menu::reconfigure() {
1345 1392
1346 1393
1347void Menu::openSubmenu() { 1394void Menu::openSubmenu() {
1348 if (!isVisible() || which_press < 0 || which_press >= static_cast<signed>(menuitems.size()) || 1395 if (!isVisible() || ! validIndex(which_press) ||
1349 which_sbl < 0 || which_sbl >= static_cast<signed>(menuitems.size())) 1396 ! validIndex(which_sbl))
1350 return; 1397 return;
1351 1398
1352 int item = which_sbl * menu.persub + which_press; 1399 int item = which_sbl * menu.persub + which_press;
1353 if (item < 0 || item >= static_cast<signed>(menuitems.size())) 1400 if (!validIndex(item))
1354 return; 1401 return;
1355 1402
1356 drawItem(item, true, true); 1403 drawItem(item,
1404 true); // clear
1357 if (menuitems[item]->submenu() != 0 && !menuitems[item]->submenu()->isVisible()) 1405 if (menuitems[item]->submenu() != 0 && !menuitems[item]->submenu()->isVisible())
1358 drawSubmenu(item); 1406 drawSubmenu(item);
1359 1407
diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh
index 625a7d7..8c6c738 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.36 2004/06/14 12:23:57 fluxgen Exp $ 25// $Id: Menu.hh,v 1.37 2004/06/27 13:51:24 fluxgen Exp $
26 26
27#ifndef FBTK_MENU_HH 27#ifndef FBTK_MENU_HH
28#define FBTK_MENU_HH 28#define FBTK_MENU_HH
@@ -125,12 +125,14 @@ public:
125 /// hide menu 125 /// hide menu
126 virtual void hide(); 126 virtual void hide();
127 virtual void clearWindow(); 127 virtual void clearWindow();
128 void setActiveIndex(int index) { m_active_index = index; }
128 /*@}*/ 129 /*@}*/
129 130
130 /** 131 /**
131 @name accessors 132 @name accessors
132 */ 133 */
133 //@{ 134 //@{
135 inline int activeIndex() const { return m_active_index; }
134 inline bool isTorn() const { return torn; } 136 inline bool isTorn() const { return torn; }
135 inline bool isVisible() const { return visible; } 137 inline bool isVisible() const { return visible; }
136 inline int screenNumber() const { return menu.window.screenNumber(); } 138 inline int screenNumber() const { return menu.window.screenNumber(); }
@@ -156,6 +158,8 @@ public:
156 inline const MenuItem *find(unsigned int index) const { return menuitems[index]; } 158 inline const MenuItem *find(unsigned int index) const { return menuitems[index]; }
157 inline MenuItem *find(unsigned int index) { return menuitems[index]; } 159 inline MenuItem *find(unsigned int index) { return menuitems[index]; }
158 //@} 160 //@}
161 /// @return true if index is valid
162 inline bool validIndex(int index) const { return (index < static_cast<int>(numberOfItems()) && index >= 0); }
159 163
160protected: 164protected:
161 165
@@ -168,8 +172,8 @@ protected:
168 } 172 }
169 173
170 virtual void itemSelected(int button, unsigned int index) { } 174 virtual void itemSelected(int button, unsigned int index) { }
171 virtual int drawItem(unsigned int index, bool highlight = false, 175 virtual int drawItem(unsigned int index,
172 bool clear= false, bool render_trans = true, 176 bool clear = false, bool render_trans = true,
173 int x= -1, int y= -1, 177 int x= -1, int y= -1,
174 unsigned int width= 0, unsigned int height= 0); 178 unsigned int width= 0, unsigned int height= 0);
175 virtual void redrawTitle(); 179 virtual void redrawTitle();
@@ -178,7 +182,8 @@ protected:
178 inline const Menu *parent() const { return m_parent; } 182 inline const Menu *parent() const { return m_parent; }
179 183
180 void update(FbTk::Subject *); 184 void update(FbTk::Subject *);
181 185 void renderTransp(int x, int y,
186 unsigned int width, unsigned int height);
182private: 187private:
183 188
184 void openSubmenu(); 189 void openSubmenu();
@@ -186,8 +191,7 @@ private:
186 void startHide(); 191 void startHide();
187 void stopHide(); 192 void stopHide();
188 193
189 void renderTransp(int x, int y, 194
190 unsigned int width, unsigned int height);
191 typedef std::vector<MenuItem *> Menuitems; 195 typedef std::vector<MenuItem *> Menuitems;
192 const MenuTheme &m_theme; 196 const MenuTheme &m_theme;
193 Menu *m_parent; 197 Menu *m_parent;
@@ -216,6 +220,8 @@ private:
216 unsigned int frame_h, item_w; 220 unsigned int frame_h, item_w;
217 } menu; 221 } menu;
218 222
223 int m_active_index; ///< current highlighted index
224
219 Drawable m_root_pm; 225 Drawable m_root_pm;
220 static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused 226 static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused
221 FbPixmap m_frame_pm, ///< buffer pixmap 227 FbPixmap m_frame_pm, ///< buffer pixmap