using QVariant

This commit is contained in:
Uwe Rathmann 2021-12-27 09:50:14 +01:00
parent 6c46c0160d
commit 9ce14619e7
4 changed files with 68 additions and 53 deletions

View File

@ -7,6 +7,7 @@
#include <QskSkinlet.h> #include <QskSkinlet.h>
#include <qvector.h> #include <qvector.h>
#include <qvariant.h>
QSK_SUBCONTROL( QskMenu, Panel ) QSK_SUBCONTROL( QskMenu, Panel )
QSK_SUBCONTROL( QskMenu, Cell ) QSK_SUBCONTROL( QskMenu, Cell )
@ -16,11 +17,20 @@ QSK_SUBCONTROL( QskMenu, Graphic )
QSK_SYSTEM_STATE( QskMenu, Selected, QskAspect::FirstSystemState << 2 ) QSK_SYSTEM_STATE( QskMenu, Selected, QskAspect::FirstSystemState << 2 )
namespace
{
struct Entry
{
QUrl graphicSource;
QskGraphic graphic;
QString text;
};
}
class QskMenu::PrivateData class QskMenu::PrivateData
{ {
public: public:
QVector< Entry > entries; QVector< Entry > entries;
QVector< QskGraphic > icons;
QskTextOptions textOptions; QskTextOptions textOptions;
QPointF origin; QPointF origin;
@ -80,30 +90,18 @@ QPointF QskMenu::origin() const
} }
void QskMenu::addItem( const QUrl& graphicSource, const QString& text ) void QskMenu::addItem( const QUrl& graphicSource, const QString& text )
{
m_data->entries += { graphicSource, text };
#if 1
{
const auto& entries = m_data->entries;
m_data->icons.clear();
m_data->icons.reserve( entries.count() );
for( const auto& entry : entries )
{ {
QskGraphic graphic; QskGraphic graphic;
if( !graphicSource.isEmpty() )
graphic = Qsk::loadGraphic( graphicSource );
if( !entry.iconSource.isEmpty() ) m_data->entries += { graphicSource, graphic, text };
graphic = Qsk::loadGraphic( entry.iconSource );
m_data->icons += graphic;
}
}
#endif
resetImplicitSize(); resetImplicitSize();
update(); update();
if ( isComponentComplete() )
countChanged( count() );
} }
void QskMenu::addItem( const QString& graphicSource, const QString& text ) void QskMenu::addItem( const QString& graphicSource, const QString& text )
@ -118,7 +116,6 @@ void QskMenu::addSeparator()
void QskMenu::clear() void QskMenu::clear()
{ {
m_data->icons.clear();
m_data->entries.clear(); m_data->entries.clear();
} }
@ -127,24 +124,20 @@ int QskMenu::count() const
return m_data->entries.count(); return m_data->entries.count();
} }
QskMenu::Entry QskMenu::entryAt( int index ) const QVariant QskMenu::itemAt( int index ) const
{ {
if( index >= 0 && index <= m_data->entries.count() ) const auto& entries = m_data->entries;
{
return m_data->entries[ index ];
}
return Entry(); if( index < 0 || index >= entries.count() )
} return QVariant();
QskGraphic QskMenu::graphicAt( int index ) const const auto& entry = m_data->entries[ index ];
{
if( index >= 0 && index <= m_data->icons.count() )
{
return m_data->icons[ index ];
}
return QskGraphic(); QVariantList list;
list += QVariant::fromValue( entry.graphic );
list += QVariant::fromValue( entry.text );
return list;
} }
void QskMenu::setTextOptions( const QskTextOptions& textOptions ) void QskMenu::setTextOptions( const QskTextOptions& textOptions )

View File

