Replace QskCheckBox by a simpler version
This commit is contained in:
parent
9f706beab1
commit
045798d084
|
@ -89,12 +89,7 @@ namespace
|
|||
setSpacing( 20 );
|
||||
setExtraSpacingAt( Qt::LeftEdge | Qt::RightEdge | Qt::BottomEdge );
|
||||
|
||||
for ( auto state : { Qt::Unchecked, Qt::PartiallyChecked, Qt::Checked } )
|
||||
{
|
||||
auto button = new QskCheckBox( this );
|
||||
button->setTristate( true );
|
||||
button->setCheckState( state );
|
||||
}
|
||||
new QskCheckBox( this );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,48 +6,18 @@
|
|||
#include "QskCheckBox.h"
|
||||
#include "QskAspect.h"
|
||||
|
||||
#include <qset.h>
|
||||
|
||||
QSK_SUBCONTROL( QskCheckBox, Panel )
|
||||
QSK_SUBCONTROL( QskCheckBox, Indicator )
|
||||
|
||||
QSK_SYSTEM_STATE( QskCheckBox, PartiallyChecked, QskAspect::LastUserState << 2 )
|
||||
|
||||
class QskCheckBox::PrivateData
|
||||
{
|
||||
public:
|
||||
PrivateData()
|
||||
: checkState( Qt::Unchecked )
|
||||
, checkStateChanging( false )
|
||||
, toggleChanging( false )
|
||||
, tristate( false )
|
||||
{
|
||||
}
|
||||
|
||||
QSet< QskAbstractButton* > group;
|
||||
|
||||
int groupItemsChecked = 0;
|
||||
|
||||
Qt::CheckState checkState : 2;
|
||||
bool checkStateChanging : 1;
|
||||
bool toggleChanging : 1;
|
||||
bool tristate : 1;
|
||||
};
|
||||
|
||||
QskCheckBox::QskCheckBox( QQuickItem* parent )
|
||||
: Inherited( parent )
|
||||
, m_data( new PrivateData() )
|
||||
{
|
||||
setAcceptHoverEvents( true );
|
||||
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||
|
||||
connect( this, &QskCheckBox::checkedChanged, this,
|
||||
[ this ]( bool on ) { setCheckStateInternal( on ? Qt::Checked : Qt::Unchecked ); } );
|
||||
}
|
||||
|
||||
QskCheckBox::~QskCheckBox()
|
||||
{
|
||||
Q_EMIT removeFromAllGroupsRequested();
|
||||
}
|
||||
|
||||
bool QskCheckBox::isCheckable() const
|
||||
|
@ -55,130 +25,4 @@ 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::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::PartiallyChecked )
|
||||
{
|
||||
setChecked( true );
|
||||
setTristate( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
setChecked( checkState == Qt::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 tristateChanged( tristate );
|
||||
}
|
||||
}
|
||||
|
||||
void QskCheckBox::updated()
|
||||
{
|
||||
if( m_data->toggleChanging )
|
||||
return;
|
||||
|
||||
const auto& groupItemsChecked = m_data->groupItemsChecked;
|
||||
|
||||
if( groupItemsChecked == m_data->group.size() )
|
||||
{
|
||||
setCheckState( Qt::Checked );
|
||||
}
|
||||
else if ( groupItemsChecked == 0 )
|
||||
{
|
||||
setCheckState( Qt::Unchecked );
|
||||
}
|
||||
else
|
||||
{
|
||||
setCheckState( Qt::PartiallyChecked );
|
||||
}
|
||||
}
|
||||
|
||||
void QskCheckBox::addToGroup( QskCheckBox* groupItem )
|
||||
{
|
||||
if( m_data->group.contains( groupItem ) )
|
||||
return;
|
||||
|
||||
m_data->group.insert( groupItem );
|
||||
|
||||
if( groupItem->checkState() == Qt::Checked )
|
||||
m_data->groupItemsChecked++;
|
||||
|
||||
updated();
|
||||
|
||||
connect( this, &QskCheckBox::checkStateChanged,
|
||||
groupItem, [ this, groupItem ]( Qt::CheckState checkState )
|
||||
{
|
||||
if( checkState == Qt::Checked )
|
||||
{
|
||||
m_data->toggleChanging = true;
|
||||
groupItem->setChecked( true );
|
||||
m_data->groupItemsChecked = m_data->group.size();
|
||||
m_data->toggleChanging = false;
|
||||
}
|
||||
else if ( checkState == Qt::Unchecked )
|
||||
{
|
||||
m_data->toggleChanging = true;
|
||||
groupItem->setChecked( false );
|
||||
m_data->groupItemsChecked = 0;
|
||||
m_data->toggleChanging = false;
|
||||
}
|
||||
} );
|
||||
|
||||
connect( groupItem, &QskAbstractButton::toggled,
|
||||
this, [ this ]( bool toggled )
|
||||
{
|
||||
m_data->groupItemsChecked += toggled ? 1 : -1;
|
||||
updated();
|
||||
} );
|
||||
|
||||
connect( groupItem, &QskCheckBox::removeFromAllGroupsRequested,
|
||||
this, [ this, groupItem ]( ) { removeFromGroup( groupItem ); } );
|
||||
}
|
||||
|
||||
void QskCheckBox::removeFromGroup( QskCheckBox* groupItem )
|
||||
{
|
||||
if( !m_data->group.remove( groupItem ) )
|
||||
return;
|
||||
|
||||
if( groupItem->checkState() == Qt::Checked )
|
||||
m_data->groupItemsChecked--;
|
||||
|
||||
updated();
|
||||
}
|
||||
|
||||
#include "moc_QskCheckBox.cpp"
|
||||
|
|
|
@ -12,43 +12,15 @@ class QSK_EXPORT QskCheckBox : public QskAbstractButton
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( Qt::CheckState checkState READ checkState
|
||||
WRITE setCheckState NOTIFY checkStateChanged FINAL )
|
||||
|
||||
Q_PROPERTY( bool tristate READ isTristate
|
||||
WRITE setTristate NOTIFY tristateChanged FINAL )
|
||||
|
||||
using Inherited = QskAbstractButton;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Panel, Indicator )
|
||||
QSK_STATES( PartiallyChecked )
|
||||
|
||||
QskCheckBox( QQuickItem* parent = nullptr );
|
||||
~QskCheckBox() override;
|
||||
|
||||
Qt::CheckState checkState() const;
|
||||
bool isTristate() const;
|
||||
bool isCheckable() const override final;
|
||||
|
||||
void addToGroup( QskCheckBox* );
|
||||
void removeFromGroup( QskCheckBox* );
|
||||
|
||||
public Q_SLOTS:
|
||||
void setCheckState( Qt::CheckState );
|
||||
void setTristate( bool triState = true );
|
||||
|
||||
Q_SIGNALS:
|
||||
void checkStateChanged( Qt::CheckState );
|
||||
void tristateChanged( bool );
|
||||
void removeFromAllGroupsRequested();
|
||||
|
||||
private:
|
||||
void setCheckStateInternal( Qt::CheckState );
|
||||
void updated();
|
||||
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace
|
|||
setMaterial( &m_material );
|
||||
}
|
||||
|
||||
void update( bool isPartially, const QRectF& rect, const QColor& color )
|
||||
void update( const QRectF& rect, const QColor& color )
|
||||
{
|
||||
if ( color != m_material.color() )
|
||||
{
|
||||
|
@ -33,10 +33,9 @@ namespace
|
|||
markDirty( QSGNode::DirtyMaterial );
|
||||
}
|
||||
|
||||
if ( rect != m_rect || isPartially != m_isPartially )
|
||||
if ( rect != m_rect )
|
||||
{
|
||||
m_rect = rect;
|
||||
m_isPartially = isPartially;
|
||||
|
||||
const auto x = rect.x();
|
||||
const auto y = rect.y();
|
||||
|
@ -44,19 +43,9 @@ namespace
|
|||
const auto h = rect.height();
|
||||
|
||||
auto points = m_geometry.vertexDataAsPoint2D();
|
||||
|
||||
if ( isPartially )
|
||||
{
|
||||
points[0].set( x, y + h / 2 );
|
||||
points[1] = points[0];
|
||||
points[2].set( x + w, y + h / 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
points[0].set( x, y + h / 2 );
|
||||
points[1].set( x + w / 3, y + h );
|
||||
points[2].set( x + w, y );
|
||||
}
|
||||
|
||||
markDirty( QSGNode::DirtyGeometry );
|
||||
}
|
||||
|
@ -67,7 +56,6 @@ namespace
|
|||
QSGGeometry m_geometry;
|
||||
|
||||
QRectF m_rect;
|
||||
bool m_isPartially;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -112,8 +100,7 @@ QSGNode* QskCheckBoxSkinlet::updateIndicatorNode(
|
|||
{
|
||||
using Q = QskCheckBox;
|
||||
|
||||
const auto state = checkBox->checkState();
|
||||
if ( state == Qt::Unchecked )
|
||||
if ( checkBox->isChecked() == false )
|
||||
return nullptr;
|
||||
|
||||
const auto rect = checkBox->subControlRect( Q::Indicator );
|
||||
|
@ -121,7 +108,7 @@ QSGNode* QskCheckBoxSkinlet::updateIndicatorNode(
|
|||
return nullptr;
|
||||
|
||||
auto indicatorNode = QskSGNode::ensureNode< IndicatorNode >( node );
|
||||
indicatorNode->update( state != Qt::Checked, rect, checkBox->color( Q::Indicator ) );
|
||||
indicatorNode->update( rect, checkBox->color( Q::Indicator ) );
|
||||
|
||||
return indicatorNode;
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
CONFIG += qskexample
|
||||
CONFIG += console
|
||||
CONFIG += testcase
|
||||
|
||||
QT += testlib
|
||||
|
||||
HEADERS += \
|
||||
main.h
|
||||
|
||||
SOURCES += \
|
||||
main.cpp
|
|
@ -1,223 +0,0 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <QskCheckBox.h>
|
||||
|
||||
void CheckBoxTests::init()
|
||||
{
|
||||
root = new QskControl();
|
||||
}
|
||||
|
||||
void CheckBoxTests::cleanup()
|
||||
{
|
||||
delete root;
|
||||
}
|
||||
|
||||
void CheckBoxTests::checkbox()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
|
||||
QVERIFY( t->isCheckable() );
|
||||
}
|
||||
|
||||
void CheckBoxTests::click()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
|
||||
QVERIFY( t->isChecked() == false );
|
||||
t->click();
|
||||
QVERIFY( t->isChecked() );
|
||||
}
|
||||
|
||||
void CheckBoxTests::toggle()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
|
||||
QVERIFY( t->isChecked() == false );
|
||||
t->toggle();
|
||||
QVERIFY( t->isChecked() );
|
||||
|
||||
t->toggle();
|
||||
QVERIFY( t->isChecked() == false );
|
||||
}
|
||||
|
||||
void CheckBoxTests::tristate()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
|
||||
QVERIFY( t->isChecked() == false );
|
||||
QVERIFY( t->isTristate() == false );
|
||||
|
||||
t->setCheckState( Qt::CheckState::PartiallyChecked );
|
||||
|
||||
QVERIFY( t->isChecked() == true );
|
||||
QVERIFY( t->isTristate() == true );
|
||||
}
|
||||
|
||||
void CheckBoxTests::higherGroupUpdatesLower()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
auto t1 = new QskCheckBox( root );
|
||||
auto t2 = new QskCheckBox( root );
|
||||
auto t3 = new QskCheckBox( root );
|
||||
|
||||
t->addToGroup( t1 );
|
||||
t->addToGroup( t2 );
|
||||
t->addToGroup( t3 );
|
||||
|
||||
QVERIFY( t->isChecked() == false );
|
||||
QVERIFY( t1->isChecked() == false );
|
||||
QVERIFY( t2->isChecked() == false );
|
||||
QVERIFY( t3->isChecked() == false );
|
||||
|
||||
t->setChecked( true );
|
||||
QVERIFY( t->isChecked() );
|
||||
QVERIFY( t1->isChecked() );
|
||||
QVERIFY( t2->isChecked() );
|
||||
QVERIFY( t3->isChecked() );
|
||||
|
||||
t->setChecked( false );
|
||||
QVERIFY( t->isChecked() == false );
|
||||
QVERIFY( t1->isChecked() == false );
|
||||
QVERIFY( t2->isChecked() == false );
|
||||
QVERIFY( t3->isChecked() == false );
|
||||
|
||||
}
|
||||
|
||||
void CheckBoxTests::lowerGroupUpdatesHigher()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
|
||||
auto t1 = new QskCheckBox( root );
|
||||
auto t2 = new QskCheckBox( root );
|
||||
|
||||
t->addToGroup( t1 );
|
||||
t->addToGroup( t2 );
|
||||
|
||||
t1->setChecked( true );
|
||||
QVERIFY( t->isChecked() );
|
||||
QVERIFY( t->isTristate() );
|
||||
QVERIFY( t->checkState() == Qt::CheckState::PartiallyChecked );
|
||||
QVERIFY( t1->isChecked() == true );
|
||||
QVERIFY( t2->isChecked() == false );
|
||||
|
||||
|
||||
t2->setChecked( true );
|
||||
QVERIFY( t->isChecked() );
|
||||
QVERIFY( t->isTristate() );
|
||||
QVERIFY( t->checkState() == Qt::CheckState::Checked );
|
||||
QVERIFY( t1->isChecked() == true );
|
||||
QVERIFY( t2->isChecked() == true );
|
||||
|
||||
t1->setChecked( false );
|
||||
QVERIFY( t->isChecked() );
|
||||
QVERIFY( t->isTristate() );
|
||||
QVERIFY( t->checkState() == Qt::CheckState::PartiallyChecked );
|
||||
QVERIFY( t1->isChecked() == false );
|
||||
QVERIFY( t2->isChecked() == true );
|
||||
|
||||
t2->setChecked( false );
|
||||
QVERIFY( t->isChecked() == false );
|
||||
QVERIFY( t->isTristate() );
|
||||
QVERIFY( t->checkState() == Qt::CheckState::Unchecked );
|
||||
QVERIFY( t1->isChecked() == false );
|
||||
QVERIFY( t2->isChecked() == false );
|
||||
}
|
||||
|
||||
void CheckBoxTests::addToGroup()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
|
||||
auto t1 = new QskCheckBox( root );
|
||||
auto t2 = new QskCheckBox( root );
|
||||
|
||||
t->addToGroup( t1 );
|
||||
t->addToGroup( t2 );
|
||||
|
||||
t->setChecked( true );
|
||||
QVERIFY( t->isChecked() );
|
||||
QVERIFY( t1->isChecked() );
|
||||
QVERIFY( t2->isChecked() );
|
||||
|
||||
auto t3 = new QskCheckBox( root );
|
||||
t->addToGroup( t3 );
|
||||
|
||||
QVERIFY( t->checkState() == Qt::CheckState::PartiallyChecked );
|
||||
|
||||
t3->setChecked( true );
|
||||
QVERIFY( t->checkState() == Qt::CheckState::Checked );
|
||||
auto t4 = new QskCheckBox( root );
|
||||
t4->setChecked( true );
|
||||
t->addToGroup( t4 );
|
||||
QVERIFY( t->checkState() == Qt::CheckState::Checked );
|
||||
}
|
||||
|
||||
void CheckBoxTests::addPartlyToGroup() {
|
||||
auto t = new QskCheckBox( root );
|
||||
|
||||
auto t1 = new QskCheckBox( root );
|
||||
auto t1a = new QskCheckBox( root );
|
||||
auto t1b = new QskCheckBox( root );
|
||||
|
||||
t1->addToGroup( t1a );
|
||||
t1->addToGroup( t1b );
|
||||
|
||||
t1a->setChecked( true );
|
||||
|
||||
QVERIFY( t1->checkState() == Qt::CheckState::PartiallyChecked );
|
||||
t->addToGroup( t1 );
|
||||
QVERIFY( t1->checkState() == Qt::CheckState::PartiallyChecked );
|
||||
}
|
||||
|
||||
void CheckBoxTests::removeFromGroup()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
|
||||
auto t1 = new QskCheckBox( root );
|
||||
auto t2 = new QskCheckBox( root );
|
||||
|
||||
t->addToGroup( t1 );
|
||||
t->addToGroup( t2 );
|
||||
|
||||
t2->setChecked( true );
|
||||
QVERIFY( t->checkState() == Qt::CheckState::PartiallyChecked );
|
||||
|
||||
t->removeFromGroup( t2 );
|
||||
QVERIFY( t->isChecked() == false );
|
||||
}
|
||||
|
||||
void CheckBoxTests::groupMemberGetsDeleted()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
auto t1 = new QskCheckBox( root );
|
||||
auto t2 = new QskCheckBox( root );
|
||||
|
||||
t->addToGroup( t1 );
|
||||
t->addToGroup( t2 );
|
||||
|
||||
t2->setChecked( true );
|
||||
QVERIFY( t->checkState() == Qt::CheckState::PartiallyChecked );
|
||||
|
||||
delete t2;
|
||||
QVERIFY( t->isChecked() == false );
|
||||
}
|
||||
|
||||
void CheckBoxTests::addTwiceToSameGroup()
|
||||
{
|
||||
auto t = new QskCheckBox( root );
|
||||
|
||||
auto t1 = new QskCheckBox( root );
|
||||
auto t2 = new QskCheckBox( root );
|
||||
|
||||
t->addToGroup( t1 );
|
||||
t->addToGroup( t1 );
|
||||
t->removeFromGroup( t1 );
|
||||
|
||||
t->addToGroup( t2 );
|
||||
|
||||
t2->setChecked( true );
|
||||
|
||||
QVERIFY( t->checkState() == Qt::CheckState::Checked );
|
||||
}
|
||||
|
||||
#include "moc_main.cpp"
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <qobject.h>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class QskControl;
|
||||
class CheckBoxTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QskControl * root;
|
||||
private Q_SLOTS:
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
void checkbox();
|
||||
void click();
|
||||
void toggle();
|
||||
void tristate();
|
||||
void higherGroupUpdatesLower();
|
||||
void lowerGroupUpdatesHigher();
|
||||
void addToGroup();
|
||||
void addPartlyToGroup();
|
||||
void removeFromGroup();
|
||||
void groupMemberGetsDeleted();
|
||||
void addTwiceToSameGroup();
|
||||
};
|
||||
|
||||
QTEST_MAIN(CheckBoxTests)
|
||||
|
|
@ -1,5 +1,2 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += \
|
||||
checkboxes
|
||||
|
||||
|
|
Loading…
Reference in New Issue