QskComboBox is creating its menu only temporary now
This commit is contained in:
parent
69546707d2
commit
fa998a9496
@ -73,16 +73,16 @@ void SelectorPage::populate()
|
|||||||
|
|
||||||
auto* comboBox1 = new QskComboBox( comboBoxBox );
|
auto* comboBox1 = new QskComboBox( comboBoxBox );
|
||||||
comboBox1->setPlaceholderText( "< options >" );
|
comboBox1->setPlaceholderText( "< options >" );
|
||||||
comboBox1->addOption( {}, "airport" );
|
comboBox1->addOption( "airport" );
|
||||||
comboBox1->addOption( {}, "flight" );
|
comboBox1->addOption( "flight" );
|
||||||
comboBox1->addOption( {}, "pizza" );
|
comboBox1->addOption( "pizza" );
|
||||||
comboBox1->addOption( {}, "soccer" );
|
comboBox1->addOption( "soccer" );
|
||||||
|
|
||||||
auto* comboBox2 = new QskComboBox( comboBoxBox );
|
auto* comboBox2 = new QskComboBox( comboBoxBox );
|
||||||
comboBox2->addOption( { "airport_shuttle" }, "airport" );
|
comboBox2->addOption( "airport_shuttle", "airport" );
|
||||||
comboBox2->addOption( { "flight" }, "flight" );
|
comboBox2->addOption( "flight", "flight" );
|
||||||
comboBox2->addOption( { "local_pizza" }, "pizza" );
|
comboBox2->addOption( "local_pizza", "pizza" );
|
||||||
comboBox2->addOption( { "sports_soccer" }, "soccer" );
|
comboBox2->addOption( "sports_soccer", "soccer" );
|
||||||
comboBox2->setCurrentIndex( 2 );
|
comboBox2->setCurrentIndex( 2 );
|
||||||
|
|
||||||
setStretchFactor( 0, 0 );
|
setStretchFactor( 0, 0 );
|
||||||
|
@ -5,11 +5,13 @@
|
|||||||
|
|
||||||
#include "QskComboBox.h"
|
#include "QskComboBox.h"
|
||||||
|
|
||||||
|
#include "QskGraphicProvider.h"
|
||||||
#include "QskGraphic.h"
|
#include "QskGraphic.h"
|
||||||
#include "QskMenu.h"
|
#include "QskMenu.h"
|
||||||
#include "QskTextOptions.h"
|
#include "QskTextOptions.h"
|
||||||
#include "QskEvent.h"
|
#include "QskEvent.h"
|
||||||
|
|
||||||
|
#include <qpointer.h>
|
||||||
#include <qquickwindow.h>
|
#include <qquickwindow.h>
|
||||||
|
|
||||||
QSK_SUBCONTROL( QskComboBox, Panel )
|
QSK_SUBCONTROL( QskComboBox, Panel )
|
||||||
@ -19,7 +21,7 @@ QSK_SUBCONTROL( QskComboBox, PopupIndicator )
|
|||||||
|
|
||||||
QSK_SYSTEM_STATE( QskComboBox, PopupOpen, QskAspect::FirstSystemState << 1 )
|
QSK_SYSTEM_STATE( QskComboBox, PopupOpen, QskAspect::FirstSystemState << 1 )
|
||||||
|
|
||||||
static inline void qskIncrement( QskComboBox* comboBox, int steps )
|
static inline void qskTraverseOptions( QskComboBox* comboBox, int steps )
|
||||||
{
|
{
|
||||||
const auto count = comboBox->count();
|
const auto count = comboBox->count();
|
||||||
if ( count == 0 )
|
if ( count == 0 )
|
||||||
@ -33,29 +35,46 @@ static inline void qskIncrement( QskComboBox* comboBox, int steps )
|
|||||||
int nextIndex = ( index + steps ) % count;
|
int nextIndex = ( index + steps ) % count;
|
||||||
if ( nextIndex < 0 )
|
if ( nextIndex < 0 )
|
||||||
nextIndex += count;
|
nextIndex += count;
|
||||||
|
|
||||||
if ( nextIndex != index )
|
if ( nextIndex != index )
|
||||||
comboBox->setCurrentIndex( nextIndex );
|
comboBox->setCurrentIndex( nextIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
class QskComboBox::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PrivateData( QskComboBox* comboBox )
|
QPointer < QskPopup > menu;
|
||||||
{
|
|
||||||
menu = new QskMenu();
|
|
||||||
|
|
||||||
/*
|
QVector< Option > options;
|
||||||
The popup menu is supposed to be modal for the window and
|
|
||||||
therefore needs the root item of the window as parent item.
|
|
||||||
So we set the box as QObject parent only, so that it gets
|
|
||||||
destroyed properly.
|
|
||||||
*/
|
|
||||||
menu->setParent( comboBox );
|
|
||||||
menu->setPopupFlag( QskPopup::DeleteOnClose, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
QskMenu* menu;
|
|
||||||
QString placeholderText;
|
QString placeholderText;
|
||||||
|
|
||||||
int currentIndex = -1;
|
int currentIndex = -1;
|
||||||
@ -63,7 +82,7 @@ class QskComboBox::PrivateData
|
|||||||
|
|
||||||
QskComboBox::QskComboBox( QQuickItem* parent )
|
QskComboBox::QskComboBox( QQuickItem* parent )
|
||||||
: Inherited( parent )
|
: Inherited( parent )
|
||||||
, m_data( new PrivateData( this ) )
|
, m_data( new PrivateData() )
|
||||||
{
|
{
|
||||||
initSizePolicy( QskSizePolicy::Minimum, QskSizePolicy::Fixed );
|
initSizePolicy( QskSizePolicy::Minimum, QskSizePolicy::Fixed );
|
||||||
|
|
||||||
@ -75,14 +94,6 @@ QskComboBox::QskComboBox( QQuickItem* parent )
|
|||||||
|
|
||||||
setAcceptHoverEvents( true );
|
setAcceptHoverEvents( true );
|
||||||
|
|
||||||
connect( m_data->menu, &QskMenu::triggered,
|
|
||||||
this, &QskComboBox::setCurrentIndex );
|
|
||||||
|
|
||||||
connect( m_data->menu, &QskMenu::countChanged,
|
|
||||||
this, &QskComboBox::countChanged );
|
|
||||||
|
|
||||||
connect( m_data->menu, &QskMenu::closed, this,
|
|
||||||
[ this ]() { setPopupOpen( false ); setFocus( true ); } );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QskComboBox::~QskComboBox()
|
QskComboBox::~QskComboBox()
|
||||||
@ -128,14 +139,52 @@ QskTextOptions QskComboBox::textOptions() const
|
|||||||
return textOptionsHint( Text );
|
return textOptionsHint( Text );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskComboBox::addOption( const QString& text )
|
||||||
|
{
|
||||||
|
addOption( QUrl(), text );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskComboBox::addOption( const QskGraphic& graphic, const QString& text )
|
||||||
|
{
|
||||||
|
m_data->options += Option( graphic, text );
|
||||||
|
|
||||||
|
resetImplicitSize();
|
||||||
|
update();
|
||||||
|
|
||||||
|
if ( isComponentComplete() )
|
||||||
|
Q_EMIT countChanged( count() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskComboBox::addOption( const QString& graphicSource, const QString& text )
|
||||||
|
{
|
||||||
|
addOption( QUrl( graphicSource ), text );
|
||||||
|
}
|
||||||
|
|
||||||
void QskComboBox::addOption( const QUrl& graphicSource, const QString& text )
|
void QskComboBox::addOption( const QUrl& graphicSource, const QString& text )
|
||||||
{
|
{
|
||||||
m_data->menu->addOption( graphicSource, text );
|
m_data->options += Option( graphicSource, text );
|
||||||
|
|
||||||
|
resetImplicitSize();
|
||||||
|
update();
|
||||||
|
|
||||||
|
if ( isComponentComplete() )
|
||||||
|
Q_EMIT countChanged( count() );
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantList QskComboBox::optionAt( int index ) const
|
QVariantList QskComboBox::optionAt( int index ) const
|
||||||
{
|
{
|
||||||
return m_data->menu->optionAt( index );
|
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 QskComboBox::placeholderText() const
|
QString QskComboBox::placeholderText() const
|
||||||
@ -170,20 +219,37 @@ QString QskComboBox::currentText() const
|
|||||||
|
|
||||||
void QskComboBox::openPopup()
|
void QskComboBox::openPopup()
|
||||||
{
|
{
|
||||||
|
if ( m_data->menu )
|
||||||
|
return;
|
||||||
|
|
||||||
const auto cr = contentsRect();
|
const auto cr = contentsRect();
|
||||||
|
|
||||||
auto menu = m_data->menu;
|
auto menu = new QskMenu();
|
||||||
|
|
||||||
|
menu->setParent( this );
|
||||||
menu->setParentItem( window()->contentItem() );
|
menu->setParentItem( window()->contentItem() );
|
||||||
|
menu->setPopupFlag( QskPopup::DeleteOnClose, true );
|
||||||
|
|
||||||
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->addOption( option.graphic, option.text );
|
||||||
|
|
||||||
|
connect( menu, &QskMenu::triggered,
|
||||||
|
this, &QskComboBox::setCurrentIndex );
|
||||||
|
|
||||||
|
connect( menu, &QskMenu::closed, this,
|
||||||
|
[ this ]() { setPopupOpen( false ); setFocus( true ); } );
|
||||||
|
|
||||||
|
m_data->menu = menu;
|
||||||
menu->open();
|
menu->open();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskComboBox::closePopup()
|
void QskComboBox::closePopup()
|
||||||
{
|
{
|
||||||
m_data->menu->close();
|
if ( m_data->menu )
|
||||||
|
m_data->menu->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskComboBox::mousePressEvent( QMouseEvent* )
|
void QskComboBox::mousePressEvent( QMouseEvent* )
|
||||||
@ -219,13 +285,13 @@ void QskComboBox::keyPressEvent( QKeyEvent* event )
|
|||||||
case Qt::Key_Up:
|
case Qt::Key_Up:
|
||||||
case Qt::Key_PageUp:
|
case Qt::Key_PageUp:
|
||||||
{
|
{
|
||||||
qskIncrement( this, -1 );
|
qskTraverseOptions( this, -1 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case Qt::Key_Down:
|
case Qt::Key_Down:
|
||||||
case Qt::Key_PageDown:
|
case Qt::Key_PageDown:
|
||||||
{
|
{
|
||||||
qskIncrement( this, 1 );
|
qskTraverseOptions( this, 1 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case Qt::Key_Home:
|
case Qt::Key_Home:
|
||||||
@ -256,17 +322,27 @@ void QskComboBox::keyReleaseEvent( QKeyEvent* event )
|
|||||||
|
|
||||||
void QskComboBox::wheelEvent( QWheelEvent* event )
|
void QskComboBox::wheelEvent( QWheelEvent* event )
|
||||||
{
|
{
|
||||||
if ( !isPopupOpen() )
|
if ( isPopupOpen() )
|
||||||
|
{
|
||||||
|
if ( m_data->menu )
|
||||||
|
QCoreApplication::postEvent( m_data->menu, event->clone() );
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
const auto steps = -qRound( qskWheelSteps( event ) );
|
const auto steps = -qRound( qskWheelSteps( event ) );
|
||||||
qskIncrement( this, steps );
|
qskTraverseOptions( this, steps );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskComboBox::clear()
|
void QskComboBox::clear()
|
||||||
{
|
{
|
||||||
m_data->menu->clear();
|
if ( !m_data->options.isEmpty() )
|
||||||
setCurrentIndex( -1 );
|
{
|
||||||
|
m_data->options.clear();
|
||||||
|
|
||||||
|
if ( isComponentComplete() )
|
||||||
|
Q_EMIT countChanged( count() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskComboBox::setCurrentIndex( int index )
|
void QskComboBox::setCurrentIndex( int index )
|
||||||
@ -287,7 +363,7 @@ int QskComboBox::currentIndex() const
|
|||||||
|
|
||||||
int QskComboBox::count() const
|
int QskComboBox::count() const
|
||||||
{
|
{
|
||||||
return m_data->menu->count();
|
return m_data->options.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_QskComboBox.cpp"
|
#include "moc_QskComboBox.cpp"
|
||||||
|
@ -42,7 +42,10 @@ class QSK_EXPORT QskComboBox : public QskControl
|
|||||||
void setTextOptions( const QskTextOptions& );
|
void setTextOptions( const QskTextOptions& );
|
||||||
QskTextOptions textOptions() const;
|
QskTextOptions textOptions() const;
|
||||||
|
|
||||||
void addOption( const QUrl&, const QString& );
|
void addOption( const QString& text );
|
||||||
|
void addOption( const QUrl& graphicSource, const QString& text );
|
||||||
|
void addOption( const QString& graphicSource, const QString& text );
|
||||||
|
void addOption( const QskGraphic&, const QString& text );
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
@ -61,7 +64,7 @@ class QSK_EXPORT QskComboBox : public QskControl
|
|||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void currentIndexChanged( int );
|
void currentIndexChanged( int );
|
||||||
|
|
||||||
void countChanged();
|
void countChanged( int );
|
||||||
void placeholderTextChanged( const QString& );
|
void placeholderTextChanged( const QString& );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user