aboutsummaryrefslogtreecommitdiff
path: root/src/IconbarTool.cc
diff options
context:
space:
mode:
authorfluxgen <fluxgen>2003-09-08 17:52:34 (GMT)
committerfluxgen <fluxgen>2003-09-08 17:52:34 (GMT)
commit925f968a6af7765f3a37e54eb80483fb87e74449 (patch)
treebf32cb609c4d11184d298f3586f919b30dcb5c6e /src/IconbarTool.cc
parent935616cab63bae8a380bcc03510c1f9263640778 (diff)
downloadfluxbox_pavel-925f968a6af7765f3a37e54eb80483fb87e74449.zip
fluxbox_pavel-925f968a6af7765f3a37e54eb80483fb87e74449.tar.bz2
add iconbar mode
Diffstat (limited to 'src/IconbarTool.cc')
-rw-r--r--src/IconbarTool.cc400
1 files changed, 333 insertions, 67 deletions
diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc
index f7f9954..fcaac39 100644
--- a/src/IconbarTool.cc
+++ b/src/IconbarTool.cc
@@ -20,31 +20,177 @@
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE. 21// DEALINGS IN THE SOFTWARE.
22 22
23// $Id: IconbarTool.cc,v 1.9 2003/08/18 11:13:32 fluxgen Exp $ 23// $Id: IconbarTool.cc,v 1.10 2003/09/08 17:52:34 fluxgen Exp $
24 24
25#include "IconbarTool.hh" 25#include "IconbarTool.hh"
26 26
27#include "Screen.hh" 27#include "Screen.hh"
28#include "ImageControl.hh"
29#include "IconbarTheme.hh" 28#include "IconbarTheme.hh"
30#include "Window.hh" 29#include "Window.hh"
31#include "IconButton.hh" 30#include "IconButton.hh"
32#include "Workspace.hh" 31#include "Workspace.hh"
32#include "fluxbox.hh"
33
34
35#include "FbTk/Menu.hh"
36#include "FbTk/MenuItem.hh"
37#include "FbTk/RefCount.hh"
38#include "FbTk/SimpleCommand.hh"
39#include "FbTk/ImageControl.hh"
33 40
34#include <typeinfo> 41#include <typeinfo>
42#include <string>
43#include <iterator>
44#include <iostream>
45using namespace std;
46
47template<>
48void FbTk::Resource<IconbarTool::Mode>::setFromString(const char *strval) {
49 if (strcasecmp(strval, "None") == 0)
50 m_value = IconbarTool::NONE;
51 else if (strcasecmp(strval, "Icons") == 0)
52 m_value = IconbarTool::ICONS;
53 else if (strcasecmp(strval, "WorkspaceIcons") == 0)
54 m_value = IconbarTool::WORKSPACEICONS;
55 else if (strcasecmp(strval, "Workspace") == 0)
56 m_value = IconbarTool::WORKSPACE;
57 else if (strcasecmp(strval, "AllWindows") == 0)
58 m_value = IconbarTool::ALLWINDOWS;
59 else
60 setDefaultValue();
61}
62
63
64template<>
65string FbTk::Resource<IconbarTool::Mode>::getString() {
66
67 switch (m_value) {
68 case IconbarTool::NONE:
69 return string("None");
70 break;
71 case IconbarTool::ICONS:
72 return string("Icons");
73 break;
74 case IconbarTool::WORKSPACEICONS:
75 return string("WorkspaceIcons");
76 break;
77 case IconbarTool::WORKSPACE:
78 return string("Workspace");
79 break;
80 case IconbarTool::ALLWINDOWS:
81 return string("AllWindows");
82 break;
83 }
84 // default string
85 return string("Icons");
86}
87
88namespace {
89
90class ToolbarModeMenuItem : public FbTk::MenuItem {
91public:
92 ToolbarModeMenuItem(const char *label, IconbarTool &handler,
93 IconbarTool::Mode mode,
94 FbTk::RefCount<FbTk::Command> &cmd):
95 FbTk::MenuItem(label, cmd), m_handler(handler), m_mode(mode) {
96 }
97 bool isEnabled() const { return m_handler.mode() != m_mode; }
98 void click(int button, int time) {
99 m_handler.setMode(m_mode);
100 FbTk::MenuItem::click(button, time);
101 }
102
103private:
104 IconbarTool &m_handler;
105 IconbarTool::Mode m_mode;
106};
107
108void setupModeMenu(FbTk::Menu &menu, IconbarTool &handler) {
109 using namespace FbTk;
110
111 // TODO: nls
112 menu.setLabel("Iconbar Mode");
113
114 RefCount<Command> saverc_cmd(new SimpleCommand<Fluxbox>(
115 *Fluxbox::instance(),
116 &Fluxbox::save_rc));
117
118 //TODO: nls
119 menu.insert(new ToolbarModeMenuItem("None", handler,
120 IconbarTool::NONE, saverc_cmd));
121 menu.insert(new ToolbarModeMenuItem("Icons", handler,
122 IconbarTool::ICONS, saverc_cmd));
123 menu.insert(new ToolbarModeMenuItem("Workspace Icons", handler,
124 IconbarTool::WORKSPACEICONS, saverc_cmd));
125 menu.insert(new ToolbarModeMenuItem("Workspace", handler,
126 IconbarTool::WORKSPACE, saverc_cmd));
127 menu.insert(new ToolbarModeMenuItem("All Windows", handler,
128 IconbarTool::ALLWINDOWS, saverc_cmd));
129 menu.update();
130}
131
132inline bool checkAddWindow(IconbarTool::Mode mode, const FluxboxWindow &win) {
133
134 // just add the icons that are on the this workspace
135 switch (mode) {
136 case IconbarTool::NONE:
137 break;
138 case IconbarTool::ICONS:
139 if (win.isIconic())
140 return true;
141 break;
142 case IconbarTool::WORKSPACEICONS:
143 if(win.workspaceNumber() == win.screen().currentWorkspaceID() &&
144 win.isIconic())
145 return true;
146 break;
147 case IconbarTool::WORKSPACE:
148 if (win.workspaceNumber() == win.screen().currentWorkspaceID())
149 return true;
150 break;
151 case IconbarTool::ALLWINDOWS:
152 return true;
153 break;
154 }
155
156 return false;
157}
158
159void removeDuplicate(const IconbarTool::IconList &iconlist, std::list<FluxboxWindow *> &windowlist) {
160 IconbarTool::IconList::const_iterator win_it = iconlist.begin();
161 IconbarTool::IconList::const_iterator win_it_end = iconlist.end();
162 std::list<FluxboxWindow *>::iterator remove_it = windowlist.end();
163 for (; win_it != win_it_end; ++win_it)
164 remove_it = remove(windowlist.begin(), remove_it, &(*win_it)->win());
165
166 // remove already existing windows
167 windowlist.erase(remove_it, windowlist.end());
168
169}
170
171}; // end anonymous namespace
35 172
36IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, BScreen &screen): 173IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, BScreen &screen,
174 FbTk::Menu &menu):
37 ToolbarItem(ToolbarItem::RELATIVE), 175 ToolbarItem(ToolbarItem::RELATIVE),
38 m_screen(screen), 176 m_screen(screen),
39 m_icon_container(parent), 177 m_icon_container(parent),
40 m_theme(theme), 178 m_theme(theme),
41 m_focused_pm(0), 179 m_focused_pm(0),
42 m_unfocused_pm(0), 180 m_unfocused_pm(0),
43 m_empty_pm(0) { 181 m_empty_pm(0),
182 m_rc_mode(screen.resourceManager(), WORKSPACE,
183 screen.name() + ".iconbar.mode", screen.altName() + ".Iconbar.Mode"),
184 m_menu(*screen.menuTheme(), menu.screenNumber(), screen.imageControl()) {
185
186 // setup menu
187 setupModeMenu(m_menu, *this);
188 menu.insert(m_menu.label().c_str(), &m_menu);
44 189
45 // setup signals 190 // setup signals
46 theme.reconfigSig().attach(this); 191 theme.reconfigSig().attach(this);
47 screen.clientListSig().attach(this); 192 screen.clientListSig().attach(this);
193 screen.iconListSig().attach(this);
48 screen.currentWorkspaceSig().attach(this); 194 screen.currentWorkspaceSig().attach(this);
49 195
50 update(0); 196 update(0);
@@ -88,6 +234,41 @@ void IconbarTool::hide() {
88 m_icon_container.hide(); 234 m_icon_container.hide();
89} 235}
90 236
237void IconbarTool::setMode(Mode mode) {
238 if (mode == *m_rc_mode)
239 return;
240
241 *m_rc_mode = mode;
242
243 // lock graphics update
244 m_icon_container.setUpdateLock(true);
245
246 deleteIcons();
247
248 // update mode
249 switch (*m_rc_mode) {
250 case NONE:
251 break;
252 case ICONS:
253 case WORKSPACEICONS:
254 updateIcons();
255 break;
256 case WORKSPACE:
257 updateWorkspace();
258 break;
259 case ALLWINDOWS:
260 updateAllWindows();
261 break;
262 };
263
264 // unlock graphics update
265 m_icon_container.setUpdateLock(false);
266 m_icon_container.update();
267 m_icon_container.showSubwindows();
268
269 renderTheme();
270}
271
91unsigned int IconbarTool::width() const { 272unsigned int IconbarTool::width() const {
92 return m_icon_container.width(); 273 return m_icon_container.width();
93} 274}
@@ -105,7 +286,14 @@ void IconbarTool::update(FbTk::Subject *subj) {
105 if (m_screen.isShuttingdown()) 286 if (m_screen.isShuttingdown())
106 return; 287 return;
107 288
108 // just focus signal? 289 if (mode() == NONE) {
290 if (typeid(*subj) == typeid(FbTk::Theme))
291 renderTheme();
292
293 return;
294 }
295
296 // handle window signal
109 if (subj != 0 && typeid(*subj) == typeid(FluxboxWindow::WinSubject)) { 297 if (subj != 0 && typeid(*subj) == typeid(FluxboxWindow::WinSubject)) {
110 // we handle everything except die signal here 298 // we handle everything except die signal here
111 FluxboxWindow::WinSubject *winsubj = static_cast<FluxboxWindow::WinSubject *>(subj); 299 FluxboxWindow::WinSubject *winsubj = static_cast<FluxboxWindow::WinSubject *>(subj);
@@ -113,83 +301,80 @@ void IconbarTool::update(FbTk::Subject *subj) {
113 renderWindow(winsubj->win()); 301 renderWindow(winsubj->win());
114 return; 302 return;
115 } else if (subj == &(winsubj->win().workspaceSig())) { 303 } else if (subj == &(winsubj->win().workspaceSig())) {
304 // we can ignore this signal if we're in ALLWINDOWS mode
305 if (mode() == ALLWINDOWS)
306 return;
307
116 // workspace changed for this window, and if it's not on current workspace we remove it 308 // workspace changed for this window, and if it's not on current workspace we remove it
117 if (m_screen.currentWorkspaceID() != winsubj->win().workspaceNumber()) 309 if (m_screen.currentWorkspaceID() != winsubj->win().workspaceNumber()) {
118 removeWindow(winsubj->win()); 310 removeWindow(winsubj->win());
311 renderTheme();
312 }
119 return; 313 return;
120 } else { // die sig 314 } else if (subj == &(winsubj->win().dieSig())) { // die sig
121 removeWindow(winsubj->win()); 315 removeWindow(winsubj->win());
316 renderTheme();
122 return; // we don't need to update the entire list 317 return; // we don't need to update the entire list
318 } else if (subj == &(winsubj->win().stateSig())) {
319 if (mode() == ICONS || mode() == WORKSPACEICONS) {
320 if (!winsubj->win().isIconic()) {
321 removeWindow(winsubj->win());
322 renderTheme();
323 }
324 } else {
325 if (winsubj->win().isIconic()) {
326 removeWindow(winsubj->win());
327 renderTheme();
328 }
329 }
330 return;
331 } else {
332 // signal not handled
333 return;
123 } 334 }
124 } 335 }
125 336
126 bool remove_all = false; // if we should readd all windows 337 bool remove_all = false; // if we should readd all windows
127 338
128 if (subj != 0 && typeid(*subj) == typeid(BScreen::ScreenSubject)) { 339 if (subj != 0 && typeid(*subj) == typeid(BScreen::ScreenSubject) && mode() != ALLWINDOWS) {
129 BScreen::ScreenSubject *screen_subj = static_cast<BScreen::ScreenSubject *>(subj); 340 BScreen::ScreenSubject *screen_subj = static_cast<BScreen::ScreenSubject *>(subj);
130 if (&screen_subj->screen().currentWorkspaceSig() == screen_subj) { 341 // current workspace sig
342 if (&m_screen.currentWorkspaceSig() == screen_subj &&
343 mode() != ALLWINDOWS && mode() != ICONS) {
131 remove_all = true; // remove and readd all windows 344 remove_all = true; // remove and readd all windows
345 } else if (&m_screen.iconListSig() == screen_subj &&
346 (mode() == ALLWINDOWS || mode() == ICONS)) {
347 remove_all = true;
132 } 348 }
133 } 349 }
134 350
135 // ok, we got some signal that we need to update our iconbar container 351 // lock graphic update
136 352 m_icon_container.setUpdateLock(true);
137 // get current workspace and all it's clients
138 Workspace &space = *m_screen.currentWorkspace();
139 // build a ItemList and add it (faster than adding single items)
140 Container::ItemList items;
141 Workspace::Windows itemlist(space.windowList());
142 // add icons to the itemlist
143 {
144 BScreen::Icons::iterator icon_it = m_screen.getIconList().begin();
145 BScreen::Icons::iterator icon_it_end = m_screen.getIconList().end();
146 for (; icon_it != icon_it_end; ++icon_it) {
147 // just add the icons that are on the this workspace
148 if ((*icon_it)->workspaceNumber() == m_screen.currentWorkspaceID())
149 itemlist.push_back(*icon_it);
150 }
151 }
152
153 // go through the current list and see if there're windows to be added
154 // (note: we dont need to check if there's one deleted since we're listening
155 // to dieSig )
156 if (!remove_all) {
157 IconList::iterator win_it = m_icon_list.begin();
158 IconList::iterator win_it_end = m_icon_list.end();
159 Workspace::Windows::iterator remove_it = itemlist.end();
160 for (; win_it != win_it_end; ++win_it)
161 remove_it = remove(itemlist.begin(), remove_it, &(*win_it)->win());
162
163 itemlist.erase(remove_it, itemlist.end());
164 // we dont need to do anything
165 // since we dont have anything to add ...
166 if (itemlist.size() == 0)
167 return;
168 353
169 } else { 354 if (remove_all)
170 deleteIcons(); 355 deleteIcons();
171 }
172
173 // ok, now we should have a list of icons that we need to add
174 Workspace::Windows::iterator it = itemlist.begin();
175 Workspace::Windows::iterator it_end = itemlist.end();
176 for (; it != it_end; ++it) {
177
178 // we just want windows that has clients
179 if ((*it)->clientList().size() == 0)
180 continue;
181 356
182 IconButton *button = new IconButton(m_icon_container, m_theme.focusedText().font(), **it); 357 // ok, we got some signal that we need to update our iconbar container
183 items.push_back(button); 358 switch (mode()) {
184 m_icon_list.push_back(button); 359 case NONE:
185 360 return;
186 (*it)->focusSig().attach(this); 361 break;
187 (*it)->dieSig().attach(this); 362 case ICONS:
188 (*it)->workspaceSig().attach(this); 363 case WORKSPACEICONS:
364 updateIcons();
365 break;
366 case WORKSPACE:
367 updateWorkspace();
368 break;
369 case ALLWINDOWS:
370 updateAllWindows();
371 break;
189 } 372 }
190 373
374 // unlock container and update graphics
375 m_icon_container.setUpdateLock(false);
191 m_icon_container.showSubwindows(); 376 m_icon_container.showSubwindows();
192 m_icon_container.insertItems(items); 377 m_icon_container.update();
193 378
194 renderTheme(); 379 renderTheme();
195} 380}
@@ -255,8 +440,6 @@ void IconbarTool::renderTheme() {
255 IconList::iterator icon_it_end = m_icon_list.end(); 440 IconList::iterator icon_it_end = m_icon_list.end();
256 for (; icon_it != icon_it_end; ++icon_it) 441 for (; icon_it != icon_it_end; ++icon_it)
257 renderButton(*(*icon_it)); 442 renderButton(*(*icon_it));
258
259
260} 443}
261 444
262void IconbarTool::renderButton(IconButton &button) { 445void IconbarTool::renderButton(IconButton &button) {
@@ -300,7 +483,6 @@ void IconbarTool::deleteIcons() {
300} 483}
301 484
302void IconbarTool::removeWindow(FluxboxWindow &win) { 485void IconbarTool::removeWindow(FluxboxWindow &win) {
303
304 // got window die signal, lets find and remove the window 486 // got window die signal, lets find and remove the window
305 IconList::iterator it = m_icon_list.begin(); 487 IconList::iterator it = m_icon_list.begin();
306 IconList::iterator it_end = m_icon_list.end(); 488 IconList::iterator it_end = m_icon_list.end();
@@ -311,10 +493,94 @@ void IconbarTool::removeWindow(FluxboxWindow &win) {
311 // did we find it? 493 // did we find it?
312 if (it == m_icon_list.end()) 494 if (it == m_icon_list.end())
313 return; 495 return;
496
497 win.focusSig().detach(this);
498 win.dieSig().detach(this);
499 win.workspaceSig().detach(this);
500 win.stateSig().detach(this);
501
314 502
315 // remove from list and render theme again 503 // remove from list and render theme again
316 delete *it; 504 IconButton *button = *it;
317 m_icon_list.erase(it); 505
318 m_icon_container.removeItem(m_icon_container.find(*it)); 506 m_icon_container.removeItem(m_icon_container.find(*it));
319 renderTheme(); 507 m_icon_list.erase(it);
508
509 delete button;
510
511}
512
513void IconbarTool::addWindow(FluxboxWindow &win) {
514 // we just want windows that has clients
515 if (win.clientList().size() == 0)
516 return;
517
518 IconButton *button = new IconButton(m_icon_container, m_theme.focusedText().font(), win);
519 m_icon_container.insertItem(button);
520 m_icon_list.push_back(button);
521
522 // dont forget to detach signal in removeWindow
523 win.focusSig().attach(this);
524 win.dieSig().attach(this);
525 win.workspaceSig().attach(this);
526 win.stateSig().attach(this);
527}
528
529
530void IconbarTool::updateIcons() {
531 std::list<FluxboxWindow *> itemlist;
532 // add icons to the itemlist
533 BScreen::Icons::iterator icon_it = m_screen.getIconList().begin();
534 BScreen::Icons::iterator icon_it_end = m_screen.getIconList().end();
535 for (; icon_it != icon_it_end; ++icon_it) {
536 if (mode() == ICONS)
537 itemlist.push_back(*icon_it);
538 else if (mode() == WORKSPACEICONS && (*icon_it)->workspaceNumber() == m_screen.currentWorkspaceID())
539 itemlist.push_back(*icon_it);
540 }
541 removeDuplicate(m_icon_list, itemlist);
542 addList(itemlist);
320} 543}
544
545void IconbarTool::updateWorkspace() {
546 std::list<FluxboxWindow *> itemlist;
547 Workspace &space = *m_screen.currentWorkspace();
548 Workspace::Windows::iterator it = space.windowList().begin();
549 Workspace::Windows::iterator it_end = space.windowList().end();
550 for (; it != it_end; ++it) {
551 if (checkAddWindow(mode(), **it))
552 itemlist.push_back(*it);
553 }
554 removeDuplicate(m_icon_list, itemlist);
555 addList(itemlist);
556}
557
558
559void IconbarTool::updateAllWindows() {
560 std::list<FluxboxWindow *> full_list;
561 // for each workspace add clients to full list
562 BScreen::Workspaces::iterator workspace_it = m_screen.getWorkspacesList().begin();
563 BScreen::Workspaces::iterator workspace_it_end = m_screen.getWorkspacesList().end();
564 for (; workspace_it != workspace_it_end; ++workspace_it) {
565 full_list.insert(full_list.end(),
566 (*workspace_it)->windowList().begin(),
567 (*workspace_it)->windowList().end());
568 }
569 // add icons
570 full_list.insert(full_list.end(),
571 m_screen.getIconList().begin(),
572 m_screen.getIconList().end());
573
574 removeDuplicate(m_icon_list, full_list);
575 addList(full_list);
576}
577
578void IconbarTool::addList(std::list<FluxboxWindow *> &winlist) {
579 // ok, now we should have a list of icons that we need to add
580 std::list<FluxboxWindow *>::iterator it = winlist.begin();
581 std::list<FluxboxWindow *>::iterator it_end = winlist.end();
582 for (; it != it_end; ++it)
583 addWindow(**it);
584}
585
586