This commit is contained in:
Uwe Rathmann 2023-05-15 10:06:01 +02:00
parent a5a28bebc2
commit b1a816e61e
2 changed files with 44 additions and 43 deletions

View File

@ -28,17 +28,13 @@ QSK_SUBCONTROL( QskMenu, Separator )
QSK_SYSTEM_STATE( QskMenu, Selected, QskAspect::FirstSystemState << 2 ) QSK_SYSTEM_STATE( QskMenu, Selected, QskAspect::FirstSystemState << 2 )
QVector< int > qskSeparators( const QVector< QskLabelData >& options ) static inline int qskActionIndex( const QVector< int >& actions, int index )
{ {
QVector< int > separators; if ( index < 0 )
return -1;
for ( int i = 0; i < options.count(); i++ ) auto it = std::lower_bound( actions.constBegin(), actions.constEnd(), index );
{ return it - actions.constBegin();
if ( options[i].isEmpty() )
separators += i;
}
return separators;
} }
class QskMenu::PrivateData class QskMenu::PrivateData
@ -47,7 +43,9 @@ class QskMenu::PrivateData
QPointF origin; QPointF origin;
QVector< QskLabelData > options; QVector< QskLabelData > options;
QVector< int > separators; QVector< int > separators;
QVector< int > actions;
int triggeredIndex = -1; int triggeredIndex = -1;
int currentIndex = -1; int currentIndex = -1;
@ -138,10 +136,14 @@ int QskMenu::addOption( const QUrl& graphicSource, const QString& text )
int QskMenu::addOption( const QskLabelData& option ) int QskMenu::addOption( const QskLabelData& option )
{ {
const int index = m_data->options.count();
m_data->options += option; m_data->options += option;
if ( option.isEmpty() ) if ( option.isEmpty() )
m_data->separators += m_data->options.count() - 1; m_data->separators += index;
else
m_data->actions += index;
resetImplicitSize(); resetImplicitSize();
update(); update();
@ -149,7 +151,7 @@ int QskMenu::addOption( const QskLabelData& option )
if ( isComponentComplete() ) if ( isComponentComplete() )
Q_EMIT optionsChanged(); Q_EMIT optionsChanged();
return m_data->options.count() - 1; return index;
} }
void QskMenu::setOptions( const QStringList& options ) void QskMenu::setOptions( const QStringList& options )
@ -160,7 +162,14 @@ void QskMenu::setOptions( const QStringList& options )
void QskMenu::setOptions( const QVector< QskLabelData >& options ) void QskMenu::setOptions( const QVector< QskLabelData >& options )
{ {
m_data->options = options; m_data->options = options;
m_data->separators = qskSeparators( options );
for ( int i = 0; i < options.count(); i++ )
{
if ( options[i].isEmpty() )
m_data->separators += i;
else
m_data->actions += i;
}
if ( m_data->currentIndex >= 0 ) if ( m_data->currentIndex >= 0 )
{ {
@ -207,6 +216,11 @@ QVector< int > QskMenu::separators() const
return m_data->separators; return m_data->separators;
} }
QVector< int > QskMenu::actions() const
{
return m_data->actions;
}
int QskMenu::currentIndex() const int QskMenu::currentIndex() const
{ {
return m_data->currentIndex; return m_data->currentIndex;
@ -322,42 +336,28 @@ void QskMenu::wheelEvent( QWheelEvent* event )
void QskMenu::traverse( int steps ) void QskMenu::traverse( int steps )
{ {
const auto count = m_data->options.count(); const auto& actions = m_data->actions;
const auto count = actions.count();
const auto n = count - m_data->separators.count(); // -1 -> only one entry ?
if ( ( n <= 0 ) || ( steps % n == 0 ) ) if ( actions.isEmpty() || ( steps % count == 0 ) )
return; return;
auto index = m_data->currentIndex; int action1 = qskActionIndex( actions, m_data->currentIndex );
for ( auto i : m_data->separators ) int action2 = action1 + steps;
{
if ( i < index )
index--;
}
index += steps; // when cycling we want to slide in
if ( action2 < 0 )
action1 = count;
else if ( action2 >= count )
action1 = -1;
auto newIndex = index % n; action2 %= count;
if ( newIndex < 0 ) if ( action2 < 0 )
newIndex += n; action2 += count;
for ( int i = 0; i < newIndex; i++) movePositionHint( Cursor, actions[ action1 ], actions[ action2 ] );
{ setCurrentIndex( actions[ action2 ] );
if ( m_data->options[i].isEmpty() )
newIndex++;
}
// when cycling we want slide in
int startIndex = m_data->currentIndex;
if ( index < 0 )
startIndex = count;
else if ( index >= n )
startIndex = -1;
movePositionHint( Cursor, startIndex, newIndex );
setCurrentIndex( newIndex );
} }
void QskMenu::mousePressEvent( QMouseEvent* event ) void QskMenu::mousePressEvent( QMouseEvent* event )

View File

@ -58,6 +58,7 @@ class QSK_EXPORT QskMenu : public QskPopup
int addOption( const QString&, const QString& ); int addOption( const QString&, const QString& );
int addOption( const QUrl&, const QString& ); int addOption( const QUrl&, const QString& );
int addOption( const QskLabelData& ); int addOption( const QskLabelData& );
void addSeparator();
void setOptions( const QVector< QskLabelData >& ); void setOptions( const QVector< QskLabelData >& );
void setOptions( const QStringList& ); void setOptions( const QStringList& );
@ -67,8 +68,8 @@ class QSK_EXPORT QskMenu : public QskPopup
int optionsCount() const; int optionsCount() const;
void addSeparator();
QVector< int > separators() const; QVector< int > separators() const;
QVector< int > actions() const;
void clear(); void clear();