segmented bar: Add splash rect and style for M3

This commit is contained in:
Peter Hartmann 2023-02-05 13:45:29 +01:00 committed by uwerat
parent 11f74a2f57
commit 6b43231ca2
6 changed files with 93 additions and 3 deletions

View File

@ -571,6 +571,13 @@ void Editor::setupSegmentedBar()
setBoxBorderColors( Q::Cursor, Qt::transparent );
}
{
// Splash
setBoxShape( Q::Splash, 20_dp );
setGradient( Q::Splash, stateLayerColor( m_pal.onSecondaryContainer, m_pal.pressedOpacity ) );
setAnimation( Q::Splash | A::Color, qskDuration );
}
{
// Text

View File

@ -306,6 +306,7 @@ void QskPushButton::mousePressEvent( QMouseEvent* event )
using A = QskAspect;
const auto hint = animationHint( Splash | A::Color );
if( hint.isValid() )
{
setPositionHint( Splash, qskMousePosition( event ).x() );

View File

@ -10,12 +10,14 @@
#include "QskEvent.h"
#include "QskSkinlet.h"
#include "QskAspect.h"
#include "QskAnimationHint.h"
#include <qguiapplication.h>
#include <qstylehints.h>
#include <qfontmetrics.h>
QSK_SUBCONTROL( QskSegmentedBar, Panel )
QSK_SUBCONTROL( QskSegmentedBar, Splash )
QSK_SUBCONTROL( QskSegmentedBar, Segment )
QSK_SUBCONTROL( QskSegmentedBar, Separator )
QSK_SUBCONTROL( QskSegmentedBar, Cursor )
@ -148,6 +150,8 @@ QskAspect::Variation QskSegmentedBar::effectiveVariation() const
void QskSegmentedBar::mousePressEvent( QMouseEvent* event )
{
using A = QskAspect;
const int index = indexAtPosition( qskMousePosition( event ) );
if( isSegmentEnabled( index ) )
@ -163,6 +167,14 @@ void QskSegmentedBar::mousePressEvent( QMouseEvent* event )
}
}
}
const auto hint = animationHint( Splash | A::Color );
if( hint.isValid() )
{
setSkinHint( Splash | A::Metric | A::Position, event->pos() );
startTransition( Splash | A::Metric | A::Size, hint, 0.0, 1.0 );
}
}
void QskSegmentedBar::mouseUngrabEvent()

View File

@ -36,7 +36,7 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
using Inherited = QskControl;
public:
QSK_SUBCONTROLS( Panel, Segment, Separator, Cursor, Text, Icon )
QSK_SUBCONTROLS( Panel, Splash, Segment, Separator, Cursor, Text, Icon )
QSK_STATES( Selected, Minimum, Maximum )
QskSegmentedBar( QQuickItem* parent = nullptr );

View File

@ -10,6 +10,7 @@
#include "QskGraphic.h"
#include "QskColorFilter.h"
#include "QskFunctions.h"
#include "QskSGNode.h"
#include "QskSkin.h"
#include "QskStandardSymbol.h"
#include "QskSubcontrolLayoutEngine.h"
@ -66,8 +67,8 @@ namespace
QskSegmentedBarSkinlet::QskSegmentedBarSkinlet( QskSkin* skin )
: Inherited( skin )
{
setNodeRoles( { PanelRole, SegmentRole,
SeparatorRole, CursorRole, TextRole, IconRole } );
setNodeRoles( { PanelRole, SegmentRole, SeparatorRole,
CursorRole, SplashRole, TextRole, IconRole } );
}
QskSegmentedBarSkinlet::~QskSegmentedBarSkinlet() = default;
@ -86,6 +87,9 @@ QRectF QskSegmentedBarSkinlet::subControlRect(
if( subControl == Q::Cursor )
return cursorRect( bar, contentsRect );
if( subControl == Q::Splash )
return splashRect( bar, contentsRect );
return Inherited::subControlRect( skinnable, contentsRect, subControl );
}
@ -120,6 +124,35 @@ QRectF QskSegmentedBarSkinlet::cursorRect(
return cursorRect;
}
QRectF QskSegmentedBarSkinlet::splashRect(
const QskSegmentedBar* bar, const QRectF& contentsRect ) const
{
using Q = QskSegmentedBar;
QRectF rect;
const auto ratio = bar->metric( Q::Splash | QskAspect::Size );
if ( ratio > 0.0 )
{
const auto pos = bar->effectiveSkinHint(
Q::Splash | QskAspect::Metric | QskAspect::Position ).toPointF();
const int index = bar->indexAtPosition( pos );
if( index >= 0 && index < bar->count() )
{
const auto sr = segmentRect( bar, contentsRect, index );
rect = sr;
rect.setSize( { 2.0 * rect.width() * ratio, rect.height() * 2.0 } );
rect.moveCenter( pos );
rect = rect.intersected( sr );
}
}
return rect;
}
QRectF QskSegmentedBarSkinlet::segmentRect(
const QskSegmentedBar* bar, const QRectF& contentsRect, int index ) const
{
@ -183,11 +216,16 @@ QSGNode* QskSegmentedBarSkinlet::updateSubNode(
{
using Q = QskSegmentedBar;
const auto bar = static_cast< const QskSegmentedBar* >( skinnable );
switch( nodeRole )
{
case CursorRole:
return updateBoxNode( skinnable, node, Q::Cursor );
case SplashRole:
return updateSplashNode( bar, node );
case PanelRole:
return updateBoxNode( skinnable, node, Q::Panel );
@ -387,4 +425,32 @@ QSGNode* QskSegmentedBarSkinlet::updateSampleNode( const QskSkinnable* skinnable
return Inherited::updateSampleNode( skinnable, subControl, index, node );
}
QSGNode* QskSegmentedBarSkinlet::updateSplashNode(
const QskSegmentedBar* bar, QSGNode* node ) const
{
using Q = QskSegmentedBar;
const auto splashRect = bar->subControlRect( Q::Splash );
if ( splashRect.isEmpty() )
return nullptr;
auto clipNode = updateBoxClipNode( bar, node,
bar->subControlRect( Q::Cursor ), Q::Cursor );
if ( clipNode )
{
auto boxNode = QskSGNode::findChildNode( clipNode, SplashRole );
boxNode = updateBoxNode( bar, boxNode, splashRect, Q::Splash );
if ( boxNode == nullptr )
return nullptr;
QskSGNode::setNodeRole( boxNode, SplashRole );
if ( boxNode->parent() != clipNode )
clipNode->appendChildNode( boxNode );
}
return clipNode;
}
#include "moc_QskSegmentedBarSkinlet.cpp"

View File

@ -23,6 +23,7 @@ class QSK_EXPORT QskSegmentedBarSkinlet : public QskSkinlet
SegmentRole,
SeparatorRole,
CursorRole,
SplashRole,
TextRole,
IconRole,
@ -60,6 +61,9 @@ class QSK_EXPORT QskSegmentedBarSkinlet : public QskSkinlet
QRectF segmentRect( const QskSegmentedBar*, const QRectF&, int index ) const;
QRectF separatorRect( const QskSegmentedBar*, const QRectF&, int index ) const;
QRectF cursorRect( const QskSegmentedBar*, const QRectF& ) const;
QRectF splashRect( const QskSegmentedBar*, const QRectF& ) const;
QSGNode* updateSplashNode( const QskSegmentedBar*, QSGNode* ) const;
};
#endif