auto-updating the control, when setting a skinHint

This commit is contained in:
Uwe Rathmann 2020-12-27 16:31:07 +01:00
parent 92b1ed669b
commit 98343dec60
14 changed files with 227 additions and 219 deletions

View File

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

View File

@ -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() );
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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() );
}

View File

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

View File

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

View File

@ -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.removeHint( aspect ) )
{
qskTriggerUpdates( aspect, owningControl() );
return true;
}
if ( !m_data->hintTable.hasHint( aspect ) )
return false;
/*
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 );
}
QVariant QskSkinnable::effectiveSkinHint(

View File

@ -519,38 +519,53 @@ void QskTextInput::setActivationModes( ActivationModes modes )
}
}
int QskTextInput::fontRole() const
static inline void qskUpdateInputMethodFont( const QskTextInput* input )
{
return fontRoleHint( Text );
}
void QskTextInput::setFontRole( int role )
{
if ( role != fontRole() )
{
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 );
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::setAlignment( Qt::Alignment alignment )
{
if ( alignment != this->alignment() )
if ( setAlignmentHint( Text, alignment ) )
{
setAlignmentHint( Text, alignment );
m_data->textInput->setAlignment( alignment );
Q_EMIT alignmentChanged();
}
}
polish();
void QskTextInput::resetAlignment()
{
if ( resetAlignmentHint( Text ) )
{
m_data->textInput->setAlignment( alignment() );
Q_EMIT alignmentChanged();
}
}

View File

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

View File

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

View File

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