diff --git a/src/controls/QskBox.cpp b/src/controls/QskBox.cpp index 8aa93605..bda4bdc0 100644 --- a/src/controls/QskBox.cpp +++ b/src/controls/QskBox.cpp @@ -49,29 +49,14 @@ void QskBox::setPadding( const QMarginsF& padding ) { const auto pd = QskMargins().expandedTo( padding ); - if ( pd != paddingHint( Panel ) ) - { - setPaddingHint( Panel, pd ); - resetImplicitSize(); - - if ( polishOnResize() || autoLayoutChildren() ) - polish(); - + if ( setPaddingHint( Panel, pd ) ) Q_EMIT paddingChanged( pd ); - } } void QskBox::resetPadding() { if ( resetPaddingHint( Panel ) ) - { - resetImplicitSize(); - - if ( polishOnResize() || autoLayoutChildren() ) - polish(); - Q_EMIT paddingChanged( paddingHint( Panel ) ); - } } QMarginsF QskBox::padding() const diff --git a/src/controls/QskControl.cpp b/src/controls/QskControl.cpp index d68101fe..0c0752bb 100644 --- a/src/controls/QskControl.cpp +++ b/src/controls/QskControl.cpp @@ -144,25 +144,14 @@ void QskControl::setBackgroundColor( const QColor& color ) void QskControl::setBackground( const QskGradient& gradient ) { - const auto aspect = QskAspect::Control | QskAspect::Color; - - if ( gradientHint( aspect ) != gradient ) - { - setGradientHint( aspect, gradient ); - if ( autoFillBackground() ) - update(); - + if ( setGradientHint( QskAspect::Control, gradient ) ) Q_EMIT backgroundChanged(); - } } void QskControl::resetBackground() { if ( resetColor( QskAspect::Control ) ) - { - update(); Q_EMIT backgroundChanged(); - } } QskGradient QskControl::background() const @@ -179,17 +168,10 @@ void QskControl::setMargins( const QMarginsF& margins ) { const auto m = QskMargins().expandedTo( margins ); - if ( m != this->margins() ) + if ( setMarginHint( QskAspect::Control, m ) ) { - setMarginHint( QskAspect::Control, m ); - resetImplicitSize(); - - Q_D( const QskControl ); - if ( polishOnResize() || d->autoLayoutChildren ) - polish(); - qskSendEventTo( this, QEvent::ContentsRectChange ); - Q_EMIT marginsChanged(); + Q_EMIT marginsChanged( m ); } } @@ -197,14 +179,8 @@ void QskControl::resetMargins() { if ( resetMarginHint( QskAspect::Control ) ) { - resetImplicitSize(); - - Q_D( const QskControl ); - if ( polishOnResize() || d->autoLayoutChildren ) - polish(); - qskSendEventTo( this, QEvent::ContentsRectChange ); - Q_EMIT marginsChanged(); + Q_EMIT marginsChanged( margins() ); } } diff --git a/src/controls/QskControl.h b/src/controls/QskControl.h index b978d353..41c64e18 100644 --- a/src/controls/QskControl.h +++ b/src/controls/QskControl.h @@ -176,7 +176,7 @@ class QSK_EXPORT QskControl : public QskQuickItem, public QskSkinnable Q_SIGNALS: void backgroundChanged(); - void marginsChanged(); + void marginsChanged( const QMarginsF& ); void focusIndicatorRectChanged(); void localeChanged( const QLocale& ); void focusPolicyChanged(); diff --git a/src/controls/QskGraphicLabel.cpp b/src/controls/QskGraphicLabel.cpp index 6563373e..af9c0ccc 100644 --- a/src/controls/QskGraphicLabel.cpp +++ b/src/controls/QskGraphicLabel.cpp @@ -19,7 +19,6 @@ class QskGraphicLabel::PrivateData PrivateData( const QUrl& sourceUrl ) : source( sourceUrl ) , sourceSize( -1, -1 ) - , alignment( Qt::AlignLeft | Qt::AlignVCenter ) , fillMode( QskGraphicLabel::PreserveAspectFit ) , mirror( false ) , isSourceDirty( !sourceUrl.isEmpty() ) @@ -31,8 +30,6 @@ class QskGraphicLabel::PrivateData QskGraphic graphic; - Qt::Alignment alignment; - uint fillMode : 2; bool mirror : 1; bool isSourceDirty : 1; @@ -131,15 +128,14 @@ void QskGraphicLabel::setGraphic( const QskGraphic& graphic ) void QskGraphicLabel::setGraphicRole( int role ) { - const int oldRole = graphicRole(); - - setGraphicRoleHint( Graphic, role ); - - if ( role != oldRole ) - { - update(); + if ( setGraphicRoleHint( Graphic, role ) ) Q_EMIT graphicRoleChanged( role ); - } +} + +void QskGraphicLabel::resetGraphicRole() +{ + if ( resetGraphicRoleHint( Graphic ) ) + Q_EMIT graphicRoleChanged( graphicRoleHint( Graphic ) ); } int QskGraphicLabel::graphicRole() const @@ -222,23 +218,21 @@ QskGraphicLabel::FillMode QskGraphicLabel::fillMode() const return static_cast< QskGraphicLabel::FillMode >( m_data->fillMode ); } -Qt::Alignment QskGraphicLabel::alignment() const -{ - return m_data->alignment; -} - void QskGraphicLabel::setAlignment( Qt::Alignment alignment ) { - // using setAlignmentHint ... - if ( alignment != m_data->alignment ) - { - m_data->alignment = alignment; - - if ( !( m_data->sourceSize.isEmpty() || m_data->graphic.isEmpty() ) ) - update(); - + if ( setAlignmentHint( Graphic, alignment ) ) Q_EMIT alignmentChanged( alignment ); - } +} + +void QskGraphicLabel::resetAlignment() +{ + if ( resetAlignmentHint( Graphic ) ) + Q_EMIT alignmentChanged( alignment() ); +} + +Qt::Alignment QskGraphicLabel::alignment() const +{ + return alignmentHint( Graphic, Qt::AlignLeft | Qt::AlignVCenter ); } QskGraphic QskGraphicLabel::loadSource( const QUrl& url ) const diff --git a/src/controls/QskGraphicLabel.h b/src/controls/QskGraphicLabel.h index 39a14de3..a1eb43ce 100644 --- a/src/controls/QskGraphicLabel.h +++ b/src/controls/QskGraphicLabel.h @@ -23,10 +23,10 @@ class QSK_EXPORT QskGraphicLabel : public QskControl WRITE setSourceSize RESET resetSourceSize NOTIFY sourceSizeChanged ) Q_PROPERTY( int graphicRole READ graphicRole - WRITE setGraphicRole NOTIFY graphicRoleChanged ) + WRITE setGraphicRole RESET resetGraphicRole NOTIFY graphicRoleChanged ) Q_PROPERTY( Qt::Alignment alignment READ alignment - WRITE setAlignment NOTIFY alignmentChanged ) + WRITE setAlignment RESET resetAlignment NOTIFY alignmentChanged ) Q_PROPERTY( FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged ) @@ -72,6 +72,7 @@ class QSK_EXPORT QskGraphicLabel : public QskControl bool mirror() const; void setAlignment( Qt::Alignment ); + void resetAlignment(); Qt::Alignment alignment() const; void setFillMode( FillMode ); @@ -80,6 +81,7 @@ class QSK_EXPORT QskGraphicLabel : public QskControl bool isEmpty() const; void setGraphicRole( int role ); + void resetGraphicRole(); int graphicRole() const; Q_SIGNALS: diff --git a/src/controls/QskPopup.cpp b/src/controls/QskPopup.cpp index 947aef6a..1dc27c5f 100644 --- a/src/controls/QskPopup.cpp +++ b/src/controls/QskPopup.cpp @@ -386,13 +386,8 @@ bool QskPopup::testPopupFlag( PopupFlag flag ) const void QskPopup::setOverlay( bool on ) { - if ( hasOverlay() != on ) - { - setFlagHint( Overlay | QskAspect::Style, on ); - - update(); + if ( setFlagHint( Overlay | QskAspect::Style, on ) ) Q_EMIT overlayChanged( on ); - } } bool QskPopup::hasOverlay() const diff --git a/src/controls/QskProgressBar.cpp b/src/controls/QskProgressBar.cpp index 62aa5a63..2271cb52 100644 --- a/src/controls/QskProgressBar.cpp +++ b/src/controls/QskProgressBar.cpp @@ -169,20 +169,16 @@ void QskProgressBar::setBarGradient( const QskGradient& gradient ) auto g = gradient; g.setOrientation( Qt::Horizontal ); - setGradientHint( QskProgressBar::Bar | QskAspect::Horizontal, g ); + setGradientHint( Bar | QskAspect::Horizontal, g ); g.setOrientation( Qt::Vertical ); - setGradientHint( QskProgressBar::Bar | QskAspect::Vertical, g ); - - update(); + setGradientHint( Bar | QskAspect::Vertical, g ); } void QskProgressBar::resetBarGradient() { - using A = QskAspect; - - if ( resetColor( Bar | A::Vertical ) || resetColor( Bar | A::Horizontal ) ) - update(); + resetColor( Bar | QskAspect::Vertical ); + resetColor( Bar | QskAspect::Horizontal ); } QskGradient QskProgressBar::barGradient() const @@ -192,35 +188,22 @@ QskGradient QskProgressBar::barGradient() const void QskProgressBar::setExtent( qreal extent ) { - extent = qMax( extent, 0.0 ); - - const auto aspect = Groove | QskAspect::Size; - - if ( extent != metric( aspect ) ) - { - setMetric( aspect, extent ); - - resetImplicitSize(); - update(); + if ( extent < 0.0 ) + extent = 0.0; + if ( setMetric( Groove | QskAspect::Size, extent ) ) Q_EMIT extentChanged( extent ); - } -} - -qreal QskProgressBar::extent() const -{ - return metric( Groove | QskAspect::Size ); } void QskProgressBar::resetExtent() { if ( resetMetric( Groove | QskAspect::Size ) ) - { - resetImplicitSize(); - update(); - Q_EMIT extentChanged( extent() ); - } +} + +qreal QskProgressBar::extent() const +{ + return metric( Groove | QskAspect::Size ); } void QskProgressBar::setOrigin( qreal origin ) @@ -243,6 +226,7 @@ void QskProgressBar::resetOrigin() if ( m_data->hasOrigin ) { m_data->hasOrigin = false; + update(); Q_EMIT originChanged( origin() ); } diff --git a/src/controls/QskPushButton.cpp b/src/controls/QskPushButton.cpp index 6eee01f6..2f9a7aab 100644 --- a/src/controls/QskPushButton.cpp +++ b/src/controls/QskPushButton.cpp @@ -60,13 +60,8 @@ QskPushButton::~QskPushButton() void QskPushButton::setCorner( const QskCorner& corner ) { - if ( corner.metrics() != boxShapeHint( Panel ) ) - { - setBoxShapeHint( Panel, corner.metrics() ); - - update(); + if ( setBoxShapeHint( Panel, corner.metrics() ) ) Q_EMIT cornerChanged(); - } } QskCorner QskPushButton::corner() const diff --git a/src/controls/QskSeparator.cpp b/src/controls/QskSeparator.cpp index 5db2e209..6ea1a311 100644 --- a/src/controls/QskSeparator.cpp +++ b/src/controls/QskSeparator.cpp @@ -52,35 +52,22 @@ Qt::Orientation QskSeparator::orientation() const void QskSeparator::setExtent( qreal extent ) { - extent = qMax( extent, 0.0 ); - - const auto aspect = Panel | QskAspect::Size; - - if ( extent != metric( aspect ) ) - { - setMetric( aspect, extent ); - - resetImplicitSize(); - update(); + if ( extent < 0.0 ) + extent = 0.0; + if ( setMetric( Panel | QskAspect::Size, extent ) ) Q_EMIT extentChanged( extent ); - } -} - -qreal QskSeparator::extent() const -{ - return metric( Panel | QskAspect::Size ); } void QskSeparator::resetExtent() { if ( resetMetric( Panel | QskAspect::Size ) ) - { - resetImplicitSize(); - update(); - Q_EMIT extentChanged( extent() ); - } +} + +qreal QskSeparator::extent() const +{ + return metric( Panel | QskAspect::Size ); } QSizeF QskSeparator::contentsSizeHint( diff --git a/src/controls/QskSkinnable.cpp b/src/controls/QskSkinnable.cpp index 5dd5e96a..256976a5 100644 --- a/src/controls/QskSkinnable.cpp +++ b/src/controls/QskSkinnable.cpp @@ -109,6 +109,79 @@ static inline T qskColor( const QskSkinnable* skinnable, aspect | QskAspect::Color, status ).value< T >(); } +static inline void qskTriggerUpdates( QskAspect aspect, QskControl* control ) +{ + /* + To put the hint into effect we have to call the usual suspects: + + - resetImplicitSize + - polish + - update + + The following code decides about these calls based on type/primitive + of the aspect. It can be expected, that it results in more calls + than what would be mandatory and in rare cases we might even miss necessary + calls. This has to be fixed by doing the call manually in the specific + controls. + */ + + if ( control == nullptr || aspect.isAnimator() ) + return; + + bool maybeLayout = false; + + switch( aspect.type() ) + { + using A = QskAspect; + + case A::Metric: + { + if ( aspect.metricPrimitive() != A::Position ) + { + control->resetImplicitSize(); + maybeLayout = true; + } + + break; + } + + case A::Color: + { + break; + } + + case A::Flag: + { + switch( aspect.flagPrimitive() ) + { + case A::GraphicRole: + case A::FontRole: + { + break; + } + case A::Alignment: + { + maybeLayout = true; + break; + } + default: + { + control->resetImplicitSize(); + maybeLayout = true; + } + } + } + } + + control->update(); // always + + if ( maybeLayout && control->hasChildItems() ) + { + if ( control->polishOnResize() || control->autoLayoutChildren() ) + control->polish(); + } +} + class QskSkinnable::PrivateData { public: @@ -529,49 +602,51 @@ QskAnimationHint QskSkinnable::effectiveAnimation( return hint; } -bool QskSkinnable::setSkinHint( QskAspect aspect, const QVariant& skinHint ) +static inline QskAspect qskSubstitutedAspect( + const QskSkinnable* skinnable, QskAspect aspect ) { if ( aspect.hasState() ) { - qWarning() << "QskSkinnable::setSkinHint: setting hints with states is discouraged - " - "use QskSkinTableEditor if you are sure, that you need this."; - qWarning() << "QskAspect:" << aspect.stateless() << skinStateAsPrintable( aspect.state() ); + qWarning() << "QskSkinnable::(re)setSkinHint: setting hints with states " + "is discouraged - use QskSkinTableEditor if you are " + "sure, that you need this."; + + qWarning() << "QskAspect:" << aspect.stateless() + << skinnable->skinStateAsPrintable( aspect.state() ); #if 0 aspect.clearStates(); #endif } - aspect.setSubControl( effectiveSubcontrol( aspect.subControl() ) ); - return m_data->hintTable.setHint( aspect, skinHint ); + aspect.setSubControl( skinnable->effectiveSubcontrol( aspect.subControl() ) ); + return aspect; +} + +bool QskSkinnable::setSkinHint( QskAspect aspect, const QVariant& hint ) +{ + aspect = qskSubstitutedAspect( this, aspect ); + + if ( m_data->hintTable.setHint( aspect, hint ) ) + { + qskTriggerUpdates( aspect, owningControl() ); + return true; + } + + return false; } bool QskSkinnable::resetSkinHint( QskAspect aspect ) { - aspect.setSubControl( effectiveSubcontrol( aspect.subControl() ) ); + aspect = qskSubstitutedAspect( this, aspect ); - if ( !m_data->hintTable.hasHint( aspect ) ) - return false; + if ( m_data->hintTable.removeHint( aspect ) ) + { + qskTriggerUpdates( aspect, owningControl() ); + return true; + } - /* - To be able to indicate, when the resolved value has changed - we retrieve the value before and after removing the hint from - the local table. An implementation with less lookups - should be possible, but as reset is a low frequently called - operation, we prefer to keep the implementation simple. - */ - - auto a = aspect; - a.setPlacement( effectivePlacement() ); - - if ( !a.hasState() ) - a.setState( skinState() ); - - const auto oldHint = storedHint( a ); - - m_data->hintTable.removeHint( aspect ); - - return oldHint != storedHint( a ); + return false; } QVariant QskSkinnable::effectiveSkinHint( diff --git a/src/controls/QskTextInput.cpp b/src/controls/QskTextInput.cpp index 98598f11..4b0e3e13 100644 --- a/src/controls/QskTextInput.cpp +++ b/src/controls/QskTextInput.cpp @@ -519,38 +519,53 @@ void QskTextInput::setActivationModes( ActivationModes modes ) } } +static inline void qskUpdateInputMethodFont( const QskTextInput* input ) +{ + auto queries = Qt::ImCursorRectangle | Qt::ImFont; +#if QT_VERSION >= QT_VERSION_CHECK( 5, 7, 0 ) + queries |= Qt::ImAnchorRectangle; +#endif + + qskUpdateInputMethod( input, queries ); +} + +void QskTextInput::setFontRole( int role ) +{ + if ( setFontRoleHint( Text, role ) ) + { + qskUpdateInputMethodFont( this ); + Q_EMIT fontRoleChanged(); + } +} + +void QskTextInput::resetFontRole() +{ + if ( resetFontRoleHint( Text ) ) + { + qskUpdateInputMethodFont( this ); + Q_EMIT fontRoleChanged(); + } +} + int QskTextInput::fontRole() const { return fontRoleHint( Text ); } -void QskTextInput::setFontRole( int role ) +void QskTextInput::setAlignment( Qt::Alignment alignment ) { - if ( role != fontRole() ) + if ( setAlignmentHint( Text, alignment ) ) { - setFontRoleHint( Text, role ); - - polish(); - resetImplicitSize(); - - auto queries = Qt::ImCursorRectangle | Qt::ImFont; -#if QT_VERSION >= QT_VERSION_CHECK( 5, 7, 0 ) - queries |= Qt::ImAnchorRectangle; -#endif - - qskUpdateInputMethod( this, queries ); - Q_EMIT fontRoleChanged(); + m_data->textInput->setAlignment( alignment ); + Q_EMIT alignmentChanged(); } } -void QskTextInput::setAlignment( Qt::Alignment alignment ) +void QskTextInput::resetAlignment() { - if ( alignment != this->alignment() ) + if ( resetAlignmentHint( Text ) ) { - setAlignmentHint( Text, alignment ); - m_data->textInput->setAlignment( alignment ); - - polish(); + m_data->textInput->setAlignment( alignment() ); Q_EMIT alignmentChanged(); } } diff --git a/src/controls/QskTextInput.h b/src/controls/QskTextInput.h index bdc3c8eb..7a22c621 100644 --- a/src/controls/QskTextInput.h +++ b/src/controls/QskTextInput.h @@ -20,7 +20,7 @@ class QSK_EXPORT QskTextInput : public QskControl WRITE setDescription NOTIFY descriptionChanged ) Q_PROPERTY( int fontRole READ fontRole - WRITE setFontRole NOTIFY fontRoleChanged ) + WRITE setFontRole RESET resetFontRole NOTIFY fontRoleChanged ) Q_PROPERTY( QFont font READ font ) @@ -88,9 +88,11 @@ class QSK_EXPORT QskTextInput : public QskControl QString description() const; void setFontRole( int role ); + void resetFontRole(); int fontRole() const; void setAlignment( Qt::Alignment ); + void resetAlignment(); Qt::Alignment alignment() const; void setActivationModes( ActivationModes ); diff --git a/src/controls/QskTextLabel.cpp b/src/controls/QskTextLabel.cpp index d1898cae..8ddac3ea 100644 --- a/src/controls/QskTextLabel.cpp +++ b/src/controls/QskTextLabel.cpp @@ -169,17 +169,14 @@ Qt::TextElideMode QskTextLabel::elideMode() const void QskTextLabel::setFontRole( int role ) { - const int oldRole = fontRole(); + if ( setFontRoleHint( Text, role ) ) + Q_EMIT fontRoleChanged( role ); +} - setFontRoleHint( Text, role ); - - if ( oldRole != role ) - { - resetImplicitSize(); - update(); - - Q_EMIT fontRoleChanged(); - } +void QskTextLabel::resetFontRole() +{ + if ( resetFontRoleHint( Text ) ) + Q_EMIT fontRoleChanged( fontRoleHint( Text ) ); } int QskTextLabel::fontRole() const @@ -189,20 +186,31 @@ int QskTextLabel::fontRole() const void QskTextLabel::setTextColor( const QColor& color ) { - if ( color != textColor() ) - { - QskSkinnable::setColor( Text, color ); - - if ( !m_data->text.isEmpty() ) - update(); - + if ( setColor( Text, color ) ) Q_EMIT textColorChanged( color ); - } +} + +void QskTextLabel::resetTextColor() +{ + if ( resetColor( Text ) ) + Q_EMIT textColorChanged( color( Text ) ); } QColor QskTextLabel::textColor() const { - return QskSkinnable::color( Text ); + return color( Text ); +} + +void QskTextLabel::setAlignment( Qt::Alignment alignment ) +{ + if ( setAlignmentHint( Text, alignment ) ) + Q_EMIT alignmentChanged( alignment ); +} + +void QskTextLabel::resetAlignment() +{ + if ( resetAlignmentHint( Text ) ) + Q_EMIT alignmentChanged( alignment() ); } Qt::Alignment QskTextLabel::alignment() const @@ -210,19 +218,6 @@ Qt::Alignment QskTextLabel::alignment() const return alignmentHint( Text, Qt::AlignLeft | Qt::AlignTop ); } -void QskTextLabel::setAlignment( Qt::Alignment alignment ) -{ - if ( alignment != this->alignment() ) - { - setAlignmentHint( Text, alignment ); - - if ( !m_data->text.isEmpty() ) - update(); - - Q_EMIT alignmentChanged(); - } -} - QFont QskTextLabel::font() const { return effectiveFont( QskTextLabel::Text ); diff --git a/src/controls/QskTextLabel.h b/src/controls/QskTextLabel.h index 6c3ad3cc..be847206 100644 --- a/src/controls/QskTextLabel.h +++ b/src/controls/QskTextLabel.h @@ -16,12 +16,12 @@ class QSK_EXPORT QskTextLabel : public QskControl Q_PROPERTY( QString text READ text WRITE setText NOTIFY textChanged ) Q_PROPERTY( int fontRole READ fontRole - WRITE setFontRole NOTIFY fontRoleChanged ) + WRITE setFontRole RESET resetFontRole NOTIFY fontRoleChanged ) Q_PROPERTY( QFont font READ font ) Q_PROPERTY( QColor textColor READ textColor - WRITE setTextColor NOTIFY textColorChanged ) + WRITE setTextColor RESET resetTextColor NOTIFY textColorChanged ) Q_PROPERTY( QskTextOptions textOptions READ textOptions WRITE setTextOptions NOTIFY textOptionsChanged ) @@ -45,9 +45,11 @@ class QSK_EXPORT QskTextLabel : public QskControl QString text() const; void setFontRole( int role ); + void resetFontRole(); int fontRole() const; void setTextColor( const QColor& ); + void resetTextColor(); QColor textColor() const; void setTextOptions( const QskTextOptions& ); @@ -63,6 +65,7 @@ class QSK_EXPORT QskTextLabel : public QskControl Qt::TextElideMode elideMode() const; void setAlignment( Qt::Alignment ); + void resetAlignment(); Qt::Alignment alignment() const; QFont font() const; @@ -74,8 +77,8 @@ class QSK_EXPORT QskTextLabel : public QskControl void textChanged( const QString& ); void textColorChanged( const QColor& ); void textOptionsChanged( const QskTextOptions& ); - void fontRoleChanged(); - void alignmentChanged(); + void fontRoleChanged( int ); + void alignmentChanged( Qt::Alignment ); void panelChanged( bool ); public Q_SLOTS: