diff options
Diffstat (limited to 'src/FbWinFrame.cc')
-rw-r--r-- | src/FbWinFrame.cc | 163 |
1 files changed, 104 insertions, 59 deletions
diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index 3bd9bfa..bfef355 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc | |||
@@ -19,16 +19,18 @@ | |||
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: FbWinFrame.cc,v 1.16 2003/04/09 17:20:01 rathnor Exp $ | 22 | // $Id: FbWinFrame.cc,v 1.17 2003/04/14 14:40:30 fluxgen Exp $ |
23 | 23 | ||
24 | #include "FbWinFrame.hh" | 24 | #include "FbWinFrame.hh" |
25 | #include "ImageControl.hh" | 25 | #include "ImageControl.hh" |
26 | #include "EventManager.hh" | 26 | #include "EventManager.hh" |
27 | #include "TextButton.hh" | ||
27 | #include "App.hh" | 28 | #include "App.hh" |
28 | #ifdef SHAPE | 29 | #ifdef SHAPE |
29 | //#include "Shape.hh" | 30 | //#include "Shape.hh" |
30 | #endif // SHAPE | 31 | #endif // SHAPE |
31 | 32 | ||
33 | #include <algorithm> | ||
32 | #include <iostream> | 34 | #include <iostream> |
33 | using namespace std; | 35 | using namespace std; |
34 | 36 | ||
@@ -63,17 +65,18 @@ FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl, | |||
63 | ButtonPressMask | ButtonReleaseMask | | 65 | ButtonPressMask | ButtonReleaseMask | |
64 | ButtonMotionMask | ExposureMask | | 66 | ButtonMotionMask | ExposureMask | |
65 | EnterWindowMask | LeaveWindowMask), | 67 | EnterWindowMask | LeaveWindowMask), |
66 | m_clientwin(0), | ||
67 | m_bevel(1), | 68 | m_bevel(1), |
68 | m_use_titlebar(true), | 69 | m_use_titlebar(true), |
69 | m_use_handle(true), | 70 | m_use_handle(true), |
70 | m_focused(false), | 71 | m_focused(false), |
71 | m_button_pm(0), | 72 | m_button_pm(0), |
72 | m_themelistener(*this) { | 73 | m_themelistener(*this) { |
74 | |||
73 | // m_shape(new Shape(m_window, 0)) { //Shape::TOPLEFT | Shape::TOPRIGHT)) { | 75 | // m_shape(new Shape(m_window, 0)) { //Shape::TOPLEFT | Shape::TOPRIGHT)) { |
74 | theme.addListener(m_themelistener); | 76 | theme.addListener(m_themelistener); |
75 | init(); | 77 | init(); |
76 | } | 78 | } |
79 | |||
77 | /* | 80 | /* |
78 | FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl, const FbTk::FbWindow &parent, int x, int y, | 81 | FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl, const FbTk::FbWindow &parent, int x, int y, |
79 | unsigned int width, unsigned int height): | 82 | unsigned int width, unsigned int height): |
@@ -88,7 +91,6 @@ FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl, | |||
88 | m_grip_left(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask), | 91 | m_grip_left(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask), |
89 | m_handle(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask), | 92 | m_handle(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask), |
90 | m_clientarea(m_window, 0, 0, 100, 100, SubstructureRedirectMask), | 93 | m_clientarea(m_window, 0, 0, 100, 100, SubstructureRedirectMask), |
91 | m_clientwin(0), | ||
92 | m_bevel(1), | 94 | m_bevel(1), |
93 | m_use_titlebar(true), | 95 | m_use_titlebar(true), |
94 | m_use_handles(true), | 96 | m_use_handles(true), |
@@ -101,7 +103,6 @@ FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl, | |||
101 | FbWinFrame::~FbWinFrame() { | 103 | FbWinFrame::~FbWinFrame() { |
102 | removeEventHandler(); | 104 | removeEventHandler(); |
103 | removeAllButtons(); | 105 | removeAllButtons(); |
104 | |||
105 | } | 106 | } |
106 | 107 | ||
107 | bool FbWinFrame::setOnClickTitlebar(FbTk::RefCount<FbTk::Command> &ref, int mousebutton_num, | 108 | bool FbWinFrame::setOnClickTitlebar(FbTk::RefCount<FbTk::Command> &ref, int mousebutton_num, |
@@ -215,7 +216,6 @@ void FbWinFrame::addLeftButton(FbTk::Button *btn) { | |||
215 | setupButton(*btn); // setup theme and other stuff | 216 | setupButton(*btn); // setup theme and other stuff |
216 | 217 | ||
217 | m_buttons_left.push_back(btn); | 218 | m_buttons_left.push_back(btn); |
218 | reconfigureTitlebar(); | ||
219 | } | 219 | } |
220 | 220 | ||
221 | void FbWinFrame::addRightButton(FbTk::Button *btn) { | 221 | void FbWinFrame::addRightButton(FbTk::Button *btn) { |
@@ -225,7 +225,6 @@ void FbWinFrame::addRightButton(FbTk::Button *btn) { | |||
225 | setupButton(*btn); // setup theme and other stuff | 225 | setupButton(*btn); // setup theme and other stuff |
226 | 226 | ||
227 | m_buttons_right.push_back(btn); | 227 | m_buttons_right.push_back(btn); |
228 | reconfigureTitlebar(); | ||
229 | } | 228 | } |
230 | 229 | ||
231 | void FbWinFrame::removeAllButtons() { | 230 | void FbWinFrame::removeAllButtons() { |
@@ -239,21 +238,44 @@ void FbWinFrame::removeAllButtons() { | |||
239 | delete m_buttons_right.back(); | 238 | delete m_buttons_right.back(); |
240 | m_buttons_right.pop_back(); | 239 | m_buttons_right.pop_back(); |
241 | } | 240 | } |
241 | } | ||
242 | 242 | ||
243 | // update titlebar | 243 | void FbWinFrame::addLabelButton(FbTk::Button &btn) { |
244 | reconfigureTitlebar(); | 244 | ButtonList::iterator found_it = find(m_labelbuttons.begin(), |
245 | m_labelbuttons.end(), | ||
246 | &btn); | ||
247 | |||
248 | if (found_it != m_labelbuttons.end()) | ||
249 | return; | ||
250 | |||
251 | m_labelbuttons.push_back(&btn); | ||
252 | } | ||
253 | |||
254 | void FbWinFrame::removeLabelButton(FbTk::Button &btn) { | ||
255 | ButtonList::iterator erase_it = remove(m_labelbuttons.begin(), | ||
256 | m_labelbuttons.end(), | ||
257 | &btn); | ||
258 | if (erase_it == m_labelbuttons.end()) | ||
259 | return; | ||
260 | |||
261 | m_labelbuttons.erase(erase_it); | ||
262 | } | ||
263 | |||
264 | void FbWinFrame::setClientWindow(FbTk::FbWindow &win) { | ||
265 | setClientWindow(win.window()); | ||
245 | } | 266 | } |
246 | 267 | ||
247 | void FbWinFrame::setClientWindow(Window win) { | 268 | void FbWinFrame::setClientWindow(Window win) { |
248 | m_clientwin = win; | ||
249 | Display *display = FbTk::App::instance()->display(); | 269 | Display *display = FbTk::App::instance()->display(); |
250 | XSetWindowBorderWidth(display, win, 0); | 270 | XSetWindowBorderWidth(display, win, 0); |
251 | 271 | ||
252 | XChangeSaveSet(display, win, SetModeInsert); | 272 | XChangeSaveSet(display, win, SetModeInsert); |
253 | XSetWindowAttributes attrib_set; | 273 | XSetWindowAttributes attrib_set; |
254 | // no events for client window while we reparent it | 274 | // sync old events so we can discard events from reparent later |
255 | XSelectInput(display, m_clientarea.window(), NoEventMask); | 275 | XSync(display, False); |
256 | XReparentWindow(display, win, m_clientarea.window(), 0, 0); | 276 | XReparentWindow(display, win, m_clientarea.window(), 0, 0); |
277 | XSync(display, True); // discard unmap notify event | ||
278 | // redirected events from client window | ||
257 | XSelectInput(display, m_clientarea.window(), SubstructureRedirectMask); | 279 | XSelectInput(display, m_clientarea.window(), SubstructureRedirectMask); |
258 | 280 | ||
259 | XFlush(display); | 281 | XFlush(display); |
@@ -268,10 +290,6 @@ void FbWinFrame::setClientWindow(Window win) { | |||
268 | 290 | ||
269 | } | 291 | } |
270 | 292 | ||
271 | void FbWinFrame::removeClient() { | ||
272 | m_clientwin = 0; | ||
273 | } | ||
274 | |||
275 | void FbWinFrame::hideTitlebar() { | 293 | void FbWinFrame::hideTitlebar() { |
276 | if (!m_use_titlebar) | 294 | if (!m_use_titlebar) |
277 | return; | 295 | return; |
@@ -373,10 +391,16 @@ void FbWinFrame::removeEventHandler() { | |||
373 | } | 391 | } |
374 | 392 | ||
375 | void FbWinFrame::buttonPressEvent(XButtonEvent &event) { | 393 | void FbWinFrame::buttonPressEvent(XButtonEvent &event) { |
376 | if (event.window != m_titlebar.window() && | 394 | // we can ignore which window the event was generated for |
377 | event.window != m_label.window()) | 395 | ButtonList::iterator btn_it = m_labelbuttons.begin(); |
378 | return; | 396 | ButtonList::iterator btn_it_end = m_labelbuttons.end(); |
379 | 397 | for (; btn_it != btn_it_end; ++btn_it) { | |
398 | if ((*btn_it)->window() == event.window) { | ||
399 | (*btn_it)->buttonPressEvent(event); | ||
400 | break; | ||
401 | } | ||
402 | } | ||
403 | |||
380 | if (event.button > 5 || event.button < 1) | 404 | if (event.button > 5 || event.button < 1) |
381 | return; | 405 | return; |
382 | 406 | ||
@@ -385,11 +409,19 @@ void FbWinFrame::buttonPressEvent(XButtonEvent &event) { | |||
385 | } | 409 | } |
386 | 410 | ||
387 | void FbWinFrame::buttonReleaseEvent(XButtonEvent &event) { | 411 | void FbWinFrame::buttonReleaseEvent(XButtonEvent &event) { |
388 | if (event.window != m_titlebar.window() && | 412 | // we can ignore which window the event was generated for |
389 | event.window != m_label.window()) | 413 | |
390 | return; | 414 | ButtonList::iterator btn_it = m_labelbuttons.begin(); |
415 | ButtonList::iterator btn_it_end = m_labelbuttons.end(); | ||
416 | for (; btn_it != btn_it_end; ++btn_it) { | ||
417 | if ((*btn_it)->window() == event.window) { | ||
418 | (*btn_it)->buttonReleaseEvent(event); | ||
419 | break; | ||
420 | } | ||
421 | } | ||
391 | 422 | ||
392 | if (event.button < 1 || event.button > 5) | 423 | if (event.button < 1 || event.button > 5 || |
424 | event.window == m_clientarea.window()) | ||
393 | return; | 425 | return; |
394 | 426 | ||
395 | static int last_release_time = 0; | 427 | static int last_release_time = 0; |
@@ -405,14 +437,15 @@ void FbWinFrame::buttonReleaseEvent(XButtonEvent &event) { | |||
405 | } | 437 | } |
406 | 438 | ||
407 | void FbWinFrame::exposeEvent(XExposeEvent &event) { | 439 | void FbWinFrame::exposeEvent(XExposeEvent &event) { |
408 | if (m_titlebar == event.window) | 440 | if (m_label == event.window) |
409 | redrawTitlebar(); | ||
410 | else if (m_label == event.window) | ||
411 | redrawTitle(); | 441 | redrawTitle(); |
412 | else if (m_handle == event.window || | 442 | else if (m_handle == event.window || |
413 | m_grip_left == event.window || | 443 | m_grip_left == event.window || |
414 | m_grip_right == event.window) | 444 | m_grip_right == event.window) |
415 | renderHandles(); | 445 | renderHandles(); |
446 | else | ||
447 | redrawTitlebar(); | ||
448 | |||
416 | } | 449 | } |
417 | 450 | ||
418 | void FbWinFrame::handleEvent(XEvent &event) { | 451 | void FbWinFrame::handleEvent(XEvent &event) { |
@@ -433,6 +466,7 @@ void FbWinFrame::reconfigure() { | |||
433 | if (m_use_titlebar) | 466 | if (m_use_titlebar) |
434 | reconfigureTitlebar(); | 467 | reconfigureTitlebar(); |
435 | 468 | ||
469 | |||
436 | // leave client+grips alone if we're shaded (it'll get fixed when we unshade) | 470 | // leave client+grips alone if we're shaded (it'll get fixed when we unshade) |
437 | if (!m_shaded) { | 471 | if (!m_shaded) { |
438 | int client_top = 0; | 472 | int client_top = 0; |
@@ -451,12 +485,6 @@ void FbWinFrame::reconfigure() { | |||
451 | m_clientarea.moveResize(0, client_top, | 485 | m_clientarea.moveResize(0, client_top, |
452 | m_window.width(), client_height); | 486 | m_window.width(), client_height); |
453 | 487 | ||
454 | if (m_clientwin != 0) { | ||
455 | XMoveResizeWindow(FbTk::App::instance()->display(), m_clientwin, | ||
456 | 0, 0, | ||
457 | m_clientarea.width(), m_clientarea.height()); | ||
458 | } | ||
459 | |||
460 | 488 | ||
461 | if (!m_use_handle) // no need to do anything more | 489 | if (!m_use_handle) // no need to do anything more |
462 | return; | 490 | return; |
@@ -471,7 +499,8 @@ void FbWinFrame::reconfigure() { | |||
471 | grip_width, grip_height); | 499 | grip_width, grip_height); |
472 | 500 | ||
473 | m_handle.moveResize(grip_width, ypos, | 501 | m_handle.moveResize(grip_width, ypos, |
474 | m_window.width() - grip_width*2 - m_handle.borderWidth()*2, grip_height); | 502 | m_window.width() - grip_width*2 - m_handle.borderWidth()*2, |
503 | grip_height); | ||
475 | 504 | ||
476 | m_grip_right.moveResize(m_window.width() - grip_width - m_handle.borderWidth(), ypos, | 505 | m_grip_right.moveResize(m_window.width() - grip_width - m_handle.borderWidth(), ypos, |
477 | grip_width, grip_height); | 506 | grip_width, grip_height); |
@@ -500,24 +529,22 @@ unsigned int FbWinFrame::buttonHeight() const { | |||
500 | aligns and redraws title | 529 | aligns and redraws title |
501 | */ | 530 | */ |
502 | void FbWinFrame::redrawTitle() { | 531 | void FbWinFrame::redrawTitle() { |
503 | GC gc = m_theme.labelTextFocusGC(); | 532 | if (m_labelbuttons.size() == 0) |
504 | m_label.clear(); // clear window | 533 | return; |
505 | unsigned int textlen = m_titletext.size(); | 534 | |
506 | const FbTk::Font &font = m_theme.font(); | 535 | int button_width = label().width()/m_labelbuttons.size(); |
507 | // do text alignment | 536 | //!! TODO: bevel |
508 | int align_x = FbTk::doAlignment(m_label.width(), | 537 | ButtonList::iterator btn_it = m_labelbuttons.begin(); |
509 | m_bevel, | 538 | ButtonList::iterator btn_it_end = m_labelbuttons.end(); |
510 | m_theme.justify(), | 539 | for (unsigned int last_x = 0; |
511 | font, | 540 | btn_it != btn_it_end; |
512 | m_titletext.c_str(), m_titletext.size(), | 541 | ++btn_it, last_x += button_width) { |
513 | textlen // return new text len | 542 | (*btn_it)->moveResize(last_x, 0, |
514 | ); | 543 | button_width, label().height()); |
515 | 544 | (*btn_it)->setGC(theme().labelTextFocusGC()); | |
516 | font.drawText(m_label.window(), // drawable | 545 | (*btn_it)->clear(); |
517 | m_window.screenNumber(), | 546 | } |
518 | gc, // graphic context | 547 | |
519 | m_titletext.c_str(), textlen, // string and string size | ||
520 | align_x, font.ascent());// position | ||
521 | } | 548 | } |
522 | 549 | ||
523 | void FbWinFrame::redrawTitlebar() { | 550 | void FbWinFrame::redrawTitlebar() { |
@@ -549,7 +576,7 @@ void FbWinFrame::reconfigureTitlebar() { | |||
549 | m_buttons_left[i]->moveResize(next_x, m_bevel, | 576 | m_buttons_left[i]->moveResize(next_x, m_bevel, |
550 | button_size, button_size); | 577 | button_size, button_size); |
551 | } | 578 | } |
552 | 579 | ||
553 | next_x += m_bevel; | 580 | next_x += m_bevel; |
554 | 581 | ||
555 | // space left on titlebar between left and right buttons | 582 | // space left on titlebar between left and right buttons |
@@ -600,23 +627,32 @@ void FbWinFrame::renderTitlebar() { | |||
600 | m_label.width(), m_label.height()); | 627 | m_label.width(), m_label.height()); |
601 | 628 | ||
602 | // finaly set up pixmaps for titlebar windows | 629 | // finaly set up pixmaps for titlebar windows |
603 | 630 | Pixmap labelpm = None; | |
631 | FbTk::Color labelcolor; | ||
632 | |||
604 | if (m_focused) { | 633 | if (m_focused) { |
605 | if (m_label_focused_pm != 0) | 634 | if (m_label_focused_pm != 0){ |
635 | labelpm = m_label_focused_pm; | ||
606 | m_label.setBackgroundPixmap(m_label_focused_pm); | 636 | m_label.setBackgroundPixmap(m_label_focused_pm); |
607 | else | 637 | } else { |
638 | labelcolor = m_label_focused_color; | ||
608 | m_label.setBackgroundColor(m_label_focused_color); | 639 | m_label.setBackgroundColor(m_label_focused_color); |
609 | 640 | } | |
641 | |||
610 | if (m_title_focused_pm != 0) | 642 | if (m_title_focused_pm != 0) |
611 | m_titlebar.setBackgroundPixmap(m_title_focused_pm); | 643 | m_titlebar.setBackgroundPixmap(m_title_focused_pm); |
612 | else | 644 | else |
613 | m_titlebar.setBackgroundColor(m_title_focused_color); | 645 | m_titlebar.setBackgroundColor(m_title_focused_color); |
614 | 646 | ||
615 | } else { | 647 | } else { |
616 | if (m_label_unfocused_pm != 0) | 648 | if (m_label_unfocused_pm != 0) { |
649 | labelpm = m_label_unfocused_pm; | ||
617 | m_label.setBackgroundPixmap(m_label_unfocused_pm); | 650 | m_label.setBackgroundPixmap(m_label_unfocused_pm); |
618 | else | 651 | } else { |
652 | labelcolor = m_label_unfocused_color; | ||
619 | m_label.setBackgroundColor(m_label_unfocused_color); | 653 | m_label.setBackgroundColor(m_label_unfocused_color); |
654 | } | ||
655 | |||
620 | 656 | ||
621 | if (m_title_unfocused_pm != 0) | 657 | if (m_title_unfocused_pm != 0) |
622 | m_titlebar.setBackgroundPixmap(m_title_unfocused_pm); | 658 | m_titlebar.setBackgroundPixmap(m_title_unfocused_pm); |
@@ -625,6 +661,15 @@ void FbWinFrame::renderTitlebar() { | |||
625 | 661 | ||
626 | } | 662 | } |
627 | 663 | ||
664 | ButtonList::iterator btn_it = m_labelbuttons.begin(); | ||
665 | ButtonList::iterator btn_it_end = m_labelbuttons.end(); | ||
666 | for (; btn_it != btn_it_end; ++btn_it) { | ||
667 | if (labelpm) | ||
668 | (*btn_it)->setBackgroundPixmap(labelpm); | ||
669 | else | ||
670 | (*btn_it)->setBackgroundColor(labelcolor); | ||
671 | } | ||
672 | |||
628 | redrawTitle(); | 673 | redrawTitle(); |
629 | } | 674 | } |
630 | 675 | ||