From bdef864bf323809cbcee3aac8a074a97ee64168b Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 20 Jul 2023 10:41:49 +0200 Subject: [PATCH] fluent2 scrollbars improved --- skins/fluent2/QskFluent2Skin.cpp | 46 ++++++++++++++++--- skins/fluent2/QskFluent2Theme.cpp | 4 ++ skins/fluent2/QskFluent2Theme.h | 5 ++ src/controls/QskScrollViewSkinlet.cpp | 66 +++++++++++++-------------- src/controls/QskScrollViewSkinlet.h | 2 + 5 files changed, 84 insertions(+), 39 deletions(-) diff --git a/skins/fluent2/QskFluent2Skin.cpp b/skins/fluent2/QskFluent2Skin.cpp index 51db94c3..66bbbe5a 100644 --- a/skins/fluent2/QskFluent2Skin.cpp +++ b/skins/fluent2/QskFluent2Skin.cpp @@ -1108,6 +1108,9 @@ void Editor::setupScrollViewMetrics() setMetric( aspect, 2 ); setMetric( aspect | Q::Hovered, 6 ); setMetric( aspect | Q::Pressed, 6 ); + + setBoxShape( subControl, 100, Qt::RelativeSize ); + setAnimation( subControl | A::Metric, 100 ); } /* @@ -1118,26 +1121,57 @@ void Editor::setupScrollViewMetrics() setAlignment( Q::VerticalScrollBar, Qt::AlignHCenter ); setAlignment( Q::HorizontalScrollBar, Qt::AlignVCenter ); + // handles + setBoxShape( Q::HorizontalScrollHandle, 100, Qt::RelativeSize ); setBoxShape( Q::VerticalScrollHandle, 100, Qt::RelativeSize ); const auto handleExtent = 40.0; setStrutSize( Q::HorizontalScrollHandle, handleExtent, 0.0 ); setStrutSize( Q::VerticalScrollHandle, 0.0, handleExtent ); - - for ( auto subControl : { Q::HorizontalScrollBar, Q::VerticalScrollBar } ) - setAnimation( subControl | A::Metric, 100 ); } void Editor::setupScrollViewColors( QskAspect::Section section, const QskFluent2Theme& theme ) { + using A = QskAspect; using Q = QskScrollView; - const auto fillColor = theme.palette.fillColor.controlStrong.defaultColor; + const auto& pal = theme.palette; - setGradient( Q::HorizontalScrollHandle | section, fillColor ); - setGradient( Q::VerticalScrollHandle | section, fillColor ); + { + const auto fillColor = pal.fillColor.controlStrong.defaultColor; + + setGradient( Q::HorizontalScrollHandle | section, fillColor ); + setGradient( Q::VerticalScrollHandle | section, fillColor ); + } + + for ( auto subControl : { Q::HorizontalScrollBar, Q::VerticalScrollBar } ) + { + auto fillColor = pal.fillColor.acrylic.background; + +#if 1 + /* + With Fluent2 the scroll bar is supposed to be on top of scrollable + item. QskScrollViewSkinlet does not support this yet and we + always have the scrollbar on top of the panel. For the light + scheme this leads to white on white, so we better shade the scrollbar + for the moment: TODO ... + */ + const auto v = qBlue( fillColor ); + if ( v > 250 ) + { + if ( v == qRed( fillColor ) && v == qGreen( fillColor ) ) + fillColor = qRgba( 240, 240, 240, qAlpha( fillColor ) ); + } +#endif + + setGradient( subControl, QskRgb::toTransparent( fillColor, 0 ) ); + setGradient( subControl | Q::Hovered, fillColor ); + setGradient( subControl | Q::Pressed, fillColor ); + + setAnimation( subControl | A::Color, 100 ); + } } void Editor::setupSegmentedBarMetrics() diff --git a/skins/fluent2/QskFluent2Theme.cpp b/skins/fluent2/QskFluent2Theme.cpp index 402d86cf..f7c20d30 100644 --- a/skins/fluent2/QskFluent2Theme.cpp +++ b/skins/fluent2/QskFluent2Theme.cpp @@ -77,6 +77,8 @@ QskFluent2Theme::QskFluent2Theme( QskSkin::ColorScheme colorScheme, colors.accent.tertiary = toTransparentF( accentColors.secondary, 0.80 ); colors.accent.disabled = rgbGray( 0, 0.2169 ); colors.accent.selectedTextBackground = accentColors.primary; + + colors.acrylic.background = rgbGray( 252, 0.85 ); } #if 0 @@ -198,6 +200,8 @@ QskFluent2Theme::QskFluent2Theme( QskSkin::ColorScheme colorScheme, colors.accent.tertiary = toTransparentF( accentColors.tertiary, 0.80 ); colors.accent.disabled = rgbGray( 255, 0.1581 ); colors.accent.selectedTextBackground = accentColors.primary; + + colors.acrylic.background = rgbGray( 44, 0.96 ); } #if 0 diff --git a/skins/fluent2/QskFluent2Theme.h b/skins/fluent2/QskFluent2Theme.h index 8aba499b..a4d18feb 100644 --- a/skins/fluent2/QskFluent2Theme.h +++ b/skins/fluent2/QskFluent2Theme.h @@ -107,6 +107,11 @@ class QSK_FLUENT2_EXPORT QskFluent2Theme QRgb disabled; QRgb selectedTextBackground; } accent; + + struct + { + QRgb background; + } acrylic; }; struct Elevation diff --git a/src/controls/QskScrollViewSkinlet.cpp b/src/controls/QskScrollViewSkinlet.cpp index 65c32ba7..70d2ba40 100644 --- a/src/controls/QskScrollViewSkinlet.cpp +++ b/src/controls/QskScrollViewSkinlet.cpp @@ -39,6 +39,16 @@ static void qskAlignedHandle( qreal start, qreal end, } } +static inline Qt::Orientation qskSubcontrolOrientation( QskAspect::Subcontrol subControl ) +{ + using Q = QskScrollView; + + if ( subControl == Q::HorizontalScrollBar || subControl == Q::HorizontalScrollHandle ) + return Qt::Horizontal; + else + return Qt::Vertical; +} + QskScrollViewSkinlet::QskScrollViewSkinlet( QskSkin* skin ) : Inherited( skin ) { @@ -87,55 +97,45 @@ QSGNode* QskScrollViewSkinlet::updateSubNode( switch ( nodeRole ) { case PanelRole: - { return updateBoxNode( skinnable, node, Q::Panel ); - } + case ViewportRole: - { return updateBoxNode( skinnable, node, Q::Viewport ); - } case HorizontalScrollHandleRole: - { - const auto rect = subControlRect( skinnable, - scrollView->contentsRect(), Q::HorizontalScrollHandle ); - - QskSkinStateChanger stateChanger( scrollView ); - stateChanger.setStates( scrollView->scrollHandleStates( Qt::Horizontal ) ); - - return updateBoxNode( skinnable, node, rect, Q::HorizontalScrollHandle ); - } + return updateScrollBarNode( scrollView, Q::HorizontalScrollHandle, node ); case VerticalScrollHandleRole: - { - const auto rect = subControlRect( skinnable, - scrollView->contentsRect(), Q::VerticalScrollHandle ); - - QskSkinStateChanger stateChanger( scrollView ); - stateChanger.setStates( scrollView->scrollHandleStates( Qt::Vertical ) ); - - return updateBoxNode( skinnable, node, rect, Q::VerticalScrollHandle ); - } - - case ContentsRootRole: - { - return updateContentsRootNode( scrollView, node ); - } + return updateScrollBarNode( scrollView, Q::VerticalScrollHandle, node ); case HorizontalScrollBarRole: - { - return updateBoxNode( skinnable, node, Q::HorizontalScrollBar ); - } + return updateScrollBarNode( scrollView, Q::HorizontalScrollBar, node ); case VerticalScrollBarRole: - { - return updateBoxNode( skinnable, node, Q::VerticalScrollBar ); - } + return updateScrollBarNode( scrollView, Q::VerticalScrollBar, node ); + + case ContentsRootRole: + return updateContentsRootNode( scrollView, node ); + } return Inherited::updateSubNode( skinnable, nodeRole, node ); } +QSGNode* QskScrollViewSkinlet::updateScrollBarNode( const QskScrollView* scrollView, + QskAspect::Subcontrol subControl, QSGNode* node ) const +{ + const auto rect = subControlRect( scrollView, + scrollView->contentsRect(), subControl ); + + const auto orientation = qskSubcontrolOrientation( subControl ); + + QskSkinStateChanger stateChanger( scrollView ); + stateChanger.setStates( scrollView->scrollHandleStates( orientation ) ); + + return updateBoxNode( scrollView, node, rect, subControl ); +} + QSGNode* QskScrollViewSkinlet::updateContentsRootNode( const QskScrollView* scrollView, QSGNode* node ) const { diff --git a/src/controls/QskScrollViewSkinlet.h b/src/controls/QskScrollViewSkinlet.h index 94fe24e1..16c6c81f 100644 --- a/src/controls/QskScrollViewSkinlet.h +++ b/src/controls/QskScrollViewSkinlet.h @@ -47,6 +47,8 @@ class QSK_EXPORT QskScrollViewSkinlet : public QskSkinlet private: QSGNode* updateContentsRootNode( const QskScrollView*, QSGNode* ) const; + QSGNode* updateScrollBarNode( + const QskScrollView*, QskAspect::Subcontrol, QSGNode* ) const; QRectF viewportRect( const QskScrollView*, const QRectF& ) const; QRectF scrollBarRect( const QskScrollView*, const QRectF&, Qt::Orientation ) const;