diff --git a/doc/classes/QskAspect.dox b/doc/classes/QskAspect.dox index 3d1244a3..817c1a87 100644 --- a/doc/classes/QskAspect.dox +++ b/doc/classes/QskAspect.dox @@ -4,10 +4,10 @@ \brief Lookup key for a QskSkinHintTable - Used by the \ref qskskinning "themeing system" to determine how a given aspect - of a control is drawn. While an aspect is simply a 64-bit unsigned integer, it - is composed of smaller enum bitfields which can be ORed together to - describe a more specific part of the user interface. + QskAspect is used by the \ref qskskinning "themeing system" to determine how + a given aspect of a control is drawn. While an aspect is simply a 64-bit + unsigned integer, it is composed of smaller enum bitfields which can be ORed + together to describe a more specific part of the user interface. For example, the border colors of a QskPushButton while pressed is defined by combining the State (QskAbstractButton::Pressed) with the @@ -38,14 +38,12 @@ \var QskAspect::Type QskAspect::Flag Flags are all sort of attributes that are no metrics or colors - f.e - an alignment. A reasonable subset of possible flags is offered as - QskAspect::FlagPrimitive + an alignment. \var QskAspect::Type QskAspect::Metric Metrics are related to geometries in most cases corresponding to pixel distances. - Examples are the margin/padding. A reasonable subset of possible metrics - is offered as QskAspect::MetricPrimitive. + Examples are margin/padding(s). \var QskAspect::Type QskAspect::Color @@ -53,47 +51,79 @@ */ /*! - \enum QskAspect::FlagPrimitive + \enum QskAspect::Primitive - \var QskAspect::FlagPrimitive QskAspect::NoFlagPrimitive - \var QskAspect::FlagPrimitive QskAspect::Alignment - \var QskAspect::FlagPrimitive QskAspect::Direction - \var QskAspect::FlagPrimitive QskAspect::Style - \var QskAspect::FlagPrimitive QskAspect::Decoration - \var QskAspect::FlagPrimitive QskAspect::GraphicRole - \var QskAspect::FlagPrimitive QskAspect::FontRole + \sa setPrimitive(), clearPrimitive(), primitive(), + reservePrimitives(), primitiveCount() - \sa setPrimitive(), clearPrimitive(), primitive() + \var QskAspect::Primitive QskAspect::NoPrimitive + No specific primitive + + \var QskAspect::Primitive QskAspect::Alignment + Usually used in combination with QskAspect::Flag + + \sa QskSkinnable::alignmentHint(), QskSkinHintTableEditor::alignment() + + \var QskAspect::Primitive QskAspect::Style + Usually used in combination with QskAspect::Flag + + \var QskAspect::Primitive QskAspect::GraphicRole + + \sa QskSkinnable::graphicRoleHint(), QskSkinHintTableEditor::graphicRole() + + \var QskAspect::Primitive QskAspect::FontRole + + \sa QskSkinnable::fontRoleHint(), QskSkinHintTableEditor::fontRole() + + \var QskAspect::Primitive QskAspect::TextColor + bla + + \var QskAspect::Primitive QskAspect::StyleColor + bla + + \var QskAspect::Primitive QskAspect::LinkColor + bla + + \var QskAspect::Primitive QskAspect::StrutSize + bla + + \sa QskSkinnable::strutSizeHint(), QskSkinHintTableEditor::strutSize() + + \var QskAspect::Primitive QskAspect::Size + bla + + \var QskAspect::Primitive QskAspect::Position + bla + + \var QskAspect::Primitive QskAspect::Margin + bla + + \sa QskSkinnable::marginHint(), QskSkinHintTableEditor::margin() + + \var QskAspect::Primitive QskAspect::Padding + bla + + \sa QskSkinnable::paddingHint(), QskSkinHintTableEditor::padding() + + \var QskAspect::Primitive QskAspect::Spacing + bla + + \sa QskSkinnable::spacingHint(), QskSkinHintTableEditor::spacing() + + \var QskAspect::Primitive QskAspect::Shadow + bla + + \var QskAspect::Primitive QskAspect::Shape + bla + + \sa QskSkinnable::boxShapeHint(), QskSkinHintTableEditor::boxShape() + + \var QskAspect::Primitive QskAspect::Border + bla + \sa QskSkinnable::boxBorderMetricsHint(), QskSkinnable::boxBorderColorsHint() + QskSkinHintTableEditor::boxBorderMetrics(), QskSkinHintTableEditor::boxBorderColors() */ -/*! - \enum QskAspect::MetricPrimitive - - \var QskAspect::MetricPrimitive QskAspect::NoMetricPrimitive - \var QskAspect::MetricPrimitive QskAspect::StrutSize - \var QskAspect::MetricPrimitive QskAspect::Size - \var QskAspect::MetricPrimitive QskAspect::Position - \var QskAspect::MetricPrimitive QskAspect::Margin - \var QskAspect::MetricPrimitive QskAspect::Padding - \var QskAspect::MetricPrimitive QskAspect::Shadow - \var QskAspect::MetricPrimitive QskAspect::Spacing - \var QskAspect::MetricPrimitive QskAspect::Shape - \var QskAspect::MetricPrimitive QskAspect::Border - - \sa setPrimitive(), clearPrimitive(), primitive() -*/ - -/*! - \enum QskAspect::ColorPrimitive - - \var QskAspect::ColorPrimitive QskAspect::NoColorPrimitive - \var QskAspect::ColorPrimitive QskAspect::TextColor - \var QskAspect::ColorPrimitive QskAspect::StyleColor - \var QskAspect::ColorPrimitive QskAspect::LinkColor - - \sa setPrimitive(), clearPrimitive(), primitive() -*/ - /*! \enum QskAspect::Placement @@ -275,19 +305,7 @@ */ /*! - \fn QskAspect::operator|( FlagPrimitive ) const - - Sets the primitive bits -*/ - -/*! - \fn QskAspect::operator|( MetricPrimitive ) const - - Sets the primitive bits -*/ - -/*! - \fn QskAspect::operator|( ColorPrimitive ) const + \fn QskAspect::operator|( Primitive ) const Sets the primitive bits */ diff --git a/skins/material/QskMaterialSkin.cpp b/skins/material/QskMaterialSkin.cpp index 13706d25..c6b5c5db 100644 --- a/skins/material/QskMaterialSkin.cpp +++ b/skins/material/QskMaterialSkin.cpp @@ -673,7 +673,6 @@ void Editor::setupSubWindow() // Panel - setFlagHint( Q::Panel | A::Decoration, true ); setPadding( Q::Panel, 10 ); setBoxShape( Q::Panel, 0 ); setBoxBorderMetrics( Q::Panel, 2 ); @@ -685,15 +684,18 @@ void Editor::setupSubWindow() setBoxBorderColors( Q::Panel, colors ); - // TitleBar - setGradient( Q::TitleBar, m_pal.darker200 ); - setGradient( Q::TitleBar | Q::Focused, m_pal.accentColor ); + // TitleBarPanel + setFlagHint( Q::TitleBarPanel | QskAspect::Style, + Q::TitleBar | Q::Title | Q::Symbol ); + + setGradient( Q::TitleBarPanel, m_pal.darker200 ); + setGradient( Q::TitleBarPanel | Q::Focused, m_pal.accentColor ); // TitleBarText setFontRole( Q::TitleBarText, QskSkin::SmallFont ); setAlignment( Q::TitleBarText, Qt::AlignLeft | Qt::AlignVCenter ); - for ( auto subControl : { Q::Panel, Q::TitleBar, Q::TitleBarText } ) + for ( auto subControl : { Q::Panel, Q::TitleBarPanel, Q::TitleBarText } ) setAnimation( subControl | A::Color, qskDuration ); } diff --git a/skins/squiek/QskSquiekSkin.cpp b/skins/squiek/QskSquiekSkin.cpp index 46578972..288c4956 100644 --- a/skins/squiek/QskSquiekSkin.cpp +++ b/skins/squiek/QskSquiekSkin.cpp @@ -816,7 +816,6 @@ void Editor::setupSubWindow() // Panel - setFlagHint( Q::Panel | A::Decoration, true ); setPadding( Q::Panel, 10 ); setBoxBorderMetrics( Q::Panel, 2 ); setBoxShape( Q::Panel, radius, radius, 0, 0, Qt::AbsoluteSize ); @@ -828,13 +827,16 @@ void Editor::setupSubWindow() setBoxBorderColors( Q::Panel, borderColors ); setGradient( Q::Panel, m_pal.lighter135 ); - // TitleBar + // TitleBarPanel - setGradient( Q::TitleBar | Q::Focused, m_pal.highlighted ); - setGradient( Q::TitleBar, m_pal.contrasted ); - setSpacing( Q::TitleBar, 5 ); - setStrutSize( Q::TitleBar, 0, 20 ); - setBoxShape( Q::TitleBar, radius, radius, 0, 0, Qt::AbsoluteSize ); + setFlagHint( Q::TitleBarPanel | QskAspect::Style, + Q::TitleBar | Q::Title | Q::Symbol ); + + setGradient( Q::TitleBarPanel | Q::Focused, m_pal.highlighted ); + setGradient( Q::TitleBarPanel, m_pal.contrasted ); + setSpacing( Q::TitleBarPanel, 5 ); + setStrutSize( Q::TitleBarPanel, 0, 20 ); + setBoxShape( Q::TitleBarPanel, radius, radius, 0, 0, Qt::AbsoluteSize ); // TitleBarText setFontRole( Q::TitleBarText, QskSkin::SmallFont ); @@ -843,7 +845,7 @@ void Editor::setupSubWindow() setAlignment( Q::TitleBarText, Qt::AlignLeft | Qt::AlignVCenter ); - for ( auto subControl : { Q::Panel, Q::TitleBar, Q::TitleBarText } ) + for ( auto subControl : { Q::Panel, Q::TitleBarPanel, Q::TitleBarText } ) setAnimation( subControl | A::Color, qskDuration ); } diff --git a/src/common/QskAspect.h b/src/common/QskAspect.h index f8b7779f..45558cc6 100644 --- a/src/common/QskAspect.h +++ b/src/common/QskAspect.h @@ -33,9 +33,7 @@ class QSK_EXPORT QskAspect NoPrimitive = 0, Alignment, - Direction, Style, - Decoration, GraphicRole, FontRole, diff --git a/src/controls/QskSubWindow.cpp b/src/controls/QskSubWindow.cpp index a0ff84d6..a36dc85d 100644 --- a/src/controls/QskSubWindow.cpp +++ b/src/controls/QskSubWindow.cpp @@ -14,26 +14,27 @@ #include QSK_SUBCONTROL( QskSubWindow, Panel ) -QSK_SUBCONTROL( QskSubWindow, TitleBar ) +QSK_SUBCONTROL( QskSubWindow, TitleBarPanel ) QSK_SUBCONTROL( QskSubWindow, TitleBarSymbol ) QSK_SUBCONTROL( QskSubWindow, TitleBarText ) +namespace +{ + inline QskAspect aspectDecoration() + { + return QskSubWindow::TitleBarPanel | QskAspect::Flag | QskAspect::Style; + } +} + class QskSubWindow::PrivateData { public: PrivateData() : isWindowIconSourceDirty( false ) { - // should be available from the platform somehow. TODO ... - - windowButtons = QskSubWindow::WindowButtons( QskSubWindow::MinimizeButton | - QskSubWindow::MaximizeButton | QskSubWindow::CloseButton ); - windowTitleTextOptions.setElideMode( Qt::ElideRight ); } - QskSubWindow::WindowButtons windowButtons; - QString windowTitle; QskTextOptions windowTitleTextOptions; @@ -57,24 +58,38 @@ QskSubWindow::~QskSubWindow() { } -void QskSubWindow::setDecorated( bool on ) +void QskSubWindow::setDecorations( Decorations decorations ) { - if ( on == isDecorated() ) - return; - - setFlagHint( Panel | QskAspect::Decoration, on ); - - resetImplicitSize(); // in case some parent wants to layout - - polish(); - update(); - - Q_EMIT decoratedChanged(); + if ( setFlagHint( aspectDecoration(), decorations ) ) + Q_EMIT decorationsChanged( decorations ); } -bool QskSubWindow::isDecorated() const +QskSubWindow::Decorations QskSubWindow::decorations() const { - return flagHint< bool >( Panel | QskAspect::Decoration, true ); + return flagHint< QskSubWindow::Decorations >( aspectDecoration() ); +} + +void QskSubWindow::setDecoration( Decoration decoration, bool on ) +{ + auto d = decorations(); + + if ( on ) + d |= decoration; + else + d &= ~decoration; + + setDecorations( d ); +} + +void QskSubWindow::resetDecorations() +{ + if ( resetFlagHint( aspectDecoration() ) ) + Q_EMIT decorationsChanged( decorations() ); +} + +bool QskSubWindow::hasDecoration( Decoration decoration ) const +{ + return decorations() & decoration; } void QskSubWindow::setWindowTitle( const QString& title ) @@ -166,44 +181,9 @@ bool QskSubWindow::hasWindowIcon() const return !( windowIcon().isEmpty() && windowIconSource().isEmpty() ); } - -void QskSubWindow::setWindowButtons( WindowButtons buttons ) -{ - if ( buttons != m_data->windowButtons ) - { - m_data->windowButtons = buttons; - update(); - - Q_EMIT windowButtonsChanged(); - } -} - -QskSubWindow::WindowButtons QskSubWindow::windowButtons() const -{ - return m_data->windowButtons; -} - -void QskSubWindow::setWindowButton( WindowButton button, bool on ) -{ - if ( on == bool( button & m_data->windowButtons ) ) - return; - - if ( on ) - m_data->windowButtons |= button; - else - m_data->windowButtons &= ~button; - - Q_EMIT windowButtonsChanged(); -} - -bool QskSubWindow::testWindowButton( WindowButton button ) const -{ - return m_data->windowButtons & button; -} - QRectF QskSubWindow::titleBarRect() const { - return subControlRect( TitleBar ); + return subControlRect( TitleBarPanel ); } bool QskSubWindow::event( QEvent* event ) @@ -234,7 +214,7 @@ QRectF QskSubWindow::layoutRectForSize( const QSizeF& size ) const { QRectF rect; rect.setSize( size ); - rect.setTop( subControlRect( size, TitleBar ).bottom() ); + rect.setTop( subControlRect( size, TitleBarPanel ).bottom() ); return innerBox( Panel, rect ); } diff --git a/src/controls/QskSubWindow.h b/src/controls/QskSubWindow.h index 552e33c9..aa8d5243 100644 --- a/src/controls/QskSubWindow.h +++ b/src/controls/QskSubWindow.h @@ -16,8 +16,8 @@ class QSK_EXPORT QskSubWindow : public QskPopup { Q_OBJECT - Q_PROPERTY( bool decorated READ isDecorated - WRITE setDecorated NOTIFY decoratedChanged ) + Q_PROPERTY( Decorations decorations READ decorations + WRITE setDecorations RESET resetDecorations NOTIFY decorationsChanged ) Q_PROPERTY( QString windowTitle READ windowTitle WRITE setWindowTitle NOTIFY windowTitleChanged ) @@ -31,29 +31,39 @@ class QSK_EXPORT QskSubWindow : public QskPopup Q_PROPERTY( QskGraphic windowIcon READ windowIcon WRITE setWindowIcon NOTIFY windowIconChanged FINAL ) - Q_PROPERTY( WindowButtons windowButtons READ windowButtons - WRITE setWindowButtons NOTIFY windowButtonsChanged ) - using Inherited = QskPopup; public: - enum WindowButton + enum Decoration { - MinimizeButton = 0x1, - MaximizeButton = 0x2, - CloseButton = 0x4 + NoDecoration = 0, + + TitleBar = 1 << 0, + + Title = 1 << 1, + Symbol = 1 << 2 + +#if 0 + MinimizeButton = 1 << 3, + MaximizeButton = 1 << 4, + CloseButton = 1 << 5 +#endif }; - Q_ENUM( WindowButton ) - Q_DECLARE_FLAGS( WindowButtons, WindowButton ) + Q_ENUM( Decoration ) + Q_DECLARE_FLAGS( Decorations, Decoration ) - QSK_SUBCONTROLS( Panel, TitleBar, TitleBarSymbol, TitleBarText ) + QSK_SUBCONTROLS( Panel, TitleBarPanel, TitleBarSymbol, TitleBarText ) QskSubWindow( QQuickItem* parent = nullptr ); ~QskSubWindow() override; - void setDecorated( bool ); - bool isDecorated() const; + void setDecorations( Decorations ); + void resetDecorations(); + Decorations decorations() const; + + void setDecoration( Decoration, bool on = true ); + bool hasDecoration( Decoration ) const; void setWindowTitleTextOptions( const QskTextOptions& ); QskTextOptions windowTitleTextOptions() const; @@ -70,23 +80,16 @@ class QSK_EXPORT QskSubWindow : public QskPopup bool hasWindowIcon() const; - void setWindowButtons( WindowButtons ); - WindowButtons windowButtons() const; - - void setWindowButton( WindowButton, bool on = true ); - bool testWindowButton( WindowButton ) const; - QRectF titleBarRect() const; QRectF layoutRectForSize( const QSizeF& ) const override; Q_SIGNALS: - void decoratedChanged(); + void decorationsChanged( Decorations ); void windowTitleChanged(); void windowTitleTextOptionsChanged(); void windowIconChanged(); void windowIconSourceChanged(); - void windowButtonsChanged(); protected: bool event( QEvent* ) override; diff --git a/src/controls/QskSubWindowSkinlet.cpp b/src/controls/QskSubWindowSkinlet.cpp index c51e5c7d..9ad56f07 100644 --- a/src/controls/QskSubWindowSkinlet.cpp +++ b/src/controls/QskSubWindowSkinlet.cpp @@ -30,7 +30,7 @@ QRectF QskSubWindowSkinlet::subControlRect( const QskSkinnable* skinnable, { return contentsRect; } - else if ( subControl == QskSubWindow::TitleBar ) + else if ( subControl == QskSubWindow::TitleBarPanel ) { return titleBarRect( subWindow, contentsRect ); } @@ -49,37 +49,45 @@ QRectF QskSubWindowSkinlet::subControlRect( const QskSkinnable* skinnable, QSGNode* QskSubWindowSkinlet::updateSubNode( const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const { + using Q = QskSubWindow; + const auto subWindow = static_cast< const QskSubWindow* >( skinnable ); switch ( nodeRole ) { case PanelRole: { - return updateBoxNode( subWindow, node, QskSubWindow::Panel ); + return updateBoxNode( subWindow, node, Q::Panel ); } case TitleBarRole: { - if ( subWindow->isDecorated() ) - return updateBoxNode( subWindow, node, QskSubWindow::TitleBar ); + const auto decorations = subWindow->decorations(); + + if ( decorations & Q::TitleBar ) + return updateBoxNode( subWindow, node, Q::TitleBarPanel ); return nullptr; } case SymbolRole: { - if ( subWindow->isDecorated() ) + const auto decorations = subWindow->decorations(); + + if ( ( decorations & Q::TitleBar ) && ( decorations & Q::Symbol ) ) { return updateGraphicNode( subWindow, node, - subWindow->windowIcon(), QskSubWindow::TitleBarSymbol ); + subWindow->windowIcon(), Q::TitleBarSymbol ); } return nullptr; } case TitleRole: { - if ( subWindow->isDecorated() ) + const auto decorations = subWindow->decorations(); + + if ( ( decorations & Q::TitleBar ) && ( decorations & Q::Title ) ) { return updateTextNode( subWindow, node, subWindow->windowTitle(), - subWindow->windowTitleTextOptions(), QskSubWindow::TitleBarText ); + subWindow->windowTitleTextOptions(), Q::TitleBarText ); } return nullptr; @@ -104,16 +112,23 @@ qreal QskSubWindowSkinlet::titleBarHeight( const QskSubWindow* subWindow ) const { using Q = QskSubWindow; - if ( !subWindow->isDecorated() ) + const auto decorations = subWindow->decorations(); + if ( !( decorations & Q::TitleBar ) ) return 0; - const auto margins = subWindow->paddingHint( Q::TitleBar ); - const QFontMetricsF fm( subWindow->effectiveFont( Q::TitleBarText ) ); + auto height = subWindow->strutSizeHint( Q::TitleBarPanel ).height(); - const qreal height = fm.height() + margins.top() + margins.bottom(); - const auto strutSize = subWindow->strutSizeHint( Q::TitleBar ); + if ( decorations & Q::Title ) + { + const auto padding = subWindow->paddingHint( Q::TitleBarPanel ); + const QFontMetricsF fm( subWindow->effectiveFont( Q::TitleBarText ) ); - return qMax( height, strutSize.height() ); + const qreal h = fm.height() + padding.top() + padding.bottom(); + if ( h > height ) + height = h; + } + + return height; } QRectF QskSubWindowSkinlet::symbolRect( @@ -121,13 +136,16 @@ QRectF QskSubWindowSkinlet::symbolRect( { using Q = QskSubWindow; - auto rect = subWindow->subControlContentsRect( contentsRect, Q::TitleBar ); + if ( !subWindow->hasDecoration( Q::Symbol ) ) + return QRectF(); - int w = 0; + auto rect = subWindow->subControlContentsRect( contentsRect, Q::TitleBarPanel ); if ( !rect.isEmpty() ) { const auto symbol = subWindow->windowIcon(); + + int w = 0; if ( !symbol.isNull() ) w = symbol.widthForHeight( rect.height() ); @@ -142,14 +160,19 @@ QRectF QskSubWindowSkinlet::titleRect( { using Q = QskSubWindow; - auto rect = subWindow->subControlContentsRect( contentsRect, Q::TitleBar ); + if ( !subWindow->hasDecoration( Q::Title ) ) + return QRectF(); + + auto rect = subWindow->subControlContentsRect( contentsRect, Q::TitleBarPanel ); if ( !rect.isEmpty() ) { - const auto spacing = subWindow->spacingHint( Q::TitleBar ); const auto symbolRect = subControlRect( subWindow, rect, Q::TitleBarSymbol ); - - rect.setX( rect.x() + symbolRect.right() + spacing ); + if ( !symbolRect.isEmpty() ) + { + const auto spacing = subWindow->spacingHint( Q::TitleBarPanel ); + rect.setX( symbolRect.right() + spacing ); + } #if 0 const QFontMetricsF fm( subWindow->effectiveFont( Q::TitleBarText ) );