aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/FbTk/Menu.cc125
-rw-r--r--src/FbTk/Menu.hh10
-rw-r--r--src/FbTk/MenuTheme.cc5
-rw-r--r--src/FbTk/MenuTheme.hh22
-rw-r--r--src/Screen.cc38
-rw-r--r--src/Screen.hh5
6 files changed, 170 insertions, 35 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
diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh
index 9a3f425..ec75477 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.25 2003/12/10 23:08:06 fluxgen Exp $ 25// $Id: Menu.hh,v 1.26 2003/12/12 18:18:49 fluxgen Exp $
26 26
27#ifndef FBTK_MENU_HH 27#ifndef FBTK_MENU_HH
28#define FBTK_MENU_HH 28#define FBTK_MENU_HH
@@ -39,6 +39,7 @@
39#include "Observer.hh" 39#include "Observer.hh"
40#include "FbPixmap.hh" 40#include "FbPixmap.hh"
41#include "MenuTheme.hh" 41#include "MenuTheme.hh"
42#include "Timer.hh"
42 43
43namespace FbTk { 44namespace FbTk {
44 45
@@ -174,6 +175,11 @@ protected:
174 inline const Menu *parent() const { return m_parent; } 175 inline const Menu *parent() const { return m_parent; }
175 176
176private: 177private:
178 void openSubmenu();
179 void closeMenu();
180 void startHide();
181 void stopHide();
182
177 void renderTransFrame(); 183 void renderTransFrame();
178 184
179 typedef std::vector<MenuItem *> Menuitems; 185 typedef std::vector<MenuItem *> Menuitems;
@@ -215,6 +221,8 @@ private:
215 static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused 221 static Menu *s_focused; ///< holds current input focused menu, so one can determine if a menu is focused
216 FbPixmap m_frame_pm; 222 FbPixmap m_frame_pm;
217 bool m_need_update; 223 bool m_need_update;
224 Timer m_submenu_timer;
225 Timer m_hide_timer;
218}; 226};
219 227
220}; // end namespace FbTk 228}; // end namespace FbTk
diff --git a/src/FbTk/MenuTheme.cc b/src/FbTk/MenuTheme.cc
index 6159138..aea922f 100644
--- a/src/FbTk/MenuTheme.cc
+++ b/src/FbTk/MenuTheme.cc
@@ -19,7 +19,7 @@
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE. 20// DEALINGS IN THE SOFTWARE.
21 21
22// $Id: MenuTheme.cc,v 1.11 2003/09/12 23:32:02 fluxgen Exp $ 22// $Id: MenuTheme.cc,v 1.12 2003/12/12 18:18:49 fluxgen Exp $
23 23
24#include "MenuTheme.hh" 24#include "MenuTheme.hh"
25 25
@@ -60,6 +60,9 @@ MenuTheme::MenuTheme(int screen_num):
60 h_text_gc(RootWindow(m_display, screen_num)), 60 h_text_gc(RootWindow(m_display, screen_num)),
61 d_text_gc(RootWindow(m_display, screen_num)), 61 d_text_gc(RootWindow(m_display, screen_num)),
62 hilite_gc(RootWindow(m_display, screen_num)), 62 hilite_gc(RootWindow(m_display, screen_num)),
63 m_menumode(DELAY_OPEN),
64 m_delayopen(0), // no delay as default
65 m_delayclose(0), // no delay as default
63 m_alpha(255) { 66 m_alpha(255) {
64 67
65 // set default values 68 // set default values
diff --git a/src/FbTk/MenuTheme.hh b/src/FbTk/MenuTheme.hh
index 4e9deb3..07c29ad 100644
--- a/src/FbTk/MenuTheme.hh
+++ b/src/FbTk/MenuTheme.hh
@@ -19,7 +19,7 @@
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE. 20// DEALINGS IN THE SOFTWARE.
21 21
22// $Id: MenuTheme.hh,v 1.10 2003/11/28 22:53:10 fluxgen Exp $ 22// $Id: MenuTheme.hh,v 1.11 2003/12/12 18:18:49 fluxgen Exp $
23 23
24#ifndef FBTK_MENUTHEME_HH 24#ifndef FBTK_MENUTHEME_HH
25#define FBTK_MENUTHEME_HH 25#define FBTK_MENUTHEME_HH
@@ -37,6 +37,11 @@ namespace FbTk {
37 37
38class MenuTheme:public FbTk::Theme { 38class MenuTheme:public FbTk::Theme {
39public: 39public:
40 //!! TODO
41 // this isn't actually used with a theme item
42 // see setMenuMode() for more info
43 enum MenuMode {CLICK_OPEN, DELAY_OPEN};
44
40 enum BulletType { EMPTY, SQUARE, TRIANGLE, DIAMOND}; 45 enum BulletType { EMPTY, SQUARE, TRIANGLE, DIAMOND};
41 MenuTheme(int screen_num); 46 MenuTheme(int screen_num);
42 virtual ~MenuTheme(); 47 virtual ~MenuTheme();
@@ -102,7 +107,16 @@ public:
102 107
103 inline unsigned char alpha() const { return m_alpha; } 108 inline unsigned char alpha() const { return m_alpha; }
104 void setAlpha(unsigned char alpha) { m_alpha = alpha; } 109 void setAlpha(unsigned char alpha) { m_alpha = alpha; }
105 110 // this isn't actually a theme item
111 // but we'll let it be here for now, until there's a better way to
112 // get resources into menu
113 void setMenuMode(MenuMode mode) { m_menumode = mode; }
114 MenuMode menuMode() const { return m_menumode; }
115 void setDelayOpen(int usec) { m_delayopen = usec; }
116 void setDelayClose(int usec) { m_delayclose = usec; }
117 int delayOpen() const { return m_delayopen; }
118 int delayClose() const { return m_delayclose; }
119
106 const FbTk::Color &borderColor() const { return *m_border_color; } 120 const FbTk::Color &borderColor() const { return *m_border_color; }
107 FbTk::Subject &themeChangeSig() { return m_theme_change_sig; } 121 FbTk::Subject &themeChangeSig() { return m_theme_change_sig; }
108 /// attach observer 122 /// attach observer
@@ -126,6 +140,10 @@ private:
126 FbTk::Subject m_theme_change_sig; 140 FbTk::Subject m_theme_change_sig;
127 141
128 unsigned char m_alpha; 142 unsigned char m_alpha;
143 MenuMode m_menumode;
144 unsigned int m_delayopen; ///< in usec
145 unsigned int m_delayclose; ///< in usec
146
129}; 147};
130 148
131}; // end namespace FbTk 149}; // end namespace FbTk
diff --git a/src/Screen.cc b/src/Screen.cc
index c95b96b..ba5e0d5 100644
--- a/src/Screen.cc
+++ b/src/Screen.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: Screen.cc,v 1.247 2003/12/10 23:08:03 fluxgen Exp $ 25// $Id: Screen.cc,v 1.248 2003/12/12 18:18:12 fluxgen Exp $
26 26
27 27
28#include "Screen.hh" 28#include "Screen.hh"
@@ -154,7 +154,31 @@ private:
154 154
155}; // End anonymous namespace 155}; // End anonymous namespace
156 156
157template <>
158void FbTk::Resource<FbTk::MenuTheme::MenuMode>::setDefaultValue() {
159 *(*this) = FbTk::MenuTheme::DELAY_OPEN;
160}
161
162template <>
163string FbTk::Resource<FbTk::MenuTheme::MenuMode>::getString() {
164 switch (*(*this)) {
165 case FbTk::MenuTheme::DELAY_OPEN:
166 return string("Delay");
167 case FbTk::MenuTheme::CLICK_OPEN:
168 return string("Click");
169 }
170 return string("Delay");
171}
157 172
173template <>
174void FbTk::Resource<FbTk::MenuTheme::MenuMode>::setFromString(const char *str) {
175 if (strcasecmp(str, "Delay") == 0)
176 *(*this) = FbTk::MenuTheme::DELAY_OPEN;
177 else if (strcasecmp(str, "Click") == 0)
178 *(*this) = FbTk::MenuTheme::CLICK_OPEN;
179 else
180 setDefaultValue();
181}
158 182
159namespace { 183namespace {
160 184
@@ -222,7 +246,10 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
222 focus_model(rm, Fluxbox::CLICKTOFOCUS, scrname+".focusModel", altscrname+".FocusModel"), 246 focus_model(rm, Fluxbox::CLICKTOFOCUS, scrname+".focusModel", altscrname+".FocusModel"),
223 workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"), 247 workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"),
224 edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"), 248 edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"),
225 menu_alpha(rm, 255, scrname+".menuAlpha", altscrname+".MenuAlpha") { 249 menu_alpha(rm, 255, scrname+".menuAlpha", altscrname+".MenuAlpha"),
250 menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"),
251 menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"),
252 menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode") {
226 253
227}; 254};
228 255
@@ -307,6 +334,9 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
307 334
308 335
309 m_menutheme->setAlpha(*resource.menu_alpha); 336 m_menutheme->setAlpha(*resource.menu_alpha);
337 m_menutheme->setMenuMode(*resource.menu_mode);
338 m_menutheme->setDelayOpen(*resource.menu_delay);
339 m_menutheme->setDelayClose(*resource.menu_delay_close);
310 340
311 imageControl().setDither(*resource.image_dither); 341 imageControl().setDither(*resource.image_dither);
312 342
@@ -570,6 +600,10 @@ FbTk::Menu *BScreen::createMenu(const std::string &label) {
570 600
571void BScreen::reconfigure() { 601void BScreen::reconfigure() {
572 m_menutheme->setAlpha(*resource.menu_alpha); 602 m_menutheme->setAlpha(*resource.menu_alpha);
603 m_menutheme->setMenuMode(*resource.menu_mode);
604 m_menutheme->setDelayOpen(*resource.menu_delay);
605 m_menutheme->setDelayClose(*resource.menu_delay_close);
606
573 Fluxbox::instance()->loadRootCommand(*this); 607 Fluxbox::instance()->loadRootCommand(*this);
574 608
575 // setup windowtheme, toolbartheme for antialias 609 // setup windowtheme, toolbartheme for antialias
diff --git a/src/Screen.hh b/src/Screen.hh
index df836db..c73dead 100644
--- a/src/Screen.hh
+++ b/src/Screen.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: Screen.hh,v 1.126 2003/12/10 23:08:03 fluxgen Exp $ 25// $Id: Screen.hh,v 1.127 2003/12/12 18:18:12 fluxgen Exp $
26 26
27#ifndef SCREEN_HH 27#ifndef SCREEN_HH
28#define SCREEN_HH 28#define SCREEN_HH
@@ -430,7 +430,8 @@ private:
430 FbTk::Resource<std::string> resizemode; 430 FbTk::Resource<std::string> resizemode;
431 FbTk::Resource<Fluxbox::FocusModel> focus_model; 431 FbTk::Resource<Fluxbox::FocusModel> focus_model;
432 bool ordered_dither; 432 bool ordered_dither;
433 FbTk::Resource<int> workspaces, edge_snap_threshold, menu_alpha; 433 FbTk::Resource<int> workspaces, edge_snap_threshold, menu_alpha, menu_delay, menu_delay_close;
434 FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode;
434 435
435 int placement_policy, row_direction, col_direction; 436 int placement_policy, row_direction, col_direction;
436 437