From e36f81b29765defcda7903e07a889cb34371a4ea Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Thu, 9 Mar 2023 17:59:54 +0100 Subject: [PATCH] QskComboBox using QskLabelData now --- examples/gallery/selector/SelectorPage.cpp | 1 + src/common/QskLabelData.cpp | 5 + src/common/QskLabelData.h | 1 + src/controls/QskComboBox.cpp | 117 +++++++-------------- src/controls/QskComboBox.h | 24 +++-- src/controls/QskComboBoxSkinlet.cpp | 59 +++++------ src/controls/QskSegmentedBar.cpp | 1 + src/controls/QskSegmentedBar.h | 1 - 8 files changed, 85 insertions(+), 124 deletions(-) diff --git a/examples/gallery/selector/SelectorPage.cpp b/examples/gallery/selector/SelectorPage.cpp index d797e486..5e282b92 100644 --- a/examples/gallery/selector/SelectorPage.cpp +++ b/examples/gallery/selector/SelectorPage.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace { diff --git a/src/common/QskLabelData.cpp b/src/common/QskLabelData.cpp index 3175050d..40bad398 100644 --- a/src/common/QskLabelData.cpp +++ b/src/common/QskLabelData.cpp @@ -20,6 +20,11 @@ static void qskRegisterLabelData() Q_CONSTRUCTOR_FUNCTION( qskRegisterLabelData ) +QskLabelData::QskLabelData( const char* text ) + : m_text( text ) +{ +} + QskLabelData::QskLabelData( const QString& text ) : m_text( text ) { diff --git a/src/common/QskLabelData.h b/src/common/QskLabelData.h index 20845369..453e1dc5 100644 --- a/src/common/QskLabelData.h +++ b/src/common/QskLabelData.h @@ -23,6 +23,7 @@ class QSK_EXPORT QskLabelData public: QskLabelData() = default; + QskLabelData( const char* ); QskLabelData( const QString& ); QskLabelData( const QskIcon& ); QskLabelData( const QString&, const QskIcon& ); diff --git a/src/controls/QskComboBox.cpp b/src/controls/QskComboBox.cpp index a3a1b475..42e7019b 100644 --- a/src/controls/QskComboBox.cpp +++ b/src/controls/QskComboBox.cpp @@ -5,8 +5,7 @@ #include "QskComboBox.h" -#include "QskGraphicProvider.h" -#include "QskGraphic.h" +#include "QskLabelData.h" #include "QskMenu.h" #include "QskTextOptions.h" #include "QskEvent.h" @@ -60,41 +59,12 @@ static inline int qskFindOption( QskComboBox* comboBox, const QString& key ) return -1; } -namespace -{ - class Option - { - public: - Option( const QskGraphic& graphic, const QString& text ) - : text( text ) - , graphic( graphic ) - { - } - - Option( const QUrl& graphicSource, const QString& text ) - : graphicSource( graphicSource ) - , text( text ) - { -#if 1 - // lazy loading TODO ... - if( !graphicSource.isEmpty() ) - graphic = Qsk::loadGraphic( graphicSource ); -#endif - } - - QUrl graphicSource; - QString text; - - QskGraphic graphic; - }; -} - class QskComboBox::PrivateData { public: QPointer < QskMenu > menu; - QVector< Option > options; + QVector< QskLabelData > options; QString placeholderText; int currentIndex = -1; @@ -113,7 +83,6 @@ QskComboBox::QskComboBox( QQuickItem* parent ) setFocusPolicy( Qt::StrongFocus ); setAcceptHoverEvents( true ); - } QskComboBox::~QskComboBox() @@ -138,17 +107,6 @@ bool QskComboBox::isPopupOpen() const return hasSkinState( PopupOpen ); } -QskGraphic QskComboBox::icon() const -{ - if( m_data->currentIndex >= 0 ) - { - const auto option = optionAt( m_data->currentIndex ); - return option.at( 0 ).value< QskGraphic >(); - } - - return QskGraphic(); -} - void QskComboBox::setTextOptions( const QskTextOptions& textOptions ) { setTextOptionsHint( Text, textOptions ); @@ -159,52 +117,51 @@ QskTextOptions QskComboBox::textOptions() const return textOptionsHint( Text ); } -void QskComboBox::addOption( const QString& text ) +int QskComboBox::addOption( const QString& graphicSource, const QString& text ) { - addOption( QUrl(), text ); + return addOption( QskLabelData( text, QskIcon( graphicSource ) ) ); } -void QskComboBox::addOption( const QskGraphic& graphic, const QString& text ) +int QskComboBox::addOption( const QUrl& graphicSource, const QString& text ) { - m_data->options += Option( graphic, text ); + return addOption( QskLabelData( text, QskIcon( graphicSource ) ) ); +} + +int QskComboBox::addOption( const QskLabelData& option ) +{ + m_data->options += option; resetImplicitSize(); update(); if ( isComponentComplete() ) - Q_EMIT countChanged( count() ); + Q_EMIT optionsChanged(); + + return count() - 1; } -void QskComboBox::addOption( const QString& graphicSource, const QString& text ) +void QskComboBox::setOptions( const QVector< QskLabelData >& options ) { - addOption( QUrl( graphicSource ), text ); -} + if ( options == m_data->options ) + return; -void QskComboBox::addOption( const QUrl& graphicSource, const QString& text ) -{ - m_data->options += Option( graphicSource, text ); + m_data->options = options; + m_data->currentIndex = -1; // currentIndexChanged ??? resetImplicitSize(); update(); - if ( isComponentComplete() ) - Q_EMIT countChanged( count() ); + Q_EMIT optionsChanged(); } -QVariantList QskComboBox::optionAt( int index ) const +QVector< QskLabelData > QskComboBox::options() const { - const auto& options = m_data->options; + return m_data->options; +} - if( index < 0 || index >= options.count() ) - return QVariantList(); - - const auto& option = options[ index ]; - - QVariantList list; - list += QVariant::fromValue( option.graphic ); - list += QVariant::fromValue( option.text ); - - return list; +QskLabelData QskComboBox::optionAt( int index ) const +{ + return m_data->options.value( index ); } QString QskComboBox::placeholderText() const @@ -228,16 +185,13 @@ void QskComboBox::setPlaceholderText( const QString& text ) QString QskComboBox::textAt( int index ) const { - if ( index >= 0 && index < m_data->options.count() ) - return m_data->options[ index ].text; - - return QString(); + return optionAt( index ).text(); } QString QskComboBox::currentText() const { - if( m_data->currentIndex >= 0 ) - return m_data->options[ m_data->currentIndex ].text; + if( m_data->currentIndex >= 0 && m_data->currentIndex < m_data->options.count() ) + return m_data->options[ m_data->currentIndex ].text(); return m_data->placeholderText; } @@ -265,7 +219,7 @@ void QskComboBox::openPopup() menu->setFixedWidth( cr.width() ); for ( const auto& option : m_data->options ) - menu->addOption( option.graphic, option.text ); + menu->addOption( option.icon().graphic(), option.text() ); connect( menu, &QskMenu::currentIndexChanged, this, &QskComboBox::indexInPopupChanged ); @@ -391,8 +345,15 @@ void QskComboBox::clear() { m_data->options.clear(); - if ( isComponentComplete() ) - Q_EMIT countChanged( count() ); + Q_EMIT optionsChanged(); + + if ( m_data->currentIndex >= 0 ) + { + m_data->currentIndex = -1; + Q_EMIT currentIndexChanged( m_data->currentIndex ); + } + + update(); } } diff --git a/src/controls/QskComboBox.h b/src/controls/QskComboBox.h index 48373f4d..f1576907 100644 --- a/src/controls/QskComboBox.h +++ b/src/controls/QskComboBox.h @@ -8,19 +8,22 @@ #include "QskControl.h" -class QskGraphic; +class QskLabelData; class QSK_EXPORT QskComboBox : public QskControl { Q_OBJECT + Q_PROPERTY( QVector< QskLabelData > options READ options + WRITE setOptions NOTIFY optionsChanged ) + Q_PROPERTY( int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged ) Q_PROPERTY( QString currentText READ currentText NOTIFY currentIndexChanged ) - Q_PROPERTY( int count READ count NOTIFY countChanged ) + Q_PROPERTY( int count READ count ) Q_PROPERTY( QString placeholderText READ placeholderText WRITE setPlaceholderText NOTIFY placeholderTextChanged ) @@ -41,15 +44,17 @@ class QSK_EXPORT QskComboBox : public QskControl void setPopupOpen( bool ); bool isPopupOpen() const; - QskGraphic icon() const; - void setTextOptions( const QskTextOptions& ); QskTextOptions textOptions() const; - void addOption( const QString& text ); - void addOption( const QUrl& iconSource, const QString& text ); - void addOption( const QString& iconSource, const QString& text ); - void addOption( const QskGraphic&, const QString& text ); + int addOption( const QUrl&, const QString& ); + int addOption( const QString&, const QString& ); + int addOption( const QskLabelData& ); + + void setOptions( const QVector< QskLabelData >& ); + + QVector< QskLabelData > options() const; + QskLabelData optionAt( int ) const; void clear(); @@ -60,7 +65,6 @@ class QSK_EXPORT QskComboBox : public QskControl virtual int indexInPopup() const; int count() const; - QVariantList optionAt( int ) const; QString textAt( int ) const; QString placeholderText() const; @@ -73,7 +77,7 @@ class QSK_EXPORT QskComboBox : public QskControl void currentIndexChanged( int ); void indexInPopupChanged( int ); - void countChanged( int ); + void optionsChanged(); void placeholderTextChanged( const QString& ); protected: diff --git a/src/controls/QskComboBoxSkinlet.cpp b/src/controls/QskComboBoxSkinlet.cpp index 8a220a48..d0e91bb3 100644 --- a/src/controls/QskComboBoxSkinlet.cpp +++ b/src/controls/QskComboBoxSkinlet.cpp @@ -7,43 +7,13 @@ #include "QskComboBox.h" #include "QskGraphic.h" +#include "QskLabelData.h" + #include "QskSGNode.h" #include "QskSubcontrolLayoutEngine.h" namespace { -#if 1 // unify with the implementation from QskMenu - template< class T > - static inline QVariant qskSampleAt( const QskComboBox* box ) - { - if( std::is_same< T, QString >() ) - { - return box->currentText(); - } - - const int index = box->currentIndex(); - - if( index < 0 ) - return QVariant::fromValue( T() ); - - const auto list = box->optionAt( index ); - for ( const auto& value : list ) - { - if ( value.canConvert< T >() ) - return value; - } - - return QVariant(); - } - - template< class T > - static inline T qskValueAt( const QskComboBox* box ) - { - const auto sample = qskSampleAt< T >( box ); - return sample.template value< T >(); - } -#endif - class LayoutEngine : public QskSubcontrolLayoutEngine { public: @@ -52,12 +22,27 @@ namespace { setSpacing( box->spacingHint( QskComboBox::Panel ) ); + QSizeF graphicSize; + QString text; + + if ( box->currentIndex() >= 0 ) + { + const auto option = box->optionAt( box->currentIndex() ); + + graphicSize = option.icon().graphic().defaultSize(); + text = option.text(); + } + else + { + text = box->placeholderText(); + } + setGraphicTextElements( box, - QskComboBox::Text, qskValueAt< QString >( box ), - QskComboBox::Icon, qskValueAt< QskGraphic >( box ).defaultSize() ); + QskComboBox::Text, text, QskComboBox::Icon, graphicSize ); const auto alignment = box->alignmentHint( QskComboBox::Panel, Qt::AlignLeft ); + setFixedContent( QskComboBox::Text, Qt::Horizontal, alignment ); } }; @@ -115,7 +100,11 @@ QSGNode* QskComboBoxSkinlet::updateSubNode( return updateBoxNode( box, node, Q::Panel ); case IconRole: - return updateGraphicNode( box, node, box->icon(), Q::Icon ); + { + const auto option = box->optionAt( box->currentIndex() ); + return updateGraphicNode( box, node, + option.icon().graphic(), Q::Icon ); + } case TextRole: return updateTextNode( box, node ); diff --git a/src/controls/QskSegmentedBar.cpp b/src/controls/QskSegmentedBar.cpp index e85f2177..57b78f94 100644 --- a/src/controls/QskSegmentedBar.cpp +++ b/src/controls/QskSegmentedBar.cpp @@ -131,6 +131,7 @@ void QskSegmentedBar::setOptions( const QVector< QskLabelData >& options ) resetImplicitSize(); update(); + // selectedIndex ??? Q_EMIT optionsChanged(); } diff --git a/src/controls/QskSegmentedBar.h b/src/controls/QskSegmentedBar.h index 61ce9663..40e27df0 100644 --- a/src/controls/QskSegmentedBar.h +++ b/src/controls/QskSegmentedBar.h @@ -12,7 +12,6 @@ #include class QskTextOptions; -class QskGraphic; class QskLabelData; class QSK_EXPORT QskSegmentedBar : public QskControl