Add checkbox
This commit is contained in:
parent
de48deb7c8
commit
08837285a4
|
@ -8,6 +8,7 @@
|
||||||
#include <QskSkinHintTableEditor.h>
|
#include <QskSkinHintTableEditor.h>
|
||||||
|
|
||||||
#include <QskBox.h>
|
#include <QskBox.h>
|
||||||
|
#include <QskCheckBox.h>
|
||||||
#include <QskDialogButton.h>
|
#include <QskDialogButton.h>
|
||||||
#include <QskDialogButtonBox.h>
|
#include <QskDialogButtonBox.h>
|
||||||
#include <QskFocusIndicator.h>
|
#include <QskFocusIndicator.h>
|
||||||
|
@ -112,6 +113,7 @@ namespace
|
||||||
void setupControl();
|
void setupControl();
|
||||||
|
|
||||||
void setupBox();
|
void setupBox();
|
||||||
|
void setupCheckBox();
|
||||||
void setupDialogButtonBox();
|
void setupDialogButtonBox();
|
||||||
void setupDialogButton();
|
void setupDialogButton();
|
||||||
void setupFocusIndicator();
|
void setupFocusIndicator();
|
||||||
|
@ -142,6 +144,7 @@ void Editor::setup()
|
||||||
setupControl();
|
setupControl();
|
||||||
|
|
||||||
setupBox();
|
setupBox();
|
||||||
|
setupCheckBox();
|
||||||
setupDialogButtonBox();
|
setupDialogButtonBox();
|
||||||
setupDialogButton();
|
setupDialogButton();
|
||||||
setupFocusIndicator();
|
setupFocusIndicator();
|
||||||
|
@ -177,6 +180,24 @@ void Editor::setupControl()
|
||||||
qskShadedColor( m_pal.textColor, 0.6 ) );
|
qskShadedColor( m_pal.textColor, 0.6 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::setupCheckBox()
|
||||||
|
{
|
||||||
|
using Q = QskCheckBox;
|
||||||
|
|
||||||
|
const qreal radius = qskDpiScaled( 18 );
|
||||||
|
|
||||||
|
setMargin( QskCheckBox::Tick, QMarginsF( 3, 5, 3, 3 ) );
|
||||||
|
setStrutSize( Q::Box, radius, radius );
|
||||||
|
|
||||||
|
setBoxShape( Q::Box, 2 );
|
||||||
|
|
||||||
|
setColor( Q::Box, m_pal.baseColor);
|
||||||
|
setColor( Q::Box | Q::Checked, m_pal.accentColor );
|
||||||
|
setGradient( Q::Box | Q::Checked | Q::Disabled, QskRgb::Grey );
|
||||||
|
|
||||||
|
setColor( Q::Tick, m_pal.contrastColor );
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::setupBox()
|
void Editor::setupBox()
|
||||||
{
|
{
|
||||||
using Q = QskBox;
|
using Q = QskBox;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <QskSkinHintTableEditor.h>
|
#include <QskSkinHintTableEditor.h>
|
||||||
|
|
||||||
#include <QskBox.h>
|
#include <QskBox.h>
|
||||||
|
#include <QskCheckBox.h>
|
||||||
#include <QskDialogButton.h>
|
#include <QskDialogButton.h>
|
||||||
#include <QskDialogButtonBox.h>
|
#include <QskDialogButtonBox.h>
|
||||||
#include <QskFocusIndicator.h>
|
#include <QskFocusIndicator.h>
|
||||||
|
@ -132,6 +133,7 @@ namespace
|
||||||
void setupControl();
|
void setupControl();
|
||||||
|
|
||||||
void setupBox();
|
void setupBox();
|
||||||
|
void setupCheckBox();
|
||||||
void setupDialogButton();
|
void setupDialogButton();
|
||||||
void setupDialogButtonBox();
|
void setupDialogButtonBox();
|
||||||
void setupFocusIndicator();
|
void setupFocusIndicator();
|
||||||
|
@ -251,6 +253,7 @@ void Editor::setup()
|
||||||
setupControl();
|
setupControl();
|
||||||
|
|
||||||
setupBox();
|
setupBox();
|
||||||
|
setupCheckBox();
|
||||||
setupDialogButtonBox();
|
setupDialogButtonBox();
|
||||||
setupDialogButton();
|
setupDialogButton();
|
||||||
setupFocusIndicator();
|
setupFocusIndicator();
|
||||||
|
@ -292,6 +295,23 @@ void Editor::setupBox()
|
||||||
setPanel( QskBox::Panel, Plain );
|
setPanel( QskBox::Panel, Plain );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::setupCheckBox()
|
||||||
|
{
|
||||||
|
using Q = QskCheckBox;
|
||||||
|
|
||||||
|
const qreal size = qskDpiScaled( 26 );
|
||||||
|
|
||||||
|
setMargin( Q::Tick, QskMargins( qskDpiScaled( 5 ) ) );
|
||||||
|
|
||||||
|
setStrutSize( Q::Box, QSizeF( size, size ) );
|
||||||
|
setBoxShape( Q::Box, qskDpiScaled( 3 ) );
|
||||||
|
setBoxBorderMetrics( Q::Box, qskDpiScaled( 1 ) );
|
||||||
|
setBoxBorderColors( Q::Box, m_pal.darker125 );
|
||||||
|
setColor( Q::Box, m_pal.lighter135 );
|
||||||
|
setColor( Q::Box | Q::Checked, m_pal.highlighted );
|
||||||
|
setColor( Q::Tick, m_pal.lighter135 );
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::setupPopup()
|
void Editor::setupPopup()
|
||||||
{
|
{
|
||||||
using A = QskAspect;
|
using A = QskAspect;
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
#include "QskCheckBox.h"
|
||||||
|
|
||||||
|
#include "QskAspect.h"
|
||||||
|
|
||||||
|
#include <qset.h>
|
||||||
|
|
||||||
|
QSK_SUBCONTROL( QskCheckBox, Box )
|
||||||
|
QSK_SUBCONTROL( QskCheckBox, Tick )
|
||||||
|
|
||||||
|
QSK_SYSTEM_STATE( QskCheckBox, PartiallyChecked, QskAspect::LastUserState << 2 )
|
||||||
|
|
||||||
|
struct QskCheckBox::PrivateData
|
||||||
|
{
|
||||||
|
Qt::CheckState checkState;
|
||||||
|
bool checkStateChanging : 1;
|
||||||
|
bool toggleChanging : 1;
|
||||||
|
bool triState : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
QskCheckBox::QskCheckBox( QQuickItem* parent )
|
||||||
|
: Inherited( parent ), m_data( new PrivateData{ Qt::CheckState::Unchecked,
|
||||||
|
false, false, false } ) {
|
||||||
|
setAcceptHoverEvents( true );
|
||||||
|
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||||
|
|
||||||
|
connect( this, &QskCheckBox::checkedChanged, this, [ this ]( bool t )
|
||||||
|
{
|
||||||
|
setCheckStateInternal( t ? Qt::CheckState::Checked :
|
||||||
|
Qt::CheckState::Unchecked );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskCheckBox::~QskCheckBox()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskCheckBox::isCheckable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::CheckState QskCheckBox::checkState() const
|
||||||
|
{
|
||||||
|
return m_data->checkState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskCheckBox::setCheckStateInternal( Qt::CheckState checkState )
|
||||||
|
{
|
||||||
|
if( m_data->checkStateChanging )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSkinStateFlag( PartiallyChecked,
|
||||||
|
checkState == Qt::CheckState::PartiallyChecked );
|
||||||
|
|
||||||
|
m_data->checkState = checkState;
|
||||||
|
Q_EMIT checkStateChanged( checkState );
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskCheckBox::setCheckState( Qt::CheckState checkState )
|
||||||
|
{
|
||||||
|
if( checkState == m_data->checkState )
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data->checkStateChanging = true;
|
||||||
|
if( checkState == Qt::CheckState::PartiallyChecked )
|
||||||
|
{
|
||||||
|
setChecked( true );
|
||||||
|
setTriState( true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setChecked( checkState == Qt::CheckState::Checked );
|
||||||
|
}
|
||||||
|
m_data->checkStateChanging = false;
|
||||||
|
|
||||||
|
setCheckStateInternal( checkState );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QskCheckBox::isTriState() const
|
||||||
|
{
|
||||||
|
return m_data->triState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskCheckBox::setTriState( bool triState )
|
||||||
|
{
|
||||||
|
if( m_data->triState != triState )
|
||||||
|
{
|
||||||
|
m_data->triState = triState;
|
||||||
|
Q_EMIT isTriStateChanged( triState );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_QskCheckBox.cpp"
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef QSK_CHECK_BOX_H
|
||||||
|
#define QSK_CHECK_BOX_H
|
||||||
|
|
||||||
|
#include "QskAbstractButton.h"
|
||||||
|
|
||||||
|
class QSK_EXPORT QskCheckBox : public QskAbstractButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY( Qt::CheckState checkState READ checkState
|
||||||
|
WRITE setCheckState NOTIFY checkStateChanged FINAL )
|
||||||
|
Q_PROPERTY( bool isTriState READ isTriState
|
||||||
|
WRITE setTriState NOTIFY isTriStateChanged FINAL )
|
||||||
|
|
||||||
|
using Inherited = QskAbstractButton;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QSK_SUBCONTROLS( Box, Tick )
|
||||||
|
QSK_STATES( PartiallyChecked )
|
||||||
|
|
||||||
|
QskCheckBox( QQuickItem* parent = nullptr );
|
||||||
|
~QskCheckBox() override;
|
||||||
|
|
||||||
|
Qt::CheckState checkState() const;
|
||||||
|
bool isTriState() const;
|
||||||
|
bool isCheckable() const override final;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void setCheckState( Qt::CheckState );
|
||||||
|
void setTriState( bool triState = true );
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void checkStateChanged( Qt::CheckState );
|
||||||
|
void isTriStateChanged( bool );
|
||||||
|
private:
|
||||||
|
void setCheckStateInternal( Qt::CheckState );
|
||||||
|
|
||||||
|
struct PrivateData;
|
||||||
|
std::unique_ptr< PrivateData > m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QSK_CHECK_BOX_H
|
|
@ -0,0 +1,134 @@
|
||||||
|
#include "QskCheckBoxSkinlet.h"
|
||||||
|
#include "QskCheckBox.h"
|
||||||
|
|
||||||
|
#include <QSGFlatColorMaterial>
|
||||||
|
#include <qsgnode.h>
|
||||||
|
|
||||||
|
class Tic : public QSGGeometryNode {
|
||||||
|
QSGFlatColorMaterial material;
|
||||||
|
QSGGeometry geometry = QSGGeometry(
|
||||||
|
QSGGeometry::defaultAttributes_Point2D(), 3 );
|
||||||
|
const QRectF& target;
|
||||||
|
public:
|
||||||
|
Tic( const QRectF& rect, const QColor& color ): target( rect ) {
|
||||||
|
geometry.setDrawingMode( QSGGeometry::DrawLineStrip );
|
||||||
|
geometry.setLineWidth( 2 );
|
||||||
|
setGeometry( &geometry );
|
||||||
|
|
||||||
|
material.setColor( color );
|
||||||
|
setMaterial( &material );
|
||||||
|
|
||||||
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
void setColor( const QColor& color ) {
|
||||||
|
material.setColor( color );
|
||||||
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeTic() {
|
||||||
|
const auto& size = target.size();
|
||||||
|
const auto x = target.x();
|
||||||
|
const auto y = target.y();
|
||||||
|
|
||||||
|
geometry.vertexDataAsPoint2D()[0].set( x, y + size.height() / 2 );
|
||||||
|
geometry.vertexDataAsPoint2D()[1].set( x + size.width() / 3,
|
||||||
|
y + size.height() );
|
||||||
|
geometry.vertexDataAsPoint2D()[2].set( x + size.width(), y );
|
||||||
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
void makePartially() {
|
||||||
|
const auto& size = target.size();
|
||||||
|
const auto x = target.x();
|
||||||
|
const auto y = target.y();
|
||||||
|
|
||||||
|
geometry.vertexDataAsPoint2D()[0].set( x, y + size.height() / 2 );
|
||||||
|
geometry.vertexDataAsPoint2D()[1].set( x, y + size.height() / 2 );
|
||||||
|
geometry.vertexDataAsPoint2D()[2].set( x + size.width(),
|
||||||
|
y + size.height() / 2 );
|
||||||
|
|
||||||
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
void makeEmpty() {
|
||||||
|
const auto x = target.x();
|
||||||
|
const auto y = target.y();
|
||||||
|
|
||||||
|
geometry.vertexDataAsPoint2D()[0].set( x, y );
|
||||||
|
geometry.vertexDataAsPoint2D()[1].set( x, y );
|
||||||
|
geometry.vertexDataAsPoint2D()[2].set( x, y );
|
||||||
|
|
||||||
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QskCheckBoxSkinlet::QskCheckBoxSkinlet( QskSkin* skin )
|
||||||
|
: QskSkinlet( skin )
|
||||||
|
{
|
||||||
|
setNodeRoles( { BoxRole, TickRole } );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskCheckBoxSkinlet::~QskCheckBoxSkinlet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QskCheckBoxSkinlet::subControlRect(
|
||||||
|
const QskSkinnable*,
|
||||||
|
const QRectF& contentsRect,
|
||||||
|
QskAspect::Subcontrol ) const
|
||||||
|
{
|
||||||
|
return contentsRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode* QskCheckBoxSkinlet::updateSubNode(
|
||||||
|
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||||
|
{
|
||||||
|
switch( nodeRole ) {
|
||||||
|
case BoxRole:
|
||||||
|
return updateBoxNode( skinnable, node,
|
||||||
|
QskCheckBox::Box );
|
||||||
|
case TickRole:
|
||||||
|
auto control = dynamic_cast< const QskCheckBox* >( skinnable );
|
||||||
|
auto rect = control->subControlRect( QskCheckBox::Tick );
|
||||||
|
rect = rect.marginsRemoved(
|
||||||
|
skinnable->marginHint( QskCheckBox::Tick ) );
|
||||||
|
|
||||||
|
Tic* tic;
|
||||||
|
if ( static_cast< Tic* >( node ) == nullptr )
|
||||||
|
{
|
||||||
|
tic = new Tic( rect, skinnable->color( QskCheckBox::Tick ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tic = static_cast< Tic* >( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( control->checkState() ) {
|
||||||
|
case Qt::CheckState::Unchecked:
|
||||||
|
tic->setColor( skinnable->color( QskCheckBox::Tick ) );
|
||||||
|
tic->makeEmpty();
|
||||||
|
break;
|
||||||
|
case Qt::CheckState::PartiallyChecked:
|
||||||
|
tic->setColor( skinnable->color(
|
||||||
|
QskCheckBox::Tick | QskCheckBox::PartiallyChecked ) );
|
||||||
|
tic->makePartially();
|
||||||
|
break;
|
||||||
|
case Qt::CheckState::Checked:
|
||||||
|
tic->setColor( skinnable->color(
|
||||||
|
QskCheckBox::Tick | QskCheckBox::Checked ) );
|
||||||
|
tic->makeTic();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tic;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF QskCheckBoxSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||||
|
Qt::SizeHint, const QSizeF& ) const
|
||||||
|
{
|
||||||
|
return skinnable->strutSizeHint( QskCheckBox::Box );
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef QSK_CHECK_BOX_SKINLET_H
|
||||||
|
#define QSK_CHECK_BOX_SKINLET_H
|
||||||
|
|
||||||
|
#include "QskSkinlet.h"
|
||||||
|
|
||||||
|
class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
|
||||||
|
using Inherited = QskSkinlet;
|
||||||
|
public:
|
||||||
|
enum NodeRole
|
||||||
|
{
|
||||||
|
BoxRole,
|
||||||
|
TickRole,
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_INVOKABLE QskCheckBoxSkinlet( QskSkin* = nullptr );
|
||||||
|
~QskCheckBoxSkinlet() override;
|
||||||
|
|
||||||
|
QRectF subControlRect( const QskSkinnable*,
|
||||||
|
const QRectF&, QskAspect::Subcontrol ) const override;
|
||||||
|
|
||||||
|
QSizeF sizeHint( const QskSkinnable*,
|
||||||
|
Qt::SizeHint, const QSizeF& ) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QSGNode* updateSubNode( const QskSkinnable*,
|
||||||
|
quint8 nodeRole, QSGNode* ) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QSK_CHECK_BOX_SKINLET_H
|
|
@ -29,6 +29,9 @@ QSK_QT_PRIVATE_END
|
||||||
#include "QskBox.h"
|
#include "QskBox.h"
|
||||||
#include "QskBoxSkinlet.h"
|
#include "QskBoxSkinlet.h"
|
||||||
|
|
||||||
|
#include "QskCheckBox.h"
|
||||||
|
#include "QskCheckBoxSkinlet.h"
|
||||||
|
|
||||||
#include "QskFocusIndicator.h"
|
#include "QskFocusIndicator.h"
|
||||||
#include "QskFocusIndicatorSkinlet.h"
|
#include "QskFocusIndicatorSkinlet.h"
|
||||||
|
|
||||||
|
@ -143,6 +146,7 @@ QskSkin::QskSkin( QObject* parent )
|
||||||
declareSkinlet< QskControl, QskSkinlet >();
|
declareSkinlet< QskControl, QskSkinlet >();
|
||||||
|
|
||||||
declareSkinlet< QskBox, QskBoxSkinlet >();
|
declareSkinlet< QskBox, QskBoxSkinlet >();
|
||||||
|
declareSkinlet< QskCheckBox, QskCheckBoxSkinlet >();
|
||||||
declareSkinlet< QskFocusIndicator, QskFocusIndicatorSkinlet >();
|
declareSkinlet< QskFocusIndicator, QskFocusIndicatorSkinlet >();
|
||||||
declareSkinlet< QskGraphicLabel, QskGraphicLabelSkinlet >();
|
declareSkinlet< QskGraphicLabel, QskGraphicLabelSkinlet >();
|
||||||
declareSkinlet< QskListView, QskListViewSkinlet >();
|
declareSkinlet< QskListView, QskListViewSkinlet >();
|
||||||
|
|
|
@ -141,6 +141,8 @@ HEADERS += \
|
||||||
controls/QskBoundedValueInput.h \
|
controls/QskBoundedValueInput.h \
|
||||||
controls/QskBox.h \
|
controls/QskBox.h \
|
||||||
controls/QskBoxSkinlet.h \
|
controls/QskBoxSkinlet.h \
|
||||||
|
controls/QskCheckBox.h \
|
||||||
|
controls/QskCheckBoxSkinlet.h \
|
||||||
controls/QskControl.h \
|
controls/QskControl.h \
|
||||||
controls/QskControlPrivate.h \
|
controls/QskControlPrivate.h \
|
||||||
controls/QskDirtyItemFilter.h \
|
controls/QskDirtyItemFilter.h \
|
||||||
|
@ -221,6 +223,8 @@ SOURCES += \
|
||||||
controls/QskBoundedValueInput.cpp \
|
controls/QskBoundedValueInput.cpp \
|
||||||
controls/QskBox.cpp \
|
controls/QskBox.cpp \
|
||||||
controls/QskBoxSkinlet.cpp \
|
controls/QskBoxSkinlet.cpp \
|
||||||
|
controls/QskCheckBox.cpp \
|
||||||
|
controls/QskCheckBoxSkinlet.cpp \
|
||||||
controls/QskControl.cpp \
|
controls/QskControl.cpp \
|
||||||
controls/QskControlPrivate.cpp \
|
controls/QskControlPrivate.cpp \
|
||||||
controls/QskDirtyItemFilter.cpp \
|
controls/QskDirtyItemFilter.cpp \
|
||||||
|
|
Loading…
Reference in New Issue