menus update their values when they are reconfigure()d.
[mikachu/openbox.git] / src / Configmenu.cc
1 // Configmenu.cc for Openbox
2 // Copyright (c) 2001 Sean 'Shaleh' Perry <shaleh@debian.org>
3 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
22
23 // stupid macros needed to access some functions in version 2 of the GNU C
24 // library
25 #ifndef   _GNU_SOURCE
26 #  define _GNU_SOURCE
27 #endif // _GNU_SOURCE
28
29 #ifdef    HAVE_CONFIG_H
30 # include "../config.h"
31 #endif // HAVE_CONFIG_H
32
33 #include "i18n.h"
34 #include "Configmenu.h"
35 #include "Toolbar.h"
36 #include "Window.h"
37 #include "Screen.h"
38
39 Configmenu::Configmenu(BScreen &scr) : Basemenu(scr), screen(scr)
40 {
41   setLabel(i18n->getMessage(ConfigmenuSet, ConfigmenuConfigOptions,
42                             "Config options"));
43   setInternalMenu();
44
45   focusmenu = new Focusmenu(this);
46   placementmenu = new Placementmenu(this);
47
48   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuFocusModel,
49                           "Focus Model"), focusmenu);
50   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuWindowPlacement,
51                           "Window Placement"), placementmenu);
52   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuImageDithering,
53                           "Image Dithering"), 1);
54   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuOpaqueMove,
55                           "Opaque Window Moving"), 2);
56   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuFullMax,
57                           "Full Maximization"), 3);
58   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuFocusNew,
59                           "Focus New Windows"), 4);
60   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuFocusLast,
61                           "Focus Last Window on Workspace"), 5);
62   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuHideToolbar,
63                           "Hide toolbar"), 6);
64   update();
65
66   setValues();
67 }
68
69 void Configmenu::setValues() {
70   setItemSelected(2, screen.getImageControl()->doDither());
71   setItemSelected(3, screen.opaqueMove());
72   setItemSelected(4, screen.fullMax());
73   setItemSelected(5, screen.focusNew());
74   setItemSelected(6, screen.focusLast());
75   setItemSelected(7, screen.hideToolbar());
76 }
77
78 Configmenu::~Configmenu() {
79   delete focusmenu;
80   delete placementmenu;
81 }
82
83 void Configmenu::itemSelected(int button, int index) {
84   if (button != 1)
85     return;
86
87   BasemenuItem *item = find(index);
88
89   if (!item->function())
90     return;
91
92   switch(item->function()) {
93   case 1: { // dither
94     screen.getImageControl()->
95       setDither((! screen.getImageControl()->doDither()));
96
97     setItemSelected(index, screen.getImageControl()->doDither());
98
99     break;
100   }
101
102   case 2: { // opaque move
103     screen.setOpaqueMove(!screen.opaqueMove());
104
105     setItemSelected(index, screen.opaqueMove());
106
107     break;
108   }
109
110   case 3: { // full maximization
111     screen.setFullMax(!screen.fullMax());
112
113     setItemSelected(index, screen.fullMax());
114
115     break;
116   }
117   case 4: { // focus new windows
118     screen.setFocusNew(!screen.focusNew());
119
120     setItemSelected(index, screen.focusNew());
121     break;
122   }
123
124   case 5: { // focus last window on workspace
125     screen.setFocusLast(!screen.focusLast());
126     setItemSelected(index, screen.focusLast());
127     break;
128   }
129   case 6:{ //toggle toolbar hide
130     screen.setHideToolbar(!screen.hideToolbar());
131     setItemSelected(index, screen.hideToolbar());
132     break;
133   }
134   } // switch
135 }
136
137 void Configmenu::reconfigure() {
138   setValues();
139   focusmenu->reconfigure();
140   placementmenu->reconfigure();
141
142   Basemenu::reconfigure();
143 }
144
145 Configmenu::Focusmenu::Focusmenu(Configmenu *cm) : Basemenu(cm->screen) {
146   configmenu = cm;
147
148   setLabel(i18n->getMessage(ConfigmenuSet, ConfigmenuFocusModel,
149                             "Focus Model"));
150   setInternalMenu();
151
152   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuClickToFocus,
153                           "Click To Focus"), 1);
154   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuSloppyFocus,
155                           "Sloppy Focus"), 2);
156   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuAutoRaise,
157                           "Auto Raise"), 3);
158   update();
159
160   setValues();
161 }
162
163 void Configmenu::Focusmenu::setValues() {
164   setItemSelected(0, !configmenu->screen.sloppyFocus());
165   setItemSelected(1, configmenu->screen.sloppyFocus());
166   setItemEnabled(2, configmenu->screen.sloppyFocus());
167   setItemSelected(2, configmenu->screen.autoRaise());
168 }
169
170 void Configmenu::Focusmenu::reconfigure() {
171   setValues();
172   Basemenu::reconfigure();
173 }
174
175 void Configmenu::Focusmenu::itemSelected(int button, int index) {
176   if (button != 1)
177     return;
178
179   BasemenuItem *item = find(index);
180
181   if (!item->function())
182     return;
183
184   switch (item->function()) {
185   case 1: // click to focus
186     configmenu->screen.setSloppyFocus(false);
187     configmenu->screen.setAutoRaise(false);
188
189     if (! configmenu->screen.getOpenbox().getFocusedWindow())
190       XSetInputFocus(configmenu->screen.getOpenbox().getXDisplay(),
191                      configmenu->screen.getToolbar()->getWindowID(),
192                      RevertToParent, CurrentTime);
193     else
194       XSetInputFocus(configmenu->screen.getOpenbox().getXDisplay(),
195                      configmenu->screen.getOpenbox().
196                      getFocusedWindow()->getClientWindow(),
197                      RevertToParent, CurrentTime);
198
199     configmenu->screen.reconfigure();
200
201     break;
202
203   case 2: // sloppy focus
204     configmenu->screen.setSloppyFocus(true);
205
206     configmenu->screen.reconfigure();
207
208     break;
209
210   case 3: // auto raise with sloppy focus
211     bool change = ((configmenu->screen.autoRaise()) ? false : true);
212     configmenu->screen.setAutoRaise(change);
213
214     break;
215   }
216
217   setItemSelected(0, !configmenu->screen.sloppyFocus());
218   setItemSelected(1, configmenu->screen.sloppyFocus());
219   setItemEnabled(2, configmenu->screen.sloppyFocus());
220   setItemSelected(2, configmenu->screen.autoRaise());
221 }
222
223 Configmenu::Placementmenu::Placementmenu(Configmenu *cm) :
224  Basemenu(cm->screen) {
225   configmenu = cm;
226
227   setLabel(i18n->getMessage(ConfigmenuSet, ConfigmenuWindowPlacement,
228                             "Window Placement"));
229   setInternalMenu();
230   
231   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuSmartRows,
232                           "Smart Placement (Rows)"),
233          BScreen::RowSmartPlacement);
234   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuSmartCols,
235                           "Smart Placement (Columns)"),
236          BScreen::ColSmartPlacement);
237   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuCascade,
238                           "Cascade Placement"), BScreen::CascadePlacement);
239   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuBestFit,
240                           "Best Fit Placement"), BScreen::BestFitPlacement);
241   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuLeftRight,
242                           "Left to Right"), BScreen::LeftRight);
243   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuRightLeft,
244                           "Right to Left"), BScreen::RightLeft);
245   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuTopBottom,
246                           "Top to Bottom"), BScreen::TopBottom);
247   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuBottomTop,
248                           "Bottom to Top"), BScreen::BottomTop);
249   update();
250
251   setValues();
252 }
253
254 void Configmenu::Placementmenu::setValues() {
255   switch (configmenu->screen.placementPolicy()) {
256   case BScreen::RowSmartPlacement:
257     setItemSelected(0, True);
258     break;
259
260   case BScreen::ColSmartPlacement:
261     setItemSelected(1, True);
262     break;
263
264   case BScreen::CascadePlacement:
265     setItemSelected(2, True);
266     break;
267
268   case BScreen::BestFitPlacement:
269     setItemSelected(3, True);
270     break;
271   }
272
273   Bool rl = (configmenu->screen.rowPlacementDirection() ==
274              BScreen::LeftRight),
275        tb = (configmenu->screen.colPlacementDirection() ==
276              BScreen::TopBottom);
277
278   setItemSelected(4, rl);
279   setItemSelected(5, !rl);
280
281   setItemSelected(6, tb);
282   setItemSelected(7, !tb);
283 }
284
285 void Configmenu::Placementmenu::reconfigure() {
286   setValues();
287   Basemenu::reconfigure();
288 }
289
290 void Configmenu::Placementmenu::itemSelected(int button, int index) {
291   if (button != 1)
292     return;
293
294   BasemenuItem *item = find(index);
295
296   if (!item->function())
297     return;
298
299   switch (item->function()) {
300   case BScreen::RowSmartPlacement:
301     configmenu->screen.setPlacementPolicy(item->function());
302
303     setItemSelected(0, True);
304     setItemSelected(1, False);
305     setItemSelected(2, False);
306     setItemSelected(3, False);
307
308     break;
309
310   case BScreen::ColSmartPlacement:
311     configmenu->screen.setPlacementPolicy(item->function());
312
313     setItemSelected(0, False);
314     setItemSelected(1, True);
315     setItemSelected(2, False);
316     setItemSelected(3, False);
317
318     break;
319
320   case BScreen::CascadePlacement:
321     configmenu->screen.setPlacementPolicy(item->function());
322
323     setItemSelected(0, False);
324     setItemSelected(1, False);
325     setItemSelected(2, True);
326     setItemSelected(3, False);
327
328     break;
329
330   case BScreen::BestFitPlacement:
331     configmenu->screen.setPlacementPolicy(item->function());
332
333     setItemSelected(0, False);
334     setItemSelected(1, False);
335     setItemSelected(2, False);
336     setItemSelected(3, True);
337
338     break;
339
340   case BScreen::LeftRight:
341     configmenu->screen.setRowPlacementDirection(BScreen::LeftRight);
342
343     setItemSelected(4, True);
344     setItemSelected(5, False);
345
346     break;
347
348   case BScreen::RightLeft:
349     configmenu->screen.setRowPlacementDirection(BScreen::RightLeft);
350
351     setItemSelected(4, False);
352     setItemSelected(5, True);
353
354     break;
355
356   case BScreen::TopBottom:
357     configmenu->screen.setColPlacementDirection(BScreen::TopBottom);
358
359     setItemSelected(5, True);
360     setItemSelected(6, False);
361
362     break;
363
364   case BScreen::BottomTop:
365     configmenu->screen.setColPlacementDirection(BScreen::BottomTop);
366
367     setItemSelected(5, False);
368     setItemSelected(6, True);
369
370     break;
371   }
372 }