Starting with a simpler version of QskCheckBox ( no tristate ), but with

having an optional text.
This commit is contained in:
Uwe Rathmann 2022-07-01 11:10:59 +02:00
parent e67bc4a5ed
commit cda5a8b45c
13 changed files with 197 additions and 476 deletions

View File

@ -86,15 +86,14 @@ namespace
CheckButtonBox( QQuickItem* parent = nullptr ) CheckButtonBox( QQuickItem* parent = nullptr )
: QskLinearBox( Qt::Horizontal, parent ) : QskLinearBox( Qt::Horizontal, parent )
{ {
setSpacing( 20 ); setSpacing( 40 );
setExtraSpacingAt( Qt::LeftEdge | Qt::RightEdge | Qt::BottomEdge ); setExtraSpacingAt( Qt::LeftEdge | Qt::RightEdge | Qt::BottomEdge );
for ( auto state : { Qt::Unchecked, Qt::PartiallyChecked, Qt::Checked } ) auto button1 = new QskCheckBox( "Options 1", this );
{ button1->setChecked( true );
auto button = new QskCheckBox( this );
button->setTristate( true ); auto button2 = new QskCheckBox( "Options 2", this );
button->setCheckState( state ); button2->setLayoutMirroring( true );
}
} }
}; };
} }

View File

@ -7,7 +7,6 @@ SUBDIRS = \
qmlexport \ qmlexport \
tools \ tools \
support \ support \
tests \
examples \ examples \
playground playground

View File

@ -201,20 +201,27 @@ void Editor::setupCheckBox()
using A = QskAspect; using A = QskAspect;
using Q = QskCheckBox; using Q = QskCheckBox;
setSpacing( Q::Panel, 5 );
const qreal size = qskDpiScaled( 18 ); const qreal size = qskDpiScaled( 18 );
setStrutSize( Q::Panel, size, size ); setStrutSize( Q::Box, size, size );
setPadding( Q::Panel, 3 ); setPadding( Q::Box, 3 );
setBoxShape( Q::Panel, 2 ); setBoxShape( Q::Box, 2 );
setGradient( Q::Panel, m_pal.baseColor); setGradient( Q::Box, m_pal.baseColor);
setGradient( Q::Panel | Q::Checked, m_pal.accentColor ); setGradient( Q::Box | Q::Checked, m_pal.accentColor );
setGradient( Q::Panel | Q::Checked | Q::Disabled, QskRgb::Grey ); setGradient( Q::Box | Q::Disabled, QskRgb::Grey );
setColor( Q::Indicator, m_pal.contrastColor ); setColor( Q::Indicator, m_pal.contrastColor );
setAnimation( Q::Panel | A::Color, qskDuration ); setColor( Q::Text, m_pal.textColor );
setColor( Q::Text | Q::Disabled, qskShadedColor( m_pal.textColor, 0.6 ) );
setFontRole( Q::Text, ButtonFontRole );
setAnimation( Q::Box | A::Color, qskDuration );
setAnimation( Q::Text | A::Color, qskDuration );
} }
void Editor::setupBox() void Editor::setupBox()

View File

