From 493197e840420903dd5a0490e74ae474e539d0a5 Mon Sep 17 00:00:00 2001 From: formiano Date: Thu, 12 Dec 2024 16:34:47 +0100 Subject: [PATCH] errore: 'eRect eListbox::getPadding()' contrassegnato come 'override', ma non esegue l'override --- lib/gui/elabel.cpp | 90 ++++++++---- lib/gui/elabel.h | 32 +++-- lib/gui/eslider.cpp | 243 ++++++++++++++++++++++++-------- lib/gui/ewidget.cpp | 143 ++++++++++++++----- lib/gui/ewidget.h | 69 +++++++-- lib/gui/ewidgetdesktop.cpp | 12 +- lib/gui/ewidgetdesktop.h | 2 +- lib/gui/ewindow.cpp | 13 +- lib/gui/ewindow.h | 5 +- lib/gui/ewindowstyle.cpp | 5 + lib/gui/ewindowstyle.h | 7 +- lib/gui/ewindowstyleskinned.cpp | 28 ++++ lib/gui/ewindowstyleskinned.h | 15 +- 13 files changed, 514 insertions(+), 150 deletions(-) diff --git a/lib/gui/elabel.cpp b/lib/gui/elabel.cpp index b915b24fa..15398ef23 100644 --- a/lib/gui/elabel.cpp +++ b/lib/gui/elabel.cpp @@ -1,5 +1,6 @@ #include #include +#include eLabel::eLabel(eWidget *parent, int markedPos) : eWidget(parent) { @@ -12,14 +13,6 @@ eLabel::eLabel(eWidget *parent, int markedPos) : eWidget(parent) /* default to topleft alignment */ m_valign = alignTop; m_halign = alignBidi; - - m_have_foreground_color = 0; - m_have_shadow_color = 0; - - m_wrap = 1; - m_border_size = 0; - - m_text_offset = 0; } int eLabel::event(int event, void *data, void *data2) @@ -66,6 +59,12 @@ int eLabel::event(int event, void *data, void *data2) else if (m_wrap == 2) flags |= gPainter::RT_ELLIPSIS; + if (m_underline) + flags |= gPainter::RT_UNDERLINE; + + if (isGradientSet() || m_blend) + flags |= gPainter::RT_BLEND; + int x = m_padding.x(); int y = m_padding.y(); @@ -75,7 +74,7 @@ int eLabel::event(int event, void *data, void *data2) auto position = eRect(x, y, w, h); /* if we don't have shadow, m_shadow_offset will be 0,0 */ auto shadowposition = eRect(position.x() - m_shadow_offset.x(), position.y() - m_shadow_offset.y(), position.width() - m_shadow_offset.x(), position.height() - m_shadow_offset.y()); - painter.renderText(shadowposition, m_text, flags, m_border_color, m_border_size, m_pos, &m_text_offset); + painter.renderText(shadowposition, m_text, flags, m_text_border_color, m_text_border_width, m_pos, &m_text_offset, m_tab_width); if (m_have_shadow_color) { @@ -83,8 +82,11 @@ int eLabel::event(int event, void *data, void *data2) style->setStyle(painter, eWindowStyle::styleLabel); else painter.setForegroundColor(m_foreground_color); + painter.setBackgroundColor(m_shadow_color); - painter.renderText(position, m_text, flags, gRGB(), 0, m_pos); + + painter.renderText(position, m_text, flags, gRGB(), 0, m_pos, &m_text_shaddowoffset, m_tab_width); + } return 0; @@ -120,11 +122,6 @@ void eLabel::setFont(gFont *font) event(evtChangedFont); } -gFont *eLabel::getFont() -{ - return m_font; -} - void eLabel::setVAlign(int align) { m_valign = align; @@ -147,6 +144,25 @@ void eLabel::setForegroundColor(const gRGB &col) } } +gRGB eLabel::getForegroundColor(int styleID) +{ + if (m_have_foreground_color) + return m_foreground_color; + + ePtr mgr; + eWindowStyleManager::getInstance(mgr); + + if (mgr) { + ePtr style; + mgr->getStyle(styleID, style); + if(style) + { + return style->getColor(eWindowStyleSkinned::colForeground); + } + } + return gRGB(0xFFFFFF); +} + void eLabel::setShadowColor(const gRGB &col) { if ((!m_have_shadow_color) || (m_shadow_color != col)) @@ -157,30 +173,39 @@ void eLabel::setShadowColor(const gRGB &col) } } -void eLabel::setShadowOffset(const ePoint &offset) +void eLabel::setTextBorderColor(const gRGB &col) { - m_shadow_offset = offset; + if (m_text_border_color != col) + { + m_text_border_color = col; + invalidate(); + } } -void eLabel::setBorderColor(const gRGB &col) +void eLabel::setWrap(int wrap) { - if (m_border_color != col) + if (m_wrap != wrap) { - m_border_color = col; + m_wrap = wrap; invalidate(); } } -void eLabel::setBorderWidth(int size) +void eLabel::setUnderline(bool underline) { - m_border_size = size; + if (m_underline != underline) + { + m_underline = underline; + invalidate(); + } } -void eLabel::setWrap(int wrap) +void eLabel::setAlphatest(int alphatest) { - if (m_wrap != wrap) + bool blend = (alphatest > 0); // blend if BT_ALPHATEST or BT_ALPHABLEND + if (m_blend != blend) { - m_wrap = wrap; + m_blend = blend; invalidate(); } } @@ -194,6 +219,21 @@ void eLabel::clearForegroundColor() } } +void eLabel::setTabWidth(int width) +{ + if (width == -1) + { + eTextPara para(eRect(0, 0, 1000, 1000)); + para.setFont(m_font); + para.renderString("W", 0); + m_tab_width = para.getBoundBox().size().width() * 8; + } + else + { + m_tab_width = width; + } +} + eSize eLabel::calculateSize() { return calculateTextSize(m_font, m_text, size(), m_wrap == 0); diff --git a/lib/gui/elabel.h b/lib/gui/elabel.h index 44f336c98..8a445dc05 100644 --- a/lib/gui/elabel.h +++ b/lib/gui/elabel.h @@ -10,7 +10,7 @@ class eLabel : public eWidget void setText(const std::string &string); void setMarkedPos(int markedPos); void setFont(gFont *font); - gFont *getFont(); + gFont *getFont() { return m_font; } enum { @@ -28,16 +28,20 @@ class eLabel : public eWidget void setForegroundColor(const gRGB &col); void setShadowColor(const gRGB &col); - void setShadowOffset(const ePoint &offset); - void setBorderColor(const gRGB &col); - void setBorderWidth(int size); + void setShadowOffset(const ePoint &offset) { m_shadow_offset = offset; } + void setBorderColor(const gRGB &col) override { setTextBorderColor(col); } // WILL BE CHANGED !!!! + void setBorderWidth(int width) override { setTextBorderWidth(width); } // WILL BE CHANGED !!!! + void setTextBorderColor(const gRGB &col); + void setTextBorderWidth(int width) { m_text_border_width = width; } void setWrap(int wrap); void setNoWrap(int nowrap) { setWrap((nowrap == 1) ? 0 : 1); } // DEPRECATED + void setUnderline(bool underline); void clearForegroundColor(); int getWrap() const { return m_wrap; } int getNoWrap() const { return (m_wrap == 0) ? 1 : 0; } // DEPRECATED - void setTextPadding(const eRect &padding) { m_padding = padding; } - + void setAlphatest(int alphatest); + void setTabWidth(int width); + gRGB getForegroundColor(int styleID = 0 ); eSize calculateSize(); static eSize calculateTextSize(gFont *font, const std::string &string, eSize targetSize, bool nowrap = false); @@ -47,15 +51,19 @@ class eLabel : public eWidget std::string m_text; int event(int event, void *data = 0, void *data2 = 0); int m_pos; - int m_text_offset; + int m_text_offset = 0; + int m_text_shaddowoffset = 0; private: - int m_have_foreground_color, m_have_shadow_color; - gRGB m_foreground_color, m_shadow_color, m_border_color; + int m_have_foreground_color = 0; + int m_have_shadow_color = 0; + gRGB m_foreground_color, m_shadow_color, m_text_border_color; ePoint m_shadow_offset; - eRect m_padding = eRect(0, 0, 0, 0); - int m_border_size; - int m_wrap; + int m_text_border_width = 0; + int m_wrap = 1; + bool m_blend = false; + bool m_underline = false; + int m_tab_width = -1; enum eLabelEvent { diff --git a/lib/gui/eslider.cpp b/lib/gui/eslider.cpp index 4494f6daa..2d32a7475 100644 --- a/lib/gui/eslider.cpp +++ b/lib/gui/eslider.cpp @@ -1,13 +1,13 @@ #include +#include int eSlider::defaultSliderBorderWidth = eSlider::DefaultBorderWidth; eSlider::eSlider(eWidget *parent) - :eWidget(parent), m_have_border_color(false), m_have_foreground_color(false), m_have_background_color(false), m_scrollbar(false), m_pixel_mode(false), - m_min(0), m_max(0), m_value(0), m_start(0), m_orientation(orHorizontal), m_orientation_swapped(0), - m_border_width(0), m_scale(0) + : eWidget(parent), m_have_slider_border_color(false), m_have_foreground_color(false), m_scrollbar(false), m_pixel_mode(false), + m_min(0), m_max(0), m_value(0), m_start(0), m_slider_border_width(0), m_orientation(orHorizontal), m_orientation_swapped(0) { - m_border_width = eSlider::defaultSliderBorderWidth; + m_slider_border_width = eSlider::defaultSliderBorderWidth; } void eSlider::setIsScrollbar() @@ -46,19 +46,6 @@ void eSlider::setPixmapScale(int flags) } } -void eSlider::setBorderWidth(int width) -{ - m_border_width=width; - invalidate(); -} - -void eSlider::setBorderColor(const gRGB &color) -{ - m_border_color=color; - m_have_border_color=true; - invalidate(); -} - void eSlider::setForegroundColor(const gRGB &color) { m_foreground_color = color; @@ -68,8 +55,7 @@ void eSlider::setForegroundColor(const gRGB &color) void eSlider::setBackgroundColor(const gRGB &color) { - m_background_color = color; - m_have_background_color = true; + eWidget::setBackgroundColor(color); invalidate(); } @@ -89,48 +75,134 @@ int eSlider::event(int event, void *data, void *data2) eSize s(size()); getStyle(style); + /* paint background */ - eWidget::event(evtPaint, data, data2); + const int cornerRadius = getCornerRadius(); + if (!cornerRadius && !isGradientSet()) // don't call eWidget paint if radius or gradient + eWidget::event(evtPaint, data, data2); + + gPainter &painter = *(gPainter *)data2; - gPainter &painter = *(gPainter*)data2; + bool drawborder = (m_slider_border_width > 0); if (m_backgroundpixmap) { + if (cornerRadius) + painter.setRadius(cornerRadius, getCornerRadiusEdges()); painter.blit(m_backgroundpixmap, ePoint(0, 0), eRect(), isTransparent() ? gPainter::BT_ALPHATEST : 0); } - else if(m_have_background_color) { + else if (m_have_background_color && !cornerRadius && !m_background_gradient_set) + { painter.setBackgroundColor(m_background_color); painter.clear(); } + else if (!cornerRadius && !m_background_gradient_set) + { + style->setStyle(painter, m_scrollbar ? eWindowStyle::styleScollbar : eWindowStyle::styleSlider); + } + + if (cornerRadius || m_background_gradient_set) + { + painter.setRadius(cornerRadius, getCornerRadiusEdges()); + + if (drawborder) + { + if (m_have_slider_border_color) + painter.setBackgroundColor(m_slider_border_color); + else + { + const gRGB color = style->getColor(m_scrollbar ? eWindowStyleSkinned::colScrollbarBorder : eWindowStyleSkinned::colSliderBorder); + painter.setBackgroundColor(color); + } + painter.drawRectangle(eRect(ePoint(0, 0), size())); + if(m_background_gradient_set) { + if (m_orientation == orHorizontal) + painter.setGradient(m_background_gradient_colors, 2, m_background_gradient_alphablend, 0); + else + painter.setGradient(m_background_gradient_colors, 1, m_background_gradient_alphablend, 0); + } + else + painter.setBackgroundColor(m_have_background_color ? m_background_color : gRGB(0, 0, 0)); + painter.setRadius(cornerRadius, getCornerRadiusEdges()); + painter.drawRectangle(eRect(m_slider_border_width, m_slider_border_width, size().width() - m_slider_border_width * 2, size().height() - m_slider_border_width * 2)); + drawborder = false; + } + else if(m_have_background_color) + { + painter.setBackgroundColor(m_background_color); + painter.drawRectangle(eRect(ePoint(0, 0), size())); + } + else + { + style->setStyle(painter, m_scrollbar ? eWindowStyle::styleScollbar : eWindowStyle::styleSlider); + } + } - style->setStyle(painter, m_scrollbar ? eWindowStyle::styleScollbar : eWindowStyle::styleSlider ); if (!m_pixmap) { - if (m_have_foreground_color) - painter.setForegroundColor(m_foreground_color); - painter.fill(m_currently_filled); + if (cornerRadius || m_foreground_gradient_set) + { + if (m_foreground_gradient_set) + { + if (m_orientation == orHorizontal) + painter.setGradient(m_foreground_gradient_colors, 2, m_foreground_gradient_alphablend, m_foreground_gradient_fullcolor ? 0 : m_currently_filled.extends.size().height()); + else + painter.setGradient(m_foreground_gradient_colors, 1, m_foreground_gradient_alphablend, m_foreground_gradient_fullcolor ? 0 : m_currently_filled.extends.size().width()); + } + else + { + if (m_have_foreground_color) + { + painter.setBackgroundColor(m_foreground_color); + } + else + { + const gRGB color = style->getColor(m_scrollbar ? eWindowStyleSkinned::colScrollbarForeground : eWindowStyleSkinned::colSliderForeground); + painter.setBackgroundColor(color); + } + } + painter.setRadius(cornerRadius, getCornerRadiusEdges()); + eRect rect = eRect(m_currently_filled.extends); + if (m_orientation == orHorizontal) + rect.setHeight(size().height() - m_slider_border_width * 2); + else + rect.setWidth(size().width() - m_slider_border_width * 2); + painter.drawRectangle(rect); + } + else + { + if (m_have_foreground_color) + painter.setForegroundColor(m_foreground_color); + painter.fill(m_currently_filled); + } } - else { + else + { + if (cornerRadius) + painter.setRadius(cornerRadius, getCornerRadiusEdges()); + if(m_scale && (m_pixmap->size().width() != m_currently_filled.extends.width() || m_pixmap->size().height() != m_currently_filled.extends.height())) - painter.blitScale(m_pixmap, eRect(ePoint(0,0),s),m_currently_filled.extends, isTransparent() ? gPainter::BT_ALPHATEST : 0); + painter.blitScale(m_pixmap, eRect(ePoint(0,0),s),m_currently_filled.extends, isTransparent() ? gPainter::BT_ALPHATEST : 0, m_scale); else painter.blit(m_pixmap, ePoint(0, 0), m_currently_filled.extends, isTransparent() ? gPainter::BT_ALPHATEST : 0); + } // Border - if(m_border_width>0) { + if (drawborder) + { - if (m_have_border_color) - painter.setForegroundColor(m_border_color); - else { - style->setStyle(painter, m_scrollbar ? eWindowStyle::styleScollbarBorder : eWindowStyle::styleSliderBorder ); + if (m_have_slider_border_color) + painter.setForegroundColor(m_slider_border_color); + else + { + style->setStyle(painter, m_scrollbar ? eWindowStyle::styleScollbarBorder : eWindowStyle::styleSliderBorder); } - - painter.fill(eRect(0, 0, s.width(), m_border_width)); - painter.fill(eRect(0, m_border_width, m_border_width, s.height() - m_border_width)); - painter.fill(eRect(m_border_width, s.height() - m_border_width, s.width() - m_border_width, m_border_width)); - painter.fill(eRect(s.width() - m_border_width, m_border_width, m_border_width, s.height() - m_border_width)); + painter.fill(eRect(0, 0, s.width(), m_slider_border_width)); + painter.fill(eRect(0, m_slider_border_width, m_slider_border_width, s.height() - m_slider_border_width)); + painter.fill(eRect(m_slider_border_width, s.height() - m_slider_border_width, s.width() - m_slider_border_width, m_slider_border_width)); + painter.fill(eRect(s.width() - m_slider_border_width, m_slider_border_width, m_slider_border_width, s.height() - m_slider_border_width)); } return 0; @@ -138,32 +210,33 @@ int eSlider::event(int event, void *data, void *data2) case evtChangedSlider: { int num_pix = 0, start_pix = 0; - gRegion old_currently_filled = m_currently_filled; + const gRegion old_currently_filled = m_currently_filled; // calculate the pixel size of the thumb - int offset = m_border_width * 2; - int pixsize = (m_orientation == orHorizontal) ? size().width()-offset : size().height()-offset; + const int offset = m_slider_border_width * 2; + const int pixsize = (m_orientation == orHorizontal) ? size().width() - offset : size().height() - offset; if (m_min < m_max) { int val_range = m_max - m_min; - if(m_pixel_mode) { + if (m_pixel_mode) + { // don't round - start_pix = m_start + m_border_width; - num_pix = m_value - m_start + m_border_width; + start_pix = m_start + m_slider_border_width; + num_pix = m_value - m_start + m_slider_border_width; } - else { + else + { // calculate the start_pix and num_pix with correct scaling and repective borderwidth - start_pix = (m_start * pixsize / val_range) + m_border_width; - num_pix = (m_value * pixsize / val_range) + m_border_width - start_pix; + start_pix = (m_start * pixsize / val_range) + m_slider_border_width; + num_pix = (m_value * pixsize / val_range) + m_slider_border_width - start_pix; } if (m_orientation_swapped) start_pix = pixsize - num_pix - start_pix; - } - if (start_pix < 0) + if (start_pix < 0) { num_pix += start_pix; start_pix = 0; @@ -173,14 +246,24 @@ int eSlider::event(int event, void *data, void *data2) num_pix = 0; if (m_orientation == orHorizontal) - m_currently_filled = eRect(start_pix, m_border_width, num_pix, pixsize); + m_currently_filled = eRect(start_pix, m_slider_border_width, num_pix, pixsize); else - m_currently_filled = eRect(m_border_width, start_pix, pixsize, num_pix); + m_currently_filled = eRect(m_slider_border_width, start_pix, pixsize, num_pix); - // redraw what *was* filled before and now isn't. - invalidate(m_currently_filled - old_currently_filled); - // redraw what wasn't filled before and is now. - invalidate(old_currently_filled - m_currently_filled); + const int cornerRadius = getCornerRadius(); + + if (cornerRadius) + { + invalidate(old_currently_filled); + invalidate(m_currently_filled); + } + else + { + // redraw what *was* filled before and now isn't. + invalidate(m_currently_filled - old_currently_filled); + // redraw what wasn't filled before and is now. + invalidate(old_currently_filled - m_currently_filled); + } return 0; } @@ -203,7 +286,7 @@ void eSlider::setStartEnd(int start, int end, bool pixel) event(evtChangedSlider); } -void eSlider::setOrientation(int orientation, int swapped) +void eSlider::setOrientation(uint8_t orientation, uint8_t swapped) { m_orientation = orientation; m_orientation_swapped = swapped; @@ -257,3 +340,51 @@ void eSlider::setScrollbarBackgroundColor(const gRGB &color) { setBackgroundColor(color); } + +void eSlider::setScrollbarBackgroundGradient(const gRGB &startcolor, const gRGB &midcolor, const gRGB &endcolor, uint8_t direction, bool alphablend) +{ + setBackgroundGradient(startcolor, midcolor, endcolor, direction, alphablend); +} + +void eSlider::setScrollbarForegroundGradient(const gRGB &startcolor, const gRGB &midcolor, const gRGB &endcolor, uint8_t direction, bool alphablend, bool fullColor) +{ + setForegroundGradient(startcolor, midcolor, endcolor, direction, alphablend, fullColor); +} + +void eSlider::setForegroundGradient(const gRGB &startcolor, const gRGB &midcolor, const gRGB &endcolor, uint8_t direction, bool alphablend, bool fullColor) +{ + m_foreground_gradient_colors = {startcolor, midcolor, endcolor}; + m_foreground_gradient_direction = direction; + m_foreground_gradient_alphablend = alphablend; + m_foreground_gradient_fullcolor = fullColor; + m_foreground_gradient_set = true; + invalidate(); +} + +void eSlider::setForegroundGradient(const std::vector &colors, uint8_t direction, bool alphablend, bool fullColor) +{ + m_foreground_gradient_colors = colors; + m_foreground_gradient_direction = direction; + m_foreground_gradient_alphablend = alphablend; + m_foreground_gradient_fullcolor = fullColor; + m_foreground_gradient_set = true; + invalidate(); +} + +void eSlider::setBackgroundGradient(const gRGB &startcolor, const gRGB &midcolor, const gRGB &endcolor, uint8_t direction, bool alphablend) +{ + m_background_gradient_colors = {startcolor, midcolor, endcolor}; + m_background_gradient_direction = direction; + m_background_gradient_alphablend = alphablend; + m_background_gradient_set = true; + invalidate(); +} + +void eSlider::setBackgroundGradient(const std::vector &colors, uint8_t direction, bool alphablend) +{ + m_background_gradient_colors = colors; + m_background_gradient_direction = direction; + m_background_gradient_alphablend = alphablend; + m_background_gradient_set = true; + invalidate(); +} diff --git a/lib/gui/ewidget.cpp b/lib/gui/ewidget.cpp index 967ec0cb3..a0871c8e1 100644 --- a/lib/gui/ewidget.cpp +++ b/lib/gui/ewidget.cpp @@ -3,14 +3,13 @@ extern void dumpRegion(const gRegion ®ion); -eWidget::eWidget(eWidget *parent): m_animation(this), m_parent(parent ? parent->child() : 0) +eWidget::eWidget(eWidget *parent) : m_animation(this), m_parent(parent ? parent->child() : 0) { m_gradient_set = false; m_gradient_direction = 0; m_vis = 0; m_layer = 0; m_desktop = 0; - m_have_background_color = 0; m_z_position = 0; m_lowered = 0; m_client_offset = eSize(0, 0); @@ -25,6 +24,11 @@ eWidget::eWidget(eWidget *parent): m_animation(this), m_parent(parent ? parent-> m_current_focus = 0; m_focus_owner = 0; m_notify_child_on_position_change = 1; + m_cornerRadius = 0; + m_cornerRadiusEdges = 0; + m_have_border_color = false; + m_border_width = 0; + m_padding = eRect(0, 0, 0, 0); } void eWidget::move(ePoint pos) @@ -59,6 +63,17 @@ void eWidget::resize(eSize size) eSize old_offset = m_client_offset; m_client_size = size; m_client_offset = eSize(0, 0); + if (m_cornerRadius > 0) + { + const int w = size.width(); + const int h = size.height(); + // eDebug("[eWidget] resize m_cornerRadius %d / w %d / h %d / w half %d / w even %d", m_cornerRadius, w, h, w / 2, w % 2); + if (w > -1 && w == h && (w % 2 != 0) && m_cornerRadius >= w / 2) + { + size = eSize(w - 1, h - 1); + m_client_size = size; + } + } event(evtWillChangeSize, &size, &m_client_offset); if (old_size == m_size) return; @@ -70,7 +85,8 @@ void eWidget::resize(eSize size) for (ePtrList::iterator i(m_childs.begin()); i != m_childs.end(); ++i) i->event(evtParentChangedPosition); /* position/size is the same here */ - recalcClipRegionsWhenVisible(); invalidate(); + recalcClipRegionsWhenVisible(); + invalidate(); } void eWidget::invalidate(const gRegion ®ion) @@ -108,7 +124,8 @@ void eWidget::invalidate(const gRegion ®ion) res.moveBy(abspos); // eDebug("[eWidget] region to invalidate:"); // dumpRegion(res); - if (root && root->m_desktop){ + if (root && root->m_desktop) + { root->m_desktop->invalidate(res, this, target_layer); } } @@ -122,7 +139,7 @@ void eWidget::show() // eDebug("[eWidget] show widget %p", this); notifyShowHide(); - /* TODO: optimize here to only recalc what's required. possibly merge with hide. */ + /* TODO: optimize here to only recalc what's required. possibly merge with hide. */ eWidget *root = this; ePoint abspos = position(); int target_layer = m_layer; @@ -144,7 +161,8 @@ void eWidget::show() abspos += root->position(); } - if (root && root->m_desktop){ + if (root && root->m_desktop) + { root->m_desktop->recalcClipRegions(root); gRegion abs = m_visible_with_childs; @@ -180,7 +198,8 @@ void eWidget::hide() } ASSERT(root->m_desktop); - if (root && root->m_desktop){ + if (root && root->m_desktop) + { gRegion abs = m_visible_with_childs; abs.moveBy(abspos); @@ -191,7 +210,8 @@ void eWidget::hide() void eWidget::raise() { - if (m_lowered <= 0) return; + if (m_lowered <= 0) + return; m_lowered--; setZPosition(m_z_position + 1); } @@ -212,12 +232,7 @@ void eWidget::destruct() void eWidget::setBackgroundColor(const gRGB &col) { m_background_color = col; - m_have_background_color = 1; -} - -void eWidget::clearBackgroundColor() -{ - m_have_background_color = 0; + m_have_background_color = true; } void eWidget::setZPosition(int z) @@ -236,7 +251,7 @@ void eWidget::setTransparent(int transp) if (transp) m_vis |= wVisTransparent; else - m_vis &=~wVisTransparent; + m_vis &= ~wVisTransparent; recalcClipRegionsWhenVisible(); } } @@ -347,7 +362,7 @@ void eWidget::recalcClipRegionsWhenVisible() eLogNoNewLine(lvlError, "Top level parent at (%d,%d)=>(%d,%d) has no desktop", t->position().x(), t->position().y(), t->size().width(), t->size().height()); } t = t->m_parent; - } while(t); + } while (t); } void eWidget::parentRemoved() @@ -361,25 +376,58 @@ int eWidget::event(int event, void *data, void *data2) { case evtPaint: { - gPainter &painter = *(gPainter*)data2; - // eDebug("[eWidget] evtPaint"); -// dumpRegion(*(gRegion*)data); + gPainter &painter = *(gPainter *)data2; + // eDebug("[eWidget] evtPaint"); + // dumpRegion(*(gRegion*)data); if (!isTransparent()) { + bool drawborder = (m_have_border_color && m_border_width); + if (m_gradient_set) - painter.drawGradient(eRect(ePoint(0, 0), size()), m_gradient_startcolor, m_gradient_endcolor, m_gradient_direction, m_gradient_blend); - else if (!m_have_background_color) + painter.setGradient(m_gradient_colors, m_gradient_direction, m_gradient_alphablend); + if (m_have_background_color) + painter.setBackgroundColor(m_background_color); + const int r = getCornerRadius(); + if (r || m_gradient_set) { - ePtr style; - if (!getStyle(style)) - style->paintBackground(painter, ePoint(0, 0), size()); - } + if (r) + painter.setRadius(r, m_cornerRadiusEdges); + if (r && drawborder) + { + painter.setBackgroundColor(m_border_color); + painter.drawRectangle(eRect(ePoint(0, 0), size())); + if (r) + painter.setRadius(r, m_cornerRadiusEdges); + painter.setBackgroundColor(m_have_background_color ? m_background_color : gRGB(0, 0, 0)); + painter.drawRectangle(eRect(m_border_width, m_border_width, size().width() - m_border_width * 2, size().height() - m_border_width * 2)); + drawborder = false; + } + else + painter.drawRectangle(eRect(ePoint(0, 0), size())); + } else { - painter.setBackgroundColor(m_background_color); - painter.clear(); + if (!m_have_background_color) + { + ePtr style; + if (!getStyle(style)) + style->paintBackground(painter, ePoint(0, 0), size()); + } + else + { + painter.clear(); + } } - } + if (drawborder) + { + painter.setForegroundColor(m_border_color); + eSize s(size()); + painter.fill(eRect(0, 0, s.width(), m_border_width)); + painter.fill(eRect(0, m_border_width, m_border_width, s.height() - m_border_width)); + painter.fill(eRect(m_border_width, s.height() - m_border_width, s.width() - m_border_width, m_border_width)); + painter.fill(eRect(s.width() - m_border_width, m_border_width, m_border_width, s.height() - m_border_width)); + } + } else { eWidget *w = this; @@ -394,17 +442,17 @@ int eWidget::event(int event, void *data, void *data2) case evtKey: break; case evtWillChangeSize: - m_size = *static_cast(data); + m_size = *static_cast(data); break; case evtChangedSize: - m_clip_region = gRegion(eRect(ePoint(0, 0), m_size)); + m_clip_region = gRegion(eRect(ePoint(0, 0), m_size)); break; case evtParentChangedPosition: for (ePtrList::iterator i(m_childs.begin()); i != m_childs.end(); ++i) i->event(evtParentChangedPosition); break; case evtFocusGot: - m_focus_owner = (eWidget*)data; + m_focus_owner = (eWidget *)data; break; case evtFocusLost: m_focus_owner = 0; @@ -432,12 +480,37 @@ void eWidget::notifyShowHide() i->notifyShowHide(); } -void eWidget::setBackgroundGradient(const gRGB &startcolor, const gRGB &endcolor, int direction, int blend) +void eWidget::setBackgroundGradient(const gRGB &startcolor, const gRGB &midcolor, const gRGB &endcolor, uint8_t direction, bool alphablend) { - m_gradient_startcolor = startcolor; - m_gradient_endcolor = endcolor; + m_gradient_colors = {startcolor, midcolor, endcolor}; m_gradient_direction = direction; - m_gradient_blend = blend; + m_gradient_alphablend = alphablend; m_gradient_set = true; invalidate(); } + +void eWidget::setCornerRadius(int radius, uint8_t edges) +{ + m_cornerRadius = radius; + m_cornerRadiusEdges = edges; + invalidate(); +} + +int eWidget::getCornerRadius() +{ + int r = m_cornerRadius; + if (r) + { + const int w = m_size.width(); + const int h = m_size.height(); + if (w && h) + { + int minDimension = (w < h) ? w : h; + if (r > minDimension / 2) + { + r = minDimension / 2; + } + } + } + return r; +} diff --git a/lib/gui/ewidget.h b/lib/gui/ewidget.h index fc8b16598..70b19ff3d 100644 --- a/lib/gui/ewidget.h +++ b/lib/gui/ewidget.h @@ -5,6 +5,7 @@ #include /* for eSmartPtrList */ #include /* for eWindowStyle */ #include +#include #define MAX_LAYER 16 @@ -24,7 +25,7 @@ class eWidget eSize size() const { return m_size; } eSize csize() const { return m_client_size; } - void invalidate(const gRegion ®ion = gRegion::invalidRegion()); + virtual void invalidate(const gRegion ®ion = gRegion::invalidRegion()); /* the window were to attach childs to. Normally, this is "this", but it can be overridden in case a widget @@ -45,8 +46,24 @@ class eWidget SWIG_VOID(int) getStyle(ePtr &SWIG_NAMED_OUTPUT(style)) { if (!m_style) return 1; style = m_style; return 0; } void setStyle(eWindowStyle *style) { m_style = style; } - void setBackgroundColor(const gRGB &col); - void clearBackgroundColor(); + virtual void setBackgroundColor(const gRGB &col); + virtual void clearBackgroundColor() { m_have_background_color = false; } + + virtual void setBorderWidth(int width) { setWidgetBorderWidth(width); } + virtual void setBorderColor(const gRGB &color) { setWidgetBorderColor(color); } + + virtual void setWidgetBorderWidth(int width) { + m_border_width = width; + invalidate(); + } + virtual void setWidgetBorderColor(const gRGB &color) { + m_border_color = color; + m_have_border_color = true; + invalidate(); + } + + virtual void setPadding(const eRect &padding) { m_padding = padding; } + virtual eRect getPadding() { return m_padding; } void setZPosition(int z); void setTransparent(int transp); @@ -89,8 +106,6 @@ class eWidget void parentRemoved(); - gRGB m_background_color; - int m_have_background_color; eWidget *m_current_focus, *m_focus_owner; @@ -99,11 +114,25 @@ class eWidget int m_notify_child_on_position_change; bool m_gradient_set; - int m_gradient_direction, m_gradient_blend; - gRGB m_gradient_startcolor, m_gradient_endcolor; + bool m_gradient_alphablend; + uint8_t m_gradient_direction; + std::vector m_gradient_colors; + + int m_cornerRadius; + uint8_t m_cornerRadiusEdges; + protected: void mayKillFocus(); + + gRGB m_background_color; + bool m_have_background_color = false; + + bool m_have_border_color; + int m_border_width; + gRGB m_border_color; + eRect m_padding; + public: // all in local space! @@ -138,12 +167,32 @@ class eWidget void notifyShowHide(); - void setBackgroundGradient(const gRGB &startcolor, const gRGB &endcolor, int direction, int blend); + void setBackgroundGradient(const gRGB &startcolor, const gRGB &midcolor, const gRGB &endcolor, uint8_t direction, bool alphablend); + + void setCornerRadius(int radius, uint8_t edges); + uint8_t getCornerRadiusEdges() {return m_cornerRadiusEdges;} + int getCornerRadius(); + + bool isGradientSet() {return m_gradient_set;} + + enum + { + GRADIENT_OFF = 0, + GRADIENT_VERTICAL = 1, + GRADIENT_HORIZONTAL = 2 + }; enum { - GRADIENT_VERTICAL = 0, - GRADIENT_HORIZONTAL = 1 + RADIUS_TOP_LEFT = 1, + RADIUS_TOP_RIGHT = 2, + RADIUS_TOP = 3, + RADIUS_BOTTOM_LEFT = 4, + RADIUS_BOTTOM_RIGHT = 8, + RADIUS_BOTTOM = 12, + RADIUS_LEFT = 5, + RADIUS_RIGHT = 10, + RADIUS_ALL = 15, }; }; diff --git a/lib/gui/ewidgetdesktop.cpp b/lib/gui/ewidgetdesktop.cpp index 8a443f3c4..5cbd40b64 100644 --- a/lib/gui/ewidgetdesktop.cpp +++ b/lib/gui/ewidgetdesktop.cpp @@ -59,7 +59,7 @@ int eWidgetDesktop::movedWidget(eWidget *root) return 0; /* native move ok */ } -void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible) +void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible, bool parent) { /* start with our clip region, clipped with the parent's */ if (widget->m_vis & eWidget::wVisShow) @@ -68,7 +68,7 @@ void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visib widget->m_visible_region.moveBy(widget->position()); widget->m_visible_region &= parent_visible; // in parent space! - if (!widget->isTransparent()) + if (!widget->isTransparent() && (!widget->m_gradient_alphablend || parent) && (widget->m_cornerRadius == 0 || parent)) /* remove everything this widget will contain from parent's visible list, unless widget is transparent. */ parent_visible -= widget->m_visible_region; // will remove child regions too! @@ -87,7 +87,7 @@ void eWidgetDesktop::calcWidgetClipRegion(eWidget *widget, gRegion &parent_visib if (i != widget->m_childs.end()) { if (i->m_vis & eWidget::wVisShow) - calcWidgetClipRegion(*i, widget->m_visible_region); + calcWidgetClipRegion(*i, widget->m_visible_region, false); else clearVisibility(*i); } @@ -301,6 +301,12 @@ void eWidgetDesktop::paintLayer(eWidget *widget, int layer) return; gPainter painter(comp->m_dc); painter.moveOffset(-comp->m_position); + if (widget->m_cornerRadius > 0 || widget->m_gradient_set) + { + painter.resetClip(comp->m_dirty_region); + painter.setBackgroundColor(gRGB(0, 0, 0, 0xFF)); + painter.clear(); + } widget->doPaint(painter, comp->m_dirty_region, layer); painter.resetOffset(); } diff --git a/lib/gui/ewidgetdesktop.h b/lib/gui/ewidgetdesktop.h index 7f76430fc..a4c39e0ad 100644 --- a/lib/gui/ewidgetdesktop.h +++ b/lib/gui/ewidgetdesktop.h @@ -80,7 +80,7 @@ class eWidgetDesktop: public sigc::trackable void setMargins(const eRect& value) { m_margins = value; } private: ePtrList m_root; - void calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible); + void calcWidgetClipRegion(eWidget *widget, gRegion &parent_visible, bool parent = true); void paintBackground(eWidgetDesktopCompBuffer *comp); eMainloop *m_mainloop; diff --git a/lib/gui/ewindow.cpp b/lib/gui/ewindow.cpp index 854d3be80..f05f1073a 100644 --- a/lib/gui/ewindow.cpp +++ b/lib/gui/ewindow.cpp @@ -157,9 +157,16 @@ void eWindow::setAnimationMode(int mode) m_animation_mode = (eWindow::m_has_animation_mode==1) ? mode : 0; } -void eWindow::setBackgroundGradient(const gRGB &startcolor, const gRGB &endcolor, int direction, int blend) +void eWindow::setBackgroundGradient(const gRGB &startcolor, const gRGB &midcolor, const gRGB &endcolor, uint8_t direction, bool alphablend) { /* set background gradient for child, too */ - eWidget::setBackgroundGradient(startcolor,endcolor,direction,blend); - m_child->setBackgroundGradient(startcolor,endcolor,direction,blend); + eWidget::setBackgroundGradient(startcolor, midcolor, endcolor, direction, alphablend); + m_child->setBackgroundGradient(startcolor, midcolor, endcolor, direction, alphablend); +} + +void eWindow::setCornerRadius(int radius, uint8_t edges) +{ + /* set corner radius for child, too */ + eWidget::setCornerRadius(radius, edges); + m_child->setCornerRadius(radius, edges); } diff --git a/lib/gui/ewindow.h b/lib/gui/ewindow.h index 3ea561fdf..66557a01e 100644 --- a/lib/gui/ewindow.h +++ b/lib/gui/ewindow.h @@ -22,8 +22,9 @@ class eWindow: public eWidget wfNoBorder = 1 }; - void setBackgroundColor(const gRGB &col); - void setBackgroundGradient(const gRGB &startcolor, const gRGB &endcolor, int direction, int blend); + void setBackgroundColor(const gRGB &col) override; + void setBackgroundGradient(const gRGB &startcolor, const gRGB &midcolor, const gRGB &endcolor, uint8_t direction, bool alphablend); + void setCornerRadius(int radius, uint8_t edges); void setFlag(int flags); void clearFlag(int flags); diff --git a/lib/gui/ewindowstyle.cpp b/lib/gui/ewindowstyle.cpp index b31065b61..64a1d6d39 100644 --- a/lib/gui/ewindowstyle.cpp +++ b/lib/gui/ewindowstyle.cpp @@ -129,6 +129,11 @@ void eWindowStyleSimple::setStyle(gPainter &painter, int what) } } +gRGB eWindowStyleSimple::getColor(int what) +{ + return nullptr; +} + void eWindowStyleSimple::drawFrame(gPainter &painter, const eRect &frame, int what) { gColor c1, c2; diff --git a/lib/gui/ewindowstyle.h b/lib/gui/ewindowstyle.h index c4c83afba..76240aff1 100644 --- a/lib/gui/ewindowstyle.h +++ b/lib/gui/ewindowstyle.h @@ -37,7 +37,8 @@ class eWindowStyle_ENUMS fontTitlebar, fontListbox, fontEntry, - fontValue + fontValue, + fontHeader }; }; @@ -55,6 +56,8 @@ class eWindowStyle: public eWindowStyle_ENUMS, public iObject virtual void setStyle(gPainter &painter, int what) = 0; virtual void drawFrame(gPainter &painter, const eRect &frame, int type) = 0; virtual RESULT getFont(int what, ePtr &font) = 0; + virtual gRGB getColor(int what) = 0; + virtual int getValue(int what) = 0; #endif virtual ~eWindowStyle() = 0; }; @@ -105,6 +108,8 @@ class eWindowStyleSimple: public eWindowStyle void setStyle(gPainter &painter, int what); void drawFrame(gPainter &painter, const eRect &frame, int what); RESULT getFont(int what, ePtr &font); + gRGB getColor(int what); + int getValue(int what) { return 0; } }; #endif diff --git a/lib/gui/ewindowstyleskinned.cpp b/lib/gui/ewindowstyleskinned.cpp index 0b274fa5d..1e2373bea 100644 --- a/lib/gui/ewindowstyleskinned.cpp +++ b/lib/gui/ewindowstyleskinned.cpp @@ -245,6 +245,9 @@ RESULT eWindowStyleSkinned::getFont(int what, ePtr &fnt) case fontValue: fnt = m_valuefnt; break; + case fontHeader: + fnt = m_headerfnt ? m_headerfnt : m_entryfnt; + break; case fontButton: fnt = new gFont("Regular", 20); break; @@ -311,6 +314,26 @@ void eWindowStyleSkinned::setColor(int what, const gRGB &col) m_color[what] = col; } +gRGB eWindowStyleSkinned::getColor(int what) +{ + if ((what < colMax) && (what >= 0)) + return m_color[what]; + return nullptr; +} + +void eWindowStyleSkinned::setValue(int what, int value) +{ + if ((what < valueMax) && (what >= 0)) + m_values[what] = value; +} + +int eWindowStyleSkinned::getValue(int what) +{ + if ((what < valueMax) && (what >= 0)) + return m_values[what]; + return 0; +} + void eWindowStyleSkinned::setTitleOffset(const eSize &offset) { m_title_offset = offset; @@ -340,3 +363,8 @@ void eWindowStyleSkinned::setValueFont(gFont *fnt) { m_valuefnt = fnt; } + +void eWindowStyleSkinned::setHeaderFont(gFont *fnt) +{ + m_headerfnt = fnt; +} diff --git a/lib/gui/ewindowstyleskinned.h b/lib/gui/ewindowstyleskinned.h index 79be5c2bf..5f1bfae0b 100644 --- a/lib/gui/ewindowstyleskinned.h +++ b/lib/gui/ewindowstyleskinned.h @@ -81,7 +81,13 @@ class eWindowStyleSkinned: public eWindowStyle colMax }; + enum { + valueEntryLeftOffset, + valueHeaderLeftOffset, + valueMax + }; void setColor(int what, const gRGB &back); + gRGB getColor(int what); void setTitleOffset(const eSize &offset); void setTitleFont(gFont *fnt); @@ -89,7 +95,10 @@ class eWindowStyleSkinned: public eWindowStyle void setListboxFont(gFont *fnt); void setEntryFont(gFont *fnt); void setValueFont(gFont *fnt); - + void setHeaderFont(gFont *fnt); + void setValue(int what, int value); + int getValue(int what); + private: struct borderSet { @@ -103,7 +112,9 @@ class eWindowStyleSkinned: public eWindowStyle gRGB m_color[colMax]; eSize m_title_offset; - ePtr m_fnt, m_labelfnt, m_listboxfnt, m_entryfnt, m_valuefnt; + ePtr m_fnt, m_labelfnt, m_listboxfnt, m_entryfnt, m_valuefnt, m_headerfnt; + + int m_values[valueMax] = {15, 15}; void drawBorder(gPainter &painter, const eRect &size, struct borderSet &border, int where, int flags); };