qskinny/src/controls/QskSkinnable.h

285 lines
8.8 KiB
C
Raw Normal View History

2017-07-21 18:21:34 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#ifndef QSK_SKINNABLE_H
#define QSK_SKINNABLE_H
#include "QskAspect.h"
#include <memory>
typedef unsigned int QRgb;
class QSizeF;
class QRectF;
class QColor;
class QFont;
class QMarginsF;
2017-10-30 08:08:58 +01:00
struct QMetaObject;
2018-07-19 15:21:28 +02:00
class QVariant;
2017-07-21 18:21:34 +02:00
class QDebug;
class QSGNode;
class QskArcMetrics;
2017-07-21 18:21:34 +02:00
class QskControl;
class QskAnimationHint;
class QskColorFilter;
class QskBoxShapeMetrics;
class QskBoxBorderMetrics;
class QskBoxBorderColors;
2022-01-04 13:44:53 +01:00
class QskBoxHints;
class QskGradient;
2017-07-21 18:21:34 +02:00
class QskSkin;
class QskSkinlet;
class QskSkinHintTable;
2017-07-21 18:21:34 +02:00
class QSK_EXPORT QskSkinHintStatus
{
2018-08-03 08:15:28 +02:00
public:
2017-07-21 18:21:34 +02:00
enum Source
{
NoSource = 0,
Skinnable,
Skin,
Animator
};
2018-08-03 08:15:28 +02:00
QskSkinHintStatus()
: source( NoSource )
2017-07-21 18:21:34 +02:00
{
}
inline bool isValid() const
{
return source > 0;
}
Source source;
2020-12-21 16:06:58 +01:00
QskAspect aspect;
2017-07-21 18:21:34 +02:00
};
2020-09-28 09:04:25 +02:00
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
QSK_EXPORT QDebug operator<<( QDebug, const QskSkinHintStatus& );
#endif
2017-07-21 18:21:34 +02:00
class QSK_EXPORT QskSkinnable
{
2018-08-03 08:15:28 +02:00
public:
2017-07-21 18:21:34 +02:00
QskSkinnable();
virtual ~QskSkinnable();
void setSkinlet( const QskSkinlet* );
2017-07-21 18:21:34 +02:00
const QskSkinlet* skinlet() const;
2020-12-21 16:06:58 +01:00
QFont effectiveFont( QskAspect ) const;
qreal effectiveFontHeight( QskAspect ) const;
2017-07-21 18:21:34 +02:00
2020-12-21 16:06:58 +01:00
QskColorFilter effectiveGraphicFilter( QskAspect ) const;
2017-07-21 18:21:34 +02:00
void setSubcontrolProxy( QskAspect::Subcontrol, QskAspect::Subcontrol proxy );
void resetSubcontrolProxy( QskAspect::Subcontrol );
QskAspect::Subcontrol subcontrolProxy( QskAspect::Subcontrol ) const;
bool setAnimationHint( QskAspect, QskAnimationHint );
2020-12-21 16:06:58 +01:00
QskAnimationHint animationHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
2021-12-29 15:55:44 +01:00
bool hasAnimationHint( QskAspect ) const;
2017-07-21 18:21:34 +02:00
bool setSkinHint( QskAspect, const QVariant& );
2020-12-21 16:06:58 +01:00
bool resetSkinHint( QskAspect );
2019-03-19 17:36:12 +01:00
2021-12-29 15:55:44 +01:00
bool moveSkinHint( QskAspect, const QVariant& );
bool moveSkinHint( QskAspect, const QVariant&, const QVariant& );
QskAnimationHint effectiveAnimation( QskAspect::Type, QskAspect::Subcontrol,
QskAspect::States, QskSkinHintStatus* status = nullptr ) const;
2020-12-21 16:06:58 +01:00
QVariant effectiveSkinHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
virtual QskAspect::Placement effectivePlacement() const;
2017-07-21 18:21:34 +02:00
2020-12-21 16:06:58 +01:00
QskSkinHintStatus hintStatus( QskAspect ) const;
2017-07-21 18:21:34 +02:00
2020-12-29 12:57:03 +01:00
QRectF subControlRect( const QRectF&, QskAspect::Subcontrol ) const;
QRectF subControlContentsRect( const QRectF&, QskAspect::Subcontrol ) const;
2020-12-21 16:06:58 +01:00
QSizeF outerBoxSize( QskAspect, const QSizeF& innerBoxSize ) const;
QSizeF innerBoxSize( QskAspect, const QSizeF& outerBoxSize ) const;
2017-07-21 18:21:34 +02:00
2020-12-21 16:06:58 +01:00
QRectF innerBox( QskAspect, const QRectF& outerBox ) const;
QRectF outerBox( QskAspect, const QRectF& innerBox ) const;
2017-07-21 18:21:34 +02:00
2020-12-21 16:06:58 +01:00
QMarginsF innerPadding( QskAspect, const QSizeF& ) const;
const QskSkinlet* effectiveSkinlet() const;
2017-07-21 18:21:34 +02:00
QskSkin* effectiveSkin() const;
2020-12-21 16:06:58 +01:00
void startTransition( QskAspect,
2017-07-21 18:21:34 +02:00
QskAnimationHint, QVariant from, QVariant to );
QskAspect::Subcontrol effectiveSubcontrol( QskAspect::Subcontrol ) const;
2017-07-21 18:21:34 +02:00
QskControl* controlCast();
const QskControl* controlCast() const;
virtual QskControl* owningControl() const = 0;
virtual const QMetaObject* metaObject() const = 0;
2020-12-21 16:06:58 +01:00
void debug( QskAspect ) const;
2017-07-21 18:21:34 +02:00
void debug( QskAspect::State ) const;
2020-12-21 16:06:58 +01:00
void debug( QDebug, QskAspect ) const;
2017-07-21 18:21:34 +02:00
void debug( QDebug, QskAspect::State ) const;
2021-09-17 16:32:01 +02:00
void setSkinStates( QskAspect::States );
2020-07-27 07:26:38 +02:00
void setSkinStateFlag( QskAspect::State, bool on = true );
2021-09-17 16:32:01 +02:00
void addSkinStates( QskAspect::States );
void clearSkinStates( QskAspect::States );
void replaceSkinStates( QskAspect::States );
2021-04-21 09:29:52 +02:00
2021-08-30 15:30:41 +02:00
bool hasSkinState( QskAspect::State ) const;
QskAspect::States skinStates() const;
2021-02-17 11:09:45 +01:00
const char* skinStatesAsPrintable() const;
const char* skinStatesAsPrintable( QskAspect::States ) const;
2021-02-17 11:09:45 +01:00
// type aware methods for accessing skin hints
bool setColor( QskAspect, Qt::GlobalColor );
bool setColor( QskAspect, QRgb );
bool setColor( QskAspect, const QColor& );
2021-12-29 15:55:44 +01:00
bool moveColor( QskAspect, Qt::GlobalColor );
bool moveColor( QskAspect, QRgb );
bool moveColor( QskAspect, const QColor& );
bool resetColor( QskAspect );
QColor color( QskAspect, QskSkinHintStatus* = nullptr ) const;
2021-02-01 10:24:40 +01:00
bool setMetric( QskAspect, qreal );
2021-12-29 15:55:44 +01:00
bool moveMetric( QskAspect, qreal );
bool resetMetric( QskAspect );
qreal metric( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setFlagHint( QskAspect, int flag );
bool resetFlagHint( QskAspect );
int flagHint( QskAspect ) const;
template< typename T > T flagHint( QskAspect, T = T() ) const;
2021-12-29 15:55:44 +01:00
bool setPositionHint( QskAspect, qreal );
bool movePositionHint( QskAspect, qreal );
2021-12-29 16:21:33 +01:00
bool movePositionHint( QskAspect, qreal from, qreal to );
2021-12-29 15:55:44 +01:00
bool resetPositionHint( QskAspect );
qreal positionHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setStrutSizeHint( QskAspect, const QSizeF& );
bool setStrutSizeHint( QskAspect, qreal width, qreal height );
bool resetStrutSizeHint( QskAspect );
QSizeF strutSizeHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setMarginHint( QskAspect, qreal );
bool setMarginHint( QskAspect, const QMarginsF& );
bool resetMarginHint( QskAspect );
QMarginsF marginHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setPaddingHint( QskAspect, qreal );
bool setPaddingHint( QskAspect, const QMarginsF& );
bool resetPaddingHint( QskAspect );
QMarginsF paddingHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setGradientHint( QskAspect, const QskGradient& );
QskGradient gradientHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setBoxShapeHint( QskAspect, const QskBoxShapeMetrics& );
bool resetBoxShapeHint( QskAspect );
QskBoxShapeMetrics boxShapeHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setBoxBorderMetricsHint( QskAspect, const QskBoxBorderMetrics& );
bool resetBoxBorderMetricsHint( QskAspect );
QskBoxBorderMetrics boxBorderMetricsHint(
QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setBoxBorderColorsHint( QskAspect, const QskBoxBorderColors& );
bool resetBoxBorderColorsHint( QskAspect );
QskBoxBorderColors boxBorderColorsHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
2022-01-04 13:44:53 +01:00
QskBoxHints boxHints( QskAspect ) const;
bool setArcMetricsHint( QskAspect, const QskArcMetrics& );
bool resetArcMetricsHint( QskAspect );
QskArcMetrics arcMetricsHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setSpacingHint( QskAspect, qreal );
bool resetSpacingHint( QskAspect );
qreal spacingHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setAlignmentHint( QskAspect, Qt::Alignment );
bool resetAlignmentHint( QskAspect );
Qt::Alignment alignmentHint( QskAspect, Qt::Alignment = Qt::Alignment() ) const;
bool setFontRoleHint( QskAspect, int role );
bool resetFontRoleHint( QskAspect );
int fontRoleHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
bool setGraphicRoleHint( QskAspect, int role );
bool resetGraphicRoleHint( QskAspect );
int graphicRoleHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
2020-07-27 07:26:38 +02:00
protected:
2017-07-21 18:21:34 +02:00
virtual void updateNode( QSGNode* );
2020-12-21 16:06:58 +01:00
virtual bool isTransitionAccepted( QskAspect ) const;
2017-07-21 18:21:34 +02:00
virtual QskAspect::Subcontrol substitutedSubcontrol( QskAspect::Subcontrol ) const;
QskSkinHintTable& hintTable();
const QskSkinHintTable& hintTable() const;
2017-07-21 18:21:34 +02:00
2018-08-03 08:15:28 +02:00
private:
2020-12-21 16:06:58 +01:00
void startHintTransition( QskAspect,
QskAnimationHint, QVariant from, QVariant to );
2020-12-21 16:06:58 +01:00
QVariant animatedValue( QskAspect, QskSkinHintStatus* ) const;
const QVariant& storedHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
2017-07-21 18:21:34 +02:00
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};
template< typename T >
2020-12-21 16:06:58 +01:00
inline T QskSkinnable::flagHint( QskAspect aspect, T defaultValue ) const
2017-07-21 18:21:34 +02:00
{
2020-12-21 10:24:59 +01:00
const auto& hint = effectiveSkinHint( aspect );
2017-07-21 18:21:34 +02:00
if ( hint.isValid() && hint.canConvert< int >() )
return static_cast< T >( hint.value< int >() );
return defaultValue;
}
inline Qt::Alignment QskSkinnable::alignmentHint(
2020-12-21 16:06:58 +01:00
QskAspect aspect, Qt::Alignment defaultAlignment ) const
{
return flagHint< Qt::Alignment >( aspect | QskAspect::Alignment, defaultAlignment );
}
2020-12-21 16:06:58 +01:00
inline bool QskSkinnable::resetColor( QskAspect aspect )
2020-12-15 11:01:00 +01:00
{
2020-12-21 10:24:59 +01:00
return resetSkinHint( aspect | QskAspect::Color );
2020-12-15 11:01:00 +01:00
}
2020-12-21 16:06:58 +01:00
inline bool QskSkinnable::resetMetric( QskAspect aspect )
2020-12-15 11:01:00 +01:00
{
2020-12-21 10:24:59 +01:00
return resetSkinHint( aspect | QskAspect::Metric );
2020-12-15 11:01:00 +01:00
}
2020-12-21 16:06:58 +01:00
inline bool QskSkinnable::resetFlagHint( QskAspect aspect )
2020-12-15 11:01:00 +01:00
{
2020-12-21 10:24:59 +01:00
return resetSkinHint( aspect | QskAspect::Flag );
2020-12-15 11:01:00 +01:00
}
2017-07-21 18:21:34 +02:00
#endif