8#include "QskAnimationHint.h"
10#include "QskColorFilter.h"
11#include "QskGraphic.h"
12#include "QskGraphicProviderMap.h"
13#include "QskStandardSymbol.h"
14#include "QskPlatform.h"
15#include "QskMargins.h"
16#include "QskFontRole.h"
18#include "QskSkinHintTable.h"
19#include "QskSkinManager.h"
20#include "QskSkinTransition.h"
22#include <qguiapplication.h>
23#include <qpa/qplatformdialoghelper.h>
24#include <qpa/qplatformtheme.h>
29#include "QskBoxSkinlet.h"
31#include "QskCheckBox.h"
32#include "QskCheckBoxSkinlet.h"
34#include "QskComboBox.h"
35#include "QskComboBoxSkinlet.h"
38#include "QskDrawerSkinlet.h"
40#include "QskFocusIndicator.h"
41#include "QskFocusIndicatorSkinlet.h"
43#include "QskGraphicLabel.h"
44#include "QskGraphicLabelSkinlet.h"
46#include "QskListView.h"
47#include "QskListViewSkinlet.h"
50#include "QskMenuSkinlet.h"
52#include "QskPageIndicator.h"
53#include "QskPageIndicatorSkinlet.h"
56#include "QskPopupSkinlet.h"
58#include "QskProgressBar.h"
59#include "QskProgressBarSkinlet.h"
61#include "QskProgressRing.h"
62#include "QskProgressRingSkinlet.h"
64#include "QskRadioBox.h"
65#include "QskRadioBoxSkinlet.h"
67#include "QskPushButton.h"
68#include "QskPushButtonSkinlet.h"
70#include "QskScrollView.h"
71#include "QskScrollViewSkinlet.h"
73#include "QskSegmentedBar.h"
74#include "QskSegmentedBarSkinlet.h"
76#include "QskSeparator.h"
77#include "QskSeparatorSkinlet.h"
80#include "QskSliderSkinlet.h"
82#include "QskSpinBox.h"
83#include "QskSpinBoxSkinlet.h"
85#include "QskSubWindow.h"
86#include "QskSubWindowSkinlet.h"
88#include "QskSubWindowArea.h"
89#include "QskSubWindowAreaSkinlet.h"
91#include "QskSwitchButton.h"
92#include "QskSwitchButtonSkinlet.h"
94#include "QskTabButton.h"
95#include "QskTabButtonSkinlet.h"
97#include "QskTabView.h"
98#include "QskTabViewSkinlet.h"
100#include "QskTextLabel.h"
101#include "QskTextLabelSkinlet.h"
103#include "QskTextInput.h"
104#include "QskTextInputSkinlet.h"
106#include "QskStatusIndicator.h"
107#include "QskStatusIndicatorSkinlet.h"
111static inline QskSkinlet* qskNewSkinlet(
const QMetaObject* metaObject,
QskSkin* skin )
113 const QByteArray signature = metaObject->className() + QByteArrayLiteral(
"(QskSkin*)" );
117 const int index = metaObject->indexOfConstructor( signature.constData() );
120 void* param[] = { &skinlet, &skin };
121 metaObject->static_metacall( QMetaObject::CreateInstance, index, param );
129QFont qskResolvedFont(
const QHash< QskFontRole, QFont >& fontTable,
132 auto it = fontTable.constFind( fontRole );
133 if ( it != fontTable.constEnd() )
137 if ( it != fontTable.constEnd() )
140 return QGuiApplication::font();
148 SkinletData(
const QMetaObject* metaObject )
149 : metaObject( metaObject )
159 const QMetaObject* metaObject;
164class QskSkin::PrivateData
167 QHash< const QMetaObject*, SkinletData > skinletMap;
171 QHash< QskFontRole, QFont > fonts;
172 QHash< int, QskColorFilter > graphicFilters;
176 int colorScheme = -1;
179QskSkin::QskSkin( QObject* parent )
181 , m_data( new PrivateData() )
183 declareSkinlet< QskControl, QskSkinlet >();
185 declareSkinlet< QskBox, QskBoxSkinlet >();
186 declareSkinlet< QskCheckBox, QskCheckBoxSkinlet >();
187 declareSkinlet< QskComboBox, QskComboBoxSkinlet >();
188 declareSkinlet< QskDrawer, QskDrawerSkinlet >();
189 declareSkinlet< QskFocusIndicator, QskFocusIndicatorSkinlet >();
190 declareSkinlet< QskGraphicLabel, QskGraphicLabelSkinlet >();
191 declareSkinlet< QskListView, QskListViewSkinlet >();
192 declareSkinlet< QskPageIndicator, QskPageIndicatorSkinlet >();
193 declareSkinlet< QskPopup, QskPopupSkinlet >();
194 declareSkinlet< QskMenu, QskMenuSkinlet >();
195 declareSkinlet< QskPushButton, QskPushButtonSkinlet >();
196 declareSkinlet< QskScrollView, QskScrollViewSkinlet >();
197 declareSkinlet< QskSegmentedBar, QskSegmentedBarSkinlet >();
198 declareSkinlet< QskSeparator, QskSeparatorSkinlet >();
199 declareSkinlet< QskSlider, QskSliderSkinlet >();
200 declareSkinlet< QskSpinBox, QskSpinBoxSkinlet >();
201 declareSkinlet< QskStatusIndicator, QskStatusIndicatorSkinlet >();
202 declareSkinlet< QskSubWindow, QskSubWindowSkinlet >();
203 declareSkinlet< QskSubWindowArea, QskSubWindowAreaSkinlet >();
204 declareSkinlet< QskSwitchButton, QskSwitchButtonSkinlet >();
205 declareSkinlet< QskTabButton, QskTabButtonSkinlet >();
206 declareSkinlet< QskTabView, QskTabViewSkinlet >();
207 declareSkinlet< QskTextLabel, QskTextLabelSkinlet >();
208 declareSkinlet< QskTextInput, QskTextInputSkinlet >();
209 declareSkinlet< QskProgressBar, QskProgressBarSkinlet >();
210 declareSkinlet< QskProgressRing, QskProgressRingSkinlet >();
211 declareSkinlet< QskRadioBox, QskRadioBoxSkinlet >();
213 const QFont font = QGuiApplication::font();
214 setupFontTable( font.family(), font.italic() );
216 const auto noMargins = QVariant::fromValue(
QskMargins( 0 ) );
237QskSkin::ColorScheme QskSkin::colorScheme()
const
239 if ( m_data->colorScheme < 0 )
240 return QskSkin::UnknownScheme;
242 return static_cast< QskSkin::ColorScheme
>( m_data->colorScheme );
245void QskSkin::setColorScheme( ColorScheme colorScheme )
247 if ( colorScheme == m_data->colorScheme )
250 m_data->colorScheme = colorScheme;
252 const auto transitionHint = qskSkinManager->transitionHint();
253 if ( transitionHint.isValid() )
256 transition.setMask( QskSkinTransition::Color );
257 transition.setSourceSkin(
this );
262 transition.setTargetSkin(
this );
263 transition.run( transitionHint );
271 Q_EMIT colorSchemeChanged( colorScheme );
274void QskSkin::setSkinHint(
QskAspect aspect,
const QVariant& skinHint )
276 m_data->hintTable.setHint( aspect, skinHint );
279const QVariant& QskSkin::skinHint(
QskAspect aspect )
const
281 return m_data->hintTable.hint( aspect );
284void QskSkin::declareSkinlet(
const QMetaObject* metaObject,
285 const QMetaObject* skinletMetaObject )
287 Q_ASSERT( skinletMetaObject->constructorCount() );
289 const auto it = m_data->skinletMap.find( metaObject );
291 if ( it != m_data->skinletMap.end() )
293 auto& entry = it.value();
294 if ( entry.metaObject != skinletMetaObject )
296 entry.metaObject = skinletMetaObject;
298 delete entry.skinlet;
299 entry.skinlet =
nullptr;
304 m_data->skinletMap.insert( metaObject, skinletMetaObject );
308static inline void qskSetFont(
QskSkin* skin,
309 QskFontRole::Category category, QFont font, qreal pointSize )
311 font.setPointSize( pointSize );
312 skin->setFont( { category, QskFontRole::Normal }, font );
315void QskSkin::setupFontTable(
const QString& family,
bool italic )
317 QFont font( family );
318 font.setItalic( italic );
319 font.setWeight( QFont::Normal );
321 qskSetFont(
this, QskFontRole::Caption, font, 8 );
322 qskSetFont(
this, QskFontRole::Subtitle, font, 10 );
323 qskSetFont(
this, QskFontRole::Body, font, 12 );
324 qskSetFont(
this, QskFontRole::Title, font, 20 );
325 qskSetFont(
this, QskFontRole::Headline, font, 30 );
326 qskSetFont(
this, QskFontRole::Display, font, 48 );
331void QskSkin::completeFontTable()
335 for (
int i = QskFontRole::Caption; i <= QskFontRole::Display; i++ )
337 auto& table = m_data->fonts;
339 const auto category =
static_cast< QskFontRole::Category
>( i );
341 const auto it = table.constFind( { category, QskFontRole::Normal } );
342 if ( it == table.constEnd() )
345 const auto normalFont = it.value();
347 for (
int j = QskFontRole::VeryLow; j <= QskFontRole::VeryHigh; j++ )
349 const auto emphasis =
static_cast< QskFontRole::Emphasis
>( j );
351 if ( emphasis == QskFontRole::Normal
352 || table.contains( { category, emphasis } ) )
357#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
358 const auto step = 10;
360 const auto step = 100;
363 int weight = normalFont.weight() + ( j - 2 ) * step;
364 weight = qBound(
static_cast<int>( QFont::Thin ),
365 weight,
static_cast<int>( QFont::Black ) );
367 auto font = normalFont;
368 font.setWeight(
static_cast< QFont::Weight
>( weight ) );
370 m_data->fonts[ { category, emphasis } ] = font;
375void QskSkin::setFont(
const QskFontRole& fontRole,
const QFont& font )
377 m_data->fonts[ fontRole ] = font;
380void QskSkin::resetFont(
const QskFontRole& fontRole )
382 m_data->fonts.remove( fontRole );
385QFont QskSkin::font(
const QskFontRole& fontRole )
const
387 return qskResolvedFont( m_data->fonts, fontRole );
390void QskSkin::setGraphicFilter(
int graphicRole,
const QskColorFilter& colorFilter )
392 m_data->graphicFilters[ graphicRole ] = colorFilter;
395void QskSkin::resetGraphicFilter(
int graphicRole )
397 m_data->graphicFilters.remove( graphicRole );
402 return m_data->graphicFilters.value( graphicRole );
407 return m_data->hintTable;
412 return m_data->hintTable;
415const QHash< QskFontRole, QFont >& QskSkin::fontTable()
const
417 return m_data->fonts;
420const QHash< int, QskColorFilter >& QskSkin::graphicFilters()
const
422 return m_data->graphicFilters;
425void QskSkin::addGraphicProvider(
428 m_data->graphicProviders.insert( providerId, provider );
433 return m_data->graphicProviders.provider( providerId );
436bool QskSkin::hasGraphicProvider()
const
438 return m_data->graphicProviders.size() > 0;
441void QskSkin::clearHints()
443 m_data->hintTable.clear();
444 m_data->fonts.clear();
445 m_data->graphicFilters.clear();
446 m_data->graphicProviders.clear();
449QString QskSkin::dialogButtonText(
int action )
const
451 const auto theme = qskPlatformTheme();
453 auto text = theme->standardButtonText( action );
454 text = QPlatformTheme::removeMnemonics( text );
459const int* QskSkin::dialogButtonLayout( Qt::Orientation orientation )
const
462 auto policy = QPlatformDialogHelper::WinLayout;
464 if (
const auto theme = qskPlatformTheme() )
466 const QVariant v = theme->themeHint( QPlatformTheme::DialogButtonBoxLayout );
467 policy =
static_cast< QPlatformDialogHelper::ButtonLayout
>( v.toInt() );
470 return QPlatformDialogHelper::buttonLayout( orientation, policy );
473const QMetaObject* QskSkin::skinletMetaObject(
const QMetaObject* metaObject )
const
477 auto it = m_data->skinletMap.constFind( metaObject );
478 if ( it != m_data->skinletMap.constEnd() )
479 return it.value().metaObject;
481 metaObject = metaObject->superClass();
487QskSkinlet* QskSkin::skinlet(
const QMetaObject* metaObject )
491 auto it = m_data->skinletMap.find( metaObject );
492 if ( it != m_data->skinletMap.end() )
494 auto& entry = it.value();
496 if ( entry.skinlet ==
nullptr )
497 entry.skinlet = qskNewSkinlet( entry.metaObject,
this );
499 return entry.skinlet;
502 metaObject = metaObject->superClass();
506 return &defaultSkinlet;
509#include "moc_QskSkin.cpp"
Lookup key for a QskSkinHintTable.
Describes the rendering interface of a QskControl. Change the skinlet to change the appearance of the...