aboutsummaryrefslogtreecommitdiff
path: root/src/IconButton.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/IconButton.cc')
-rw-r--r--src/IconButton.cc213
1 files changed, 75 insertions, 138 deletions
diff --git a/src/IconButton.cc b/src/IconButton.cc
index 545ee1d..34fe532 100644
--- a/src/IconButton.cc
+++ b/src/IconButton.cc
@@ -24,21 +24,19 @@
24 24
25#include "IconButton.hh" 25#include "IconButton.hh"
26#include "IconbarTool.hh" 26#include "IconbarTool.hh"
27#include "IconbarTheme.hh"
27 28
28#include "fluxbox.hh"
29#include "Screen.hh" 29#include "Screen.hh"
30#include "Window.hh" 30#include "Focusable.hh"
31#include "WinClient.hh"
32#include "CommandParser.hh"
33#include "WindowCmd.hh"
34 31
35#include "FbTk/App.hh" 32#include "FbTk/App.hh"
36#include "FbTk/SimpleCommand.hh" 33#include "FbTk/Command.hh"
37#include "FbTk/EventManager.hh" 34#include "FbTk/EventManager.hh"
35#include "FbTk/ImageControl.hh"
38#include "FbTk/MacroCommand.hh" 36#include "FbTk/MacroCommand.hh"
39#include "FbTk/Command.hh"
40#include "FbTk/RefCount.hh"
41#include "FbTk/Menu.hh" 37#include "FbTk/Menu.hh"
38#include "FbTk/RefCount.hh"
39#include "FbTk/SimpleCommand.hh"
42 40
43#ifdef HAVE_CONFIG_H 41#ifdef HAVE_CONFIG_H
44#include "config.h" 42#include "config.h"
@@ -49,127 +47,25 @@
49#include <X11/extensions/shape.h> 47#include <X11/extensions/shape.h>
50#endif // SHAPE 48#endif // SHAPE
51 49
52typedef FbTk::RefCount<FbTk::Command> RefCmd;
53
54namespace {
55
56class ShowMenu: public FbTk::Command {
57public:
58 explicit ShowMenu(FluxboxWindow &win):m_win(win) { }
59 void execute() {
60 // hide the menu if it's already showing for this FluxboxWindow
61 if (m_win.menu().isVisible() && WindowCmd<void>::window() == &m_win) {
62 m_win.screen().hideMenus();
63 return;
64 }
65 m_win.screen().hideMenus();
66 // get last button pos
67 const XEvent &event = Fluxbox::instance()->lastEvent();
68 int x = event.xbutton.x_root - (m_win.menu().width() / 2);
69 int y = event.xbutton.y_root - (m_win.menu().height() / 2);
70 m_win.showMenu(x, y);
71 }
72private:
73 FluxboxWindow &m_win;
74};
75
76class FocusCommand: public FbTk::Command {
77public:
78 explicit FocusCommand(const IconbarTool& tool, FluxboxWindow &win) :
79 m_win(win), m_tool(tool) { }
80 void execute() {
81 // this needs to be a local variable, as this object could be destroyed
82 // if the workspace is changed.
83 FluxboxWindow &win = m_win;
84 if(win.isIconic() || !win.isFocused()) {
85 switch(win.screen().getUserFollowModel()) {
86 case BScreen::SEMIFOLLOW_ACTIVE_WINDOW:
87 if (win.isIconic()) {
88 win.screen().sendToWorkspace(win.screen().currentWorkspaceID(), &win);
89 } else {
90 win.screen().changeWorkspaceID(win.workspaceNumber());
91 }
92 break;
93 case BScreen::FETCH_ACTIVE_WINDOW:
94 win.screen().sendToWorkspace(win.screen().currentWorkspaceID(), &win);
95 break;
96 case BScreen::FOLLOW_ACTIVE_WINDOW:
97 if (!win.isStuck())
98 win.screen().changeWorkspaceID(win.workspaceNumber());
99 default:
100 break;
101 };
102 win.raiseAndFocus();
103 } else
104 win.iconify();
105 }
106
107private:
108 FluxboxWindow &m_win;
109 const IconbarTool& m_tool;
110};
111
112// simple forwarding of wheeling, but only
113// if desktopwheeling is enabled
114class WheelWorkspaceCmd : public FbTk::Command {
115public:
116 explicit WheelWorkspaceCmd(const IconbarTool& tool, FluxboxWindow &win, const char* cmd) :
117 m_win(win), m_cmd(CommandParser::instance().parseLine(cmd)), m_tool(tool) { }
118 void execute() {
119
120 switch(m_tool.wheelMode()) {
121 case IconbarTool::ON:
122 m_cmd->execute();
123 break;
124 case IconbarTool::SCREEN:
125 if(m_win.screen().isDesktopWheeling())
126 m_cmd->execute();
127 break;
128 case IconbarTool::OFF:
129 default:
130 break;
131 };
132 }
133
134private:
135 FluxboxWindow &m_win;
136 RefCmd m_cmd;
137 const IconbarTool& m_tool;
138};
139
140} // end anonymous namespace
141 50
142 51IconButton::IconButton(const FbTk::FbWindow &parent, IconbarTheme &theme,
143 52 Focusable &win):
144IconButton::IconButton(const IconbarTool& tool, const FbTk::FbWindow &parent, 53 FbTk::TextButton(parent, theme.focusedText().font(), win.title()),
145 FbTk::Font &font, FluxboxWindow &win):
146 FbTk::TextButton(parent, font, win.winClient().title()),
147 m_win(win), 54 m_win(win),
148 m_icon_window(*this, 1, 1, 1, 1, 55 m_icon_window(*this, 1, 1, 1, 1,
149 ExposureMask | ButtonPressMask | ButtonReleaseMask), 56 ExposureMask | ButtonPressMask | ButtonReleaseMask),
150 m_use_pixmap(true) { 57 m_use_pixmap(true),
151 58 m_theme(theme),
59 m_focused_pm(win.screen().imageControl()),
60 m_unfocused_pm(win.screen().imageControl()) {
152 61
153 RefCmd next_workspace(new ::WheelWorkspaceCmd(tool, m_win, "nextworkspace"));
154 RefCmd prev_workspace(new ::WheelWorkspaceCmd(tool, m_win, "prevworkspace"));
155
156 RefCmd focus_cmd(new ::FocusCommand(tool, m_win));
157 RefCmd menu_cmd(new ::ShowMenu(m_win));
158 setOnClick(focus_cmd, 1);
159 setOnClick(menu_cmd, 3);
160 if(win.screen().isReverseWheeling()) {
161 setOnClick(next_workspace, 5);
162 setOnClick(prev_workspace, 4);
163 } else {
164 setOnClick(next_workspace, 4);
165 setOnClick(prev_workspace, 5);
166 }
167
168 m_win.hintSig().attach(this);
169 m_win.titleSig().attach(this); 62 m_win.titleSig().attach(this);
63 m_win.focusSig().attach(this);
64 m_win.attentionSig().attach(this);
170 65
171 FbTk::EventManager::instance()->add(*this, m_icon_window); 66 FbTk::EventManager::instance()->add(*this, m_icon_window);
172 67
68 reconfigTheme();
173 update(0); 69 update(0);
174} 70}
175 71
@@ -222,20 +118,68 @@ void IconButton::setPixmap(bool use) {
222 } 118 }
223} 119}
224 120
121void IconButton::reconfigTheme() {
122
123 if (m_theme.focusedTexture().usePixmap())
124 m_focused_pm.reset(m_win.screen().imageControl().renderImage(
125 width(), height(), m_theme.focusedTexture(),
126 orientation()));
127 else
128 m_focused_pm.reset(0);
129
130 if (m_theme.unfocusedTexture().usePixmap())
131 m_unfocused_pm.reset(m_win.screen().imageControl().renderImage(
132 width(), height(), m_theme.unfocusedTexture(),
133 orientation()));
134 else
135 m_unfocused_pm.reset(0);
136
137 setAlpha(parent()->alpha());
138
139 if (m_win.isFocused() || m_win.getAttentionState()) {
140 if (m_focused_pm != 0)
141 setBackgroundPixmap(m_focused_pm);
142 else
143 setBackgroundColor(m_theme.focusedTexture().color());
144
145 setGC(m_theme.focusedText().textGC());
146 setFont(m_theme.focusedText().font());
147 setJustify(m_theme.focusedText().justify());
148 setBorderWidth(m_theme.focusedBorder().width());
149 setBorderColor(m_theme.focusedBorder().color());
150
151 } else {
152 if (m_unfocused_pm != 0)
153 setBackgroundPixmap(m_unfocused_pm);
154 else
155 setBackgroundColor(m_theme.unfocusedTexture().color());
156
157 setGC(m_theme.unfocusedText().textGC());
158 setFont(m_theme.unfocusedText().font());
159 setJustify(m_theme.unfocusedText().justify());
160 setBorderWidth(m_theme.unfocusedBorder().width());
161 setBorderColor(m_theme.unfocusedBorder().color());
162
163 }
164
165}
166
225void IconButton::update(FbTk::Subject *subj) { 167void IconButton::update(FbTk::Subject *subj) {
168 // if the window's focus state changed, we need to update the background
169 if (subj == &m_win.focusSig() || subj == &m_win.attentionSig()) {
170 reconfigTheme();
171 clear();
172 return;
173 }
174
226 // we got signal that either title or 175 // we got signal that either title or
227 // icon pixmap was updated, 176 // icon pixmap was updated,
228 // so we refresh everything 177 // so we refresh everything
229 178
230 // we need to check our client first
231 if (m_win.clientList().empty())
232 return;
233
234 Display *display = FbTk::App::instance()->display(); 179 Display *display = FbTk::App::instance()->display();
235
236 int screen = m_win.screen().screenNumber(); 180 int screen = m_win.screen().screenNumber();
237 181
238 if (m_use_pixmap && m_win.usePixmap()) { 182 if (m_use_pixmap && m_win.icon().pixmap().drawable() != None) {
239 // setup icon window 183 // setup icon window
240 m_icon_window.show(); 184 m_icon_window.show();
241 unsigned int w = width(); 185 unsigned int w = width();
@@ -254,7 +198,8 @@ void IconButton::update(FbTk::Subject *subj) {
254 198
255 m_icon_window.moveResize(iconx, icony, neww, newh); 199 m_icon_window.moveResize(iconx, icony, neww, newh);
256 200
257 m_icon_pixmap.copy(m_win.iconPixmap().drawable(), DefaultDepth(display, screen), screen); 201 m_icon_pixmap.copy(m_win.icon().pixmap().drawable(),
202 DefaultDepth(display, screen), screen);
258 m_icon_pixmap.scale(m_icon_window.width(), m_icon_window.height()); 203 m_icon_pixmap.scale(m_icon_window.width(), m_icon_window.height());
259 204
260 // rotate the icon or not?? lets go not for now, and see what they say... 205 // rotate the icon or not?? lets go not for now, and see what they say...
@@ -269,8 +214,8 @@ void IconButton::update(FbTk::Subject *subj) {
269 m_icon_pixmap = 0; 214 m_icon_pixmap = 0;
270 } 215 }
271 216
272 if(m_use_pixmap && m_win.useMask()) { 217 if(m_icon_pixmap.drawable() && m_win.icon().mask().drawable() != None) {
273 m_icon_mask.copy(m_win.iconMask().drawable(), 0, 0); 218 m_icon_mask.copy(m_win.icon().mask().drawable(), 0, 0);
274 m_icon_mask.scale(m_icon_pixmap.width(), m_icon_pixmap.height()); 219 m_icon_mask.scale(m_icon_pixmap.width(), m_icon_pixmap.height());
275 m_icon_mask.rotate(orientation()); 220 m_icon_mask.rotate(orientation());
276 } else 221 } else
@@ -287,9 +232,6 @@ void IconButton::update(FbTk::Subject *subj) {
287 232
288#endif // SHAPE 233#endif // SHAPE
289 234
290 if (subj == &(m_win.titleSig()))
291 setText(m_win.title());
292
293 if (subj != 0) { 235 if (subj != 0) {
294 setupWindow(); 236 setupWindow();
295 } else { 237 } else {
@@ -298,13 +240,8 @@ void IconButton::update(FbTk::Subject *subj) {
298} 240}
299 241
300void IconButton::setupWindow() { 242void IconButton::setupWindow() {
301
302 m_icon_window.clear(); 243 m_icon_window.clear();
303 244 setText(m_win.title());
304 if (!m_win.clientList().empty()) {
305 setText(m_win.winClient().title());
306 // draw with x offset and y offset
307 }
308 FbTk::TextButton::clear(); 245 FbTk::TextButton::clear();
309} 246}
310 247