@ -24,7 +24,7 @@ class QSK_EXPORT QskMenu : public QskPopup
Q_PROPERTY( bool cascading READ isCascading WRITE setCascading Q_PROPERTY( bool cascading READ isCascading WRITE setCascading
RESET resetCascading NOTIFY cascadingChanged ) RESET resetCascading NOTIFY cascadingChanged )
Q_PROPERTY( int count READ count ) Q_PROPERTY( int count READ count NOTIFY countChanged )
Q_PROPERTY( int currentIndex READ currentIndex Q_PROPERTY( int currentIndex READ currentIndex
WRITE setCurrentIndex NOTIFY currentIndexChanged ) WRITE setCurrentIndex NOTIFY currentIndexChanged )
@ -32,12 +32,6 @@ class QSK_EXPORT QskMenu : public QskPopup
using Inherited = QskPopup; using Inherited = QskPopup;
public: public:
struct Entry
{
QUrl iconSource;
QString text;
};
QSK_SUBCONTROLS( Panel, Cell, Cursor, Text, Graphic ) QSK_SUBCONTROLS( Panel, Cell, Cursor, Text, Graphic )
QSK_STATES( Selected ) QSK_STATES( Selected )
@ -57,14 +51,14 @@ class QSK_EXPORT QskMenu : public QskPopup
void addSeparator(); void addSeparator();
Entry entryAt( int index ) const; virtual QVariant itemAt( int ) const;
QskGraphic graphicAt( int index ) const; virtual int count() const;
virtual void clear();
void setTextOptions( const QskTextOptions& textOptions ); void setTextOptions( const QskTextOptions& textOptions );
QskTextOptions textOptions() const; QskTextOptions textOptions() const;
int currentIndex() const; int currentIndex() const;
int count() const;
virtual QskColorFilter graphicFilterAt( int index ) const; virtual QskColorFilter graphicFilterAt( int index ) const;
QRectF focusIndicatorRect() const override; QRectF focusIndicatorRect() const override;
@ -79,9 +73,10 @@ class QSK_EXPORT QskMenu : public QskPopup
void triggered( int index ); void triggered( int index );
void currentIndexChanged( int index ); void currentIndexChanged( int index );
void countChanged( int );
public Q_SLOTS: public Q_SLOTS:
void setCurrentIndex( int index ); void setCurrentIndex( int index );
void clear();
protected: protected:
void keyPressEvent( QKeyEvent* ) override; void keyPressEvent( QKeyEvent* ) override;

View File

@ -27,6 +27,27 @@ namespace
}; };
} }
template< class T >
static T qskValueAt( const QskMenu* menu, int index )
{
const auto item = menu->itemAt( index );
if ( item.canConvert< T >() )
return item.value< T >();
if ( item.canConvert< QVariantList >() )
{
const auto list = item.value< QVariantList >();
for ( const auto& value : list )
{
if ( value.canConvert< T >() )
return value.value< T >();
}
}
return T();
}
static qreal qskMaxTextWidth( const QskMenu* menu ) static qreal qskMaxTextWidth( const QskMenu* menu )
{ {
const QFontMetricsF fm( menu->effectiveFont( QskMenu::Text ) ); const QFontMetricsF fm( menu->effectiveFont( QskMenu::Text ) );
@ -35,10 +56,12 @@ static qreal qskMaxTextWidth( const QskMenu* menu )
for ( int i = 0; i < menu->count(); i++ ) for ( int i = 0; i < menu->count(); i++ )
{ {
const auto entry = menu->entryAt( i ); const auto value = menu->itemAt( i );
if( !entry.text.isEmpty() )
const auto text = qskValueAt< QString >( menu, i );
if( !text.isEmpty() )
{ {
const auto w = qskHorizontalAdvance( fm, entry.text ); const auto w = qskHorizontalAdvance( fm, text );
if( w > maxWidth ) if( w > maxWidth )
maxWidth = w; maxWidth = w;
} }
@ -57,7 +80,8 @@ static qreal qskGraphicWidth( const QskMenu* menu )
qreal maxW = 0.0; qreal maxW = 0.0;
for ( int i = 0; i < menu->count(); i++ ) for ( int i = 0; i < menu->count(); i++ )
{ {
const auto w = menu->graphicAt( i ).widthForHeight( h ); const auto graphic = qskValueAt< QskGraphic >( menu, i );
const auto w = graphic.widthForHeight( h );
if( w > maxW ) if( w > maxW )
maxW = w; maxW = w;
} }
@ -215,8 +239,11 @@ static QSGNode* qskUpdateItemsNode( const QskMenu* menu, QSGNode* rootNode )
auto textRect = cellRect; auto textRect = cellRect;
textRect.setX( graphicRect.right() + spacing ); textRect.setX( graphicRect.right() + spacing );
qskUpdateItemNode( menu, graphicRect, menu->graphicAt( i ), const auto graphic = qskValueAt< QskGraphic >( menu, i );
textRect, menu->entryAt( i ).text, node ); const auto text = qskValueAt< QString >( menu, i );
qskUpdateItemNode( menu, graphicRect, graphic,
textRect, text, node );
} }
} }

View File

@ -24,7 +24,7 @@ class QSK_EXPORT QskMenuSkinlet : public QskPopupSkinlet
const QRectF&, QskAspect::Subcontrol ) const override; const QRectF&, QskAspect::Subcontrol ) const override;
QRectF itemRect( const QskSkinnable*, QRectF itemRect( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, int itemIndex ) const override; const QRectF&, QskAspect::Subcontrol, int index ) const override;
int itemIndexAt( const QskSkinnable*, int itemIndexAt( const QskSkinnable*,
const QRectF&, QskAspect::Subcontrol, const QPointF& ) const override; const QRectF&, QskAspect::Subcontrol, const QPointF& ) const override;