QskSegmentedBarSkinlet fixes
This commit is contained in:
parent
d33e1f1a90
commit
4bf1b019c7
@ -1180,7 +1180,7 @@ void Editor::setupSegmentedBarColors(
|
||||
|
||||
graphicRole = W::GraphicRoleFillColorTextPrimary;
|
||||
}
|
||||
else if ( states & Q::Hovered )
|
||||
else if ( states == Q::Hovered )
|
||||
{
|
||||
segmentColor = pal.fillColor.control.secondary;
|
||||
borderColor1 = pal.elevation.control.border[0];
|
||||
@ -1206,7 +1206,7 @@ void Editor::setupSegmentedBarColors(
|
||||
|
||||
graphicRole = W::GraphicRoleFillColorTextOnAccentPrimary;
|
||||
}
|
||||
else if ( states == Q::Disabled )
|
||||
else if ( states & Q::Disabled )
|
||||
{
|
||||
segmentColor = pal.fillColor.control.disabled;
|
||||
borderColor1 = borderColor2 = pal.strokeColor.control.defaultColor;
|
||||
|
@ -522,6 +522,8 @@ void Editor::setupSegmentedBar()
|
||||
|
||||
setStrutSize( Q::Panel | A::Horizontal, panelStrutSize );
|
||||
setStrutSize( Q::Panel | A::Vertical, panelStrutSize.transposed() );
|
||||
|
||||
setFlag( Q::Panel | A::Option, true ); // adjust segments to the panel radius
|
||||
}
|
||||
|
||||
{
|
||||
@ -530,53 +532,20 @@ void Editor::setupSegmentedBar()
|
||||
setStrutSize( Q::Segment | A::Horizontal, segmentStrutSize );
|
||||
setStrutSize( Q::Segment | A::Vertical, segmentStrutSize.transposed() );
|
||||
|
||||
setBoxBorderMetrics( Q::Segment | A::Horizontal, { 0, 1_dp, 0, 1_dp } );
|
||||
setBoxBorderMetrics( Q::Segment | Q::Minimum | A::Horizontal, { 1_dp, 1_dp, 0, 1_dp } );
|
||||
setBoxBorderMetrics( Q::Segment | Q::Maximum | A::Horizontal, { 0, 1_dp, 1_dp, 1_dp } );
|
||||
setGradient( Q::Segment | Q::Hovered, m_pal.onSurface8 );
|
||||
setGradient( Q::Segment | Q::Focused, m_pal.onSurface12 );
|
||||
setGradient( Q::Segment | Q::Selected, m_pal.secondaryContainer );
|
||||
|
||||
setBoxBorderMetrics( Q::Segment | A::Vertical, { 1_dp, 0, 1_dp, 0 } );
|
||||
setBoxBorderMetrics( Q::Segment | Q::Minimum | A::Vertical, { 1_dp, 1_dp, 1_dp, 0 } );
|
||||
setBoxBorderMetrics( Q::Segment | Q::Maximum | A::Vertical, { 1_dp, 0, 1_dp, 1_dp } );
|
||||
|
||||
setBoxBorderColors( Q::Segment, Qt::transparent );
|
||||
|
||||
setGradient( Q::Segment | Q::Hovered, m_pal.onSurface8,
|
||||
{ QskStateCombination::CombinationNoState, Q::Minimum | Q::Maximum } );
|
||||
|
||||
setGradient( Q::Segment | Q::Focused, m_pal.onSurface12,
|
||||
{ QskStateCombination::CombinationNoState, Q::Minimum | Q::Maximum } );
|
||||
|
||||
setGradient( Q::Segment | Q::Selected, m_pal.secondaryContainer,
|
||||
{ QskStateCombination::CombinationNoState, Q::Minimum | Q::Maximum } );
|
||||
setGradient( Q::Segment | Q::Selected | Q::Hovered,
|
||||
flattenedColor( m_pal.onSurface, m_pal.secondaryContainer, m_pal.hoverOpacity ),
|
||||
{ QskStateCombination::CombinationNoState, Q::Minimum | Q::Maximum } );
|
||||
flattenedColor( m_pal.onSurface, m_pal.secondaryContainer, m_pal.hoverOpacity ) );
|
||||
|
||||
setGradient( Q::Segment | Q::Selected | Q::Focused,
|
||||
flattenedColor( m_pal.onSurface, m_pal.secondaryContainer, m_pal.focusOpacity ),
|
||||
{ QskStateCombination::CombinationNoState, Q::Minimum | Q::Maximum } );
|
||||
flattenedColor( m_pal.onSurface, m_pal.secondaryContainer, m_pal.focusOpacity ) );
|
||||
|
||||
setGradient( Q::Segment | Q::Selected | Q::Disabled, m_pal.onSurface12,
|
||||
{ QskStateCombination::CombinationNoState, Q::Minimum | Q::Maximum } );
|
||||
setGradient( Q::Segment | Q::Selected | Q::Disabled, m_pal.onSurface12 );
|
||||
|
||||
setPadding( Q::Segment | A::Horizontal, 12_dp, 0, 12_dp, 0 );
|
||||
setPadding( Q::Segment | A::Vertical, 0, 12_dp, 0, 12_dp );
|
||||
|
||||
for( const auto subcontrol : { Q::Segment, Q::Splash } )
|
||||
{
|
||||
setBoxShape( subcontrol | Q::Minimum | A::Horizontal,
|
||||
{ 100, 0, 100, 0, Qt::RelativeSize },
|
||||
{ QskStateCombination::CombinationNoState, Q::Disabled } );
|
||||
setBoxShape( subcontrol | Q::Maximum | A::Horizontal,
|
||||
{ 0, 100, 0, 100, Qt::RelativeSize },
|
||||
{ QskStateCombination::CombinationNoState, Q::Disabled } );
|
||||
|
||||
setBoxShape( subcontrol | Q::Minimum | A::Vertical,
|
||||
{ 100, 100, 0, 0, Qt::RelativeSize },
|
||||
{ QskStateCombination::CombinationNoState, Q::Disabled } );
|
||||
setBoxShape( subcontrol | Q::Maximum | A::Vertical,
|
||||
{ 0, 0, 100, 100, Qt::RelativeSize },
|
||||
{ QskStateCombination::CombinationNoState, Q::Disabled } );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -24,10 +24,8 @@ QSK_SUBCONTROL( QskSegmentedBar, Cursor )
|
||||
QSK_SUBCONTROL( QskSegmentedBar, Text )
|
||||
QSK_SUBCONTROL( QskSegmentedBar, Icon )
|
||||
|
||||
QSK_SYSTEM_STATE( QskSegmentedBar, Minimum, QskAspect::FirstSystemState << 1 )
|
||||
QSK_SYSTEM_STATE( QskSegmentedBar, Maximum, QskAspect::FirstSystemState << 2 )
|
||||
QSK_SYSTEM_STATE( QskSegmentedBar, Selected, QskAspect::FirstSystemState << 3 )
|
||||
QSK_SYSTEM_STATE( QskSegmentedBar, Pressed, QskAspect::FirstSystemState << 4 )
|
||||
QSK_SYSTEM_STATE( QskSegmentedBar, Selected, QskAspect::FirstSystemState << 1 )
|
||||
QSK_SYSTEM_STATE( QskSegmentedBar, Pressed, QskAspect::FirstSystemState << 2 )
|
||||
|
||||
class QskSegmentedBar::PrivateData
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Panel, Splash, Segment, Separator, Cursor, Text, Icon )
|
||||
QSK_STATES( Selected, Pressed, Minimum, Maximum )
|
||||
QSK_STATES( Selected, Pressed )
|
||||
|
||||
QskSegmentedBar( QQuickItem* parent = nullptr );
|
||||
QskSegmentedBar( Qt::Orientation, QQuickItem* parent = nullptr );
|
||||
|
@ -14,19 +14,81 @@
|
||||
#include "QskSkin.h"
|
||||
#include "QskSkinStateChanger.h"
|
||||
#include "QskSubcontrolLayoutEngine.h"
|
||||
#include "QskBoxHints.h"
|
||||
|
||||
#include <qfontmetrics.h>
|
||||
#include <qmath.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
QskBoxHints effectiveBoxHints( QskAspect::Subcontrol subControl,
|
||||
const QskSegmentedBar* bar, int index )
|
||||
{
|
||||
using Q = QskSegmentedBar;
|
||||
|
||||
auto boxHints = bar->boxHints( subControl );
|
||||
|
||||
const bool leading = ( index == 0 );
|
||||
const bool trailing = ( index == bar->count() - 1 );
|
||||
|
||||
if ( !( leading || trailing ) )
|
||||
return boxHints;
|
||||
|
||||
// something more expressive than just a boolean. TODO ...
|
||||
if ( !bar->flagHint< bool >( Q::Panel | QskAspect::Option, false ) )
|
||||
return boxHints;
|
||||
|
||||
const auto panelShape = bar->boxShapeHint( Q::Panel );
|
||||
auto& shape = boxHints.shape;
|
||||
|
||||
// when there is only 1 segment we have to fit both ends
|
||||
|
||||
if ( leading )
|
||||
{
|
||||
Qt::Corner corners[2];
|
||||
|
||||
corners[0] = Qt::TopLeftCorner;
|
||||
|
||||
if ( bar->orientation() == Qt::Vertical )
|
||||
corners[1] = Qt::TopRightCorner;
|
||||
else
|
||||
corners[1] = Qt::BottomLeftCorner;
|
||||
|
||||
shape.setSizeMode( panelShape.sizeMode() );
|
||||
shape.setRadius( corners[0], panelShape.radius( corners[0] ) );
|
||||
shape.setRadius( corners[1], panelShape.radius( corners[1] ) );
|
||||
}
|
||||
|
||||
if ( trailing )
|
||||
{
|
||||
Qt::Corner corners[2];
|
||||
|
||||
corners[0] = Qt::BottomRightCorner;
|
||||
|
||||
if ( bar->orientation() == Qt::Vertical )
|
||||
corners[1] = Qt::BottomLeftCorner;
|
||||
else
|
||||
corners[1] = Qt::TopRightCorner;
|
||||
|
||||
shape.setSizeMode( panelShape.sizeMode() );
|
||||
shape.setRadius( corners[0], panelShape.radius( corners[0] ) );
|
||||
shape.setRadius( corners[1], panelShape.radius( corners[1] ) );
|
||||
}
|
||||
|
||||
boxHints.borderMetrics = bar->boxBorderMetricsHint( Q::Panel );
|
||||
boxHints.borderColors = QColor();
|
||||
|
||||
return boxHints;
|
||||
}
|
||||
|
||||
|
||||
QskGraphic iconAt( const QskSegmentedBar* bar, const int index )
|
||||
{
|
||||
using Q = QskSegmentedBar;
|
||||
|
||||
if ( bar->selectedIndex() == index )
|
||||
{
|
||||
/*
|
||||
/*
|
||||
Material 3 replaces the icon of the selected element by a checkmark,
|
||||
when icon and text are set. So this code is actually not correct
|
||||
as it also replaces the icon when there is no text
|
||||
@ -386,7 +448,8 @@ QskAspect::States QskSegmentedBarSkinlet::sampleStates(
|
||||
states |= Q::Disabled;
|
||||
}
|
||||
|
||||
const auto cursorPos = bar->effectiveSkinHint( Q::Segment | Q::Hovered | A::Metric | A::Position ).toPointF();
|
||||
const auto cursorPos = bar->effectiveSkinHint(
|
||||
Q::Segment | Q::Hovered | A::Metric | A::Position ).toPointF();
|
||||
|
||||
if( !cursorPos.isNull() && bar->indexAtPosition( cursorPos ) == index )
|
||||
{
|
||||
@ -410,25 +473,6 @@ QskAspect::States QskSegmentedBarSkinlet::sampleStates(
|
||||
states &= ~Q::Focused;
|
||||
}
|
||||
}
|
||||
|
||||
if( bar->count() > 0 )
|
||||
{
|
||||
if( index == 0 )
|
||||
{
|
||||
states &= ~Q::Maximum;
|
||||
states |= Q::Minimum;
|
||||
}
|
||||
else if( index == bar->count() - 1 )
|
||||
{
|
||||
states &= ~Q::Minimum;
|
||||
states |= Q::Maximum;
|
||||
}
|
||||
else
|
||||
{
|
||||
states &= ~Q::Minimum;
|
||||
states &= ~Q::Maximum;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( subControl == Q::Icon || subControl == Q::Text )
|
||||
{
|
||||
@ -455,11 +499,17 @@ QSGNode* QskSegmentedBarSkinlet::updateSampleNode( const QskSkinnable* skinnable
|
||||
|
||||
const auto rect = sampleRect( bar, bar->contentsRect(), subControl, index );
|
||||
|
||||
if ( subControl == Q::Segment || subControl == Q::Separator || subControl == Q::Cursor )
|
||||
if ( subControl == Q::Separator )
|
||||
{
|
||||
return updateBoxNode( skinnable, node, rect, subControl );
|
||||
}
|
||||
|
||||
if ( subControl == Q::Segment )
|
||||
{
|
||||
const auto boxHints = effectiveBoxHints( subControl, bar, index );
|
||||
return updateBoxNode( bar, node, rect, boxHints );
|
||||
}
|
||||
|
||||
const auto alignment = bar->alignmentHint( subControl, Qt::AlignCenter );
|
||||
|
||||
if ( subControl == Q::Text )
|
||||
@ -509,23 +559,34 @@ QSGNode* QskSegmentedBarSkinlet::updateSplashNode(
|
||||
if ( splashRect.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
auto clipNode = updateBoxClipNode( bar, node,
|
||||
bar->subControlRect( Q::Cursor ), Q::Cursor );
|
||||
auto panelClipNode = updateBoxClipNode(
|
||||
bar, node, bar->subControlRect( Q::Panel ), Q::Panel );
|
||||
|
||||
if ( clipNode )
|
||||
if ( panelClipNode )
|
||||
{
|
||||
auto boxNode = QskSGNode::findChildNode( clipNode, SplashRole );
|
||||
const auto segmentRect = sampleRect(
|
||||
bar, bar->contentsRect(), Q::Segment, bar->selectedIndex() );
|
||||
|
||||
auto segmentClipNode = updateBoxClipNode(
|
||||
bar, panelClipNode->firstChild(), segmentRect, Q::Segment );
|
||||
|
||||
if ( segmentClipNode == nullptr )
|
||||
return nullptr;
|
||||
|
||||
if ( segmentClipNode->parent() == nullptr )
|
||||
panelClipNode->appendChildNode( segmentClipNode );
|
||||
|
||||
auto boxNode = segmentClipNode->firstChild();
|
||||
boxNode = updateBoxNode( bar, boxNode, splashRect, Q::Splash );
|
||||
|
||||
if ( boxNode == nullptr )
|
||||
return nullptr;
|
||||
|
||||
QskSGNode::setNodeRole( boxNode, SplashRole );
|
||||
if ( boxNode->parent() != clipNode )
|
||||
clipNode->appendChildNode( boxNode );
|
||||
if ( boxNode->parent() == nullptr )
|
||||
segmentClipNode->appendChildNode( boxNode );
|
||||
}
|
||||
|
||||
return clipNode;
|
||||
return panelClipNode;
|
||||
}
|
||||
|
||||
#include "moc_QskSegmentedBarSkinlet.cpp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user