QskMenuButton introduced
This commit is contained in:
parent
99151186fb
commit
dbe1fad7ec
|
@ -24,7 +24,7 @@
|
|||
#include <QskSwitchButton.h>
|
||||
#include <QskPushButton.h>
|
||||
#include <QskScrollArea.h>
|
||||
#include <QskMenu.h>
|
||||
#include <QskMenuButton.h>
|
||||
#include <QskWindow.h>
|
||||
#include <QskDialog.h>
|
||||
#include <QskSkinManager.h>
|
||||
|
@ -36,6 +36,7 @@
|
|||
#include <QskGraphicProvider.h>
|
||||
#include <QskGraphicIO.h>
|
||||
#include <QskGraphic.h>
|
||||
#include <QskLabelData.h>
|
||||
#include <QskSetup.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
@ -111,100 +112,64 @@ namespace
|
|||
}
|
||||
};
|
||||
|
||||
class MenuButton : public QskPushButton
|
||||
{
|
||||
public:
|
||||
MenuButton( const QString& text, QQuickItem* parent = nullptr )
|
||||
: QskPushButton( text, parent )
|
||||
{
|
||||
connect( this, &QskPushButton::pressed, this, &MenuButton::openMenu );
|
||||
}
|
||||
|
||||
private:
|
||||
void openMenu()
|
||||
{
|
||||
auto menu = new QskMenu( window()->contentItem() );
|
||||
|
||||
populateMenu( menu );
|
||||
|
||||
menu->setOrigin( geometry().bottomLeft() );
|
||||
menu->open();
|
||||
}
|
||||
|
||||
virtual void populateMenu( QskMenu* ) = 0;
|
||||
};
|
||||
|
||||
class SkinButton final : public MenuButton
|
||||
class SkinButton final : public QskMenuButton
|
||||
{
|
||||
public:
|
||||
SkinButton( const QString& text, QQuickItem* parent = nullptr )
|
||||
: MenuButton( text, parent )
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void populateMenu( QskMenu* menu ) override
|
||||
: QskMenuButton( text, parent )
|
||||
{
|
||||
const auto names = qskSkinManager->skinNames();
|
||||
|
||||
for ( const auto& name : names )
|
||||
menu->addOption( QUrl(), name );
|
||||
setOptions( names );
|
||||
|
||||
if ( const auto index = names.indexOf( qskSetup->skinName() ) )
|
||||
menu->setCurrentIndex( index );
|
||||
setStartIndex( index );
|
||||
|
||||
connect( menu, &QskMenu::triggered, this, &SkinButton::changeSkin );
|
||||
connect( this, &QskMenuButton::triggered,
|
||||
this, &SkinButton::changeSkin );
|
||||
}
|
||||
|
||||
void openMenu() override
|
||||
{
|
||||
const auto names = qskSkinManager->skinNames();
|
||||
setStartIndex( names.indexOf( qskSetup->skinName() ) );
|
||||
|
||||
QskMenuButton::openMenu();
|
||||
}
|
||||
|
||||
void changeSkin( int index )
|
||||
{
|
||||
const auto names = qskSkinManager->skinNames();
|
||||
if ( index < 0 || index >= names.size() )
|
||||
return;
|
||||
|
||||
if ( index == names.indexOf( qskSetup->skinName() ) )
|
||||
return;
|
||||
|
||||
auto oldSkin = qskSetup->skin();
|
||||
if ( oldSkin->parent() == qskSetup )
|
||||
oldSkin->setParent( nullptr ); // otherwise setSkin deletes it
|
||||
|
||||
if ( auto newSkin = qskSetup->setSkin( names[ index ] ) )
|
||||
if ( ( index >= 0 ) && ( index < names.size() )
|
||||
&& ( index != names.indexOf( qskSetup->skinName() ) ) )
|
||||
{
|
||||
QskSkinTransition transition;
|
||||
|
||||
transition.setSourceSkin( oldSkin );
|
||||
transition.setTargetSkin( newSkin );
|
||||
transition.setAnimation( 500 );
|
||||
|
||||
transition.process();
|
||||
|
||||
if ( oldSkin->parent() == nullptr )
|
||||
delete oldSkin;
|
||||
Skinny::setSkin( index, 500 );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FileButton final : public MenuButton
|
||||
class FileButton final : public QskMenuButton
|
||||
{
|
||||
public:
|
||||
FileButton( const QString& text, QQuickItem* parent = nullptr )
|
||||
: MenuButton( text, parent )
|
||||
: QskMenuButton( text, parent )
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
void populateMenu( QskMenu* menu ) override
|
||||
{
|
||||
menu->addOption( "image://shapes/Rectangle/White", "Print" );
|
||||
menu->addOption( "image://shapes/Diamond/Yellow", "Save As" );
|
||||
menu->addOption( "image://shapes/Ellipse/Red", "Setup" );
|
||||
menu->addSeparator();
|
||||
menu->addOption( "image://shapes/Hexagon/PapayaWhip", "Quit" );
|
||||
addOption( "image://shapes/Rectangle/White", "Print" );
|
||||
addOption( "image://shapes/Diamond/Yellow", "Save As" );
|
||||
addOption( "image://shapes/Ellipse/Red", "Setup" );
|
||||
addSeparator();
|
||||
addOption( "image://shapes/Hexagon/PapayaWhip", "Quit" );
|
||||
|
||||
// see https://github.com/uwerat/qskinny/issues/192
|
||||
connect( menu, &QskMenu::triggered,
|
||||
[]( int index ) { if ( index == 3 ) qApp->quit(); } );
|
||||
connect( this, &QskMenuButton::triggered,
|
||||
this, &FileButton::activate );
|
||||
}
|
||||
private:
|
||||
void activate( int index )
|
||||
{
|
||||
if ( optionAt( index ).text() == "Quit" )
|
||||
qApp->quit();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -184,6 +184,7 @@ list(APPEND HEADERS
|
|||
controls/QskListViewSkinlet.h
|
||||
controls/QskMenu.h
|
||||
controls/QskMenuSkinlet.h
|
||||
controls/QskMenuButton.h
|
||||
controls/QskObjectTree.h
|
||||
controls/QskPageIndicator.h
|
||||
controls/QskPageIndicatorSkinlet.h
|
||||
|
@ -280,8 +281,9 @@ list(APPEND SOURCES
|
|||
controls/QskInputGrabber.cpp
|
||||
controls/QskListView.cpp
|
||||
controls/QskListViewSkinlet.cpp
|
||||
controls/QskMenuSkinlet.cpp
|
||||
controls/QskMenu.cpp
|
||||
controls/QskMenuSkinlet.cpp
|
||||
controls/QskMenuButton.cpp
|
||||
controls/QskObjectTree.cpp
|
||||
controls/QskPageIndicator.cpp
|
||||
controls/QskPageIndicatorSkinlet.cpp
|
||||
|
|
|
@ -71,8 +71,6 @@ class QSK_EXPORT QskMenu : public QskPopup
|
|||
QVector< int > separators() const;
|
||||
QVector< int > actions() const;
|
||||
|
||||
void clear();
|
||||
|
||||
int currentIndex() const;
|
||||
QString currentText() const;
|
||||
|
||||
|
@ -97,6 +95,7 @@ class QSK_EXPORT QskMenu : public QskPopup
|
|||
|
||||
public Q_SLOTS:
|
||||
void setCurrentIndex( int );
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
void keyPressEvent( QKeyEvent* ) override;
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "QskMenuButton.h"
|
||||
#include "QskMenu.h"
|
||||
#include "QskLabelData.h"
|
||||
|
||||
#include <qpointer.h>
|
||||
#include <qquickwindow.h>
|
||||
|
||||
class QskMenuButton::PrivateData
|
||||
{
|
||||
public:
|
||||
int triggeredIndex = -1;
|
||||
int startIndex = -1;
|
||||
|
||||
QPointer< QskMenu > menu;
|
||||
QVector< QskLabelData > options;
|
||||
};
|
||||
|
||||
QskMenuButton::QskMenuButton( QQuickItem* parent )
|
||||
: QskMenuButton( QString(), parent )
|
||||
{
|
||||
}
|
||||
|
||||
QskMenuButton::QskMenuButton( const QString& text, QQuickItem* parent )
|
||||
: QskPushButton( text, parent )
|
||||
, m_data( new PrivateData )
|
||||
{
|
||||
connect( this, &QskPushButton::pressed,
|
||||
this, &QskMenuButton::openMenu );
|
||||
}
|
||||
|
||||
QskMenuButton::~QskMenuButton()
|
||||
{
|
||||
}
|
||||
|
||||
int QskMenuButton::addOption( const QString& graphicSource, const QString& text )
|
||||
{
|
||||
return addOption( QskLabelData( text, graphicSource ) );
|
||||
}
|
||||
|
||||
int QskMenuButton::addOption( const QUrl& graphicSource, const QString& text )
|
||||
{
|
||||
return addOption( QskLabelData( text, graphicSource ) );
|
||||
}
|
||||
|
||||
int QskMenuButton::addOption( const QskLabelData& option )
|
||||
{
|
||||
const int index = m_data->options.count();
|
||||
m_data->options += option;
|
||||
|
||||
if ( m_data->menu )
|
||||
m_data->menu->setOptions( m_data->options );
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void QskMenuButton::addSeparator()
|
||||
{
|
||||
addOption( QskLabelData() );
|
||||
}
|
||||
|
||||
void QskMenuButton::setOptions( const QStringList& options )
|
||||
{
|
||||
setOptions( qskCreateLabelData( options ) );
|
||||
}
|
||||
|
||||
void QskMenuButton::setOptions( const QVector< QskLabelData >& options )
|
||||
{
|
||||
m_data->options = options;
|
||||
|
||||
if ( m_data->menu )
|
||||
m_data->menu->setOptions( m_data->options );
|
||||
}
|
||||
|
||||
void QskMenuButton::clear()
|
||||
{
|
||||
m_data->options.clear();
|
||||
|
||||
if ( m_data->menu )
|
||||
m_data->menu->clear();
|
||||
}
|
||||
|
||||
QVector< QskLabelData > QskMenuButton::options() const
|
||||
{
|
||||
return m_data->options;
|
||||
}
|
||||
|
||||
QskLabelData QskMenuButton::optionAt( int index ) const
|
||||
{
|
||||
return m_data->options.value( index );
|
||||
}
|
||||
|
||||
int QskMenuButton::optionsCount() const
|
||||
{
|
||||
return m_data->options.count();
|
||||
}
|
||||
|
||||
void QskMenuButton::setStartIndex( int index )
|
||||
{
|
||||
m_data->startIndex = index;
|
||||
}
|
||||
|
||||
int QskMenuButton::triggeredIndex() const
|
||||
{
|
||||
return m_data->triggeredIndex;
|
||||
}
|
||||
|
||||
QString QskMenuButton::triggeredText() const
|
||||
{
|
||||
return optionAt( m_data->triggeredIndex ).text();
|
||||
}
|
||||
|
||||
const QskMenu* QskMenuButton::menu() const
|
||||
{
|
||||
return m_data->menu;
|
||||
}
|
||||
|
||||
void QskMenuButton::openMenu()
|
||||
{
|
||||
if ( m_data->menu || window() == nullptr || m_data->options.isEmpty() )
|
||||
return;
|
||||
|
||||
m_data->triggeredIndex = -1;
|
||||
|
||||
auto menu = new QskMenu( window()->contentItem() );
|
||||
m_data->menu = menu;
|
||||
|
||||
menu->setOptions( m_data->options );
|
||||
if ( m_data->startIndex >= 0 )
|
||||
menu->setCurrentIndex( m_data->startIndex );
|
||||
|
||||
menu->setOrigin( geometry().bottomLeft() );
|
||||
|
||||
connect( menu, &QskMenu::triggered,
|
||||
this, &QskMenuButton::updateTriggeredIndex );
|
||||
|
||||
menu->open();
|
||||
}
|
||||
|
||||
void QskMenuButton::updateTriggeredIndex( int index )
|
||||
{
|
||||
if ( m_data->triggeredIndex != index )
|
||||
{
|
||||
m_data->triggeredIndex = index;
|
||||
Q_EMIT triggered( index );
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_QskMenuButton.cpp"
|
|
@ -0,0 +1,67 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QSK_MENU_BUTTON_H
|
||||
#define QSK_MENU_BUTTON_H
|
||||
|
||||
#include "QskPushButton.h"
|
||||
|
||||
class QskMenu;
|
||||
class QskLabelData;
|
||||
|
||||
class QSK_EXPORT QskMenuButton : public QskPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( QVector< QskLabelData > options READ options
|
||||
WRITE setOptions NOTIFY optionsChanged )
|
||||
|
||||
Q_PROPERTY( int optionsCount READ optionsCount )
|
||||
Q_PROPERTY( int triggeredIndex READ triggeredIndex NOTIFY triggered )
|
||||
Q_PROPERTY( QString triggeredText READ triggeredText NOTIFY triggered )
|
||||
|
||||
public:
|
||||
QskMenuButton( QQuickItem* parent = nullptr );
|
||||
QskMenuButton( const QString& text, QQuickItem* parent = nullptr );
|
||||
|
||||
~QskMenuButton() override;
|
||||
|
||||
int addOption( const QString&, const QString& );
|
||||
int addOption( const QUrl&, const QString& );
|
||||
int addOption( const QskLabelData& );
|
||||
void addSeparator();
|
||||
|
||||
void setOptions( const QVector< QskLabelData >& );
|
||||
void setOptions( const QStringList& );
|
||||
|
||||
QVector< QskLabelData > options() const;
|
||||
QskLabelData optionAt( int ) const;
|
||||
|
||||
int optionsCount() const;
|
||||
|
||||
const QskMenu* menu() const;
|
||||
|
||||
int triggeredIndex() const;
|
||||
QString triggeredText() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setStartIndex( int );
|
||||
void clear();
|
||||
|
||||
Q_SIGNALS:
|
||||
void triggered( int index );
|
||||
void optionsChanged();
|
||||
|
||||
protected:
|
||||
virtual void openMenu();
|
||||
|
||||
private:
|
||||
void updateTriggeredIndex( int );
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -135,13 +135,25 @@ static bool pluginPath = initPluginPath();
|
|||
Q_COREAPP_STARTUP_FUNCTION( initFonts )
|
||||
|
||||
void Skinny::changeSkin( QskAnimationHint hint )
|
||||
{
|
||||
const auto names = qskSkinManager->skinNames();
|
||||
if ( names.size() > 1 )
|
||||
{
|
||||
auto index = names.indexOf( qskSetup->skinName() );
|
||||
index = ( index + 1 ) % names.size();
|
||||
|
||||
setSkin( index, hint );
|
||||
}
|
||||
}
|
||||
|
||||
void Skinny::setSkin( int index, QskAnimationHint hint )
|
||||
{
|
||||
const auto names = qskSkinManager->skinNames();
|
||||
if ( names.size() <= 1 )
|
||||
return;
|
||||
|
||||
int index = names.indexOf( qskSetup->skinName() );
|
||||
index = ( index + 1 ) % names.size();
|
||||
if ( index == names.indexOf( qskSetup->skinName() ) )
|
||||
return;
|
||||
|
||||
auto oldSkin = qskSetup->skin();
|
||||
if ( oldSkin->parent() == qskSetup )
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
namespace Skinny
|
||||
{
|
||||
SKINNY_EXPORT void changeSkin( QskAnimationHint hint = 500 );
|
||||
SKINNY_EXPORT void setSkin( int index, QskAnimationHint hint = 500 );
|
||||
SKINNY_EXPORT void changeFonts( int increment );
|
||||
SKINNY_EXPORT void init();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue