diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp index 7b04ac491..2415cf5d8 100644 --- a/src/app/ui/context_bar.cpp +++ b/src/app/ui/context_bar.cpp @@ -150,21 +150,24 @@ protected: private: void openPopup() { + Border border = Border(2, 2, 2, 3)*jguiscale(); Rect rc = getBounds(); rc.y += rc.h; rc.w *= 3; m_popupWindow = new PopupWindow("", PopupWindow::kCloseOnClickInOtherWindow); m_popupWindow->setAutoRemap(false); - m_popupWindow->setBounds(rc); + m_popupWindow->setBorder(border); + m_popupWindow->setBounds(rc + border); - Region rgn(rc.createUnion(getBounds())); + Region rgn(m_popupWindow->getBounds().createUnion(getBounds())); m_popupWindow->setHotRegion(rgn); m_brushType = new ButtonSet(3, 1, m_penType, - PART_BRUSH_CIRCLE, - PART_BRUSH_SQUARE, - PART_BRUSH_LINE); - + PART_BRUSH_CIRCLE, + PART_BRUSH_SQUARE, + PART_BRUSH_LINE); m_brushType->ItemChange.connect(&BrushTypeField::onBrushTypeChange, this); + m_brushType->setTransparent(true); + m_brushType->setBgColor(ui::ColorNone); m_popupWindow->addChild(m_brushType); m_popupWindow->openWindow(); diff --git a/src/app/ui/skin/skin_theme.cpp b/src/app/ui/skin/skin_theme.cpp index f6e1044a4..d73d18c8b 100644 --- a/src/app/ui/skin/skin_theme.cpp +++ b/src/app/ui/skin/skin_theme.cpp @@ -913,7 +913,8 @@ void SkinTheme::paintBox(PaintEvent& ev) Widget* widget = static_cast(ev.getSource()); Graphics* g = ev.getGraphics(); - g->fillRect(BGCOLOR, g->getClipBounds()); + if (!is_transparent(BGCOLOR)) + g->fillRect(BGCOLOR, g->getClipBounds()); } void SkinTheme::paintButton(PaintEvent& ev) @@ -1039,7 +1040,8 @@ void SkinTheme::paintGrid(PaintEvent& ev) Widget* widget = static_cast(ev.getSource()); Graphics* g = ev.getGraphics(); - g->fillRect(BGCOLOR, g->getClipBounds()); + if (!is_transparent(BGCOLOR)) + g->fillRect(BGCOLOR, g->getClipBounds()); } void SkinTheme::paintEntry(PaintEvent& ev) @@ -1136,7 +1138,9 @@ void SkinTheme::paintLabel(PaintEvent& ev) ui::Color fg = widget->getTextColor(); Rect text, rc = widget->getClientBounds(); - g->fillRect(bg, rc); + if (!is_transparent(bg)) + g->fillRect(bg, rc); + rc.shrink(widget->getBorder()); widget->getTextIconInfo(NULL, &text); @@ -1639,8 +1643,10 @@ void SkinTheme::paintView(PaintEvent& ev) Graphics* g = ev.getGraphics(); View* widget = static_cast(ev.getSource()); gfx::Rect bounds = widget->getClientBounds(); + ui::Color bg = BGCOLOR; - g->fillRect(BGCOLOR, bounds); + if (!is_transparent(bg)) + g->fillRect(bg, bounds); draw_bounds_nw(g, bounds, (widget->hasFocus() ? @@ -1687,8 +1693,10 @@ void SkinTheme::paintViewViewport(PaintEvent& ev) { Viewport* widget = static_cast(ev.getSource()); Graphics* g = ev.getGraphics(); + ui::Color bg = BGCOLOR; - g->fillRect(BGCOLOR, widget->getClientBounds()); + if (!is_transparent(bg)) + g->fillRect(bg, widget->getClientBounds()); } void SkinTheme::paintWindow(PaintEvent& ev) @@ -1720,11 +1728,14 @@ void SkinTheme::paintWindow(PaintEvent& ev) void SkinTheme::paintPopupWindow(PaintEvent& ev) { + Widget* widget = static_cast(ev.getSource()); Window* window = static_cast(ev.getSource()); Graphics* g = ev.getGraphics(); gfx::Rect pos = window->getClientBounds(); - get_style("menubox")->paint(g, pos, NULL, Style::State()); + if (!is_transparent(BGCOLOR)) + get_style("menubox")->paint(g, pos, NULL, Style::State()); + pos.shrink(window->getBorder()); g->drawString(window->getText(), @@ -1814,8 +1825,12 @@ ui::Color SkinTheme::getWidgetBgColor(Widget* widget) ui::Color c = widget->getBgColor(); bool decorative = widget->isDecorative(); - return (!is_transparent(c) ? c: (decorative ? getColor(ThemeColor::Selected): - getColor(ThemeColor::Face))); + if (!is_transparent(c) || widget->getType() == kWindowWidget) + return c; + else if (decorative) + return getColor(ThemeColor::Selected); + else + return getColor(ThemeColor::Face); } void SkinTheme::drawTextString(Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color, diff --git a/src/app/ui/toolbar.cpp b/src/app/ui/toolbar.cpp index 912c812c3..e1b1aecd1 100644 --- a/src/app/ui/toolbar.cpp +++ b/src/app/ui/toolbar.cpp @@ -462,6 +462,8 @@ void ToolBar::openPopupWindow(int group_index, ToolGroup* tool_group) rgn.createUnion(rgn, Region(getBounds())); m_popupWindow->setHotRegion(rgn); + m_popupWindow->setTransparent(true); + m_popupWindow->setBgColor(ui::ColorNone); m_popupWindow->setAutoRemap(false); m_popupWindow->setBounds(rc); toolstrip->setBounds(rc); @@ -632,6 +634,7 @@ ToolBar::ToolStrip::ToolStrip(ToolGroup* group, ToolBar* toolbar) m_toolbar = toolbar; setDoubleBuffered(true); + setTransparent(true); } ToolBar::ToolStrip::~ToolStrip() @@ -730,7 +733,6 @@ void ToolBar::ToolStrip::onPaint(PaintEvent& ev) { Graphics* g = ev.getGraphics(); gfx::Rect bounds = getClientBounds(); - gfx::Rect clip = g->getClipBounds(); SkinTheme* theme = static_cast(getTheme()); ToolBox* toolbox = App::instance()->getToolBox(); Rect toolrc; diff --git a/src/ui/graphics.h b/src/ui/graphics.h index 433c8d052..a27fa5aa4 100644 --- a/src/ui/graphics.h +++ b/src/ui/graphics.h @@ -32,6 +32,10 @@ namespace ui { Graphics(BITMAP* bmp, int dx, int dy); ~Graphics(); + BITMAP* getInternalBitmap() { return m_bmp; } + int getInternalDeltaX() { return m_dx; } + int getInternalDeltaY() { return m_dy; } + gfx::Rect getClipBounds() const; void setClipBounds(const gfx::Rect& rc); bool intersectClipRect(const gfx::Rect& rc); diff --git a/src/ui/int_entry.cpp b/src/ui/int_entry.cpp index 9a674c25d..5572c3f4c 100644 --- a/src/ui/int_entry.cpp +++ b/src/ui/int_entry.cpp @@ -139,8 +139,9 @@ void IntEntry::openPopup() m_popupWindow = new PopupWindow("", PopupWindow::kCloseOnClickInOtherWindow); m_popupWindow->setAutoRemap(false); + m_popupWindow->setTransparent(true); + m_popupWindow->setBgColor(ui::ColorNone); m_popupWindow->setBounds(rc); - m_popupWindow->setBgColor(rgba(0, 0, 0, 0)); m_popupWindow->Close.connect(&IntEntry::onPopupClose, this); Region rgn(rc.createUnion(getBounds())); @@ -149,6 +150,7 @@ void IntEntry::openPopup() m_slider = new Slider(m_min, m_max, getValue()); m_slider->setFocusStop(false); // In this way the IntEntry doesn't lost the focus + m_slider->setTransparent(true); m_slider->Change.connect(&IntEntry::onChangeSlider, this); m_popupWindow->addChild(m_slider); diff --git a/src/ui/tooltips.cpp b/src/ui/tooltips.cpp index 01b341b2e..d56e24935 100644 --- a/src/ui/tooltips.cpp +++ b/src/ui/tooltips.cpp @@ -155,6 +155,8 @@ TipWindow::TipWindow(const char *text) : PopupWindow(text, kCloseOnClickInOtherWindow) , m_arrowAlign(0) { + setTransparent(true); + makeFixed(); initTheme(); } diff --git a/src/ui/widget.cpp b/src/ui/widget.cpp index 264568fbb..01fdf1722 100644 --- a/src/ui/widget.cpp +++ b/src/ui/widget.cpp @@ -76,6 +76,7 @@ Widget::Widget(WidgetType type) m_preferredSize = NULL; m_doubleBuffered = false; + m_transparent = false; } Widget::~Widget() @@ -655,6 +656,9 @@ void Widget::getDrawableRegion(gfx::Region& region, DrawableRegionFlags flags) it != windows_list.rend()) { // Subtract the rectangles for (++it; it != windows_list.rend(); ++it) { + if (!(*it)->isVisible()) + continue; + Region reg1; (*it)->getRegion(reg1); region.createSubtraction(region, reg1); @@ -917,7 +921,79 @@ void Widget::flushRedraw() } } -bool Widget::isDoubleBuffered() +void Widget::paint(Graphics* graphics, const gfx::Region& drawRegion) +{ + if (drawRegion.isEmpty()) + return; + + std::queue processing; + processing.push(this); + + while (!processing.empty()) { + Widget* widget = processing.front(); + processing.pop(); + + ASSERT_VALID_WIDGET(widget); + + // If the widget is hidden + if (!widget->isVisible()) + continue; + + UI_FOREACH_WIDGET(widget->getChildren(), it) { + Widget* child = *it; + processing.push(child); + } + + // Intersect drawRegion with widget's drawable region. + Region region; + widget->getDrawableRegion(region, kCutTopWindows); + region.createIntersection(region, drawRegion); + + Graphics graphics2(graphics->getInternalBitmap(), + widget->getBounds().x, + widget->getBounds().y); + graphics2.setFont(widget->getFont()); + + for (Region::const_iterator + it = region.begin(), + end = region.end(); it != end; ++it) { + IntersectClip clip(&graphics2, Rect(*it).offset( + -widget->getBounds().x, + -widget->getBounds().y)); + widget->paintEvent(&graphics2); + } + } +} + +bool Widget::paintEvent(Graphics* graphics) +{ + // For transparent widgets we have to draw the parent first. + if (isTransparent()) { +#if _DEBUG + // In debug mode we can fill the area with Red so we know if the + // we are drawing the parent correctly. + graphics->fillRect(ui::rgba(255, 0, 0), getClientBounds()); +#endif _DEBUG + + this->flags |= JI_HIDDEN; + + gfx::Region rgn(getParent()->getBounds()); + rgn.createIntersection(rgn, + gfx::Region( + graphics->getClipBounds().offset( + graphics->getInternalDeltaX(), + graphics->getInternalDeltaY()))); + getParent()->paint(graphics, rgn); + + this->flags &= ~JI_HIDDEN; + } + + PaintEvent ev(this, graphics); + onPaint(ev); // Fire onPaint event + return ev.isPainted(); +} + +bool Widget::isDoubleBuffered() const { return m_doubleBuffered; } @@ -927,6 +1003,16 @@ void Widget::setDoubleBuffered(bool doubleBuffered) m_doubleBuffered = doubleBuffered; } +bool Widget::isTransparent() const +{ + return m_transparent; +} + +void Widget::setTransparent(bool transparent) +{ + m_transparent = transparent; +} + void Widget::invalidate() { if (isVisible()) { @@ -1217,9 +1303,7 @@ bool Widget::onProcessMessage(Message* msg) ASSERT(ptmsg->rect().h > 0); GraphicsPtr graphics = getGraphics(toClient(ptmsg->rect())); - PaintEvent ev(this, graphics); - onPaint(ev); // Fire onPaint event - return ev.isPainted(); + return paintEvent(graphics); } case kKeyDownMessage: diff --git a/src/ui/widget.h b/src/ui/widget.h index 7ef6a118c..54280bd04 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -296,9 +296,12 @@ namespace ui { // REFRESH ISSUES // =============================================================== - bool isDoubleBuffered(); + bool isDoubleBuffered() const; void setDoubleBuffered(bool doubleBuffered); + bool isTransparent() const; + void setTransparent(bool transparent); + void invalidate(); void invalidateRect(const gfx::Rect& rect); void invalidateRegion(const gfx::Region& region); @@ -376,6 +379,9 @@ namespace ui { virtual void onSetBgColor(); private: + void paint(Graphics* graphics, const gfx::Region& drawRegion); + bool paintEvent(Graphics* graphics); + base::string m_id; // Widget's id Theme* m_theme; // Widget's theme int m_align; // Widget alignment @@ -387,7 +393,8 @@ namespace ui { WidgetsList m_children; // Sub-widgets Widget* m_parent; // Who is the parent? gfx::Size* m_preferredSize; - bool m_doubleBuffered : 1; + bool m_doubleBuffered; + bool m_transparent; }; } // namespace ui