@ -305,19 +305,28 @@ void Editor::setupCheckBox()
const qreal size = qskDpiScaled( 26 ); const qreal size = qskDpiScaled( 26 );
setStrutSize( Q::Panel, size, size ); setSpacing( Q::Panel, qskDpiScaled( 5 ) );
setPadding( Q::Panel, qskDpiScaled( 5 ) ); setStrutSize( Q::Box, size, size );
setBoxShape( Q::Panel, qskDpiScaled( 3 ) );
setBoxBorderMetrics( Q::Panel, qskDpiScaled( 1 ) );
setBoxBorderColors( Q::Panel, m_pal.darker125 ); setPadding( Q::Box, qskDpiScaled( 5 ) );
setGradient( Q::Panel, m_pal.lighter135 ); setBoxShape( Q::Box, qskDpiScaled( 3 ) );
setGradient( Q::Panel | Q::Checked, m_pal.highlighted ); setBoxBorderMetrics( Q::Box, qskDpiScaled( 1 ) );
setBoxBorderColors( Q::Box, m_pal.darker125 );
setGradient( Q::Box, m_pal.lighter135 );
setGradient( Q::Box | Q::Checked, m_pal.highlighted );
setGradient( Q::Box | Q::Disabled, m_pal.lighter110 );
setBoxBorderColors( Q::Box, m_pal.theme );
setColor( Q::Indicator, m_pal.lighter135 ); setColor( Q::Indicator, m_pal.lighter135 );
setAnimation( Q::Panel | A::Color, qskDuration ); setFlagHint( Q::Text | Q::Disabled | A::Style, Qsk::Sunken );
setColor( Q::Text, m_pal.themeForeground );
setColor( Q::Text | Q::Disabled, m_pal.darker200 );
setAnimation( Q::Box | A::Color, qskDuration );
} }
void Editor::setupPopup() void Editor::setupPopup()

View File

