QskAspect::Primitive cleanup

This commit is contained in:
Uwe Rathmann 2021-04-28 09:32:49 +02:00
parent 3112df6c2f
commit 75a9ee305c
7 changed files with 200 additions and 174 deletions

View File

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

View File

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

View File

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

View File

@ -33,9 +33,7 @@ class QSK_EXPORT QskAspect
NoPrimitive = 0,
Alignment,
Direction,
Style,
Decoration,
GraphicRole,
FontRole,

View File

@ -14,26 +14,27 @@
#include <qurl.h>
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 );
}

View File

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

View File

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