summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/FbTk/Menu.cc123
-rw-r--r--src/FbTk/Menu.hh13
2 files changed, 102 insertions, 34 deletions
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc
index 886ad0e..fd6745b 100644
--- a/src/FbTk/Menu.cc
+++ b/src/FbTk/Menu.cc
@@ -1,5 +1,5 @@
1// Menu.cc for FbTk - Fluxbox Toolkit 1// Menu.cc for FbTk - Fluxbox Toolkit
2// Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxgen at users.sourceforge.net) 2// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
3// 3//
4// Basemenu.cc for blackbox - an X11 Window manager 4// Basemenu.cc for blackbox - an X11 Window manager
5// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) 5// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
@@ -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.12 2003/04/17 14:17:33 fluxgen Exp $ 25// $Id: Menu.cc,v 1.13 2003/04/20 13:49:26 fluxgen Exp $
26 26
27//use GNU extensions 27//use GNU extensions
28#ifndef _GNU_SOURCE 28#ifndef _GNU_SOURCE
@@ -36,21 +36,22 @@
36#include "MenuTheme.hh" 36#include "MenuTheme.hh"
37#include "App.hh" 37#include "App.hh"
38#include "EventManager.hh" 38#include "EventManager.hh"
39#include "Transparent.hh"
39 40
41#include <X11/Xatom.h>
40#include <cstdio> 42#include <cstdio>
41#include <cstdlib> 43#include <cstdlib>
42#include <cstring> 44#include <cstring>
43
44
45#ifdef DEBUG
46#include <iostream> 45#include <iostream>
46
47using namespace std; 47using namespace std;
48#endif //DEBUG
49 48
50namespace FbTk { 49namespace FbTk {
51 50
52static Menu *shown = 0; 51static Menu *shown = 0;
53 52
53unsigned char Menu::s_alpha = 255;
54
54Menu::Menu(MenuTheme &tm, int screen_num, ImageControl &imgctrl): 55Menu::Menu(MenuTheme &tm, int screen_num, ImageControl &imgctrl):
55 m_theme(tm), 56 m_theme(tm),
56 m_screen_num(screen_num), 57 m_screen_num(screen_num),
@@ -61,7 +62,7 @@ Menu::Menu(MenuTheme &tm, int screen_num, ImageControl &imgctrl):
61 m_screen_height(DisplayHeight(m_display, screen_num)), 62 m_screen_height(DisplayHeight(m_display, screen_num)),
62 m_alignment(ALIGNDONTCARE), 63 m_alignment(ALIGNDONTCARE),
63 m_border_width(0), 64 m_border_width(0),
64 m_themeobserver(*this) { 65 m_themeobserver(*this), m_trans(new Transparent(0, 0, 255, screen_num)) {
65 66
66 // make sure we get updated when the theme is reloaded 67 // make sure we get updated when the theme is reloaded
67 tm.addListener(m_themeobserver); 68 tm.addListener(m_themeobserver);
@@ -104,7 +105,28 @@ Menu::Menu(MenuTheme &tm, int screen_num, ImageControl &imgctrl):
104 menu.item_h = m_theme.frameFont().height() + menu.bevel_w; 105 menu.item_h = m_theme.frameFont().height() + menu.bevel_w;
105 106
106 menu.height = menu.title_h + 2 + menu.frame_h; 107 menu.height = menu.title_h + 2 + menu.frame_h;
107 108
109 // get root pixmap for transparency
110 Display *disp = FbTk::App::instance()->display();
111 Atom real_type;
112 int real_format;
113 unsigned long items_read, items_left;
114 unsigned int *data;
115 if (XGetWindowProperty(disp, RootWindow(disp, screen_num),
116 XInternAtom(disp, "_XROOTPMAP_ID", false),
117 0L, 1L,
118 false, XA_PIXMAP, &real_type,
119 &real_format, &items_read, &items_left,
120 (unsigned char **) &data) == Success &&
121 items_read) {
122 m_root_pm = (Pixmap) (*data);
123 XFree(data);
124 } else
125 m_root_pm = 0;
126
127 m_trans->setSource(m_root_pm, screen_num);
128 m_trans->setAlpha(s_alpha);
129
108 //set attributes for menu window 130 //set attributes for menu window
109 unsigned long attrib_mask = CWOverrideRedirect | CWEventMask; 131 unsigned long attrib_mask = CWOverrideRedirect | CWEventMask;
110 XSetWindowAttributes attrib; 132 XSetWindowAttributes attrib;
@@ -210,13 +232,13 @@ int Menu::remove(unsigned int index) {
210 if (item) { 232 if (item) {
211 menuitems.erase(it); 233 menuitems.erase(it);
212 /*if ((! internal_menu) && (item->submenu())) { 234 /*if ((! internal_menu) && (item->submenu())) {
213 Menu *tmp = item->submenu(); 235 Menu *tmp = item->submenu();
214 236
215 if (! tmp->internal_menu) { 237 if (! tmp->internal_menu) {
216 delete tmp; 238 delete tmp;
217 } else 239 } else
218 tmp->internal_hide(); 240 tmp->internal_hide();
219 } 241 }
220 */ 242 */
221 243
222 delete item; 244 delete item;
@@ -373,7 +395,8 @@ void Menu::update() {
373 menu.width + menu.title.borderWidth(), menu.title_h); 395 menu.width + menu.title.borderWidth(), menu.title_h);
374 } 396 }
375 397
376 menu.frame.moveResize(0, ((title_vis) ? menu.title.y() + menu.title.height() + menu.title.borderWidth()*2 : 0), 398 menu.frame.moveResize(0, ((title_vis) ? menu.title.y() + menu.title.height() +
399 menu.title.borderWidth()*2 : 0),
377 menu.window.width(), menu.frame_h); 400 menu.window.width(), menu.frame_h);
378 clearWindow(); 401 clearWindow();
379 402
@@ -383,15 +406,22 @@ void Menu::update() {
383 unsigned int i = 0; 406 unsigned int i = 0;
384 for (i = 0; visible && i < menuitems.size(); i++) { 407 for (i = 0; visible && i < menuitems.size(); i++) {
385 if (i == (unsigned int)which_sub) { 408 if (i == (unsigned int)which_sub) {
386 drawItem(i, true, 0); 409 drawItem(i, true, false, false);
387 drawSubmenu(i); 410 drawSubmenu(i);
388 } else 411 } else
389 drawItem(i, false, 0); 412 drawItem(i, false, false, false);
390 } 413 }
391 414
392 if (m_parent && visible) 415 if (m_parent && visible)
393 m_parent->drawSubmenu(m_parent->which_sub); 416 m_parent->drawSubmenu(m_parent->which_sub);
394 417
418 m_trans->setDest(menu.frame.window(), menu.frame.screenNumber());
419 m_trans->render(menu.window.x() + menu.frame.x() - menu.window.borderWidth(),
420 menu.window.y() + menu.frame.y() - menu.window.borderWidth(),
421 0, 0,
422 menu.frame.width(), menu.frame.height());
423
424
395 menu.window.showSubwindows(); 425 menu.window.showSubwindows();
396} 426}
397 427
@@ -408,6 +438,11 @@ void Menu::show() {
408 shown = this; 438 shown = this;
409 } 439 }
410 440
441 m_trans->setDest(menu.frame.window(), menu.frame.screenNumber());
442 m_trans->render(menu.window.x() + menu.frame.x(),
443 menu.window.y() + menu.frame.y(),
444 0, 0,
445 menu.frame.width(), menu.frame.height());
411} 446}
412 447
413 448
@@ -435,7 +470,7 @@ void Menu::internal_hide() {
435 } 470 }
436 471
437 if (m_parent && (! torn)) { 472 if (m_parent && (! torn)) {
438 m_parent->drawItem(m_parent->which_sub, False, True); 473 m_parent->drawItem(m_parent->which_sub, false, true);
439 474
440 m_parent->which_sub = -1; 475 m_parent->which_sub = -1;
441 } else if (shown && shown->menu.window == menu.window) 476 } else if (shown && shown->menu.window == menu.window)
@@ -484,6 +519,12 @@ void Menu::redrawTitle() {
484 text, len, // text string with lenght 519 text, len, // text string with lenght
485 dx, font.ascent() + menu.bevel_w); // position 520 dx, font.ascent() + menu.bevel_w); // position
486 521
522 m_trans->setDest(menu.title.window(), menu.title.screenNumber());
523 m_trans->render(menu.window.x() + menu.title.x() - menu.window.borderWidth(),
524 menu.window.y() + menu.title.y() - menu.window.borderWidth(),
525 menu.title.x(), menu.title.y(),
526 menu.title.width(), menu.title.height());
527
487 528
488} 529}
489 530
@@ -547,7 +588,7 @@ void Menu::drawSubmenu(unsigned int index) {
547 588
548 item->submenu()->move(x, y); 589 item->submenu()->move(x, y);
549 if (! moving) 590 if (! moving)
550 drawItem(index, True); 591 drawItem(index, true);
551 592
552 if (! item->submenu()->isVisible()) { 593 if (! item->submenu()->isVisible()) {
553 item->submenu()->show(); 594 item->submenu()->show();
@@ -573,7 +614,7 @@ bool Menu::hasSubmenu(unsigned int index) const {
573} 614}
574 615
575 616
576void Menu::drawItem(unsigned int index, bool highlight, bool clear, 617void Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_trans,
577 int x, int y, unsigned int w, unsigned int h) 618 int x, int y, unsigned int w, unsigned int h)
578{ 619{
579 if (index >= menuitems.size() || menuitems.size() == 0 || 620 if (index >= menuitems.size() || menuitems.size() == 0 ||
@@ -691,7 +732,6 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear,
691 tgc, 732 tgc,
692 text, len, // text string and lenght 733 text, len, // text string and lenght
693 text_x, text_y); // position 734 text_x, text_y); // position
694
695 } 735 }
696 736
697 if (dosel && item->submenu()) { 737 if (dosel && item->submenu()) {
@@ -742,6 +782,18 @@ void Menu::drawItem(unsigned int index, bool highlight, bool clear,
742 break; 782 break;
743 } 783 }
744 } 784 }
785
786 if (render_trans) {
787 m_trans->setDest(menu.frame.window(), menu.frame.screenNumber());
788 m_trans->render(menu.window.x() + menu.frame.x() + item_x -
789 menu.window.borderWidth(),
790 menu.window.y() + menu.frame.y() + item_y -
791 menu.window.borderWidth(),
792
793 item_x, item_y,
794 menu.item_w, menu.item_h);
795
796 }
745} 797}
746 798
747 799
@@ -759,7 +811,10 @@ void Menu::setItemSelected(unsigned int index, bool sel) {
759 if (! item) return; 811 if (! item) return;
760 812
761 item->setSelected(sel); 813 item->setSelected(sel);
762 if (visible) drawItem(index, (index == (unsigned int)which_sub), true); 814 if (visible) {
815 drawItem(index, (index == (unsigned int)which_sub), true, true);
816
817 }
763} 818}
764 819
765 820
@@ -782,7 +837,7 @@ void Menu::setItemEnabled(unsigned int index, bool enable) {
782 837
783 item->setEnabled(enable); 838 item->setEnabled(enable);
784 if (visible) 839 if (visible)
785 drawItem(index, (index == static_cast<unsigned int>(which_sub)), True); 840 drawItem(index, (index == static_cast<unsigned int>(which_sub)), true, true);
786} 841}
787 842
788 843
@@ -811,7 +866,7 @@ void Menu::buttonPressEvent(XButtonEvent &be) {
811 if (item->submenu()) 866 if (item->submenu())
812 drawSubmenu(w); 867 drawSubmenu(w);
813 else 868 else
814 drawItem(w, (item->isEnabled()), true); 869 drawItem(w, (item->isEnabled()), true, true);
815 } 870 }
816 } else { 871 } else {
817 menu.x_move = be.x_root - menu.x; 872 menu.x_move = be.x_root - menu.x;
@@ -827,6 +882,7 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) {
827 882
828 if (which_sub >= 0) 883 if (which_sub >= 0)
829 drawSubmenu(which_sub); 884 drawSubmenu(which_sub);
885 update();
830 } 886 }
831 887
832 if (re.x >= 0 && re.x <= (signed) menu.width && 888 if (re.x >= 0 && re.x <= (signed) menu.width &&
@@ -846,7 +902,7 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) {
846 p = (which_sbl * menu.persub) + which_press; 902 p = (which_sbl * menu.persub) + which_press;
847 903
848 if (w < static_cast<int>(menuitems.size()) && w >= 0) { 904 if (w < static_cast<int>(menuitems.size()) && w >= 0) {
849 drawItem(p, (p == which_sub), True); 905 drawItem(p, (p == which_sub), true, true);
850 906
851 if (p == w && isItemEnabled(w)) { 907 if (p == w && isItemEnabled(w)) {
852 if (re.x > ix && re.x < (signed) (ix + menu.item_w) && 908 if (re.x > ix && re.x < (signed) (ix + menu.item_w) &&
@@ -858,7 +914,7 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) {
858 } 914 }
859 } 915 }
860 } else 916 } else
861 drawItem(p, false, true); 917 drawItem(p, false, true, true);
862 918
863 919
864 } 920 }
@@ -870,7 +926,7 @@ void Menu::motionNotifyEvent(XMotionEvent &me) {
870 if (movable) { 926 if (movable) {
871 if (! moving) { 927 if (! moving) {
872 if (m_parent && (! torn)) { 928 if (m_parent && (! torn)) {
873 m_parent->drawItem(m_parent->which_sub, false, true); 929 m_parent->drawItem(m_parent->which_sub, false, true, true);
874 m_parent->which_sub = -1; 930 m_parent->which_sub = -1;
875 } 931 }
876 932
@@ -900,7 +956,7 @@ void Menu::motionNotifyEvent(XMotionEvent &me) {
900 int p = (which_sbl * menu.persub) + which_press; 956 int p = (which_sbl * menu.persub) + which_press;
901 MenuItem *item = menuitems[p]; 957 MenuItem *item = menuitems[p];
902 958
903 drawItem(p, False, True); 959 drawItem(p, false, true, true);
904 if (item->submenu()) { 960 if (item->submenu()) {
905 if (item->submenu()->isVisible() && 961 if (item->submenu()->isVisible() &&
906 (! item->submenu()->isTorn())) { 962 (! item->submenu()->isTorn())) {
@@ -918,7 +974,7 @@ void Menu::motionNotifyEvent(XMotionEvent &me) {
918 if (itmp->submenu()) 974 if (itmp->submenu())
919 drawSubmenu(w); 975 drawSubmenu(w);
920 else 976 else
921 drawItem(w, (itmp->isEnabled()), True); 977 drawItem(w, (itmp->isEnabled()), true, true);
922 } 978 }
923 } 979 }
924} 980}
@@ -955,7 +1011,7 @@ void Menu::exposeEvent(XExposeEvent &ee) {
955 Menuitems::iterator it_end = menuitems.end(); 1011 Menuitems::iterator it_end = menuitems.end();
956 for (ii = id; ii <= id_d && it != it_end; ++it, ii++) { 1012 for (ii = id; ii <= id_d && it != it_end; ++it, ii++) {
957 unsigned int index = ii + (i * menu.persub); 1013 unsigned int index = ii + (i * menu.persub);
958 drawItem(index, (which_sub == index), true, 1014 drawItem(index, (which_sub == index), true, true,
959 ee.x, ee.y, ee.width, ee.height); 1015 ee.x, ee.y, ee.width, ee.height);
960 } 1016 }
961 } 1017 }
@@ -999,7 +1055,7 @@ void Menu::enterNotifyEvent(XCrossingEvent &ce) {
999 if (w != which_sub && (! tmp->submenu()->isTorn())) { 1055 if (w != which_sub && (! tmp->submenu()->isTorn())) {
1000 tmp->submenu()->internal_hide(); 1056 tmp->submenu()->internal_hide();
1001 1057
1002 drawItem(which_sub, false, true); 1058 drawItem(which_sub, false, true, true);
1003 which_sub = -1; 1059 which_sub = -1;
1004 } 1060 }
1005 } 1061 }
@@ -1013,7 +1069,7 @@ void Menu::leaveNotifyEvent(XCrossingEvent &ce) {
1013 if (which_press != -1 && which_sbl != -1 && menuitems.size() > 0) { 1069 if (which_press != -1 && which_sbl != -1 && menuitems.size() > 0) {
1014 int p = (which_sbl * menu.persub) + which_press; 1070 int p = (which_sbl * menu.persub) + which_press;
1015 1071
1016 drawItem(p, (p == which_sub), true); 1072 drawItem(p, (p == which_sub), true, true);
1017 1073
1018 which_sbl = which_press = -1; 1074 which_sbl = which_press = -1;
1019 } 1075 }
@@ -1051,8 +1107,11 @@ void Menu::reconfigure() {
1051 menu.window.setBorderWidth(m_border_width); 1107 menu.window.setBorderWidth(m_border_width);
1052 menu.title.setBorderWidth(m_border_width); 1108 menu.title.setBorderWidth(m_border_width);
1053 1109
1110 if (m_trans.get())
1111 m_trans->setAlpha(s_alpha);
1054 1112
1055 update(); 1113 update();
1056} 1114}
1057 1115
1116
1058}; // end namespace FbTk 1117}; // end namespace FbTk
diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh
index f808820..54cabcf 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.10 2003/02/23 00:59:13 fluxgen Exp $ 25// $Id: Menu.hh,v 1.11 2003/04/20 13:47:20 fluxgen Exp $
26 26
27#ifndef FBTK_MENU_HH 27#ifndef FBTK_MENU_HH
28#define FBTK_MENU_HH 28#define FBTK_MENU_HH
@@ -43,6 +43,7 @@ namespace FbTk {
43class MenuItem; 43class MenuItem;
44class MenuTheme; 44class MenuTheme;
45class ImageControl; 45class ImageControl;
46class Transparent;
46 47
47/// Base class for menus 48/// Base class for menus
48class Menu: public FbTk::EventHandler { 49class Menu: public FbTk::EventHandler {
@@ -85,6 +86,9 @@ public:
85 86
86 void disableTitle(); 87 void disableTitle();
87 void enableTitle(); 88 void enableTitle();
89
90 static void setAlpha(unsigned char alpha) { s_alpha = alpha; }
91
88 /** 92 /**
89 @name event handlers 93 @name event handlers
90 */ 94 */
@@ -135,6 +139,7 @@ public:
135 bool hasSubmenu(unsigned int index) const; 139 bool hasSubmenu(unsigned int index) const;
136 bool isItemSelected(unsigned int index) const; 140 bool isItemSelected(unsigned int index) const;
137 bool isItemEnabled(unsigned int index) const; 141 bool isItemEnabled(unsigned int index) const;
142 static unsigned char alpha() { return s_alpha; }
138 //@} 143 //@}
139 144
140protected: 145protected:
@@ -147,7 +152,7 @@ protected:
147 152
148 virtual void itemSelected(int button, unsigned int index) { } 153 virtual void itemSelected(int button, unsigned int index) { }
149 virtual void drawItem(unsigned int index, bool highlight = false, 154 virtual void drawItem(unsigned int index, bool highlight = false,
150 bool clear= false, 155 bool clear= false, bool render_trans = true,
151 int x= -1, int y= -1, 156 int x= -1, int y= -1,
152 unsigned int width= 0, unsigned int height= 0); 157 unsigned int width= 0, unsigned int height= 0);
153 virtual void redrawTitle(); 158 virtual void redrawTitle();
@@ -156,6 +161,7 @@ protected:
156 inline const Menu *parent() const { return m_parent; } 161 inline const Menu *parent() const { return m_parent; }
157 162
158private: 163private:
164
159 typedef std::vector<MenuItem *> Menuitems; 165 typedef std::vector<MenuItem *> Menuitems;
160 const MenuTheme &m_theme; 166 const MenuTheme &m_theme;
161 Display *m_display; 167 Display *m_display;
@@ -193,6 +199,9 @@ private:
193 }; 199 };
194 200
195 ThemeObserver m_themeobserver; 201 ThemeObserver m_themeobserver;
202 std::auto_ptr<Transparent> m_trans;
203 Drawable m_root_pm;
204 static unsigned char s_alpha;
196}; 205};
197 206
198}; // end namespace FbTk 207}; // end namespace FbTk