aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/FbTk/Menu.cc171
1 files changed, 67 insertions, 104 deletions
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc
index 2a91ee4..7869376 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.66 2004/06/13 12:01:52 fluxgen Exp $ 25// $Id: Menu.cc,v 1.67 2004/06/14 12:24:23 fluxgen Exp $
26 26
27//use GNU extensions 27//use GNU extensions
28#ifndef _GNU_SOURCE 28#ifndef _GNU_SOURCE
@@ -381,7 +381,6 @@ void Menu::enableTitle() {
381} 381}
382 382
383void Menu::update(int active_index) { 383void Menu::update(int active_index) {
384
385 if (title_vis) { 384 if (title_vis) {
386 menu.item_w = theme().titleFont().textWidth(menu.label.c_str(), 385 menu.item_w = theme().titleFont().textWidth(menu.label.c_str(),
387 menu.label.size()); 386 menu.label.size());
@@ -485,7 +484,7 @@ void Menu::update(int active_index) {
485 m_title_pm.width(), m_title_pm.height()); 484 m_title_pm.width(), m_title_pm.height());
486 485
487 } 486 }
488 487
489 } 488 }
490 } 489 }
491 490
@@ -536,8 +535,8 @@ void Menu::update(int active_index) {
536 width(), menu.frame_h); 535 width(), menu.frame_h);
537 536
538 537
539 if (m_need_update && (m_frame_pm.width() != menu.frame.width() || 538 if (m_need_update || m_frame_pm.width() != menu.frame.width() ||
540 m_frame_pm.height() != menu.frame.height() )){ 539 m_frame_pm.height() != menu.frame.height()){
541 540
542 m_frame_pm = FbTk::FbPixmap(menu.frame.window(), 541 m_frame_pm = FbTk::FbPixmap(menu.frame.window(),
543 menu.frame.width(), menu.frame.height(), 542 menu.frame.width(), menu.frame.height(),
@@ -548,82 +547,61 @@ void Menu::update(int active_index) {
548 menu.frame.depth()); 547 menu.frame.depth());
549 548
550 menu.frame.setBackgroundPixmap(m_real_frame_pm.drawable()); 549 menu.frame.setBackgroundPixmap(m_real_frame_pm.drawable());
551 550 GContext def_gc(menu.frame);
552 if (m_frame_pm.drawable() == 0) { 551 if (m_frame_pm.drawable() == 0) {
553 _FB_USES_NLS; 552 _FB_USES_NLS;
554 cerr<<"FbTk::Menu: "<<_FBTKTEXT(Error, CreatePixmap, "Error creating pixmap", "Couldn't create a pixmap - image - for some reason")<<" ("<< 553 cerr<<"FbTk::Menu: "<<_FBTKTEXT(Error, CreatePixmap, "Error creating pixmap", "Couldn't create a pixmap - image - for some reason")<<" ("<<
555 menu.frame.window()<<", "<<menu.frame.width()<<", "<< 554 menu.frame.window()<<", "<<menu.frame.width()<<", "<<
556 menu.frame.height()<< 555 menu.frame.height()<<
557 ", "<<menu.frame.depth()<<") !"<<endl; 556 ", "<<menu.frame.depth()<<") !"<<endl;
558 } else if (menu.sublevels > 0 && menu.persub * menu.sublevels != (int)menuitems.size()) { 557 } else {
559 558
560 // TODO: fill only that part of the menuframe with the
561 // pixmap/color, that has actually NO buttons on it
562 // ??? did I made this comment ? (fluxgen)
563 // if so, what am I talking about?
564 GContext def_gc(menu.frame);
565 if (menu.frame_pixmap == 0) { 559 if (menu.frame_pixmap == 0) {
566 def_gc.setForeground(theme().frameTexture().color()); 560 def_gc.setForeground(theme().frameTexture().color());
567 m_frame_pm.fillRectangle(def_gc.gc(), 561 m_frame_pm.fillRectangle(def_gc.gc(),
568 0, 0, 562 0, 0,
569 width(), menu.frame_h); 563 width(), menu.frame_h);
570 m_real_frame_pm.fillRectangle(def_gc.gc(),
571 0, 0,
572 width(), menu.frame_h);
573 } else { 564 } else {
574 m_frame_pm.copyArea(menu.frame_pixmap, def_gc.gc(), 565 m_frame_pm.copyArea(menu.frame_pixmap, def_gc.gc(),
575 0, 0, 566 0, 0,
576 0, 0, 567 0, 0,
577 width(), menu.frame_h); 568 width(), menu.frame_h);
578
579 m_real_frame_pm.copyArea(menu.frame_pixmap,
580 def_gc.gc(),
581 0, 0,
582 0, 0,
583 width(), menu.frame_h);
584 } 569 }
570
585 571
586 } 572 }
587 573
574 m_real_frame_pm.copyArea(m_frame_pm.drawable(),
575 def_gc.gc(),
576 0, 0,
577 0, 0,
578 m_frame_pm.width(), m_frame_pm.height());
579
588 } 580 }
589 581
590 // if menu visible and title visible 582 // if menu visible and title visible
591 if (title_vis && visible) 583 if (title_vis && visible)
592 redrawTitle(); 584 redrawTitle();
593 585
594 if (active_index >= 0 && isVisible()) { 586 if (active_index >= 0 || m_need_update) {
595 move(x(), y()); 587
596 renderTransp(0, 0, 588 renderTransp(0, 0,
597 m_real_frame_pm.width(), m_real_frame_pm.height()); 589 m_real_frame_pm.width(), m_real_frame_pm.height());
598 for (unsigned int i = 0; i < menuitems.size(); i++) { 590 for (unsigned int i = 0; i < menuitems.size(); i++) {
599 if (i == (unsigned int)which_sub) { 591 if (i == (unsigned int)which_sub) {
600 drawItem(i, true, // highlight 592 drawItem(i, // index
601 true, // clear 593 true, // highlight
594 true, // clear
602 false); // render_trans 595 false); // render_trans
603 } else 596 } else {
604 drawItem(i, 597 drawItem(i, // index
605 // high light 598 // highlight
606 (static_cast<signed>(i) == active_index && isItemEnabled(i)), 599 (static_cast<signed>(i) == active_index && isItemEnabled(i)),
607 true, // clear 600 true, // clear
608 false); // render transparent 601 false); // render transparent
602 }
609 } 603 }
610 604
611 // if (m_parent)
612 // m_parent->drawSubmenu(m_parent->which_sub);
613 /*
614 renderTransp(0, active_index*menu.item_h,
615 width(), menu.item_h);
616 */
617
618 }
619
620 if (m_need_update) {
621 for (unsigned int i = 0; i < menuitems.size(); i++) {
622 if (i == (unsigned int)which_sub) {
623 drawItem(i, true, true, false);
624 } else
625 drawItem(i, (static_cast<signed>(i) == active_index && isItemEnabled(i)), true, true);
626 }
627 } 605 }
628 606
629 m_need_update = false; 607 m_need_update = false;
@@ -633,6 +611,7 @@ void Menu::update(int active_index) {
633void Menu::show() { 611void Menu::show() {
634 if (m_need_update) 612 if (m_need_update)
635 update(); 613 update();
614
636 menu.window.showSubwindows(); 615 menu.window.showSubwindows();
637 menu.window.show(); 616 menu.window.show();
638 raise(); 617 raise();
@@ -644,7 +623,7 @@ void Menu::show() {
644 623
645 shown = this; 624 shown = this;
646 } 625 }
647 626
648} 627}
649 628
650 629
@@ -707,6 +686,15 @@ void Menu::internal_hide() {
707 686
708 687
709void Menu::move(int x, int y) { 688void Menu::move(int x, int y) {
689 if (x == this->x() && y == this->y())
690 return;
691
692 // if we're not visible and we do transparency
693 // we need to update transparency when we call
694 // show() next time
695 if (alpha() < 255)
696 m_need_update = true;
697
710 menu.window.move(x, y); 698 menu.window.move(x, y);
711 699
712 if (!isVisible()) 700 if (!isVisible())
@@ -725,7 +713,7 @@ void Menu::move(int x, int y) {
725 true, // clear 713 true, // clear
726 false); // transparent 714 false); // transparent
727 } 715 }
728 716 m_need_update = false;
729 } 717 }
730 718
731} 719}
@@ -962,18 +950,20 @@ int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_t
962 950
963 } 951 }
964 952
965 if (render_trans) 953 if (render_trans) {
966 renderTransp(item_x, item_y, 954 renderTransp(item_x, item_y,
967 width(), theme().itemHeight()); 955 width(), theme().itemHeight());
956 }
968 957
969 item->draw(m_real_frame_pm, theme(), highlight, 958 item->draw(m_real_frame_pm, theme(), highlight,
970 item_x, item_y, 959 item_x, item_y,
971 menu.item_w, theme().itemHeight()); 960 menu.item_w, theme().itemHeight());
972 961
973 962
974 if (clear) 963 if (clear) {
975 menu.frame.clearArea(item_x, item_y, 964 menu.frame.clearArea(item_x, item_y,
976 menu.item_w, theme().itemHeight(), False); 965 menu.item_w, theme().itemHeight(), False);
966 }
977 967
978 968
979 return item_y; 969 return item_y;
@@ -1072,7 +1062,22 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) {
1072 if (re.window == menu.title) { 1062 if (re.window == menu.title) {
1073 if (moving) { 1063 if (moving) {
1074 moving = false; 1064 moving = false;
1075 move(x(), y()); 1065
1066 if (which_sub != -1)
1067 drawSubmenu(which_sub);
1068
1069 if (alpha() < 255) {
1070 redrawTitle();
1071 menu.title.clear();
1072 renderTransp(0, 0,
1073 m_real_frame_pm.width(), m_real_frame_pm.height());
1074 for (size_t i=0; i < menuitems.size(); ++i) {
1075 drawItem(i, false, // highlight
1076 true, // clear
1077 false); // transparent
1078 }
1079
1080 }
1076 } 1081 }
1077 1082
1078 if (re.x >= 0 && re.x <= (signed) width() && 1083 if (re.x >= 0 && re.x <= (signed) width() &&
@@ -1196,54 +1201,8 @@ void Menu::exposeEvent(XExposeEvent &ee) {
1196 if (ee.window == menu.title) { 1201 if (ee.window == menu.title) {
1197 redrawTitle(); 1202 redrawTitle();
1198 menu.title.clearArea(ee.x, ee.y, ee.width, ee.height); 1203 menu.title.clearArea(ee.x, ee.y, ee.width, ee.height);
1199 } else if (ee.window == menu.frame) { 1204 } else if (ee.window == menu.frame)
1200
1201 if (moving) {
1202 menu.frame.clearArea(ee.x, ee.y, ee.width, ee.height);
1203 return;
1204 }
1205
1206 // this is a compilicated algorithm... lets do it step by step...
1207 // first... we see in which sub level the expose starts... and how many
1208 // items down in that sublevel
1209
1210 // Simon was here :-) I think this all makes much more sense when
1211 // we rename sbl to "start_col", sbl_d to "end_col", ditto id -> row
1212 // a "sublevel" is basically a column in a multi-column menu (e.g. placement)
1213
1214 if (menu.item_w == 0)
1215 menu.item_w = 1;
1216
1217 unsigned int
1218 start_column = (ee.x / menu.item_w),
1219 end_column = ((ee.x + ee.width) / menu.item_w),
1220 start_row = (ee.y / theme().itemHeight()),
1221 end_row = ((ee.y + ee.height) / theme().itemHeight());
1222 if (static_cast<signed>(end_row) > menu.persub)
1223 end_row = menu.persub;
1224
1225 // draw the sublevels and the number of items the exposure spans
1226 unsigned int col, row;
1227 int max_y = 0;
1228 for (col = start_column; col <= end_column; col++) {
1229 // set the iterator to the first item in the column needing redrawing
1230 unsigned int index = start_row + col * menu.persub;
1231 if (index < menuitems.size()) {
1232 Menuitems::iterator it = menuitems.begin() + index;
1233 Menuitems::iterator it_end = menuitems.end();
1234 for (row = start_row; row <= end_row && it != it_end; ++it, row++) {
1235 unsigned int index = row + (col * menu.persub);
1236 max_y = max(drawItem(index,
1237 (which_sub == static_cast<signed>(index)), // highlight
1238 false, // clear
1239 true), max_y); // render trans
1240 }
1241 }
1242 }
1243
1244 menu.frame.clearArea(ee.x, ee.y, ee.width, ee.height); 1205 menu.frame.clearArea(ee.x, ee.y, ee.width, ee.height);
1245
1246 }
1247} 1206}
1248 1207
1249 1208
@@ -1375,6 +1334,7 @@ void Menu::reconfigure() {
1375 1334
1376 1335
1377 update(); 1336 update();
1337
1378} 1338}
1379 1339
1380 1340
@@ -1424,10 +1384,8 @@ void Menu::update(FbTk::Subject *subj) {
1424 1384
1425void Menu::renderTransp(int x, int y, 1385void Menu::renderTransp(int x, int y,
1426 unsigned int width, unsigned int height) { 1386 unsigned int width, unsigned int height) {
1427 // no need to render transparent unless visible 1387 // even though we dont render transparency
1428 if (!isVisible()) 1388 // we do need to copy the style background
1429 return;
1430
1431 GContext def_gc(menu.frame); 1389 GContext def_gc(menu.frame);
1432 m_real_frame_pm.copyArea(m_frame_pm.drawable(), 1390 m_real_frame_pm.copyArea(m_frame_pm.drawable(),
1433 def_gc.gc(), 1391 def_gc.gc(),
@@ -1435,9 +1393,14 @@ void Menu::renderTransp(int x, int y,
1435 x, y, 1393 x, y,
1436 width, height); 1394 width, height);
1437 1395
1438 if (m_transp.get() == 0) 1396 // no need to render transparent unless visible
1397 // but we do need to render it if we marked it as
1398 // need update
1399 if (!isVisible() && !m_need_update || m_transp.get() == 0)
1439 return; 1400 return;
1440 1401
1402
1403 // render the root background
1441#ifdef HAVE_XRENDER 1404#ifdef HAVE_XRENDER
1442 1405
1443 Pixmap root = getRootPixmap(screenNumber()); 1406 Pixmap root = getRootPixmap(screenNumber());