]> Dogcows Code - chaz/openbox/blob - src/Slit.cc
workspace warping. this needs to be optional! also motion events are retarded!
[chaz/openbox] / src / Slit.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Slit.cc for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a
7 // copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 // DEALINGS IN THE SOFTWARE.
23
24 #ifdef HAVE_CONFIG_H
25 # include "../config.h"
26 #endif // HAVE_CONFIG_H
27
28 extern "C" {
29 #include <X11/keysym.h>
30 }
31
32 #include "i18n.hh"
33 #include "blackbox.hh"
34 #include "Image.hh"
35 #include "Screen.hh"
36 #include "Slit.hh"
37 #include "Toolbar.hh"
38
39
40 Slit::Slit(BScreen *scr) {
41 screen = scr;
42 blackbox = screen->getBlackbox();
43 slitstr = "session.screen" + itostring(screen->getScreenNumber()) + ".slit.";
44 config = blackbox->getConfig();
45
46 load_rc();
47
48 display = screen->getBaseDisplay()->getXDisplay();
49 frame.window = frame.pixmap = None;
50
51 timer = new BTimer(blackbox, this);
52 timer->setTimeout(blackbox->getAutoRaiseDelay());
53
54 slitmenu = new Slitmenu(this);
55
56 XSetWindowAttributes attrib;
57 unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel |
58 CWColormap | CWOverrideRedirect | CWEventMask;
59 attrib.background_pixmap = None;
60 attrib.background_pixel = attrib.border_pixel =
61 screen->getBorderColor()->pixel();
62 attrib.colormap = screen->getColormap();
63 attrib.override_redirect = True;
64 attrib.event_mask = SubstructureRedirectMask | ButtonPressMask |
65 EnterWindowMask | LeaveWindowMask;
66
67 frame.rect.setSize(1, 1);
68
69 frame.window =
70 XCreateWindow(display, screen->getRootWindow(),
71 frame.rect.x(), frame.rect.y(),
72 frame.rect.width(), frame.rect.height(),
73 screen->getBorderWidth(), screen->getDepth(), InputOutput,
74 screen->getVisual(), create_mask, &attrib);
75 blackbox->saveSlitSearch(frame.window, this);
76
77 screen->addStrut(&strut);
78
79 reconfigure();
80 }
81
82
83 Slit::~Slit(void) {
84 delete timer;
85
86 delete slitmenu;
87
88 screen->removeStrut(&strut);
89 screen->updateAvailableArea();
90
91 screen->getImageControl()->removeImage(frame.pixmap);
92
93 blackbox->removeSlitSearch(frame.window);
94
95 XDestroyWindow(display, frame.window);
96 }
97
98
99 void Slit::addClient(Window w) {
100 if (! blackbox->validateWindow(w))
101 return;
102
103 SlitClient *client = new SlitClient;
104 client->client_window = w;
105
106 XWMHints *wmhints = XGetWMHints(display, w);
107
108 if (wmhints) {
109 if ((wmhints->flags & IconWindowHint) &&
110 (wmhints->icon_window != None)) {
111 // some dock apps use separate windows, we need to hide these
112 XMoveWindow(display, client->client_window, screen->getWidth() + 10,
113 screen->getHeight() + 10);
114 XMapWindow(display, client->client_window);
115
116 client->icon_window = wmhints->icon_window;
117 client->window = client->icon_window;
118 } else {
119 client->icon_window = None;
120 client->window = client->client_window;
121 }
122
123 XFree(wmhints);
124 } else {
125 client->icon_window = None;
126 client->window = client->client_window;
127 }
128
129 XWindowAttributes attrib;
130 if (XGetWindowAttributes(display, client->window, &attrib)) {
131 client->rect.setSize(attrib.width, attrib.height);
132 } else {
133 client->rect.setSize(64, 64);
134 }
135
136 XSetWindowBorderWidth(display, client->window, 0);
137
138 XGrabServer(display);
139 XSelectInput(display, frame.window, NoEventMask);
140 XSelectInput(display, client->window, NoEventMask);
141 XReparentWindow(display, client->window, frame.window, 0, 0);
142 XMapRaised(display, client->window);
143 XChangeSaveSet(display, client->window, SetModeInsert);
144 XSelectInput(display, frame.window, SubstructureRedirectMask |
145 ButtonPressMask | EnterWindowMask | LeaveWindowMask);
146 XSelectInput(display, client->window, StructureNotifyMask |
147 SubstructureNotifyMask | EnterWindowMask);
148
149 XUngrabServer(display);
150
151 clientList.push_back(client);
152
153 blackbox->saveSlitSearch(client->client_window, this);
154 blackbox->saveSlitSearch(client->icon_window, this);
155 reconfigure();
156 }
157
158
159 void Slit::removeClient(SlitClient *client, bool remap) {
160 blackbox->removeSlitSearch(client->client_window);
161 blackbox->removeSlitSearch(client->icon_window);
162 clientList.remove(client);
163
164 screen->removeNetizen(client->window);
165
166 if (remap && blackbox->validateWindow(client->window)) {
167 XGrabServer(display);
168 XSelectInput(display, frame.window, NoEventMask);
169 XSelectInput(display, client->window, NoEventMask);
170 XReparentWindow(display, client->window, screen->getRootWindow(),
171 client->rect.x(), client->rect.y());
172 XChangeSaveSet(display, client->window, SetModeDelete);
173 XSelectInput(display, frame.window, SubstructureRedirectMask |
174 ButtonPressMask | EnterWindowMask | LeaveWindowMask);
175 XUngrabServer(display);
176 }
177
178 delete client;
179 client = (SlitClient *) 0;
180 }
181
182
183 struct SlitClientMatch {
184 Window window;
185 SlitClientMatch(Window w): window(w) {}
186 inline bool operator()(const Slit::SlitClient* client) const {
187 return (client->window == window);
188 }
189 };
190
191
192 void Slit::removeClient(Window w, bool remap) {
193 SlitClientList::iterator it = clientList.begin();
194 const SlitClientList::iterator end = clientList.end();
195
196 it = std::find_if(it, end, SlitClientMatch(w));
197 if (it != end) {
198 removeClient(*it, remap);
199 reconfigure();
200 }
201 }
202
203
204 void Slit::saveOnTop(bool b) {
205 on_top = b;
206 config->setValue(slitstr + "onTop", on_top);
207 }
208
209 void Slit::saveAutoHide(bool b) {
210 do_auto_hide = b;
211 config->setValue(slitstr + "autoHide", do_auto_hide);
212 }
213
214 void Slit::savePlacement(int p) {
215 placement = p;
216 const char *pname;
217 switch (placement) {
218 case TopLeft: pname = "TopLeft"; break;
219 case CenterLeft: pname = "CenterLeft"; break;
220 case BottomLeft: pname = "BottomLeft"; break;
221 case TopCenter: pname = "TopCenter"; break;
222 case BottomCenter: pname = "BottomCenter"; break;
223 case TopRight: pname = "TopRight"; break;
224 case BottomRight: pname = "BottomRight"; break;
225 case CenterRight: default: pname = "CenterRight"; break;
226 }
227 config->setValue(slitstr + "placement", pname);
228 }
229
230 void Slit::saveDirection(int d) {
231 direction = d;
232 config->setValue(slitstr + "direction", (direction == Horizontal ?
233 "Horizontal" : "Vertical"));
234 }
235
236 void Slit::save_rc(void) {
237 saveOnTop(on_top);
238 saveAutoHide(do_auto_hide);
239 savePlacement(placement);
240 saveDirection(direction);
241 }
242
243 void Slit::load_rc(void) {
244 std::string s;
245
246 if (! config->getValue(slitstr + "onTop", on_top))
247 on_top = false;
248
249 if (! config->getValue(slitstr + "autoHide", do_auto_hide))
250 do_auto_hide = false;
251 hidden = do_auto_hide;
252
253 if (config->getValue(slitstr + "direction", s) && s == "Horizontal")
254 direction = Horizontal;
255 else
256 direction = Vertical;
257
258 if (config->getValue(slitstr + "placement", s)) {
259 if (s == "TopLeft")
260 placement = TopLeft;
261 else if (s == "CenterLeft")
262 placement = CenterLeft;
263 else if (s == "BottomLeft")
264 placement = BottomLeft;
265 else if (s == "TopCenter")
266 placement = TopCenter;
267 else if (s == "BottomCenter")
268 placement = BottomCenter;
269 else if (s == "TopRight")
270 placement = TopRight;
271 else if (s == "BottomRight")
272 placement = BottomRight;
273 else //if (s == "CenterRight")
274 placement = CenterRight;
275 } else
276 placement = CenterRight;
277 }
278
279
280 void Slit::reconfigure(void) {
281 SlitClientList::iterator it = clientList.begin();
282 const SlitClientList::iterator end = clientList.end();
283 SlitClient *client;
284
285 unsigned int width = 0, height = 0;
286
287 switch (direction) {
288 case Vertical:
289 for (; it != end; ++it) {
290 client = *it;
291 height += client->rect.height() + screen->getBevelWidth();
292
293 if (width < client->rect.width())
294 width = client->rect.width();
295 }
296
297 if (width < 1)
298 width = 1;
299 else
300 width += (screen->getBevelWidth() * 2);
301
302 if (height < 1)
303 height = 1;
304 else
305 height += screen->getBevelWidth();
306
307 break;
308
309 case Horizontal:
310 for (; it != end; ++it) {
311 client = *it;
312 width += client->rect.width() + screen->getBevelWidth();
313
314 if (height < client->rect.height())
315 height = client->rect.height();
316 }
317
318 if (width < 1)
319 width = 1;
320 else
321 width += screen->getBevelWidth();
322
323 if (height < 1)
324 height = 1;
325 else
326 height += (screen->getBevelWidth() * 2);
327
328 break;
329 }
330 frame.rect.setSize(width, height);
331
332 reposition();
333
334 XSetWindowBorderWidth(display ,frame.window, screen->getBorderWidth());
335 XSetWindowBorder(display, frame.window,
336 screen->getBorderColor()->pixel());
337
338 if (clientList.empty())
339 XUnmapWindow(display, frame.window);
340 else
341 XMapWindow(display, frame.window);
342
343 BTexture *texture = &(screen->getToolbarStyle()->toolbar);
344 frame.pixmap = texture->render(frame.rect.width(), frame.rect.height(),
345 frame.pixmap);
346 if (! frame.pixmap)
347 XSetWindowBackground(display, frame.window, texture->color().pixel());
348 else
349 XSetWindowBackgroundPixmap(display, frame.window, frame.pixmap);
350
351 XClearWindow(display, frame.window);
352
353 it = clientList.begin();
354
355 int x, y;
356
357 switch (direction) {
358 case Vertical:
359 x = 0;
360 y = screen->getBevelWidth();
361
362 for (; it != end; ++it) {
363 client = *it;
364 x = (frame.rect.width() - client->rect.width()) / 2;
365
366 XMoveResizeWindow(display, client->window, x, y,
367 client->rect.width(), client->rect.height());
368 XMapWindow(display, client->window);
369
370 // for ICCCM compliance
371 client->rect.setPos(x, y);
372
373 XEvent event;
374 event.type = ConfigureNotify;
375
376 event.xconfigure.display = display;
377 event.xconfigure.event = client->window;
378 event.xconfigure.window = client->window;
379 event.xconfigure.x = x;
380 event.xconfigure.y = y;
381 event.xconfigure.width = client->rect.width();
382 event.xconfigure.height = client->rect.height();
383 event.xconfigure.border_width = 0;
384 event.xconfigure.above = frame.window;
385 event.xconfigure.override_redirect = False;
386
387 XSendEvent(display, client->window, False, StructureNotifyMask, &event);
388
389 y += client->rect.height() + screen->getBevelWidth();
390 }
391
392 break;
393
394 case Horizontal:
395 x = screen->getBevelWidth();
396 y = 0;
397
398 for (; it != end; ++it) {
399 client = *it;
400 y = (frame.rect.height() - client->rect.height()) / 2;
401
402 XMoveResizeWindow(display, client->window, x, y,
403 client->rect.width(), client->rect.height());
404 XMapWindow(display, client->window);
405
406 // for ICCCM compliance
407 client->rect.setPos(x, y);
408
409 XEvent event;
410 event.type = ConfigureNotify;
411
412 event.xconfigure.display = display;
413 event.xconfigure.event = client->window;
414 event.xconfigure.window = client->window;
415 event.xconfigure.x = x;
416 event.xconfigure.y = y;
417 event.xconfigure.width = client->rect.width();
418 event.xconfigure.height = client->rect.height();
419 event.xconfigure.border_width = 0;
420 event.xconfigure.above = frame.window;
421 event.xconfigure.override_redirect = False;
422
423 XSendEvent(display, client->window, False, StructureNotifyMask, &event);
424
425 x += client->rect.width() + screen->getBevelWidth();
426 }
427 break;
428 }
429
430 slitmenu->reconfigure();
431 }
432
433
434 void Slit::updateStrut(void) {
435 strut.top = strut.bottom = strut.left = strut.right = 0;
436
437 if (! clientList.empty()) {
438 // when not hidden both borders are in use, when hidden only one is
439 unsigned int border_width = screen->getBorderWidth();
440 if (! do_auto_hide)
441 border_width *= 2;
442
443 switch (direction) {
444 case Vertical:
445 switch (placement) {
446 case TopCenter:
447 strut.top = getExposedHeight() + border_width;
448 break;
449 case BottomCenter:
450 strut.bottom = getExposedHeight() + border_width;
451 break;
452 case TopLeft:
453 case CenterLeft:
454 case BottomLeft:
455 strut.left = getExposedWidth() + border_width;
456 break;
457 case TopRight:
458 case CenterRight:
459 case BottomRight:
460 strut.right = getExposedWidth() + border_width;
461 break;
462 }
463 break;
464 case Horizontal:
465 switch (placement) {
466 case TopCenter:
467 case TopLeft:
468 case TopRight:
469 strut.top = getExposedHeight() + border_width;
470 break;
471 case BottomCenter:
472 case BottomLeft:
473 case BottomRight:
474 strut.bottom = getExposedHeight() + border_width;
475 break;
476 case CenterLeft:
477 strut.left = getExposedWidth() + border_width;
478 break;
479 case CenterRight:
480 strut.right = getExposedWidth() + border_width;
481 break;
482 }
483 break;
484 }
485 }
486
487 // update area with new Strut info
488 screen->updateAvailableArea();
489 }
490
491
492 void Slit::reposition(void) {
493 int x = 0, y = 0;
494
495 switch (placement) {
496 case TopLeft:
497 case CenterLeft:
498 case BottomLeft:
499 x = 0;
500 frame.x_hidden = screen->getBevelWidth() - screen->getBorderWidth()
501 - frame.rect.width();
502
503 if (placement == TopLeft)
504 y = 0;
505 else if (placement == CenterLeft)
506 y = (screen->getHeight() - frame.rect.height()) / 2;
507 else
508 y = screen->getHeight() - frame.rect.height()
509 - (screen->getBorderWidth() * 2);
510
511 break;
512
513 case TopCenter:
514 case BottomCenter:
515 x = (screen->getWidth() - frame.rect.width()) / 2;
516 frame.x_hidden = x;
517
518 if (placement == TopCenter)
519 y = 0;
520 else
521 y = screen->getHeight() - frame.rect.height()
522 - (screen->getBorderWidth() * 2);
523
524 break;
525
526 case TopRight:
527 case CenterRight:
528 case BottomRight:
529 x = screen->getWidth() - frame.rect.width()
530 - (screen->getBorderWidth() * 2);
531 frame.x_hidden = screen->getWidth() - screen->getBevelWidth()
532 - screen->getBorderWidth();
533
534 if (placement == TopRight)
535 y = 0;
536 else if (placement == CenterRight)
537 y = (screen->getHeight() - frame.rect.height()) / 2;
538 else
539 y = screen->getHeight() - frame.rect.height()
540 - (screen->getBorderWidth() * 2);
541 break;
542 }
543
544 frame.rect.setPos(x, y);
545
546 // we have to add the border to the rect as it is not accounted for
547 Rect tbar_rect = screen->getToolbar()->getRect();
548 tbar_rect.setSize(tbar_rect.width() + (screen->getBorderWidth() * 2),
549 tbar_rect.height() + (screen->getBorderWidth() * 2));
550 Rect slit_rect = frame.rect;
551 slit_rect.setSize(slit_rect.width() + (screen->getBorderWidth() * 2),
552 slit_rect.height() + (screen->getBorderWidth() * 2));
553
554 if (slit_rect.intersects(tbar_rect)) {
555 int delta = screen->getToolbar()->getExposedHeight() +
556 screen->getBorderWidth();
557 if (frame.rect.bottom() <= tbar_rect.bottom())
558 delta = -delta;
559
560 frame.rect.setY(frame.rect.y() + delta);
561 }
562
563 if (placement == TopCenter)
564 frame.y_hidden = 0 - frame.rect.height() + screen->getBorderWidth()
565 + screen->getBevelWidth();
566 else if (placement == BottomCenter)
567 frame.y_hidden = screen->getHeight() - screen->getBorderWidth()
568 - screen->getBevelWidth();
569 else
570 frame.y_hidden = frame.rect.y();
571
572 updateStrut();
573
574 if (hidden)
575 XMoveResizeWindow(display, frame.window,
576 frame.x_hidden, frame.y_hidden,
577 frame.rect.width(), frame.rect.height());
578 else
579 XMoveResizeWindow(display, frame.window,
580 frame.rect.x(), frame.rect.y(),
581 frame.rect.width(), frame.rect.height());
582 }
583
584
585 void Slit::shutdown(void) {
586 while (! clientList.empty())
587 removeClient(clientList.front());
588 }
589
590
591 void Slit::buttonPressEvent(const XButtonEvent *e) {
592 if (e->window != frame.window) return;
593
594 if (e->button == Button1 && (! on_top)) {
595 Window w[1] = { frame.window };
596 screen->raiseWindows(w, 1);
597 } else if (e->button == Button2 && (! on_top)) {
598 XLowerWindow(display, frame.window);
599 } else if (e->button == Button3) {
600 if (! slitmenu->isVisible()) {
601 int x, y;
602
603 x = e->x_root - (slitmenu->getWidth() / 2);
604 y = e->y_root - (slitmenu->getHeight() / 2);
605
606 if (x < 0)
607 x = 0;
608 else if (x + slitmenu->getWidth() > screen->getWidth())
609 x = screen->getWidth() - slitmenu->getWidth();
610
611 if (y < 0)
612 y = 0;
613 else if (y + slitmenu->getHeight() > screen->getHeight())
614 y = screen->getHeight() - slitmenu->getHeight();
615
616 slitmenu->move(x, y);
617 slitmenu->show();
618 } else {
619 slitmenu->hide();
620 }
621 }
622 }
623
624
625 void Slit::enterNotifyEvent(const XCrossingEvent *) {
626 if (! do_auto_hide)
627 return;
628
629 if (hidden) {
630 if (! timer->isTiming()) timer->start();
631 } else {
632 if (timer->isTiming()) timer->stop();
633 }
634 }
635
636
637 void Slit::leaveNotifyEvent(const XCrossingEvent *) {
638 if (! do_auto_hide)
639 return;
640
641 if (hidden) {
642 if (timer->isTiming()) timer->stop();
643 } else if (! slitmenu->isVisible()) {
644 if (! timer->isTiming()) timer->start();
645 }
646 }
647
648
649 void Slit::configureRequestEvent(const XConfigureRequestEvent *e) {
650 if (! blackbox->validateWindow(e->window))
651 return;
652
653 XWindowChanges xwc;
654
655 xwc.x = e->x;
656 xwc.y = e->y;
657 xwc.width = e->width;
658 xwc.height = e->height;
659 xwc.border_width = 0;
660 xwc.sibling = e->above;
661 xwc.stack_mode = e->detail;
662
663 XConfigureWindow(display, e->window, e->value_mask, &xwc);
664
665 SlitClientList::iterator it = clientList.begin();
666 const SlitClientList::iterator end = clientList.end();
667 for (; it != end; ++it) {
668 SlitClient *client = *it;
669 if (client->window == e->window &&
670 (static_cast<signed>(client->rect.width()) != e->width ||
671 static_cast<signed>(client->rect.height()) != e->height)) {
672 client->rect.setSize(e->width, e->height);
673
674 reconfigure();
675 return;
676 }
677 }
678 }
679
680
681 void Slit::timeout(void) {
682 hidden = ! hidden;
683 if (hidden)
684 XMoveWindow(display, frame.window, frame.x_hidden, frame.y_hidden);
685 else
686 XMoveWindow(display, frame.window, frame.rect.x(), frame.rect.y());
687 }
688
689
690 void Slit::toggleAutoHide(void) {
691 saveAutoHide(do_auto_hide ? False : True);
692
693 updateStrut();
694
695 if (do_auto_hide == False && hidden) {
696 // force the slit to be visible
697 if (timer->isTiming()) timer->stop();
698 timeout();
699 }
700 }
701
702
703 void Slit::unmapNotifyEvent(const XUnmapEvent *e) {
704 removeClient(e->window);
705 }
706
707
708 Slitmenu::Slitmenu(Slit *sl) : Basemenu(sl->screen) {
709 slit = sl;
710
711 setLabel(i18n(SlitSet, SlitSlitTitle, "Slit"));
712 setInternalMenu();
713
714 directionmenu = new Directionmenu(this);
715 placementmenu = new Placementmenu(this);
716
717 insert(i18n(CommonSet, CommonDirectionTitle, "Direction"),
718 directionmenu);
719 insert(i18n(CommonSet, CommonPlacementTitle, "Placement"),
720 placementmenu);
721 insert(i18n(CommonSet, CommonAlwaysOnTop, "Always on top"), 1);
722 insert(i18n(CommonSet, CommonAutoHide, "Auto hide"), 2);
723
724 update();
725
726 if (slit->isOnTop()) setItemSelected(2, True);
727 if (slit->doAutoHide()) setItemSelected(3, True);
728 }
729
730
731 Slitmenu::~Slitmenu(void) {
732 delete directionmenu;
733 delete placementmenu;
734 }
735
736
737 void Slitmenu::itemSelected(int button, unsigned int index) {
738 if (button != 1)
739 return;
740
741 BasemenuItem *item = find(index);
742 if (! item) return;
743
744 switch (item->function()) {
745 case 1: { // always on top
746 slit->saveOnTop(! slit->isOnTop());
747 setItemSelected(2, slit->isOnTop());
748
749 if (slit->isOnTop()) slit->screen->raiseWindows((Window *) 0, 0);
750 break;
751 }
752
753 case 2: { // auto hide
754 slit->toggleAutoHide();
755 setItemSelected(3, slit->doAutoHide());
756
757 break;
758 }
759 } // switch
760 }
761
762
763 void Slitmenu::internal_hide(void) {
764 Basemenu::internal_hide();
765 if (slit->doAutoHide())
766 slit->timeout();
767 }
768
769
770 void Slitmenu::reconfigure(void) {
771 directionmenu->reconfigure();
772 placementmenu->reconfigure();
773
774 Basemenu::reconfigure();
775 }
776
777
778 Slitmenu::Directionmenu::Directionmenu(Slitmenu *sm)
779 : Basemenu(sm->slit->screen), slit(sm->slit) {
780
781 setLabel(i18n(SlitSet, SlitSlitDirection, "Slit Direction"));
782 setInternalMenu();
783
784 insert(i18n(CommonSet, CommonDirectionHoriz, "Horizontal"),
785 Slit::Horizontal);
786 insert(i18n(CommonSet, CommonDirectionVert, "Vertical"),
787 Slit::Vertical);
788
789 update();
790 setValues();
791 }
792
793
794 void Slitmenu::Directionmenu::reconfigure(void) {
795 setValues();
796 Basemenu::reconfigure();
797 }
798
799
800 void Slitmenu::Directionmenu::setValues(void) {
801 const bool horiz = slit->getDirection() == Slit::Horizontal;
802 setItemSelected(0, horiz);
803 setItemSelected(1, ! horiz);
804 }
805
806
807 void Slitmenu::Directionmenu::itemSelected(int button, unsigned int index) {
808 if (button != 1)
809 return;
810
811 BasemenuItem *item = find(index);
812 if (! item) return;
813
814 slit->saveDirection(item->function());
815 hide();
816 slit->reconfigure();
817 }
818
819
820 Slitmenu::Placementmenu::Placementmenu(Slitmenu *sm)
821 : Basemenu(sm->slit->screen), slit(sm->slit) {
822
823 setLabel(i18n(SlitSet, SlitSlitPlacement, "Slit Placement"));
824 setMinimumSublevels(3);
825 setInternalMenu();
826
827 insert(i18n(CommonSet, CommonPlacementTopLeft, "Top Left"),
828 Slit::TopLeft);
829 insert(i18n(CommonSet, CommonPlacementCenterLeft, "Center Left"),
830 Slit::CenterLeft);
831 insert(i18n(CommonSet, CommonPlacementBottomLeft, "Bottom Left"),
832 Slit::BottomLeft);
833 insert(i18n(CommonSet, CommonPlacementTopCenter, "Top Center"),
834 Slit::TopCenter);
835 insert("");
836 insert(i18n(CommonSet, CommonPlacementBottomCenter, "Bottom Center"),
837 Slit::BottomCenter);
838 insert(i18n(CommonSet, CommonPlacementTopRight, "Top Right"),
839 Slit::TopRight);
840 insert(i18n(CommonSet, CommonPlacementCenterRight, "Center Right"),
841 Slit::CenterRight);
842 insert(i18n(CommonSet, CommonPlacementBottomRight, "Bottom Right"),
843 Slit::BottomRight);
844
845 update();
846
847 setValues();
848 }
849
850
851 void Slitmenu::Placementmenu::reconfigure(void) {
852 setValues();
853 Basemenu::reconfigure();
854 }
855
856
857 void Slitmenu::Placementmenu::setValues(void) {
858 int place = 0;
859 switch (slit->getPlacement()) {
860 case Slit::BottomRight:
861 place++;
862 case Slit::CenterRight:
863 place++;
864 case Slit::TopRight:
865 place++;
866 case Slit::BottomCenter:
867 place++;
868 case Slit::TopCenter:
869 place++;
870 case Slit::BottomLeft:
871 place++;
872 case Slit::CenterLeft:
873 place++;
874 case Slit::TopLeft:
875 break;
876 }
877 setItemSelected(0, 0 == place);
878 setItemSelected(1, 1 == place);
879 setItemSelected(2, 2 == place);
880 setItemSelected(3, 3 == place);
881 setItemSelected(5, 4 == place);
882 setItemSelected(6, 5 == place);
883 setItemSelected(7, 6 == place);
884 setItemSelected(8, 7 == place);
885 }
886
887
888 void Slitmenu::Placementmenu::itemSelected(int button, unsigned int index) {
889 if (button != 1)
890 return;
891
892 BasemenuItem *item = find(index);
893 if (! (item && item->function())) return;
894
895 slit->savePlacement(item->function());
896 hide();
897 slit->reconfigure();
898 }
899
This page took 0.072981 seconds and 4 git commands to generate.