diff options
author | fluxgen <fluxgen> | 2004-06-07 20:28:50 (GMT) |
---|---|---|
committer | fluxgen <fluxgen> | 2004-06-07 20:28:50 (GMT) |
commit | 34edd2640a35cb825a647e8d37db6cbc8e6afea1 (patch) | |
tree | 4845b4d0353b5d9a4d7bd1d2f4a5a8c30a3bb824 /src/FbTk/Menu.cc | |
parent | 5530ce6450d0d96f504d000a0cfe4fb29c6c323c (diff) | |
download | fluxbox_pavel-34edd2640a35cb825a647e8d37db6cbc8e6afea1.zip fluxbox_pavel-34edd2640a35cb825a647e8d37db6cbc8e6afea1.tar.bz2 |
improved transparent rendering and fixed drawing of menu items in MenuItem class
Diffstat (limited to 'src/FbTk/Menu.cc')
-rw-r--r-- | src/FbTk/Menu.cc | 512 |
1 files changed, 268 insertions, 244 deletions
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc index 8736edf..f0e5c59 100644 --- a/src/FbTk/Menu.cc +++ b/src/FbTk/Menu.cc | |||
@@ -1,5 +1,5 @@ | |||
1 | // Menu.cc for FbTk - Fluxbox Toolkit | 1 | // Menu.cc for FbTk - Fluxbox Toolkit |
2 | // Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) | 2 | // Copyright (c) 2001 - 2004 Henrik Kinnunen (fluxgen at users.sourceforge.net) |
3 | // | 3 | // |
4 | // Basemenu.cc for blackbox - an X11 Window manager | 4 | // Basemenu.cc for blackbox - an X11 Window manager |
5 | // Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) | 5 | // Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net) |
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Menu.cc,v 1.61 2004/06/07 11:46:05 rathnor Exp $ | 25 | // $Id: Menu.cc,v 1.62 2004/06/07 20:28:50 fluxgen Exp $ |
26 | 26 | ||
27 | //use GNU extensions | 27 | //use GNU extensions |
28 | #ifndef _GNU_SOURCE | 28 | #ifndef _GNU_SOURCE |
@@ -31,6 +31,10 @@ | |||
31 | 31 | ||
32 | #include "Menu.hh" | 32 | #include "Menu.hh" |
33 | 33 | ||
34 | #ifdef HAVE_CONFIG_H | ||
35 | #include "config.h" | ||
36 | #endif //HAVE_CONFIG_H | ||
37 | |||
34 | #include "MenuItem.hh" | 38 | #include "MenuItem.hh" |
35 | #include "ImageControl.hh" | 39 | #include "ImageControl.hh" |
36 | #include "MenuTheme.hh" | 40 | #include "MenuTheme.hh" |
@@ -56,6 +60,28 @@ static Menu *shown = 0; | |||
56 | 60 | ||
57 | Menu *Menu::s_focused = 0; | 61 | Menu *Menu::s_focused = 0; |
58 | 62 | ||
63 | static Pixmap getRootPixmap(int screen_num) { | ||
64 | Pixmap root_pm = 0; | ||
65 | // get root pixmap for transparency | ||
66 | Display *disp = FbTk::App::instance()->display(); | ||
67 | Atom real_type; | ||
68 | int real_format; | ||
69 | unsigned long items_read, items_left; | ||
70 | unsigned int *data; | ||
71 | if (XGetWindowProperty(disp, RootWindow(disp, screen_num), | ||
72 | XInternAtom(disp, "_XROOTPMAP_ID", false), | ||
73 | 0L, 1L, | ||
74 | false, XA_PIXMAP, &real_type, | ||
75 | &real_format, &items_read, &items_left, | ||
76 | (unsigned char **) &data) == Success && | ||
77 | items_read) { | ||
78 | root_pm = (Pixmap) (*data); | ||
79 | XFree(data); | ||
80 | } | ||
81 | |||
82 | return root_pm; | ||
83 | } | ||
84 | |||
59 | Menu::Menu(MenuTheme &tm, ImageControl &imgctrl): | 85 | Menu::Menu(MenuTheme &tm, ImageControl &imgctrl): |
60 | m_theme(tm), | 86 | m_theme(tm), |
61 | m_parent(0), | 87 | m_parent(0), |
@@ -135,23 +161,30 @@ Menu::Menu(MenuTheme &tm, ImageControl &imgctrl): | |||
135 | 161 | ||
136 | event_mask |= EnterWindowMask | LeaveWindowMask; | 162 | event_mask |= EnterWindowMask | LeaveWindowMask; |
137 | //create menu title | 163 | //create menu title |
138 | menu.title = FbTk::FbWindow(menu.window, | 164 | menu.title = FbTk::FbWindow(menu.window, // parent |
139 | 0, 0, width(), menu.title_h, | 165 | 0, 0, width(), menu.title_h, // pos and size |
140 | event_mask); | 166 | event_mask, // mask |
167 | false, // override redirect | ||
168 | true); // save under | ||
141 | 169 | ||
142 | evm.add(*this, menu.title); | 170 | evm.add(*this, menu.title); |
143 | 171 | ||
144 | event_mask |= PointerMotionMask; | 172 | event_mask |= PointerMotionMask; |
145 | menu.frame = FbTk::FbWindow(menu.window, | 173 | menu.frame = FbTk::FbWindow(menu.window, // parent |
146 | 0, menu.title_h, | 174 | 0, menu.title_h, // pos |
147 | width(), menu.frame_h ? menu.frame_h : 1, | 175 | width(), menu.frame_h ? menu.frame_h : 1, // size |
148 | event_mask, false, true); | 176 | event_mask, // mask |
177 | false, // override redirect | ||
178 | true); // save under | ||
149 | evm.add(*this, menu.frame); | 179 | evm.add(*this, menu.frame); |
180 | |||
181 | |||
150 | // update style | 182 | // update style |
151 | reconfigure(); | 183 | // reconfigure(); |
152 | } | 184 | } |
153 | 185 | ||
154 | Menu::~Menu() { | 186 | Menu::~Menu() { |
187 | |||
155 | menu.window.hide(); | 188 | menu.window.hide(); |
156 | 189 | ||
157 | if (shown && shown->window() == window()) | 190 | if (shown && shown->window() == window()) |
@@ -361,35 +394,34 @@ void Menu::update(int active_index) { | |||
361 | if (m_border_width > 20) | 394 | if (m_border_width > 20) |
362 | m_border_width = 20; | 395 | m_border_width = 20; |
363 | 396 | ||
364 | menu.item_h = m_theme.frameFont().height() + menu.bevel_w; | 397 | if (theme().titleHeight() != 0) |
365 | menu.title_h = m_theme.titleFont().height() + menu.bevel_w*2; | 398 | menu.title_h = std::max(theme().titleHeight(), theme().titleFont().height() + menu.bevel_w*2); |
399 | else | ||
400 | menu.title_h = theme().titleFont().height() + menu.bevel_w*2; | ||
401 | |||
402 | if (theme().itemHeight() != 0) | ||
403 | menu.item_h = std::max(theme().itemHeight(), theme().frameFont().height() + menu.bevel_w); | ||
404 | else | ||
405 | menu.item_h = theme().frameFont().height() + menu.bevel_w; | ||
406 | |||
366 | 407 | ||
367 | if (title_vis) { | 408 | if (title_vis) { |
368 | menu.item_w = m_theme.titleFont().textWidth(menu.label.c_str(), | 409 | menu.item_w = theme().titleFont().textWidth(menu.label.c_str(), |
369 | menu.label.size()); | 410 | menu.label.size()); |
370 | 411 | ||
371 | menu.item_w += (menu.bevel_w * 2); | 412 | menu.item_w += (menu.bevel_w * 2); |
372 | } else | 413 | } else |
373 | menu.item_w = 1; | 414 | menu.item_w = 1; |
374 | 415 | ||
375 | int ii = 0; | 416 | unsigned int ii = 0; |
376 | Menuitems::iterator it = menuitems.begin(); | 417 | Menuitems::iterator it = menuitems.begin(); |
377 | Menuitems::iterator it_end = menuitems.end(); | 418 | Menuitems::iterator it_end = menuitems.end(); |
378 | for (; it != it_end; ++it) { | 419 | for (; it != it_end; ++it) { |
379 | MenuItem *itmp = (*it); | 420 | ii = (*it)->width(theme()); |
380 | 421 | menu.item_w = (ii > menu.item_w ? ii : menu.item_w); | |
381 | const char *s = itmp->label().c_str(); | ||
382 | int l = itmp->label().size(); | ||
383 | |||
384 | ii = m_theme.frameFont().textWidth(s, l); | ||
385 | |||
386 | |||
387 | ii += (menu.bevel_w * 2) + (menu.item_h * 2); | ||
388 | |||
389 | menu.item_w = ((menu.item_w < (unsigned int) ii) ? ii : menu.item_w); | ||
390 | } | 422 | } |
391 | 423 | ||
392 | if (menuitems.size()) { | 424 | if (!menuitems.empty()) { |
393 | menu.sublevels = 1; | 425 | menu.sublevels = 1; |
394 | 426 | ||
395 | while (menu.item_h * (menuitems.size() + 1) / menu.sublevels + | 427 | while (menu.item_h * (menuitems.size() + 1) / menu.sublevels + |
@@ -425,10 +457,10 @@ void Menu::update(int active_index) { | |||
425 | 457 | ||
426 | menu.window.resize(new_width, new_height); | 458 | menu.window.resize(new_width, new_height); |
427 | 459 | ||
428 | Pixmap tmp; | 460 | Pixmap tmp = 0; |
429 | if (title_vis) { | 461 | if (title_vis && m_need_update) { |
430 | tmp = menu.title_pixmap; | 462 | tmp = menu.title_pixmap; |
431 | const FbTk::Texture &tex = m_theme.titleTexture(); | 463 | const FbTk::Texture &tex = theme().titleTexture(); |
432 | if (!tex.usePixmap()) { | 464 | if (!tex.usePixmap()) { |
433 | menu.title_pixmap = None; | 465 | menu.title_pixmap = None; |
434 | menu.title.setBackgroundColor(tex.color()); | 466 | menu.title.setBackgroundColor(tex.color()); |
@@ -444,19 +476,21 @@ void Menu::update(int active_index) { | |||
444 | } | 476 | } |
445 | 477 | ||
446 | tmp = menu.frame_pixmap; | 478 | tmp = menu.frame_pixmap; |
447 | const FbTk::Texture &frame_tex = m_theme.frameTexture(); | 479 | const FbTk::Texture &frame_tex = theme().frameTexture(); |
448 | if (!frame_tex.usePixmap()) { | 480 | if (m_need_update) { |
449 | menu.frame_pixmap = None; | 481 | if (!frame_tex.usePixmap()) { |
450 | } else { | 482 | menu.frame_pixmap = None; |
451 | menu.frame_pixmap = | 483 | } else { |
452 | m_image_ctrl.renderImage(width(), menu.frame_h, frame_tex); | 484 | menu.frame_pixmap = |
453 | } | 485 | m_image_ctrl.renderImage(width(), menu.frame_h, frame_tex); |
486 | } | ||
454 | 487 | ||
455 | if (tmp) | 488 | if (tmp) |
456 | m_image_ctrl.removeImage(tmp); | 489 | m_image_ctrl.removeImage(tmp); |
457 | 490 | ||
491 | } | ||
458 | tmp = menu.hilite_pixmap; | 492 | tmp = menu.hilite_pixmap; |
459 | const FbTk::Texture &hilite_tex = m_theme.hiliteTexture(); | 493 | const FbTk::Texture &hilite_tex = theme().hiliteTexture(); |
460 | if (!hilite_tex.usePixmap()) { | 494 | if (!hilite_tex.usePixmap()) { |
461 | menu.hilite_pixmap = None; | 495 | menu.hilite_pixmap = None; |
462 | } else | 496 | } else |
@@ -495,62 +529,86 @@ void Menu::update(int active_index) { | |||
495 | menu.frame.width(), menu.frame.height(), | 529 | menu.frame.width(), menu.frame.height(), |
496 | menu.frame.depth()); | 530 | menu.frame.depth()); |
497 | 531 | ||
532 | m_real_frame_pm = FbTk::FbPixmap(menu.frame.window(), | ||
533 | menu.frame.width(), menu.frame.height(), | ||
534 | menu.frame.depth()); | ||
535 | |||
536 | menu.frame.setBackgroundPixmap(m_real_frame_pm.drawable()); | ||
498 | if (m_frame_pm.drawable() == 0) { | 537 | if (m_frame_pm.drawable() == 0) { |
499 | _FB_USES_NLS; | 538 | _FB_USES_NLS; |
500 | cerr<<"FbTk::Menu: "<<_FBTKTEXT(Error, CreatePixmap, "Error creating pixmap", "Couldn't create a pixmap - image - for some reason")<<" ("<< | 539 | cerr<<"FbTk::Menu: "<<_FBTKTEXT(Error, CreatePixmap, "Error creating pixmap", "Couldn't create a pixmap - image - for some reason")<<" ("<< |
501 | menu.frame.window()<<", "<<menu.frame.width()<<", "<< | 540 | menu.frame.window()<<", "<<menu.frame.width()<<", "<< |
502 | menu.frame.height()<< | 541 | menu.frame.height()<< |
503 | ", "<<menu.frame.depth()<<") !"<<endl; | 542 | ", "<<menu.frame.depth()<<") !"<<endl; |
504 | } else if (menu.sublevels > 0 && menu.persub * menu.sublevels != menuitems.size()) { | 543 | } else if (menu.sublevels > 0 && menu.persub * menu.sublevels != (int)menuitems.size()) { |
505 | 544 | ||
506 | // TODO: fill only that part of the menuframe with the | 545 | // TODO: fill only that part of the menuframe with the |
507 | // pixmap/color, that has actually NO buttons on it | 546 | // pixmap/color, that has actually NO buttons on it |
508 | FbTk::GContext def_gc(menu.frame.window()); | 547 | GContext def_gc(menu.frame); |
509 | if (menu.frame_pixmap == 0) { | 548 | if (menu.frame_pixmap == 0) { |
510 | def_gc.setForeground(m_theme.frameTexture().color()); | 549 | def_gc.setForeground(m_theme.frameTexture().color()); |
511 | m_frame_pm.fillRectangle(def_gc.gc(), | 550 | m_frame_pm.fillRectangle(def_gc.gc(), |
512 | 0, 0, | 551 | 0, 0, |
513 | width(), menu.frame_h); | 552 | width(), menu.frame_h); |
514 | 553 | m_real_frame_pm.fillRectangle(def_gc.gc(), | |
554 | 0, 0, | ||
555 | width(), menu.frame_h); | ||
515 | } else { | 556 | } else { |
516 | m_frame_pm.copyArea(menu.frame_pixmap, def_gc.gc(), | 557 | m_frame_pm.copyArea(menu.frame_pixmap, def_gc.gc(), |
517 | 0, 0, | 558 | 0, 0, |
518 | 0, 0, | 559 | 0, 0, |
519 | width(), menu.frame_h); | 560 | width(), menu.frame_h); |
561 | |||
562 | m_real_frame_pm.copyArea(menu.frame_pixmap, | ||
563 | def_gc.gc(), | ||
564 | 0, 0, | ||
565 | 0, 0, | ||
566 | width(), menu.frame_h); | ||
520 | } | 567 | } |
568 | |||
521 | } | 569 | } |
570 | |||
522 | } | 571 | } |
523 | 572 | ||
524 | menu.frame.setBackgroundPixmap(m_frame_pm.drawable()); | 573 | // if menu visible and title visible |
525 | |||
526 | // clearWindow(); | ||
527 | |||
528 | if (title_vis && visible) | 574 | if (title_vis && visible) |
529 | redrawTitle(); | 575 | redrawTitle(); |
530 | 576 | ||
531 | if (active_index >= 0) { | 577 | if (active_index >= 0 && visible) { |
532 | for (unsigned int i = 0; visible && i < menuitems.size(); i++) { | 578 | renderTransp(0, 0, |
579 | m_real_frame_pm.width(), m_real_frame_pm.height()); | ||
580 | for (unsigned int i = 0; i < menuitems.size(); i++) { | ||
533 | if (i == (unsigned int)which_sub) { | 581 | if (i == (unsigned int)which_sub) { |
534 | drawItem(i, true, true, false); | 582 | drawItem(i, true, // highlight |
583 | true, // clear | ||
584 | false); // render_trans | ||
535 | } else | 585 | } else |
536 | drawItem(i, (static_cast<signed>(i) == active_index && isItemEnabled(i)), true, false); | 586 | drawItem(i, |
587 | // high light | ||
588 | (static_cast<signed>(i) == active_index && isItemEnabled(i)), | ||
589 | true, // clear | ||
590 | false); // render transparent | ||
537 | } | 591 | } |
538 | 592 | ||
539 | if (m_parent && visible) | 593 | if (m_parent) |
540 | m_parent->drawSubmenu(m_parent->which_sub); | 594 | m_parent->drawSubmenu(m_parent->which_sub); |
595 | /* | ||
596 | renderTransp(0, active_index*menu.item_h, | ||
597 | width(), menu.item_h); | ||
598 | */ | ||
541 | 599 | ||
542 | menu.frame.clearArea(0, active_index * menu.item_h, | 600 | } |
543 | width(), menu.item_h); | ||
544 | menu.frame.updateTransparent(0, active_index * menu.item_h, | ||
545 | width(), menu.item_h); | ||
546 | 601 | ||
602 | if (m_need_update) { | ||
603 | for (unsigned int i = 0; i < menuitems.size(); i++) { | ||
604 | if (i == (unsigned int)which_sub) { | ||
605 | drawItem(i, true, true, false); | ||
606 | } else | ||
607 | drawItem(i, (static_cast<signed>(i) == active_index && isItemEnabled(i)), true, true); | ||
608 | } | ||
547 | } | 609 | } |
548 | 610 | ||
549 | menu.window.clear(); | ||
550 | renderTransFrame(); | ||
551 | |||
552 | m_need_update = false; | 611 | m_need_update = false; |
553 | menu.window.showSubwindows(); | ||
554 | } | 612 | } |
555 | 613 | ||
556 | 614 | ||
@@ -559,7 +617,6 @@ void Menu::show() { | |||
559 | update(); | 617 | update(); |
560 | menu.window.showSubwindows(); | 618 | menu.window.showSubwindows(); |
561 | menu.window.show(); | 619 | menu.window.show(); |
562 | //!! TODO, this should probably be done explicit if one don't want to raise | ||
563 | raise(); | 620 | raise(); |
564 | visible = true; | 621 | visible = true; |
565 | 622 | ||
@@ -596,7 +653,11 @@ void Menu::grabInputFocus() { | |||
596 | 653 | ||
597 | void Menu::clearWindow() { | 654 | void Menu::clearWindow() { |
598 | menu.window.clear(); | 655 | menu.window.clear(); |
599 | menu.title.clear(); | 656 | redrawTitle(); |
657 | |||
658 | renderTransp(0, 0, | ||
659 | m_real_frame_pm.width(), m_real_frame_pm.height()); | ||
660 | |||
600 | menu.frame.clear(); | 661 | menu.frame.clear(); |
601 | } | 662 | } |
602 | 663 | ||
@@ -627,9 +688,14 @@ void Menu::move(int x, int y) { | |||
627 | if (which_sub != -1) | 688 | if (which_sub != -1) |
628 | drawSubmenu(which_sub); | 689 | drawSubmenu(which_sub); |
629 | 690 | ||
691 | redrawTitle(); | ||
630 | if (!(m_parent && m_parent->moving) && !torn) { | 692 | if (!(m_parent && m_parent->moving) && !torn) { |
631 | redrawTitle(); | 693 | |
632 | renderTransFrame(); | 694 | renderTransp(0, 0, |
695 | m_real_frame_pm.width(), m_real_frame_pm.height()); | ||
696 | } else if (!moving) { | ||
697 | renderTransp(0, 0, | ||
698 | m_real_frame_pm.width(), m_real_frame_pm.height()); | ||
633 | } | 699 | } |
634 | } | 700 | } |
635 | 701 | ||
@@ -652,15 +718,18 @@ void Menu::redrawTitle() { | |||
652 | default: | 718 | default: |
653 | break; | 719 | break; |
654 | } | 720 | } |
721 | |||
722 | if (menu.title.alpha() != alpha()) | ||
723 | menu.title.setAlpha(alpha()); | ||
724 | |||
655 | menu.title.clear(); | 725 | menu.title.clear(); |
726 | menu.title.updateTransparent(); | ||
656 | font.drawText(menu.title.window(), // drawable | 727 | font.drawText(menu.title.window(), // drawable |
657 | screenNumber(), | 728 | screenNumber(), |
658 | m_theme.titleTextGC().gc(), // graphic context | 729 | m_theme.titleTextGC().gc(), // graphic context |
659 | text, len, // text string with lenght | 730 | text, len, // text string with lenght |
660 | dx, font.ascent() + menu.bevel_w); // position | 731 | dx, font.ascent() + menu.bevel_w); // position |
661 | 732 | ||
662 | menu.title.updateTransparent(); | ||
663 | |||
664 | } | 733 | } |
665 | 734 | ||
666 | 735 | ||
@@ -697,7 +766,7 @@ void Menu::drawSubmenu(unsigned int index) { | |||
697 | (menu.item_h * i) + | 766 | (menu.item_h * i) + |
698 | ((title_vis) ? menu.title_h + menu.window.borderWidth() : 0) - | 767 | ((title_vis) ? menu.title_h + menu.window.borderWidth() : 0) - |
699 | ((item->submenu()->title_vis) ? | 768 | ((item->submenu()->title_vis) ? |
700 | item->submenu()->menu.title_h + menu.window.borderWidth() : 0)); | 769 | item->submenu()->menu.title_h + menu.window.borderWidth() : 0)); |
701 | } | 770 | } |
702 | 771 | ||
703 | if (m_alignment == ALIGNBOTTOM && | 772 | if (m_alignment == ALIGNBOTTOM && |
@@ -752,50 +821,24 @@ bool Menu::hasSubmenu(unsigned int index) const { | |||
752 | 821 | ||
753 | 822 | ||
754 | int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_trans, | 823 | int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_trans, |
755 | int x, int y, unsigned int w, unsigned int h) { | 824 | int x, int y, unsigned int w, unsigned int h) { |
756 | if (index >= menuitems.size() || menuitems.size() == 0 || | 825 | if (index >= menuitems.size() || menuitems.size() == 0 || |
757 | menu.persub == 0) | 826 | menu.persub == 0) |
758 | return 0; | 827 | return 0; |
759 | 828 | ||
760 | MenuItem *item = menuitems[index]; | 829 | MenuItem *item = menuitems[index]; |
761 | if (! item) return 0; | 830 | if (! item) return 0; |
762 | 831 | ||
763 | bool dotext = true, dohilite = true, dosel = true; | ||
764 | const char *text = item->label().c_str(); | ||
765 | int sbl = index / menu.persub, i = index - (sbl * menu.persub); | 832 | int sbl = index / menu.persub, i = index - (sbl * menu.persub); |
766 | int item_x = (sbl * menu.item_w), item_y = (i * menu.item_h); | 833 | int item_x = (sbl * menu.item_w), item_y = (i * menu.item_h); |
767 | int hilite_x = item_x, hilite_y = item_y, hoff_x = 0, hoff_y = 0; | 834 | int hilite_x = item_x, hilite_y = item_y, hoff_x = 0, hoff_y = 0; |
768 | int text_x = 0, text_y = 0, len = strlen(text), sel_x = 0, sel_y = 0; | 835 | int sel_x = 0, sel_y = 0; |
769 | unsigned int hilite_w = menu.item_w, hilite_h = menu.item_h, text_w = 0, text_h = 0; | 836 | unsigned int hilite_w = menu.item_w, hilite_h = menu.item_h; |
770 | unsigned int half_w = menu.item_h / 2, quarter_w = menu.item_h / 4; | 837 | unsigned int half_w = menu.item_h / 2, quarter_w = menu.item_h / 4; |
771 | const FbTk::Font &font = m_theme.frameFont(); | ||
772 | if (text) { | ||
773 | text_w = font.textWidth(text, len); | ||
774 | |||
775 | text_y = item_y + menu.bevel_w/2 + font.ascent(); | ||
776 | |||
777 | switch(m_theme.frameFontJustify()) { | ||
778 | case FbTk::LEFT: | ||
779 | text_x = item_x + menu.bevel_w + menu.item_h + 1; | ||
780 | break; | ||
781 | |||
782 | case FbTk::RIGHT: | ||
783 | text_x = item_x + menu.item_w - (menu.item_h + menu.bevel_w + text_w); | ||
784 | break; | ||
785 | default: //center | ||
786 | text_x = item_x + ((menu.item_w + 1 - text_w) / 2); | ||
787 | break; | ||
788 | } | ||
789 | 838 | ||
790 | text_h = menu.item_h - menu.bevel_w; | ||
791 | } | ||
792 | |||
793 | GC gc = | 839 | GC gc = |
794 | ((highlight || item->isSelected()) ? m_theme.hiliteTextGC().gc() : | 840 | ((highlight || item->isSelected()) ? m_theme.hiliteTextGC().gc() : |
795 | m_theme.frameTextGC().gc()); | 841 | m_theme.frameTextGC().gc()); |
796 | const GContext &tgc = | ||
797 | (highlight ? m_theme.hiliteTextGC() : | ||
798 | (item->isEnabled() ? m_theme.frameTextGC() : m_theme.disableTextGC() ) ); | ||
799 | 842 | ||
800 | sel_x = item_x; | 843 | sel_x = item_x; |
801 | 844 | ||
@@ -806,7 +849,7 @@ int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_t | |||
806 | sel_y = item_y + quarter_w; | 849 | sel_y = item_y + quarter_w; |
807 | 850 | ||
808 | if (clear) { | 851 | if (clear) { |
809 | FbTk::GContext def_gc(menu.frame.window()); | 852 | GContext def_gc(menu.frame); |
810 | if (menu.frame_pixmap == 0) { | 853 | if (menu.frame_pixmap == 0) { |
811 | def_gc.setForeground(m_theme.frameTexture().color()); | 854 | def_gc.setForeground(m_theme.frameTexture().color()); |
812 | m_frame_pm.fillRectangle(def_gc.gc(), item_x, item_y, menu.item_w, menu.item_h); | 855 | m_frame_pm.fillRectangle(def_gc.gc(), item_x, item_y, menu.item_w, menu.item_h); |
@@ -820,10 +863,8 @@ int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_t | |||
820 | } | 863 | } |
821 | } else if (! (x == y && y == -1 && w == h && h == 0)) { | 864 | } else if (! (x == y && y == -1 && w == h && h == 0)) { |
822 | // calculate the which part of the hilite to redraw | 865 | // calculate the which part of the hilite to redraw |
823 | if (! (std::max(item_x, x) <= (signed) std::min(item_x + menu.item_w, x + w) && | 866 | if (!(std::max(item_x, x) <= (signed) std::min(item_x + menu.item_w, x + w) && |
824 | std::max(item_y, y) <= (signed) std::min(item_y + menu.item_h, y + h))) { | 867 | std::max(item_y, y) <= (signed) std::min(item_y + menu.item_h, y + h))) { |
825 | dohilite = False; | ||
826 | } else { | ||
827 | hilite_x = std::max(item_x, x); | 868 | hilite_x = std::max(item_x, x); |
828 | hilite_y = std::max(item_y, y); | 869 | hilite_y = std::max(item_y, y); |
829 | hilite_w = std::min(item_x + menu.item_w, x + w) - hilite_x; | 870 | hilite_w = std::min(item_x + menu.item_w, x + w) - hilite_x; |
@@ -832,20 +873,9 @@ int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_t | |||
832 | hoff_y = hilite_y % menu.item_h; | 873 | hoff_y = hilite_y % menu.item_h; |
833 | } | 874 | } |
834 | 875 | ||
835 | // check if we need to redraw the text | ||
836 | int text_ry = item_y + (menu.bevel_w / 2); | ||
837 | if (! (std::max(text_x, x) <= (signed) std::min(text_x + text_w, x + w) && | ||
838 | std::max(text_ry, y) <= (signed) std::min(text_ry + text_h, y + h))) | ||
839 | dotext = false; | ||
840 | |||
841 | // check if we need to redraw the select pixmap/menu bullet | ||
842 | if (! (std::max(sel_x, x) <= (signed) std::min(sel_x + half_w, x + w) && | ||
843 | std::max(sel_y, y) <= (signed) std::min(sel_y + half_w, y + h))) | ||
844 | dosel = false; | ||
845 | |||
846 | } | 876 | } |
847 | 877 | ||
848 | if (dohilite && highlight && (menu.hilite_pixmap != ParentRelative)) { | 878 | if (highlight && (menu.hilite_pixmap != ParentRelative)) { |
849 | if (menu.hilite_pixmap) { | 879 | if (menu.hilite_pixmap) { |
850 | m_frame_pm.copyArea(menu.hilite_pixmap, | 880 | m_frame_pm.copyArea(menu.hilite_pixmap, |
851 | m_theme.hiliteGC().gc(), hoff_x, hoff_y, | 881 | m_theme.hiliteGC().gc(), hoff_x, hoff_y, |
@@ -859,8 +889,7 @@ int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_t | |||
859 | } | 889 | } |
860 | 890 | ||
861 | 891 | ||
862 | if (item->isToggleItem() && item->isSelected() && | 892 | if (item->isToggleItem() && item->isSelected()) { |
863 | menu.sel_pixmap != ParentRelative) { | ||
864 | if (m_theme.selectedPixmap().pixmap().drawable()) { | 893 | if (m_theme.selectedPixmap().pixmap().drawable()) { |
865 | // enable clip mask | 894 | // enable clip mask |
866 | XSetClipMask(FbTk::App::instance()->display(), | 895 | XSetClipMask(FbTk::App::instance()->display(), |
@@ -892,119 +921,22 @@ int Menu::drawItem(unsigned int index, bool highlight, bool clear, bool render_t | |||
892 | } | 921 | } |
893 | } | 922 | } |
894 | 923 | ||
895 | } else if (item->isToggleItem() && m_theme.unselectedPixmap().pixmap().drawable() != 0) { | ||
896 | // enable clip mask | ||
897 | XSetClipMask(FbTk::App::instance()->display(), | ||
898 | gc, | ||
899 | m_theme.unselectedPixmap().mask().drawable()); | ||
900 | XSetClipOrigin(FbTk::App::instance()->display(), | ||
901 | gc, sel_x, item_y); | ||
902 | // copy bullet pixmap to frame | ||
903 | m_frame_pm.copyArea(m_theme.unselectedPixmap().pixmap().drawable(), | ||
904 | gc, | ||
905 | 0, 0, | ||
906 | sel_x, item_y, | ||
907 | m_theme.unselectedPixmap().width(), | ||
908 | m_theme.unselectedPixmap().height()); | ||
909 | // disable clip mask | ||
910 | XSetClipMask(FbTk::App::instance()->display(), | ||
911 | gc, | ||
912 | None); | ||
913 | } | ||
914 | |||
915 | if (dotext && text) { | ||
916 | //!! TODO: this is just temporarly and will be removed | ||
917 | // once we've cleaned up the menu code this will be somewhere else... | ||
918 | if (strcmp(text, "---") == 0){ // draw separator | ||
919 | m_frame_pm.drawRectangle(tgc.gc(), | ||
920 | item_x + menu.bevel_w + menu.item_h + 1, item_y + (menu.item_h / 2), | ||
921 | menu.item_w - ((menu.bevel_w + menu.item_h) * 2) - 1, 0); | ||
922 | } else { // draw normal text | ||
923 | m_theme.frameFont().drawText(m_frame_pm.drawable(), // drawable | ||
924 | screenNumber(), | ||
925 | tgc.gc(), | ||
926 | text, len, // text string and lenght | ||
927 | text_x, text_y); // position | ||
928 | } | ||
929 | } | 924 | } |
930 | 925 | ||
931 | if (dosel && item->submenu()) { | 926 | if (render_trans) |
932 | if (m_theme.bulletPixmap().pixmap().drawable() != 0) { | 927 | renderTransp(item_x, item_y, |
933 | // enable clip mask | 928 | width(), menu.item_h); |
934 | XSetClipMask(FbTk::App::instance()->display(), | 929 | |
935 | gc, | 930 | item->draw(m_real_frame_pm, m_theme, highlight, |
936 | m_theme.bulletPixmap().mask().drawable()); | 931 | item_x, item_y, |
937 | XSetClipOrigin(FbTk::App::instance()->display(), | 932 | menu.item_w, menu.item_h); |
938 | gc, sel_x, item_y); | 933 | |
939 | // copy bullet pixmap to frame | 934 | |
940 | m_frame_pm.copyArea(m_theme.bulletPixmap().pixmap().drawable(), | 935 | if (clear) |
941 | gc, | 936 | menu.frame.clearArea(item_x, item_y, |
942 | 0, 0, | 937 | menu.item_w, menu.item_h, False); |
943 | sel_x, item_y, | ||
944 | m_theme.bulletPixmap().width(), | ||
945 | m_theme.bulletPixmap().height()); | ||
946 | // disable clip mask | ||
947 | XSetClipMask(FbTk::App::instance()->display(), | ||
948 | gc, | ||
949 | None); | ||
950 | } else { | ||
951 | switch (m_theme.bullet()) { | ||
952 | case MenuTheme::SQUARE: | ||
953 | m_frame_pm.drawRectangle(gc, sel_x, sel_y, half_w, half_w); | ||
954 | break; | ||
955 | |||
956 | case MenuTheme::TRIANGLE: | ||
957 | XPoint tri[3]; | ||
958 | |||
959 | if (m_theme.bulletPos() == FbTk::RIGHT) { | ||
960 | tri[0].x = sel_x + quarter_w - 2; | ||
961 | tri[0].y = sel_y + quarter_w - 2; | ||
962 | tri[1].x = 4; | ||
963 | tri[1].y = 2; | ||
964 | tri[2].x = -4; | ||
965 | tri[2].y = 2; | ||
966 | } else { | ||
967 | tri[0].x = sel_x + quarter_w - 2; | ||
968 | tri[0].y = item_y + half_w; | ||
969 | tri[1].x = 4; | ||
970 | tri[1].y = 2; | ||
971 | tri[2].x = 0; | ||
972 | tri[2].y = -4; | ||
973 | } | ||
974 | |||
975 | m_frame_pm.fillPolygon(gc, tri, 3, Convex, | ||
976 | CoordModePrevious); | ||
977 | break; | ||
978 | |||
979 | case MenuTheme::DIAMOND: | ||
980 | XPoint dia[4]; | ||
981 | |||
982 | dia[0].x = sel_x + quarter_w - 3; | ||
983 | dia[0].y = item_y + half_w; | ||
984 | dia[1].x = 3; | ||
985 | dia[1].y = -3; | ||
986 | dia[2].x = 3; | ||
987 | dia[2].y = 3; | ||
988 | dia[3].x = -3; | ||
989 | dia[3].y = 3; | ||
990 | |||
991 | m_frame_pm.fillPolygon(gc, dia, 4, Convex, | ||
992 | CoordModePrevious); | ||
993 | break; | ||
994 | default: | ||
995 | break; | ||
996 | } | ||
997 | } | ||
998 | } | ||
999 | 938 | ||
1000 | menu.frame.clearArea(item_x, item_y, | ||
1001 | menu.item_w, menu.item_h, False); | ||
1002 | 939 | ||
1003 | if (render_trans) { | ||
1004 | menu.frame.updateTransparent(item_x, item_y, | ||
1005 | menu.item_w, menu.item_h); | ||
1006 | } | ||
1007 | |||
1008 | return item_y; | 940 | return item_y; |
1009 | } | 941 | } |
1010 | 942 | ||
@@ -1088,6 +1020,7 @@ void Menu::buttonPressEvent(XButtonEvent &be) { | |||
1088 | drawSubmenu(w); | 1020 | drawSubmenu(w); |
1089 | } else | 1021 | } else |
1090 | drawItem(w, item->isEnabled(), true, true); | 1022 | drawItem(w, item->isEnabled(), true, true); |
1023 | |||
1091 | } | 1024 | } |
1092 | } else { | 1025 | } else { |
1093 | menu.x_move = be.x_root - x(); | 1026 | menu.x_move = be.x_root - x(); |
@@ -1103,7 +1036,18 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) { | |||
1103 | 1036 | ||
1104 | if (which_sub >= 0) | 1037 | if (which_sub >= 0) |
1105 | drawSubmenu(which_sub); | 1038 | drawSubmenu(which_sub); |
1106 | update(); | 1039 | if (alpha() < 255) { |
1040 | //m_need_update = true; | ||
1041 | // update(); | ||
1042 | renderTransp(0, 0, | ||
1043 | m_real_frame_pm.width(), m_real_frame_pm.height()); | ||
1044 | for (size_t i=0; i < menuitems.size(); ++i) { | ||
1045 | drawItem(i, false, // highlight | ||
1046 | true, // clear | ||
1047 | false); // transparent | ||
1048 | |||
1049 | } | ||
1050 | } | ||
1107 | } | 1051 | } |
1108 | 1052 | ||
1109 | if (re.x >= 0 && re.x <= (signed) width() && | 1053 | if (re.x >= 0 && re.x <= (signed) width() && |
@@ -1126,9 +1070,8 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) { | |||
1126 | re.y > iy && re.y < (signed) (iy + menu.item_h)) { | 1070 | re.y > iy && re.y < (signed) (iy + menu.item_h)) { |
1127 | menuitems[w]->click(re.button, re.time); | 1071 | menuitems[w]->click(re.button, re.time); |
1128 | itemSelected(re.button, w); | 1072 | itemSelected(re.button, w); |
1129 | // redraw whole menu as enableds for any item | 1073 | // just redraw this item |
1130 | // may have changed | 1074 | drawItem(w, true, true, true); |
1131 | update(w); | ||
1132 | } | 1075 | } |
1133 | } else { | 1076 | } else { |
1134 | drawItem(p, isItemEnabled(p) && (p == which_sub), true, true); | 1077 | drawItem(p, isItemEnabled(p) && (p == which_sub), true, true); |
@@ -1140,11 +1083,12 @@ void Menu::buttonReleaseEvent(XButtonEvent &re) { | |||
1140 | 1083 | ||
1141 | 1084 | ||
1142 | void Menu::motionNotifyEvent(XMotionEvent &me) { | 1085 | void Menu::motionNotifyEvent(XMotionEvent &me) { |
1143 | 1086 | // if draging the with the titlebar: | |
1144 | if (me.window == menu.title && (me.state & Button1Mask)) { | 1087 | if (me.window == menu.title && (me.state & Button1Mask)) { |
1145 | stopHide(); | 1088 | stopHide(); |
1146 | if (movable) { | 1089 | if (movable) { |
1147 | if (! moving) { | 1090 | if (! moving) { |
1091 | // if not moving: start moving operation | ||
1148 | if (m_parent && (! torn)) { | 1092 | if (m_parent && (! torn)) { |
1149 | m_parent->drawItem(m_parent->which_sub, false, true, true); | 1093 | m_parent->drawItem(m_parent->which_sub, false, true, true); |
1150 | m_parent->which_sub = -1; | 1094 | m_parent->which_sub = -1; |
@@ -1178,7 +1122,9 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { | |||
1178 | // don't redraw disabled items on enter/leave | 1122 | // don't redraw disabled items on enter/leave |
1179 | if (item != 0 && item->isEnabled()) { | 1123 | if (item != 0 && item->isEnabled()) { |
1180 | 1124 | ||
1181 | drawItem(p, false, true, true); | 1125 | drawItem(p, false, // highlight |
1126 | true, // clear | ||
1127 | true); // transparent | ||
1182 | 1128 | ||
1183 | if (item->submenu()) { | 1129 | if (item->submenu()) { |
1184 | 1130 | ||
@@ -1200,7 +1146,7 @@ void Menu::motionNotifyEvent(XMotionEvent &me) { | |||
1200 | 1146 | ||
1201 | if (itmp->submenu()) { | 1147 | if (itmp->submenu()) { |
1202 | 1148 | ||
1203 | drawItem(w, true); | 1149 | drawItem(w, true, true); |
1204 | 1150 | ||
1205 | if (theme().menuMode() == MenuTheme::DELAY_OPEN) { | 1151 | if (theme().menuMode() == MenuTheme::DELAY_OPEN) { |
1206 | // setup show menu timer | 1152 | // setup show menu timer |
@@ -1226,6 +1172,12 @@ void Menu::exposeEvent(XExposeEvent &ee) { | |||
1226 | if (ee.window == menu.title) { | 1172 | if (ee.window == menu.title) { |
1227 | redrawTitle(); | 1173 | redrawTitle(); |
1228 | } else if (ee.window == menu.frame) { | 1174 | } else if (ee.window == menu.frame) { |
1175 | |||
1176 | if (moving) { | ||
1177 | menu.frame.clearArea(ee.x, ee.y, ee.width, ee.height); | ||
1178 | return; | ||
1179 | } | ||
1180 | |||
1229 | // this is a compilicated algorithm... lets do it step by step... | 1181 | // this is a compilicated algorithm... lets do it step by step... |
1230 | // first... we see in which sub level the expose starts... and how many | 1182 | // first... we see in which sub level the expose starts... and how many |
1231 | // items down in that sublevel | 1183 | // items down in that sublevel |
@@ -1259,16 +1211,20 @@ void Menu::exposeEvent(XExposeEvent &ee) { | |||
1259 | unsigned int index = row + (col * menu.persub); | 1211 | unsigned int index = row + (col * menu.persub); |
1260 | max_y = max(drawItem(index, | 1212 | max_y = max(drawItem(index, |
1261 | (which_sub == static_cast<signed>(index)), // highlight | 1213 | (which_sub == static_cast<signed>(index)), // highlight |
1262 | true, // clear | 1214 | false, // clear |
1263 | false, // render trans | 1215 | true), max_y); // render trans |
1264 | ee.x, ee.y, ee.width, ee.height), max_y); | 1216 | // ee.x, ee.y, ee.width, ee.height), max_y); |
1265 | } | 1217 | } |
1266 | } | 1218 | } |
1267 | } | 1219 | } |
1220 | |||
1221 | menu.frame.clearArea(ee.x, ee.y, ee.width, ee.height); | ||
1222 | /* | ||
1268 | menu.frame.updateTransparent(start_column * menu.item_w, | 1223 | menu.frame.updateTransparent(start_column * menu.item_w, |
1269 | start_row * menu.item_h, | 1224 | start_row * menu.item_h, |
1270 | (end_column-start_column+1) * menu.item_w, | 1225 | (end_column-start_column+1) * menu.item_w, |
1271 | (end_row-start_row+1) * menu.item_h); | 1226 | (end_row-start_row+1) * menu.item_h); |
1227 | */ | ||
1272 | } | 1228 | } |
1273 | } | 1229 | } |
1274 | 1230 | ||
@@ -1373,10 +1329,24 @@ void Menu::keyPressEvent(XKeyEvent &event) { | |||
1373 | } | 1329 | } |
1374 | 1330 | ||
1375 | void Menu::reconfigure() { | 1331 | void Menu::reconfigure() { |
1332 | |||
1333 | |||
1334 | if (alpha() == 255 && m_transp.get() != 0) { | ||
1335 | m_transp.reset(0); | ||
1336 | } else if (alpha () < 255) { | ||
1337 | |||
1338 | if (m_transp.get() == 0) { | ||
1339 | m_transp.reset(new Transparent(getRootPixmap(screenNumber()), | ||
1340 | m_real_frame_pm.drawable(), alpha(), | ||
1341 | screenNumber())); | ||
1342 | } else | ||
1343 | m_transp->setAlpha(alpha()); | ||
1344 | } | ||
1345 | |||
1376 | m_need_update = true; // redraw items | 1346 | m_need_update = true; // redraw items |
1377 | 1347 | ||
1378 | menu.bevel_w = m_theme.bevelWidth(); | 1348 | menu.bevel_w = theme().bevelWidth(); |
1379 | m_border_width = m_theme.borderWidth(); | 1349 | m_border_width = theme().borderWidth(); |
1380 | 1350 | ||
1381 | if (menu.bevel_w > 10) // clamp to "normal" size | 1351 | if (menu.bevel_w > 10) // clamp to "normal" size |
1382 | menu.bevel_w = 10; | 1352 | menu.bevel_w = 10; |
@@ -1386,6 +1356,7 @@ void Menu::reconfigure() { | |||
1386 | if (m_border_width < 0) | 1356 | if (m_border_width < 0) |
1387 | m_border_width = 0; | 1357 | m_border_width = 0; |
1388 | 1358 | ||
1359 | menu.title.setAlpha(alpha()); | ||
1389 | menu.window.setBackgroundColor(m_theme.borderColor()); | 1360 | menu.window.setBackgroundColor(m_theme.borderColor()); |
1390 | menu.title.setBackgroundColor(m_theme.borderColor()); | 1361 | menu.title.setBackgroundColor(m_theme.borderColor()); |
1391 | 1362 | ||
@@ -1396,17 +1367,10 @@ void Menu::reconfigure() { | |||
1396 | menu.window.setBorderWidth(m_border_width); | 1367 | menu.window.setBorderWidth(m_border_width); |
1397 | menu.title.setBorderWidth(m_border_width); | 1368 | menu.title.setBorderWidth(m_border_width); |
1398 | 1369 | ||
1399 | menu.frame.setAlpha(alpha()); | ||
1400 | menu.title.setAlpha(alpha()); | ||
1401 | menu.window.setAlpha(alpha()); | ||
1402 | 1370 | ||
1403 | update(); | 1371 | update(); |
1404 | } | 1372 | } |
1405 | 1373 | ||
1406 | void Menu::renderTransFrame() { | ||
1407 | menu.frame.clear(); | ||
1408 | menu.frame.updateTransparent(); | ||
1409 | } | ||
1410 | 1374 | ||
1411 | void Menu::openSubmenu() { | 1375 | void Menu::openSubmenu() { |
1412 | if (!isVisible() || which_press < 0 || which_press >= static_cast<signed>(menuitems.size()) || | 1376 | if (!isVisible() || which_press < 0 || which_press >= static_cast<signed>(menuitems.size()) || |
@@ -1417,7 +1381,7 @@ void Menu::openSubmenu() { | |||
1417 | if (item < 0 || item >= static_cast<signed>(menuitems.size())) | 1381 | if (item < 0 || item >= static_cast<signed>(menuitems.size())) |
1418 | return; | 1382 | return; |
1419 | 1383 | ||
1420 | drawItem(item, true); | 1384 | drawItem(item, true, true); |
1421 | if (menuitems[item]->submenu() != 0 && !menuitems[item]->submenu()->isVisible()) | 1385 | if (menuitems[item]->submenu() != 0 && !menuitems[item]->submenu()->isVisible()) |
1422 | drawSubmenu(item); | 1386 | drawSubmenu(item); |
1423 | 1387 | ||
@@ -1440,4 +1404,64 @@ void Menu::stopHide() { | |||
1440 | m_hide_timer.stop(); | 1404 | m_hide_timer.stop(); |
1441 | } | 1405 | } |
1442 | 1406 | ||
1407 | void Menu::update(FbTk::Subject *subj) { | ||
1408 | |||
1409 | m_need_update = true; | ||
1410 | |||
1411 | Menuitems::iterator it = menuitems.begin(); | ||
1412 | Menuitems::iterator it_end = menuitems.end(); | ||
1413 | for (; it != it_end; ++it) | ||
1414 | (*it)->updateTheme(theme()); | ||
1415 | reconfigure(); | ||
1416 | } | ||
1417 | |||
1418 | void Menu::renderTransp(int x, int y, | ||
1419 | unsigned int width, unsigned int height) { | ||
1420 | GContext def_gc(menu.frame); | ||
1421 | m_real_frame_pm.copyArea(m_frame_pm.drawable(), | ||
1422 | def_gc.gc(), | ||
1423 | x, y, | ||
1424 | x, y, | ||
1425 | width, height); | ||
1426 | if (m_transp.get() == 0) | ||
1427 | return; | ||
1428 | |||
1429 | #ifdef HAVE_XRENDER | ||
1430 | |||
1431 | Pixmap root = getRootPixmap(screenNumber()); | ||
1432 | if (m_transp->source() != root) | ||
1433 | m_transp->setSource(root, screenNumber()); | ||
1434 | |||
1435 | |||
1436 | |||
1437 | if (m_transp->dest() != m_real_frame_pm.drawable()) | ||
1438 | m_transp->setDest(m_real_frame_pm.drawable(), screenNumber()); | ||
1439 | |||
1440 | if (m_transp->alpha() != alpha()) | ||
1441 | m_transp->setAlpha(alpha()); | ||
1442 | |||
1443 | const FbWindow *root_parent = menu.frame.parent(); | ||
1444 | // our position in parent ("root") | ||
1445 | int root_x = menu.frame.x() - menu.frame.borderWidth(), | ||
1446 | root_y = menu.frame.y() - menu.frame.borderWidth(); | ||
1447 | if (root_parent != 0) { | ||
1448 | root_x += root_parent->x() + root_parent->borderWidth(); | ||
1449 | root_y += root_parent->y() + root_parent->borderWidth(); | ||
1450 | while (root_parent->parent() != 0) { | ||
1451 | root_parent = root_parent->parent(); | ||
1452 | root_x += root_parent->x() + root_parent->borderWidth(); | ||
1453 | root_y += root_parent->y() + root_parent->borderWidth(); | ||
1454 | } | ||
1455 | |||
1456 | } // else toplevel window so we already have x, y set | ||
1457 | |||
1458 | // render background image from root pos to our window | ||
1459 | m_transp->render(root_x + x, root_y + y, | ||
1460 | x, y, | ||
1461 | width, height); | ||
1462 | |||
1463 | #endif // HAVE_XRENDER | ||
1464 | |||
1465 | } | ||
1466 | |||
1443 | }; // end namespace FbTk | 1467 | }; // end namespace FbTk |