Merge branch 'master' into cmake

This commit is contained in:
Uwe Rathmann 2023-03-10 12:46:45 +01:00
commit 525aad2cb0
10 changed files with 198 additions and 177 deletions

View File

@ -68,6 +68,17 @@ QskHashValue QskLabelData::hash( QskHashValue seed ) const
return m_icon.hash( hash ); return m_icon.hash( hash );
} }
QVector< QskLabelData > qskCreateLabelData( const QVector< QString >& list )
{
QVector< QskLabelData > labelData;
labelData.reserve( list.size() );
for ( const auto& text : list )
labelData += QskLabelData( text );
return labelData;
}
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
#include <qdebug.h> #include <qdebug.h>

View File

@ -10,6 +10,7 @@
#include "QskIcon.h" #include "QskIcon.h"
#include <qstring.h> #include <qstring.h>
#include <qvector.h>
#include <qmetatype.h> #include <qmetatype.h>
#include <qdebug.h> #include <qdebug.h>
@ -69,6 +70,8 @@ inline bool QskLabelData::operator!=( const QskLabelData& other ) const noexcept
return ( !( *this == other ) ); return ( !( *this == other ) );
} }
QSK_EXPORT QVector< QskLabelData > qskCreateLabelData( const QVector< QString >& );
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
class QDebug; class QDebug;

View File

@ -140,6 +140,11 @@ int QskComboBox::addOption( const QskLabelData& option )
return count() - 1; return count() - 1;
} }
void QskComboBox::setOptions( const QStringList& options )
{
setOptions( qskCreateLabelData( options ) );
}
void QskComboBox::setOptions( const QVector< QskLabelData >& options ) void QskComboBox::setOptions( const QVector< QskLabelData >& options )
{ {
if ( options == m_data->options ) if ( options == m_data->options )
@ -218,8 +223,7 @@ void QskComboBox::openPopup()
menu->setOrigin( mapToScene( cr.bottomLeft() ) ); menu->setOrigin( mapToScene( cr.bottomLeft() ) );
menu->setFixedWidth( cr.width() ); menu->setFixedWidth( cr.width() );
for ( const auto& option : m_data->options ) menu->setOptions( m_data->options );
menu->addOption( option.icon().graphic(), option.text() );
connect( menu, &QskMenu::currentIndexChanged, connect( menu, &QskMenu::currentIndexChanged,
this, &QskComboBox::indexInPopupChanged ); this, &QskComboBox::indexInPopupChanged );

View File

@ -7,8 +7,11 @@
#define QSK_COMBO_BOX_H #define QSK_COMBO_BOX_H
#include "QskControl.h" #include "QskControl.h"
#include <qstringlist.h>
class QskTextOptions;
class QskLabelData; class QskLabelData;
class QUrl;
class QSK_EXPORT QskComboBox : public QskControl class QSK_EXPORT QskComboBox : public QskControl
{ {
@ -52,6 +55,7 @@ class QSK_EXPORT QskComboBox : public QskControl
int addOption( const QskLabelData& ); int addOption( const QskLabelData& );
void setOptions( const QVector< QskLabelData >& ); void setOptions( const QVector< QskLabelData >& );
void setOptions( const QStringList& );
QVector< QskLabelData > options() const; QVector< QskLabelData > options() const;
QskLabelData optionAt( int ) const; QskLabelData optionAt( int ) const;

View File

@ -6,6 +6,7 @@
#include "QskMenu.h" #include "QskMenu.h"
#include "QskGraphicProvider.h" #include "QskGraphicProvider.h"
#include "QskLabelData.h"
#include "QskTextOptions.h" #include "QskTextOptions.h"
#include "QskGraphic.h" #include "QskGraphic.h"
#include "QskColorFilter.h" #include "QskColorFilter.h"
@ -27,52 +28,17 @@ QSK_SUBCONTROL( QskMenu, Separator )
QSK_SYSTEM_STATE( QskMenu, Selected, QskAspect::FirstSystemState << 2 ) QSK_SYSTEM_STATE( QskMenu, Selected, QskAspect::FirstSystemState << 2 )
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;
#if 0
// TODO ...
bool isEnabled = true;
#endif
};
}
class QskMenu::PrivateData class QskMenu::PrivateData
{ {
public: public:
QVector< Option > options;
QVector< int > separators;
QPointF origin; QPointF origin;
// current/selected are not well defined yet, TODO ... QVector< QskLabelData > options;
int currentIndex = -1; // QVector< bool > enabled;
int selectedIndex = -1; QVector< int > separators;
int triggeredIndex = -1;
int currentIndex = -1;
bool isPressed = false; bool isPressed = false;
}; };
@ -93,6 +59,9 @@ QskMenu::QskMenu( QQuickItem* parent )
// we hide the focus indicator while fading // we hide the focus indicator while fading
connect( this, &QskMenu::fadingChanged, this, connect( this, &QskMenu::fadingChanged, this,
&QskControl::focusIndicatorRectChanged ); &QskControl::focusIndicatorRectChanged );
connect( this, &QskMenu::opened, this,
[this]() { m_data->triggeredIndex = -1; } );
} }
QskMenu::~QskMenu() QskMenu::~QskMenu()
@ -135,36 +104,77 @@ QPointF QskMenu::origin() const
return m_data->origin; return m_data->origin;
} }
void QskMenu::addOption( const QString& text ) void QskMenu::setTextOptions( const QskTextOptions& textOptions )
{ {
addOption( QUrl(), text ); setTextOptionsHint( Text, textOptions );
} }
void QskMenu::addOption( const QUrl& graphicSource, const QString& text ) QskTextOptions QskMenu::textOptions() const
{ {
m_data->options += Option( graphicSource, text ); return textOptionsHint( Text );
}
int QskMenu::addOption( const QString& graphicSource, const QString& text )
{
return addOption( QskLabelData( text, graphicSource ) );
}
int QskMenu::addOption( const QUrl& graphicSource, const QString& text )
{
return addOption( QskLabelData( text, graphicSource ) );
}
int QskMenu::addOption( const QskLabelData& option )
{
m_data->options += option;
resetImplicitSize(); resetImplicitSize();
update(); update();
if ( isComponentComplete() ) if ( isComponentComplete() )
Q_EMIT countChanged( count() ); Q_EMIT optionsChanged();
return count() - 1;
} }
void QskMenu::addOption( const QskGraphic& graphic, const QString& text ) void QskMenu::setOptions( const QStringList& options )
{ {
m_data->options += Option( graphic, text ); setOptions( qskCreateLabelData( options ) );
}
void QskMenu::setOptions( const QVector< QskLabelData >& options )
{
m_data->options = options;
if ( m_data->currentIndex >= 0 )
{
m_data->currentIndex = -1;
if ( isComponentComplete() )
Q_EMIT currentIndexChanged( m_data->currentIndex );
}
resetImplicitSize(); resetImplicitSize();
update(); update();
if ( isComponentComplete() ) if ( isComponentComplete() )
Q_EMIT countChanged( count() ); Q_EMIT optionsChanged();
} }
void QskMenu::addOption( const QString& graphicSource, const QString& text ) void QskMenu::clear()
{ {
addOption( QUrl( graphicSource ), text ); m_data->separators.clear();
setOptions( QVector< QskLabelData >() );
}
QVector< QskLabelData > QskMenu::options() const
{
return m_data->options;
}
QskLabelData QskMenu::optionAt( int index ) const
{
return m_data->options.value( index );
} }
int QskMenu::count() const int QskMenu::count() const
@ -190,55 +200,9 @@ int QskMenu::separatorCount() const
return m_data->separators.count(); return m_data->separators.count();
} }
void QskMenu::clear() int QskMenu::currentIndex() const
{ {
m_data->separators.clear(); return m_data->currentIndex;
if ( !m_data->options.isEmpty() )
{
m_data->options.clear();
if ( isComponentComplete() )
Q_EMIT countChanged( count() );
}
}
QVariantList QskMenu::optionAt( int index ) const
{
const auto& options = 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;
}
QString QskMenu::textAt( int index ) const
{
if ( index >= 0 && index < m_data->options.count() )
return m_data->options[ index ].text;
return QString();
}
QString QskMenu::currentText() const
{
return textAt( m_data->currentIndex );
}
void QskMenu::setTextOptions( const QskTextOptions& textOptions )
{
setTextOptionsHint( Text, textOptions );
}
QskTextOptions QskMenu::textOptions() const
{
return textOptionsHint( Text );
} }
void QskMenu::setCurrentIndex( int index ) void QskMenu::setCurrentIndex( int index )
@ -258,9 +222,19 @@ void QskMenu::setCurrentIndex( int index )
} }
} }
int QskMenu::currentIndex() const QString QskMenu::currentText() const
{ {
return m_data->currentIndex; return optionAt( m_data->currentIndex ).text();
}
int QskMenu::triggeredIndex() const
{
return m_data->triggeredIndex;
}
QString QskMenu::triggeredText() const
{
return optionAt( m_data->triggeredIndex ).text();
} }
void QskMenu::keyPressEvent( QKeyEvent* event ) void QskMenu::keyPressEvent( QKeyEvent* event )
@ -296,18 +270,14 @@ void QskMenu::keyPressEvent( QKeyEvent* event )
case Qt::Key_Escape: case Qt::Key_Escape:
case Qt::Key_Cancel: case Qt::Key_Cancel:
{ {
setSelectedIndex( -1 ); close();
return; return;
} }
default: default:
{ {
const int steps = qskFocusChainIncrement( event ); if ( const int steps = qskFocusChainIncrement( event ) )
if( steps != 0 )
{
traverse( steps ); traverse( steps );
}
} }
} }
} }
@ -317,7 +287,12 @@ void QskMenu::keyReleaseEvent( QKeyEvent* )
if( m_data->isPressed ) if( m_data->isPressed )
{ {
m_data->isPressed = false; m_data->isPressed = false;
setSelectedIndex( m_data->currentIndex );
if ( m_data->currentIndex >= 0 )
{
trigger( m_data->currentIndex );
close();
}
} }
} }
@ -374,6 +349,12 @@ void QskMenu::mousePressEvent( QMouseEvent* event )
Inherited::mousePressEvent( event ); Inherited::mousePressEvent( event );
} }
void QskMenu::mouseUngrabEvent()
{
m_data->isPressed = false;
Inherited::mouseUngrabEvent();
}
void QskMenu::mouseReleaseEvent( QMouseEvent* event ) void QskMenu::mouseReleaseEvent( QMouseEvent* event )
{ {
if ( event->button() == Qt::LeftButton ) if ( event->button() == Qt::LeftButton )
@ -382,9 +363,14 @@ void QskMenu::mouseReleaseEvent( QMouseEvent* event )
{ {
m_data->isPressed = false; m_data->isPressed = false;
const auto index = indexAtPosition( qskMousePosition( event ) ); const auto index = m_data->currentIndex;
if ( index == m_data->currentIndex )
setSelectedIndex( index ); if ( ( index >= 0 )
&& ( index == indexAtPosition( qskMousePosition( event ) ) ) )
{
trigger( m_data->currentIndex );
close();
}
} }
return; return;
@ -417,20 +403,6 @@ QRectF QskMenu::focusIndicatorRect() const
return Inherited::focusIndicatorRect(); return Inherited::focusIndicatorRect();
} }
void QskMenu::setSelectedIndex( int index )
{
if ( !isOpen() )
return;
if ( index >= 0 )
setCurrentIndex( index );
m_data->selectedIndex = index;
Q_EMIT triggered( index );
close();
}
QRectF QskMenu::cellRect( int index ) const QRectF QskMenu::cellRect( int index ) const
{ {
return effectiveSkinlet()->sampleRect( return effectiveSkinlet()->sampleRect(
@ -443,11 +415,19 @@ int QskMenu::indexAtPosition( const QPointF& pos ) const
this, contentsRect(), QskMenu::Segment, pos ); this, contentsRect(), QskMenu::Segment, pos );
} }
void QskMenu::trigger( int index )
{
if ( index >= 0 && index < m_data->options.count() )
{
m_data->triggeredIndex = index;
Q_EMIT triggered( index );
}
}
int QskMenu::exec() int QskMenu::exec()
{ {
m_data->selectedIndex = -1;
(void) execPopup(); (void) execPopup();
return m_data->selectedIndex; return m_data->triggeredIndex;
} }
#include "moc_QskMenu.cpp" #include "moc_QskMenu.cpp"

View File

@ -7,12 +7,11 @@
#define QSK_MENU_H #define QSK_MENU_H
#include "QskPopup.h" #include "QskPopup.h"
#include <qstringlist.h>
#include <qurl.h>
#include <qstring.h>
class QskTextOptions; class QskTextOptions;
class QskGraphic; class QskLabelData;
class QUrl;
class QSK_EXPORT QskMenu : public QskPopup class QSK_EXPORT QskMenu : public QskPopup
{ {
@ -24,12 +23,18 @@ 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 NOTIFY countChanged ) Q_PROPERTY( QVector< QskLabelData > options READ options
WRITE setOptions NOTIFY optionsChanged )
Q_PROPERTY( int count READ count )
Q_PROPERTY( int currentIndex READ currentIndex Q_PROPERTY( int currentIndex READ currentIndex
WRITE setCurrentIndex NOTIFY currentIndexChanged ) WRITE setCurrentIndex NOTIFY currentIndexChanged )
Q_PROPERTY( QString currentText READ currentText ) Q_PROPERTY( int triggeredIndex READ triggeredIndex NOTIFY triggered )
Q_PROPERTY( QString triggeredText READ triggeredText NOTIFY triggered )
Q_PROPERTY( QString currentText READ currentText NOTIFY currentIndexChanged )
using Inherited = QskPopup; using Inherited = QskPopup;
@ -50,14 +55,15 @@ class QSK_EXPORT QskMenu : public QskPopup
void setTextOptions( const QskTextOptions& ); void setTextOptions( const QskTextOptions& );
QskTextOptions textOptions() const; QskTextOptions textOptions() const;
// insert, remove, functors, actions int addOption( const QString&, const QString& );
void addOption( const QUrl& iconSource, const QString& text ); int addOption( const QUrl&, const QString& );
void addOption( const QString& iconSource, const QString& text ); int addOption( const QskLabelData& );
void addOption( const QskGraphic&, const QString& text );
void addOption( const QString& text );
QVariantList optionAt( int ) const; void setOptions( const QVector< QskLabelData >& );
QString textAt( int ) const; void setOptions( const QStringList& );
QVector< QskLabelData > options() const;
QskLabelData optionAt( int ) const;
int count() const; int count() const;
@ -71,6 +77,9 @@ class QSK_EXPORT QskMenu : public QskPopup
int currentIndex() const; int currentIndex() const;
QString currentText() const; QString currentText() const;
int triggeredIndex() const;
QString triggeredText() const;
QRectF focusIndicatorRect() const override; QRectF focusIndicatorRect() const override;
QRectF cellRect( int index ) const; QRectF cellRect( int index ) const;
@ -83,12 +92,12 @@ class QSK_EXPORT QskMenu : public QskPopup
void originChanged( const QPointF& ); void originChanged( const QPointF& );
void triggered( int index ); void triggered( int index );
void currentIndexChanged( int index ); void currentIndexChanged( int );
void countChanged( int ); void optionsChanged();
public Q_SLOTS: public Q_SLOTS:
void setCurrentIndex( int index ); void setCurrentIndex( int );
protected: protected:
void keyPressEvent( QKeyEvent* ) override; void keyPressEvent( QKeyEvent* ) override;
@ -99,13 +108,14 @@ class QSK_EXPORT QskMenu : public QskPopup
#endif #endif
void mousePressEvent( QMouseEvent* ) override; void mousePressEvent( QMouseEvent* ) override;
void mouseUngrabEvent() override;
void mouseReleaseEvent( QMouseEvent* ) override; void mouseReleaseEvent( QMouseEvent* ) override;
void aboutToShow() override; void aboutToShow() override;
void trigger( int );
private: private:
void traverse( int steps ); void traverse( int steps );
void setSelectedIndex( int index );
class PrivateData; class PrivateData;
std::unique_ptr< PrivateData > m_data; std::unique_ptr< PrivateData > m_data;

View File

@ -13,30 +13,11 @@
#include "QskFunctions.h" #include "QskFunctions.h"
#include "QskMargins.h" #include "QskMargins.h"
#include "QskFunctions.h" #include "QskFunctions.h"
#include "QskLabelData.h"
#include <qfontmetrics.h> #include <qfontmetrics.h>
#include <qmath.h> #include <qmath.h>
template< class T >
static inline QVariant qskSampleAt( const QskMenu* menu, int index )
{
const auto list = menu->optionAt( index );
for ( const auto& value : list )
{
if ( value.canConvert< T >() )
return value;
}
return QVariant();
}
template< class T >
static inline T qskValueAt( const QskMenu* menu, int index )
{
const auto sample = qskSampleAt< T >( menu, index );
return sample.template value< T >();
}
class QskMenuSkinlet::PrivateData class QskMenuSkinlet::PrivateData
{ {
public: public:
@ -415,13 +396,17 @@ QVariant QskMenuSkinlet::sampleAt( const QskSkinnable* skinnable,
{ {
using Q = QskMenu; using Q = QskMenu;
const auto menu = static_cast< const QskMenu* >( skinnable ); if ( subControl == Q::Icon || subControl == Q::Text )
{
const auto menu = static_cast< const QskMenu* >( skinnable );
if ( subControl == Q::Icon ) const auto option = menu->optionAt( index );
return qskSampleAt< QskGraphic >( menu, index );
if ( subControl == Q::Text ) if ( subControl == Q::Icon )
return qskSampleAt< QString >( menu, index ); return QVariant::fromValue( option.icon().graphic() );
else
return QVariant::fromValue( option.text() );
}
return Inherited::sampleAt( skinnable, subControl, index ); return Inherited::sampleAt( skinnable, subControl, index );
} }
@ -504,7 +489,7 @@ QSGNode* QskMenuSkinlet::updateSampleNode( const QskSkinnable* skinnable,
if ( subControl == Q::Icon ) if ( subControl == Q::Icon )
{ {
const auto graphic = qskValueAt< QskGraphic >( menu, index ); const auto graphic = menu->optionAt( index ).icon().graphic();
if ( graphic.isNull() ) if ( graphic.isNull() )
return nullptr; return nullptr;
@ -517,7 +502,7 @@ QSGNode* QskMenuSkinlet::updateSampleNode( const QskSkinnable* skinnable,
if ( subControl == Q::Text ) if ( subControl == Q::Text )
{ {
const auto text = qskValueAt< QString >( menu, index ); const auto text = menu->optionAt( index ).text();
if ( text.isEmpty() ) if ( text.isEmpty() )
return nullptr; return nullptr;

View File

@ -110,7 +110,8 @@ int QskSegmentedBar::addOption( const QskLabelData& option )
resetImplicitSize(); resetImplicitSize();
update(); update();
Q_EMIT optionsChanged(); if ( isComponentComplete() )
Q_EMIT optionsChanged();
if ( count() == 1 ) if ( count() == 1 )
setSelectedIndex( 0 ); setSelectedIndex( 0 );
@ -123,6 +124,11 @@ QskLabelData QskSegmentedBar::optionAt( int index ) const
return m_data->options.value( index ); return m_data->options.value( index );
} }
void QskSegmentedBar::setOptions( const QStringList& options )
{
setOptions( qskCreateLabelData( options ) );
}
void QskSegmentedBar::setOptions( const QVector< QskLabelData >& options ) void QskSegmentedBar::setOptions( const QVector< QskLabelData >& options )
{ {
m_data->options = options; m_data->options = options;
@ -325,6 +331,14 @@ int QskSegmentedBar::currentIndex() const
return m_data->currentIndex; return m_data->currentIndex;
} }
QString QskSegmentedBar::currentText() const
{
if ( m_data->currentIndex >= 0 )
return optionAt( m_data->currentIndex ).text();
return QString();
}
void QskSegmentedBar::setSelectedIndex( int index ) void QskSegmentedBar::setSelectedIndex( int index )
{ {
if ( !isSegmentEnabled( index ) ) if ( !isSegmentEnabled( index ) )

View File

@ -7,12 +7,11 @@
#define QSK_SEGMENTED_BAR_H #define QSK_SEGMENTED_BAR_H
#include "QskControl.h" #include "QskControl.h"
#include <qstringlist.h>
#include <qurl.h>
#include <qstring.h>
class QskTextOptions; class QskTextOptions;
class QskLabelData; class QskLabelData;
class QUrl;
class QSK_EXPORT QskSegmentedBar : public QskControl class QSK_EXPORT QskSegmentedBar : public QskControl
{ {
@ -24,13 +23,15 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
Q_PROPERTY( QVector< QskLabelData > options READ options Q_PROPERTY( QVector< QskLabelData > options READ options
WRITE setOptions NOTIFY optionsChanged ) WRITE setOptions NOTIFY optionsChanged )
Q_PROPERTY( int count READ count )
Q_PROPERTY( int selectedIndex READ selectedIndex Q_PROPERTY( int selectedIndex READ selectedIndex
WRITE setSelectedIndex NOTIFY selectedIndexChanged USER true ) WRITE setSelectedIndex NOTIFY selectedIndexChanged USER true )
Q_PROPERTY( int currentIndex READ currentIndex Q_PROPERTY( int currentIndex READ currentIndex
WRITE setCurrentIndex NOTIFY currentIndexChanged ) WRITE setCurrentIndex NOTIFY currentIndexChanged )
Q_PROPERTY( int count READ count ) Q_PROPERTY( QString currentText READ currentText )
using Inherited = QskControl; using Inherited = QskControl;
@ -53,6 +54,7 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
int addOption( const QskLabelData& ); int addOption( const QskLabelData& );
void setOptions( const QVector< QskLabelData >& ); void setOptions( const QVector< QskLabelData >& );
void setOptions( const QStringList& );
QVector< QskLabelData > options() const; QVector< QskLabelData > options() const;
QskLabelData optionAt( int ) const; QskLabelData optionAt( int ) const;
@ -62,6 +64,8 @@ class QSK_EXPORT QskSegmentedBar : public QskControl
int selectedIndex() const; int selectedIndex() const;
int currentIndex() const; int currentIndex() const;
QString currentText() const;
int count() const; int count() const;
void setSegmentEnabled( int, bool ); void setSegmentEnabled( int, bool );

View File

@ -37,6 +37,7 @@ class QSK_EXPORT QskIcon
public: public:
QskIcon(); QskIcon();
QskIcon( const QString& );
QskIcon( const QUrl& ); QskIcon( const QUrl& );
QskIcon( const QskGraphic& ); QskIcon( const QskGraphic& );
@ -70,6 +71,11 @@ class QSK_EXPORT QskIcon
Q_DECLARE_METATYPE( QskIcon ) Q_DECLARE_METATYPE( QskIcon )
inline QskIcon::QskIcon( const QString& source )
: QskIcon( QUrl( source ) )
{
}
inline bool QskIcon::isNull() const inline bool QskIcon::isNull() const
{ {
if ( m_data->graphic ) if ( m_data->graphic )