From e4a07909ac9f33bd4e55900e0c5c15d37a173b87 Mon Sep 17 00:00:00 2001 From: Clemens Manert Date: Wed, 15 Feb 2023 00:20:19 +0100 Subject: [PATCH] Add Squiek theme --- skins/material3/QskMaterial3Skin.cpp | 2 +- skins/squiek/QskSquiekSkin.cpp | 35 +++++++++++++++ src/controls/QskRadioBox.cpp | 67 +++++++++++++++++++++++----- src/controls/QskRadioBox.h | 3 ++ src/controls/QskRadioBoxSkinlet.cpp | 15 +++++-- 5 files changed, 106 insertions(+), 16 deletions(-) diff --git a/skins/material3/QskMaterial3Skin.cpp b/skins/material3/QskMaterial3Skin.cpp index b2385434..9177d514 100644 --- a/skins/material3/QskMaterial3Skin.cpp +++ b/skins/material3/QskMaterial3Skin.cpp @@ -496,7 +496,7 @@ void Editor::setupRadioBox() setColor( Q::Symbol | Q::Disabled, m_pal.onSurface38 ); - setMargin( Q::Text, QskMargins( 10_dp, 0, 0, 0 )); + setMargin( Q::Text, QskMargins( 10_dp, 0, 10_dp, 0 )); setAlignment( Q::Text, Qt::AlignBottom ); diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index 9ae9a25f..c93525e8 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -144,6 +145,7 @@ namespace void setupPopup(); void setupProgressBar(); void setupPushButton(); + void setupRadioBox(); void setupScrollView(); void setupSegmentedBar(); void setupSeparator(); @@ -259,6 +261,7 @@ void Editor::setup() setupPopup(); setupProgressBar(); setupPushButton(); + setupRadioBox(); setupScrollView(); setupSegmentedBar(); setupSeparator(); @@ -607,6 +610,38 @@ void Editor::setupPushButton() setAlignment( Q::Graphic, Qt::AlignCenter ); } +void Editor::setupRadioBox() +{ + using Q = QskRadioBox; + + setSpacing(Q::Panel, qskDpiScaled( 10 ) ); + + setStrutSize( Q::Button, { qskDpiScaled( 20 ), qskDpiScaled( 20 ) }); + setStrutSize( Q::Symbol, { qskDpiScaled( 9 ), qskDpiScaled( 9 ) }); + + setBoxShape(Q::Button, qskDpiScaled( 20 ) ); + setBoxShape(Q::Ripple, qskDpiScaled( 40 ) ); + setBoxBorderMetrics( Q::Button, qskDpiScaled( 1 ) ); + + setBoxBorderColors( Q::Button, m_pal.darker125 ); + setBoxBorderColors( Q::Button | Q::Disabled, m_pal.theme ); + + setColor( Q::Text, m_pal.themeForeground ); + setColor( Q::Symbol, m_pal.themeForeground ); + setColor( Q::Panel, m_pal.lighter125 ); + setColor( Q::Panel | Q::Disabled, m_pal.lighter125 ); + + setColor( Q::Button | Q::Disabled, m_pal.lighter110 ); + + setColor( Q::Text | Q::Disabled, m_pal.darker200 ); + + setColor( Q::Symbol | Q::Disabled, m_pal.darker200 ); + + setMargin( Q::Text, QskMargins( qskDpiScaled( 10 ), 0, qskDpiScaled( 10 ), 0 )); + + setAlignment( Q::Text, Qt::AlignBottom ); +} + void Editor::setupDialogButtonBox() { using Q = QskDialogButtonBox; diff --git a/src/controls/QskRadioBox.cpp b/src/controls/QskRadioBox.cpp index bad4c1fd..b651ce77 100644 --- a/src/controls/QskRadioBox.cpp +++ b/src/controls/QskRadioBox.cpp @@ -1,7 +1,9 @@ #include "QskRadioBox.h" #include "QskEvent.h" #include "QskAnimationHint.h" +#include "QskSkinlet.h" +#include #include QSK_SUBCONTROL( QskRadioBox, Panel ) @@ -18,6 +20,7 @@ class QskRadioBox::PrivateData { public: QStringList items; int selectedIndex = -1; + int focusedIndex = -1; int pressedIndex = -1; }; @@ -37,7 +40,7 @@ QskRadioBox::QskRadioBox( QQuickItem* parent ) : } }); - setPositionHint( Ripple, -1 ); + setFocusedIndex( -1 ); } QskRadioBox::QskRadioBox( const QStringList& list, QQuickItem* parent ) : @@ -57,6 +60,37 @@ QskRadioBox::QskRadioBox( const QStringList& items, } } +QRectF QskRadioBox::focusIndicatorRect() const { + if( m_data->focusedIndex > -1) { + + auto textRect = effectiveSkinlet()->sampleRect( this, + contentsRect(), QskRadioBox::Text, m_data->focusedIndex ); + + auto buttonRect = effectiveSkinlet()->sampleRect( this, + contentsRect(), QskRadioBox::Button, m_data->focusedIndex ); + + auto result = QRectF( + qMin( textRect.x(), buttonRect.x() ), + qMin( textRect.y(), buttonRect.y() ), + buttonRect.width() + textRect.width(), + qMax( buttonRect.height(), textRect.height() )); + + if( layoutMirroring() ) { + result.setWidth( + result.width() + marginHint( Text ).right() + + marginHint( Button ).left() ); + } else { + result.setWidth( + result.width() + marginHint( Text ).left() + + marginHint( Button ).right() ); + } + + return result; + } + + return QRectF(); +} + int QskRadioBox::selectedIndex() const { return m_data->selectedIndex; } @@ -92,6 +126,10 @@ void QskRadioBox::setItems( const QStringList& items ){ m_data->items = items; itemsChanged( items ); setSelectedIndex( m_data->selectedIndex ); + + if( m_data->focusedIndex > items.size() ) { + setFocusedIndex( 0 ); + } } void QskRadioBox::keyPressEvent( QKeyEvent* event ) @@ -101,36 +139,36 @@ void QskRadioBox::keyPressEvent( QKeyEvent* event ) case Qt::Key_Up: case Qt::Key_Left: m_data->selectedIndex = qMax(m_data->selectedIndex - 1, 0); - setPositionHint( Ripple, m_data->selectedIndex ); + setFocusedIndex( m_data->selectedIndex ); event->setAccepted( true ); update(); return; case Qt::Key_Down: case Qt::Key_Right: m_data->selectedIndex = qMin(m_data->selectedIndex + 1, items().size() - 1); - setPositionHint( Ripple, m_data->selectedIndex ); + setFocusedIndex( m_data->selectedIndex ); event->setAccepted( true ); update(); return; case Qt::Key_Select: case Qt::Key_Return: case Qt::Key_Space: - m_data->selectedIndex = positionHint( Ripple ); + m_data->selectedIndex = m_data->focusedIndex; event->setAccepted( true ); update(); return; } - auto currentTabIndex = positionHint( Ripple ); + auto currentTabIndex = m_data->focusedIndex; auto nextTabIndex = currentTabIndex + qskFocusChainIncrement( event ); if( nextTabIndex >= items().size() || nextTabIndex < 0 ) { Inherited::keyPressEvent( event ); - setPositionHint(Ripple, -1); + setFocusedIndex( -1); update(); } else { event->setAccepted( true ); - setPositionHint( Ripple, (float) nextTabIndex ); + setFocusedIndex( (float) nextTabIndex ); const auto aspect = Ripple | QskAspect::Metric | QskAspect::Position; auto hint = animationHint(aspect | skinStates()); @@ -157,7 +195,7 @@ void QskRadioBox::mousePressEvent( QMouseEvent* e ) m_data->pressedIndex = indexAtPosition; m_data->selectedIndex = -1; - setPositionHint( Ripple, indexAtPosition ); + setFocusedIndex( indexAtPosition ); e->setAccepted( true ); update(); @@ -176,9 +214,9 @@ void QskRadioBox::mouseReleaseEvent( QMouseEvent* e ) void QskRadioBox::focusInEvent( QFocusEvent* e ) { if( e->reason() == Qt::TabFocusReason ) { - setPositionHint( Ripple, 0 ); + setFocusedIndex(0 ); } else if( e->reason() == Qt::BacktabFocusReason ) { - setPositionHint( Ripple, items().size() - 1 ); + setFocusedIndex(items().size() - 1 ); } update(); @@ -186,7 +224,7 @@ void QskRadioBox::focusInEvent( QFocusEvent* e ) { } void QskRadioBox::focusOutEvent( QFocusEvent* e ) { - setPositionHint(Ripple, -1); + setFocusedIndex( -1 ); update(); Inherited::focusOutEvent( e ); @@ -202,4 +240,11 @@ int QskRadioBox::indexAt( const QPointF& target ) const { return index; } +void QskRadioBox::setFocusedIndex( int index ) { + qDebug() << "setting index " << index; + m_data->focusedIndex = index; + setPositionHint( Ripple, index ); + focusIndicatorRectChanged(); +} + #include "moc_QskRadioBox.cpp" diff --git a/src/controls/QskRadioBox.h b/src/controls/QskRadioBox.h index db9fd6ab..20510ebd 100644 --- a/src/controls/QskRadioBox.h +++ b/src/controls/QskRadioBox.h @@ -28,6 +28,8 @@ class QSK_EXPORT QskRadioBox : public QskControl QskRadioBox( QQuickItem* parent = nullptr ); QskRadioBox( const QStringList&, QQuickItem* parent = nullptr ); QskRadioBox( const QStringList&, int, QQuickItem* parent = nullptr ); + + QRectF focusIndicatorRect() const override; const QStringList& items() const; int selectedIndex() const; @@ -54,6 +56,7 @@ class QSK_EXPORT QskRadioBox : public QskControl int indexAt( const QPointF& ) const; private: + void setFocusedIndex( int index ); class PrivateData; std::unique_ptr< PrivateData > m_data; }; diff --git a/src/controls/QskRadioBoxSkinlet.cpp b/src/controls/QskRadioBoxSkinlet.cpp index c7b8e3a1..7c01964d 100644 --- a/src/controls/QskRadioBoxSkinlet.cpp +++ b/src/controls/QskRadioBoxSkinlet.cpp @@ -162,16 +162,23 @@ QRectF QskRadioBoxSkinlet::textRect( const QskRadioBox* radio, auto spacing = radio->spacingHint(Q::Panel); auto lh = lineHeight( radio ); const auto textMargins = radio->marginHint( Q::Text ); + const auto font = radio->effectiveFont( Q::Text ); result.moveTop( index * ( lh + spacing ) + lh - radio->effectiveFontHeight(Q::Text) + textMargins.top()); - if( !radio->layoutMirroring() ) { - auto maxWidth = qMax( buttonRect( radio, Q::Symbol, rect, index ).width(), - buttonRect( radio, Q::Button, rect, index ).width()); + result.setHeight( lh ); + result.setWidth( qskHorizontalAdvance( font, radio->items()[index] ) ); - result.moveLeft( maxWidth + textMargins.left()); + auto buttonWidth = buttonRect( radio, Q::Button, rect, index ).width(); + auto buttonsMargins = radio->marginHint( Q::Button ); + if( radio->layoutMirroring() ) { + result.moveLeft( rect.width() - textMargins.right() + - result.width() - buttonWidth - buttonsMargins.left()); + } else { + result.moveLeft( buttonWidth + textMargins.left() + + radio->marginHint( Q::Button ).right()); } return result;