@ -4,50 +4,37 @@
*****************************************************************************/ *****************************************************************************/
#include "QskCheckBox.h" #include "QskCheckBox.h"
#include "QskAspect.h"
#include <qset.h>
QSK_SUBCONTROL( QskCheckBox, Panel ) QSK_SUBCONTROL( QskCheckBox, Panel )
QSK_SUBCONTROL( QskCheckBox, Box )
QSK_SUBCONTROL( QskCheckBox, Indicator ) QSK_SUBCONTROL( QskCheckBox, Indicator )
QSK_SUBCONTROL( QskCheckBox, Text )
QSK_SYSTEM_STATE( QskCheckBox, PartiallyChecked, QskAspect::LastUserState << 2 )
class QskCheckBox::PrivateData class QskCheckBox::PrivateData
{ {
public: public:
PrivateData() PrivateData( const QString& text )
: checkState( Qt::Unchecked ) : text( text )
, checkStateChanging( false )
, toggleChanging( false )
, tristate( false )
{ {
} }
QSet< QskAbstractButton* > group; QString text;
int groupItemsChecked = 0;
Qt::CheckState checkState : 2;
bool checkStateChanging : 1;
bool toggleChanging : 1;
bool tristate : 1;
}; };
QskCheckBox::QskCheckBox( QQuickItem* parent ) QskCheckBox::QskCheckBox( QQuickItem* parent )
: Inherited( parent ) : QskCheckBox( QString(), parent )
, m_data( new PrivateData() )
{ {
setAcceptHoverEvents( true ); }
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
connect( this, &QskCheckBox::checkedChanged, this, QskCheckBox::QskCheckBox( const QString& text, QQuickItem* parent )
[ this ]( bool on ) { setCheckStateInternal( on ? Qt::Checked : Qt::Unchecked ); } ); : Inherited( parent )
, m_data( new PrivateData( text ) )
{
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
} }
QskCheckBox::~QskCheckBox() QskCheckBox::~QskCheckBox()
{ {
Q_EMIT removeFromAllGroupsRequested();
} }
bool QskCheckBox::isCheckable() const bool QskCheckBox::isCheckable() const
@ -55,130 +42,33 @@ bool QskCheckBox::isCheckable() const
return true; return true;
} }
Qt::CheckState QskCheckBox::checkState() const void QskCheckBox::setText( const QString& text )
{ {
return m_data->checkState; if ( text != m_data->text )
}
void QskCheckBox::setCheckStateInternal( Qt::CheckState checkState )
{ {
if( m_data->checkStateChanging ) m_data->text = text;
return;
setSkinStateFlag( PartiallyChecked, checkState == Qt::PartiallyChecked ); resetImplicitSize();
update();
m_data->checkState = checkState; Q_EMIT textChanged();
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() QString QskCheckBox::text() const
{ {
if( m_data->toggleChanging ) return m_data->text;
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 ) void QskCheckBox::changeEvent( QEvent* event )
{ {
if( m_data->group.contains( groupItem ) ) if ( event->type() == QEvent::LayoutDirectionChange )
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 ) if ( !m_data->text.isEmpty() )
{ update();
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 ) Inherited::changeEvent( event );
{
if( !m_data->group.remove( groupItem ) )
return;
if( groupItem->checkState() == Qt::Checked )
m_data->groupItemsChecked--;
updated();
} }
#include "moc_QskCheckBox.cpp" #include "moc_QskCheckBox.cpp"

View File

@ -12,41 +12,32 @@ class QSK_EXPORT QskCheckBox : public QskAbstractButton
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY( Qt::CheckState checkState READ checkState Q_PROPERTY( QString text READ text WRITE setText NOTIFY textChanged FINAL )
WRITE setCheckState NOTIFY checkStateChanged FINAL )
Q_PROPERTY( bool tristate READ isTristate
WRITE setTristate NOTIFY tristateChanged FINAL )
using Inherited = QskAbstractButton; using Inherited = QskAbstractButton;
public: public:
QSK_SUBCONTROLS( Panel, Indicator ) QSK_SUBCONTROLS( Panel, Box, Indicator, Text )
QSK_STATES( PartiallyChecked )
QskCheckBox( QQuickItem* parent = nullptr ); QskCheckBox( QQuickItem* parent = nullptr );
QskCheckBox( const QString&, QQuickItem* parent = nullptr );
~QskCheckBox() override; ~QskCheckBox() override;
Qt::CheckState checkState() const; QString text() const;
bool isTristate() const;
bool isCheckable() const override final; bool isCheckable() const override final;
void addToGroup( QskCheckBox* );
void removeFromGroup( QskCheckBox* );
public Q_SLOTS: public Q_SLOTS:
void setCheckState( Qt::CheckState ); void setText( const QString& );
void setTristate( bool triState = true );
Q_SIGNALS: Q_SIGNALS:
void checkStateChanged( Qt::CheckState ); void textChanged();
void tristateChanged( bool );
void removeFromAllGroupsRequested(); protected:
void changeEvent( QEvent* ) override;
private: private:
void setCheckStateInternal( Qt::CheckState );
void updated();
class PrivateData; class PrivateData;
std::unique_ptr< PrivateData > m_data; std::unique_ptr< PrivateData > m_data;
}; };

View File

@ -6,6 +6,8 @@
#include "QskCheckBoxSkinlet.h" #include "QskCheckBoxSkinlet.h"
#include "QskCheckBox.h" #include "QskCheckBox.h"
#include "QskSGNode.h" #include "QskSGNode.h"
#include "QskTextOptions.h"
#include "QskFunctions.h"
#include <QSGFlatColorMaterial> #include <QSGFlatColorMaterial>
#include <qsgnode.h> #include <qsgnode.h>
@ -25,7 +27,7 @@ namespace
setMaterial( &m_material ); 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() ) if ( color != m_material.color() )
{ {
@ -33,10 +35,9 @@ namespace
markDirty( QSGNode::DirtyMaterial ); markDirty( QSGNode::DirtyMaterial );
} }
if ( rect != m_rect || isPartially != m_isPartially ) if ( rect != m_rect )
{ {
m_rect = rect; m_rect = rect;
m_isPartially = isPartially;
const auto x = rect.x(); const auto x = rect.x();
const auto y = rect.y(); const auto y = rect.y();
@ -45,18 +46,9 @@ namespace
auto points = m_geometry.vertexDataAsPoint2D(); 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[0].set( x, y + h / 2 );
points[1].set( x + w / 3, y + h ); points[1].set( x + w / 3, y + h );
points[2].set( x + w, y ); points[2].set( x + w, y );
}
markDirty( QSGNode::DirtyGeometry ); markDirty( QSGNode::DirtyGeometry );
} }
@ -67,14 +59,13 @@ namespace
QSGGeometry m_geometry; QSGGeometry m_geometry;
QRectF m_rect; QRectF m_rect;
bool m_isPartially;
}; };
} }
QskCheckBoxSkinlet::QskCheckBoxSkinlet( QskSkin* skin ) QskCheckBoxSkinlet::QskCheckBoxSkinlet( QskSkin* skin )
: QskSkinlet( skin ) : QskSkinlet( skin )
{ {
setNodeRoles( { PanelRole, IndicatorRole } ); setNodeRoles( { BoxRole, IndicatorRole, TextRole } );
} }
QskCheckBoxSkinlet::~QskCheckBoxSkinlet() QskCheckBoxSkinlet::~QskCheckBoxSkinlet()
@ -84,12 +75,66 @@ QskCheckBoxSkinlet::~QskCheckBoxSkinlet()
QRectF QskCheckBoxSkinlet::subControlRect( const QskSkinnable* skinnable, QRectF QskCheckBoxSkinlet::subControlRect( const QskSkinnable* skinnable,
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
{ {
if ( subControl == QskCheckBox::Indicator ) const auto checkBox = static_cast< const QskCheckBox* >( skinnable );
return skinnable->innerBox( QskCheckBox::Panel, contentsRect );
if ( subControl == QskCheckBox::Panel )
{
return contentsRect;
}
else if ( subControl == QskCheckBox::Box )
{
return boxRect( checkBox, contentsRect );
}
else if ( subControl == QskCheckBox::Indicator )
{
const auto boxRect = subControlRect( skinnable, contentsRect, QskCheckBox::Box );
return skinnable->innerBox( QskCheckBox::Box, boxRect );
return skinnable->innerBox( QskCheckBox::Box, contentsRect );
}
else if ( subControl == QskCheckBox::Text )
{
return textRect( checkBox, contentsRect );
}
return contentsRect; return contentsRect;
} }
QRectF QskCheckBoxSkinlet::textRect(
const QskCheckBox* checkBox, const QRectF& contentsRect ) const
{
const auto boxRect = subControlRect( checkBox, contentsRect, QskCheckBox::Box );
const qreal spacing = checkBox->spacingHint( QskCheckBox::Panel );
auto r = subControlRect( checkBox, contentsRect, QskCheckBox::Panel );
r = checkBox->innerBox( QskCheckBox::Panel, r );
if ( checkBox->layoutMirroring() )
r.setRight( boxRect.left() - spacing );
else
r.setLeft( boxRect.right() + spacing );
return r;
}
QRectF QskCheckBoxSkinlet::boxRect(
const QskCheckBox* checkBox, const QRectF& contentsRect ) const
{
const auto size = checkBox->strutSizeHint( QskCheckBox::Box );
auto r = checkBox->innerBox( QskCheckBox::Panel, contentsRect );
if ( checkBox->layoutMirroring() )
r.setLeft( r.right() - size.width() );
else
r.setWidth( size.width() );
r.setTop( r.top() + 0.5 * ( r.height() - size.height() ) );
r.setHeight( size.height() );
return r;
}
QSGNode* QskCheckBoxSkinlet::updateSubNode( QSGNode* QskCheckBoxSkinlet::updateSubNode(
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
{ {
@ -100,8 +145,14 @@ QSGNode* QskCheckBoxSkinlet::updateSubNode(
case PanelRole: case PanelRole:
return updateBoxNode( skinnable, node, QskCheckBox::Panel ); return updateBoxNode( skinnable, node, QskCheckBox::Panel );
case BoxRole:
return updateBoxNode( skinnable, node, QskCheckBox::Box );
case IndicatorRole: case IndicatorRole:
return updateIndicatorNode( checkBox, node ); return updateIndicatorNode( checkBox, node );
case TextRole:
return updateTextNode( checkBox, node );
} }
return Inherited::updateSubNode( skinnable, nodeRole, node ); return Inherited::updateSubNode( skinnable, nodeRole, node );
@ -112,8 +163,7 @@ QSGNode* QskCheckBoxSkinlet::updateIndicatorNode(
{ {
using Q = QskCheckBox; using Q = QskCheckBox;
const auto state = checkBox->checkState(); if ( !checkBox->isChecked() )
if ( state == Qt::Unchecked )
return nullptr; return nullptr;
const auto rect = checkBox->subControlRect( Q::Indicator ); const auto rect = checkBox->subControlRect( Q::Indicator );
@ -121,15 +171,54 @@ QSGNode* QskCheckBoxSkinlet::updateIndicatorNode(
return nullptr; return nullptr;
auto indicatorNode = QskSGNode::ensureNode< IndicatorNode >( node ); 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; return indicatorNode;
} }
QSizeF QskCheckBoxSkinlet::sizeHint( const QskSkinnable* skinnable, QSGNode* QskCheckBoxSkinlet::updateTextNode(
Qt::SizeHint, const QSizeF& ) const const QskCheckBox* checkBox, QSGNode* node ) const
{ {
return skinnable->strutSizeHint( QskCheckBox::Panel ); using Q = QskCheckBox;
const auto rect = checkBox->subControlRect( Q::Text );
const auto alignH = checkBox->layoutMirroring() ? Qt::AlignRight : Qt::AlignLeft;
QskTextOptions textOptions;
textOptions.setElideMode( Qt::ElideMiddle );
return QskSkinlet::updateTextNode( checkBox, node, rect, alignH | Qt::AlignVCenter,
checkBox->text(), textOptions, QskCheckBox::Text );
}
QSizeF QskCheckBoxSkinlet::sizeHint( const QskSkinnable* skinnable,
Qt::SizeHint which, const QSizeF& ) const
{
using Q = QskCheckBox;
if ( which == Qt::MaximumSize )
return QSizeF();
auto checkBox = static_cast< const QskCheckBox* >( skinnable );
auto size = skinnable->strutSizeHint( QskCheckBox::Box );
size = skinnable->outerBoxSize( Q::Panel, size );
auto text = checkBox->text();
if ( !text.isEmpty() )
{
qreal extra = skinnable->spacingHint( Q::Panel );
if ( which == Qt::MinimumSize )
text = 'W';
const auto font = skinnable->effectiveFont( Q::Text );
extra += qskHorizontalAdvance( font, text );
size.setWidth( size.width() + extra );
}
return size.expandedTo( skinnable->strutSizeHint( Q::Panel ) );
} }
#include "moc_QskCheckBoxSkinlet.cpp" #include "moc_QskCheckBoxSkinlet.cpp"

View File

@ -20,7 +20,9 @@ class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet
enum NodeRole enum NodeRole
{ {
PanelRole, PanelRole,
BoxRole,
IndicatorRole, IndicatorRole,
TextRole,
RoleCount RoleCount
}; };
@ -38,8 +40,12 @@ class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet
QSGNode* updateSubNode( const QskSkinnable*, QSGNode* updateSubNode( const QskSkinnable*,
quint8 nodeRole, QSGNode* ) const override; quint8 nodeRole, QSGNode* ) const override;
protected: private:
virtual QSGNode* updateIndicatorNode( const QskCheckBox*, QSGNode* ) const; QRectF textRect( const QskCheckBox*, const QRectF& ) const;
QRectF boxRect( const QskCheckBox*, const QRectF& ) const;
QSGNode* updateIndicatorNode( const QskCheckBox*, QSGNode* ) const;
QSGNode* updateTextNode( const QskCheckBox*, QSGNode* ) const;
}; };
#endif #endif

View File

@ -203,7 +203,7 @@ QSizeF QskPushButtonSkinlet::sizeHint( const QskSkinnable* skinnable,
QSizeF size( 0, 0 ); QSizeF size( 0, 0 );
const QFontMetricsF fm( button->font() ); const QFontMetricsF fm( button->effectiveFont( QskPushButton::Text ) );
if ( !button->text().isEmpty() ) if ( !button->text().isEmpty() )
{ {

View File

@ -1,11 +0,0 @@
CONFIG += qskexample
CONFIG += console
CONFIG += testcase
QT += testlib
HEADERS += \
main.h
SOURCES += \
main.cpp

View File

@ -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"

View File

@ -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)

View File

@ -1,5 +0,0 @@
TEMPLATE = subdirs
SUBDIRS += \
checkboxes