Add text label to QskCheckBox
This commit is contained in:
parent
045798d084
commit
e70851dbc8
|
@ -191,20 +191,24 @@ void Editor::setupCheckBox()
|
|||
using A = QskAspect;
|
||||
using Q = QskCheckBox;
|
||||
|
||||
const qreal size = qskDpiScaled( 18 );
|
||||
const qreal sizeTic = qskDpiScaled( 16 ); // - Border;
|
||||
const qreal sizeBox = qskDpiScaled( 26 );
|
||||
|
||||
setStrutSize( Q::Panel, size, size );
|
||||
setPadding( Q::Panel, 3 );
|
||||
setStrutSize( Q::IndicatorTic, sizeTic, sizeTic );
|
||||
setStrutSize( Q::IndicatorBox, sizeBox, sizeBox);
|
||||
|
||||
setBoxShape( Q::Panel, 2 );
|
||||
setMargin( Q::Text, QskMargins( qskDpiScaled( 5 ), 0,qskDpiScaled( 5 ), 0 ) );
|
||||
setMargin( Q::IndicatorTic, QskMargins( qskDpiScaled( 5 ) ) );
|
||||
|
||||
setGradient( Q::Panel, m_pal.baseColor);
|
||||
setGradient( Q::Panel | Q::Checked, m_pal.accentColor );
|
||||
setGradient( Q::Panel | Q::Checked | Q::Disabled, QskRgb::Grey );
|
||||
setBoxShape( Q::IndicatorBox, qskDpiScaled( 3 ) );
|
||||
setBoxBorderMetrics( Q::IndicatorBox, qskDpiScaled( 1 ) );
|
||||
setBoxBorderColors( Q::IndicatorBox, m_pal.darker125 );
|
||||
|
||||
setColor( Q::Indicator, m_pal.contrastColor );
|
||||
setGradient( Q::IndicatorBox | Q::Checked, m_pal.accentColor);
|
||||
setColor( Q::IndicatorTic, m_pal.lighter200 );
|
||||
setGradient( Q::Panel, m_pal.baseColor );
|
||||
|
||||
setAnimation( Q::Panel | A::Color, qskDuration );
|
||||
setAnimation( Q::IndicatorBox | A::Color, qskDuration );
|
||||
}
|
||||
|
||||
void Editor::setupBox()
|
||||
|
|
|
@ -303,21 +303,27 @@ void Editor::setupCheckBox()
|
|||
using A = QskAspect;
|
||||
using Q = QskCheckBox;
|
||||
|
||||
const qreal size = qskDpiScaled( 26 );
|
||||
const qreal sizeTic = qskDpiScaled( 24 ); // - Border;
|
||||
const qreal sizeBox = qskDpiScaled( 26 );
|
||||
|
||||
setStrutSize( Q::Panel, size, size );
|
||||
setStrutSize( Q::IndicatorTic, sizeTic, sizeTic );
|
||||
setStrutSize( Q::IndicatorBox, sizeBox, sizeBox);
|
||||
|
||||
setPadding( Q::Panel, qskDpiScaled( 5 ) );
|
||||
setBoxShape( Q::Panel, qskDpiScaled( 3 ) );
|
||||
setBoxBorderMetrics( Q::Panel, qskDpiScaled( 1 ) );
|
||||
setMargin( Q::Text, QskMargins(qskDpiScaled(5),0,qskDpiScaled(5),0) );
|
||||
setMargin( Q::IndicatorTic, QskMargins( qskDpiScaled( 1 ) ) );
|
||||
|
||||
setBoxBorderColors( Q::Panel, m_pal.darker125 );
|
||||
setGradient( Q::Panel, m_pal.lighter135 );
|
||||
setGradient( Q::Panel | Q::Checked, m_pal.highlighted );
|
||||
setBoxShape( Q::IndicatorBox, qskDpiScaled( 3 ) );
|
||||
setBoxBorderMetrics( Q::IndicatorBox, qskDpiScaled( 1 ) );
|
||||
setBoxBorderColors( Q::IndicatorBox, m_pal.darker125 );
|
||||
|
||||
setColor( Q::Indicator, m_pal.lighter135 );
|
||||
setGradient( Q::IndicatorBox, m_pal.lighter135 );
|
||||
setGradient( Q::IndicatorBox | Q::Checked, m_pal.highlighted );
|
||||
|
||||
setAnimation( Q::Panel | A::Color, qskDuration );
|
||||
setGradient( Q::IndicatorTic, m_pal.lighter135 );
|
||||
|
||||
setGradient( Q::Panel, m_pal.base );
|
||||
|
||||
setAnimation( Q::IndicatorBox | A::Color, qskDuration );
|
||||
}
|
||||
|
||||
void Editor::setupPopup()
|
||||
|
|
|
@ -6,11 +6,21 @@
|
|||
#include "QskCheckBox.h"
|
||||
#include "QskAspect.h"
|
||||
|
||||
#include "QskTextOptions.h"
|
||||
|
||||
QSK_SUBCONTROL( QskCheckBox, Panel )
|
||||
QSK_SUBCONTROL( QskCheckBox, Indicator )
|
||||
QSK_SUBCONTROL( QskCheckBox, IndicatorBox )
|
||||
QSK_SUBCONTROL( QskCheckBox, IndicatorTic )
|
||||
QSK_SUBCONTROL( QskCheckBox, Text )
|
||||
|
||||
class QskCheckBox::PrivateData {
|
||||
public:
|
||||
QString text;
|
||||
QskTextOptions textOptions;
|
||||
};
|
||||
|
||||
QskCheckBox::QskCheckBox( QQuickItem* parent )
|
||||
: Inherited( parent )
|
||||
: Inherited( parent ), m_data( new PrivateData )
|
||||
{
|
||||
setAcceptHoverEvents( true );
|
||||
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||
|
@ -25,4 +35,34 @@ bool QskCheckBox::isCheckable() const
|
|||
return true;
|
||||
}
|
||||
|
||||
QString QskCheckBox::text() const {
|
||||
return m_data->text;
|
||||
}
|
||||
|
||||
QskTextOptions QskCheckBox::textOptions() const {
|
||||
return m_data->textOptions;
|
||||
}
|
||||
|
||||
void QskCheckBox::setText( const QString& text ) {
|
||||
if( m_data->text == text )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_data->text = text;
|
||||
|
||||
Q_EMIT textChanged( text );
|
||||
}
|
||||
|
||||
void QskCheckBox::setTextOptions( const QskTextOptions& textOptions) {
|
||||
if( m_data->textOptions == textOptions )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_data->textOptions = textOptions;
|
||||
|
||||
Q_EMIT textOptionsChanged( textOptions );
|
||||
}
|
||||
|
||||
#include "moc_QskCheckBox.cpp"
|
||||
|
|
|
@ -8,19 +8,42 @@
|
|||
|
||||
#include "QskAbstractButton.h"
|
||||
|
||||
class QskTextOptions;
|
||||
|
||||
class QSK_EXPORT QskCheckBox : public QskAbstractButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( QString text READ text WRITE setText NOTIFY textChanged )
|
||||
Q_PROPERTY( QskTextOptions textOptions READ textOptions
|
||||
WRITE setTextOptions NOTIFY textOptionsChanged )
|
||||
|
||||
|
||||
using Inherited = QskAbstractButton;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Panel, Indicator )
|
||||
QSK_SUBCONTROLS( Panel, IndicatorBox, IndicatorTic, Text)
|
||||
|
||||
QskCheckBox( QQuickItem* parent = nullptr );
|
||||
~QskCheckBox() override;
|
||||
|
||||
bool isCheckable() const override final;
|
||||
|
||||
QString text() const;
|
||||
QskTextOptions textOptions() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void textChanged( const QString& );
|
||||
void textOptionsChanged( const QskTextOptions& );
|
||||
|
||||
public Q_SLOTS:
|
||||
void setText( const QString& );
|
||||
void setTextOptions( const QskTextOptions& );
|
||||
|
||||
|
||||
private:
|
||||
class PrivateData;
|
||||
std::unique_ptr< PrivateData > m_data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,10 +6,14 @@
|
|||
#include "QskCheckBoxSkinlet.h"
|
||||
#include "QskCheckBox.h"
|
||||
#include "QskSGNode.h"
|
||||
#include "QskTextOptions.h"
|
||||
|
||||
#include <qfontmetrics.h>
|
||||
#include <QSGFlatColorMaterial>
|
||||
#include <qsgnode.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
{
|
||||
class IndicatorNode : public QSGGeometryNode
|
||||
|
@ -62,7 +66,7 @@ namespace
|
|||
QskCheckBoxSkinlet::QskCheckBoxSkinlet( QskSkin* skin )
|
||||
: QskSkinlet( skin )
|
||||
{
|
||||
setNodeRoles( { PanelRole, IndicatorRole } );
|
||||
setNodeRoles( { PanelRole, TextRole, IndicatorBoxRole, IndicatorRole } );
|
||||
}
|
||||
|
||||
QskCheckBoxSkinlet::~QskCheckBoxSkinlet()
|
||||
|
@ -72,10 +76,26 @@ QskCheckBoxSkinlet::~QskCheckBoxSkinlet()
|
|||
QRectF QskCheckBoxSkinlet::subControlRect( const QskSkinnable* skinnable,
|
||||
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
|
||||
{
|
||||
if ( subControl == QskCheckBox::Indicator )
|
||||
return skinnable->innerBox( QskCheckBox::Panel, contentsRect );
|
||||
const auto checkBox = static_cast< const QskCheckBox* >( skinnable );
|
||||
|
||||
if ( subControl == QskCheckBox::Panel)
|
||||
{
|
||||
return contentsRect;
|
||||
}
|
||||
else if ( subControl == QskCheckBox::Text)
|
||||
{
|
||||
return textRect(checkBox, contentsRect );
|
||||
}
|
||||
else if ( subControl == QskCheckBox::IndicatorTic )
|
||||
{
|
||||
return indicatorRect(checkBox, contentsRect );
|
||||
}
|
||||
else if ( subControl == QskCheckBox::IndicatorBox )
|
||||
{
|
||||
return indicatorBoxRect(checkBox, contentsRect );
|
||||
}
|
||||
|
||||
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||
}
|
||||
|
||||
QSGNode* QskCheckBoxSkinlet::updateSubNode(
|
||||
|
@ -88,6 +108,12 @@ QSGNode* QskCheckBoxSkinlet::updateSubNode(
|
|||
case PanelRole:
|
||||
return updateBoxNode( skinnable, node, QskCheckBox::Panel );
|
||||
|
||||
case TextRole:
|
||||
return updateTextNode( checkBox, node );
|
||||
|
||||
case IndicatorBoxRole:
|
||||
return updateBoxNode( skinnable, node, QskCheckBox::IndicatorBox );
|
||||
|
||||
case IndicatorRole:
|
||||
return updateIndicatorNode( checkBox, node );
|
||||
}
|
||||
|
@ -95,6 +121,64 @@ QSGNode* QskCheckBoxSkinlet::updateSubNode(
|
|||
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||
}
|
||||
|
||||
QRectF QskCheckBoxSkinlet::textRect( const QskCheckBox* checkBox,
|
||||
const QRectF& contentsRect ) const {
|
||||
using Q = QskCheckBox;
|
||||
|
||||
QSizeF size;
|
||||
const QFontMetricsF fm( checkBox->effectiveFont(Q::Text) );
|
||||
if ( !checkBox->text().isEmpty() )
|
||||
{
|
||||
size += fm.size( Qt::TextShowMnemonic, checkBox->text() );
|
||||
}
|
||||
|
||||
auto result = contentsRect;
|
||||
|
||||
result.setTopLeft( QPointF(result.right() - size.width() -
|
||||
checkBox->marginHint( Q::Text ).right(),
|
||||
result.y() + ( result.height() - size.height() ) / 2) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QRectF QskCheckBoxSkinlet::indicatorRect( const QskCheckBox* checkBox,
|
||||
const QRectF& contentsRect) const {
|
||||
using Q = QskCheckBox;
|
||||
|
||||
auto rect = contentsRect;
|
||||
auto size =
|
||||
checkBox->strutSizeHint( Q::IndicatorTic ).grownBy(checkBox->marginHint( Q::IndicatorTic ) );
|
||||
rect.setSize(size);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
QRectF QskCheckBoxSkinlet::indicatorBoxRect( const QskCheckBox* checkBox,
|
||||
const QRectF& contentsRect ) const {
|
||||
using Q = QskCheckBox;
|
||||
|
||||
auto rect = contentsRect;
|
||||
auto size =
|
||||
checkBox->strutSizeHint( Q::IndicatorBox ).grownBy(checkBox->marginHint(Q::IndicatorBox) );
|
||||
rect.setSize(size);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
QSGNode* QskCheckBoxSkinlet::updateTextNode(
|
||||
const QskCheckBox* checkBox, QSGNode* node ) const
|
||||
{
|
||||
using Q = QskCheckBox;
|
||||
const auto rect = checkBox->subControlRect( Q::Text );
|
||||
|
||||
const auto textHeight = checkBox->effectiveFontHeight( Q::Text );
|
||||
if ( !checkBox->clip() && ( rect.height() < textHeight ) )
|
||||
return nullptr;
|
||||
|
||||
return QskSkinlet::updateTextNode( checkBox, node,
|
||||
checkBox->text(), checkBox->textOptions(), Q::Text );
|
||||
}
|
||||
|
||||
QSGNode* QskCheckBoxSkinlet::updateIndicatorNode(
|
||||
const QskCheckBox* checkBox, QSGNode* node ) const
|
||||
{
|
||||
|
@ -103,12 +187,14 @@ QSGNode* QskCheckBoxSkinlet::updateIndicatorNode(
|
|||
if ( checkBox->isChecked() == false )
|
||||
return nullptr;
|
||||
|
||||
const auto rect = checkBox->subControlRect( Q::Indicator );
|
||||
auto rect = checkBox->subControlRect(Q::IndicatorTic)
|
||||
.marginsRemoved(checkBox->marginHint(Q::IndicatorTic) );
|
||||
|
||||
if ( rect.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
auto indicatorNode = QskSGNode::ensureNode< IndicatorNode >( node );
|
||||
indicatorNode->update( rect, checkBox->color( Q::Indicator ) );
|
||||
indicatorNode->update( rect, checkBox->color( Q::IndicatorTic ) );
|
||||
|
||||
return indicatorNode;
|
||||
}
|
||||
|
@ -116,7 +202,31 @@ QSGNode* QskCheckBoxSkinlet::updateIndicatorNode(
|
|||
QSizeF QskCheckBoxSkinlet::sizeHint( const QskSkinnable* skinnable,
|
||||
Qt::SizeHint, const QSizeF& ) const
|
||||
{
|
||||
return skinnable->strutSizeHint( QskCheckBox::Panel );
|
||||
using Q = QskCheckBox;
|
||||
const auto checkBox = static_cast< const QskCheckBox* >( skinnable );
|
||||
|
||||
|
||||
const QFontMetricsF fm( checkBox->effectiveFont(Q::Text) );
|
||||
QSizeF sizeText;
|
||||
if ( !checkBox->text().isEmpty() )
|
||||
{
|
||||
sizeText += fm.size( Qt::TextShowMnemonic, checkBox->text() )
|
||||
.grownBy(checkBox->marginHint(Q::Text) );
|
||||
}
|
||||
|
||||
auto sizeIndicator =
|
||||
checkBox->strutSizeHint(Q::IndicatorTic).grownBy(checkBox->marginHint(Q::IndicatorTic) );
|
||||
auto sizeIndicatorBox =
|
||||
checkBox->strutSizeHint(Q::IndicatorBox).grownBy(checkBox->marginHint(Q::IndicatorBox) );
|
||||
|
||||
QSizeF size;
|
||||
size.setWidth( sizeText.width() +
|
||||
qMax( sizeIndicator.width(), sizeIndicatorBox.width() ) );
|
||||
|
||||
size.setHeight(std::max({ sizeIndicator.height(),
|
||||
sizeIndicatorBox.height(),
|
||||
sizeText.height() }) );
|
||||
return size;
|
||||
}
|
||||
|
||||
#include "moc_QskCheckBoxSkinlet.cpp"
|
||||
|
|
|
@ -20,6 +20,8 @@ class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet
|
|||
enum NodeRole
|
||||
{
|
||||
PanelRole,
|
||||
TextRole,
|
||||
IndicatorBoxRole,
|
||||
IndicatorRole,
|
||||
|
||||
RoleCount
|
||||
|
@ -38,8 +40,14 @@ class QSK_EXPORT QskCheckBoxSkinlet : public QskSkinlet
|
|||
QSGNode* updateSubNode( const QskSkinnable*,
|
||||
quint8 nodeRole, QSGNode* ) const override;
|
||||
|
||||
protected:
|
||||
virtual QSGNode* updateTextNode( const QskCheckBox*, QSGNode* ) const;
|
||||
virtual QSGNode* updateIndicatorNode( const QskCheckBox*, QSGNode* ) const;
|
||||
|
||||
private:
|
||||
QRectF textRect( const QskCheckBox*, const QRectF& ) const;
|
||||
QRectF indicatorRect( const QskCheckBox*, const QRectF& ) const;
|
||||
QRectF indicatorBoxRect( const QskCheckBox*, const QRectF& ) const;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue