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
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "QskSetup.h"
|
2018-08-03 08:15:28 +02:00
|
|
|
#include "QskControl.h"
|
2019-09-04 06:59:43 +02:00
|
|
|
#include "QskControlPrivate.h"
|
2018-08-03 08:15:28 +02:00
|
|
|
#include "QskGraphicProviderMap.h"
|
2017-07-21 18:21:34 +02:00
|
|
|
#include "QskSkin.h"
|
2018-01-03 11:57:05 +01:00
|
|
|
#include "QskSkinManager.h"
|
2017-07-21 18:21:34 +02:00
|
|
|
#include "QskWindow.h"
|
|
|
|
|
2018-07-19 14:10:48 +02:00
|
|
|
#include <qguiapplication.h>
|
2018-08-03 08:15:28 +02:00
|
|
|
#include <qpointer.h>
|
2018-07-19 14:10:48 +02:00
|
|
|
#include <qstylehints.h>
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
QskSetup* QskSetup::s_instance = nullptr;
|
|
|
|
|
|
|
|
static inline bool qskHasEnvironment( const char* env )
|
|
|
|
{
|
|
|
|
bool ok;
|
|
|
|
|
|
|
|
const int value = qEnvironmentVariableIntValue( env, &ok );
|
|
|
|
if ( ok )
|
|
|
|
return value != 0;
|
|
|
|
|
|
|
|
// All other strings are true, apart from "false"
|
|
|
|
auto result = qgetenv( env );
|
|
|
|
return !result.isEmpty() && result != "false";
|
|
|
|
}
|
|
|
|
|
2021-02-09 08:13:20 +01:00
|
|
|
static inline const QskQuickItem::UpdateFlags qskEnvironmentUpdateFlags()
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
QskQuickItem::UpdateFlags flags;
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
if ( qskHasEnvironment( "QSK_PREFER_RASTER" ) )
|
2021-02-09 08:13:20 +01:00
|
|
|
flags |= QskQuickItem::PreferRasterForTextures;
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
if ( qskHasEnvironment( "QSK_FORCE_BACKGROUND" ) )
|
2021-02-09 08:13:20 +01:00
|
|
|
flags |= QskQuickItem::DebugForceBackground;
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
2021-02-09 08:13:20 +01:00
|
|
|
static inline QskQuickItem::UpdateFlags qskDefaultUpdateFlags()
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
static QskQuickItem::UpdateFlags flags;
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
if ( flags == 0 )
|
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
flags |= QskQuickItem::DeferredUpdate;
|
|
|
|
flags |= QskQuickItem::DeferredPolish;
|
|
|
|
flags |= QskQuickItem::DeferredLayout;
|
|
|
|
flags |= QskQuickItem::CleanupOnVisibility;
|
|
|
|
flags |= qskEnvironmentUpdateFlags();
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void qskApplicationHook()
|
|
|
|
{
|
|
|
|
QskSetup::setup();
|
|
|
|
qAddPostRoutine( QskSetup::cleanup );
|
|
|
|
}
|
|
|
|
|
2017-10-24 19:32:54 +02:00
|
|
|
static void qskApplicationFilter()
|
|
|
|
{
|
|
|
|
QCoreApplication::instance()->installEventFilter( QskSetup::instance() );
|
|
|
|
}
|
|
|
|
|
2017-07-21 18:21:34 +02:00
|
|
|
Q_CONSTRUCTOR_FUNCTION( qskApplicationHook )
|
2017-10-24 19:32:54 +02:00
|
|
|
Q_COREAPP_STARTUP_FUNCTION( qskApplicationFilter )
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
class QskSetup::PrivateData
|
|
|
|
{
|
2018-08-03 08:15:28 +02:00
|
|
|
public:
|
|
|
|
PrivateData()
|
2021-02-09 08:13:20 +01:00
|
|
|
: itemUpdateFlags( qskDefaultUpdateFlags() )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QString skinName;
|
|
|
|
QPointer< QskSkin > skin;
|
|
|
|
|
|
|
|
QskGraphicProviderMap graphicProviders;
|
2021-02-09 08:13:20 +01:00
|
|
|
QskQuickItem::UpdateFlags itemUpdateFlags;
|
2017-07-21 18:21:34 +02:00
|
|
|
};
|
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
QskSetup::QskSetup()
|
|
|
|
: m_data( new PrivateData() )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QskSetup::~QskSetup()
|
|
|
|
{
|
|
|
|
s_instance = nullptr; // we might be destroyed from Qml !
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSetup::setup()
|
|
|
|
{
|
|
|
|
if ( s_instance == nullptr )
|
|
|
|
s_instance = new QskSetup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSetup::cleanup()
|
|
|
|
{
|
2021-01-12 16:25:33 +01:00
|
|
|
delete s_instance;
|
|
|
|
s_instance = nullptr;
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
2021-02-09 08:13:20 +01:00
|
|
|
void QskSetup::setItemUpdateFlags( QskQuickItem::UpdateFlags flags )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
if ( m_data->itemUpdateFlags != flags )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
m_data->itemUpdateFlags = flags;
|
|
|
|
Q_EMIT itemUpdateFlagsChanged();
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-09 08:13:20 +01:00
|
|
|
QskQuickItem::UpdateFlags QskSetup::itemUpdateFlags() const
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
return m_data->itemUpdateFlags;
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
2021-02-09 08:13:20 +01:00
|
|
|
void QskSetup::resetItemUpdateFlags()
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
setItemUpdateFlags( qskDefaultUpdateFlags() );
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
2021-02-09 08:13:20 +01:00
|
|
|
void QskSetup::setItemUpdateFlag( QskQuickItem::UpdateFlag flag, bool on )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
if ( m_data->itemUpdateFlags.testFlag( flag ) != on )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
|
|
|
if ( on )
|
2021-02-09 08:13:20 +01:00
|
|
|
m_data->itemUpdateFlags |= flag;
|
2017-07-21 18:21:34 +02:00
|
|
|
else
|
2021-02-09 08:13:20 +01:00
|
|
|
m_data->itemUpdateFlags &= ~flag;
|
2017-07-21 18:21:34 +02:00
|
|
|
|
2021-02-09 08:13:20 +01:00
|
|
|
Q_EMIT itemUpdateFlagsChanged();
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-09 08:13:20 +01:00
|
|
|
void QskSetup::resetItemUpdateFlag( QskQuickItem::UpdateFlag flag )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
setItemUpdateFlag( flag, flag & qskDefaultUpdateFlags() );
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
2021-02-09 08:13:20 +01:00
|
|
|
bool QskSetup::testItemUpdateFlag( QskQuickItem::UpdateFlag flag )
|
2017-07-21 18:21:34 +02:00
|
|
|
{
|
2021-02-09 08:13:20 +01:00
|
|
|
return m_data->itemUpdateFlags.testFlag( flag );
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QskSkin* QskSetup::setSkin( const QString& skinName )
|
|
|
|
{
|
|
|
|
if ( m_data->skin && ( skinName == m_data->skinName ) )
|
|
|
|
return m_data->skin;
|
|
|
|
|
2021-07-14 14:43:12 +02:00
|
|
|
auto skin = QskSkinManager::instance()->createSkin( skinName );
|
2017-07-21 18:21:34 +02:00
|
|
|
if ( skin == nullptr )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
if ( skin->parent() == nullptr )
|
|
|
|
skin->setParent( this );
|
|
|
|
|
2021-07-14 14:43:12 +02:00
|
|
|
const auto oldSkin = m_data->skin;
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
m_data->skin = skin;
|
|
|
|
m_data->skinName = skinName;
|
|
|
|
|
|
|
|
if ( oldSkin )
|
|
|
|
{
|
|
|
|
Q_EMIT skinChanged( skin );
|
|
|
|
|
|
|
|
if ( oldSkin->parent() == this )
|
|
|
|
delete oldSkin;
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_data->skin;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString QskSetup::skinName() const
|
|
|
|
{
|
|
|
|
return m_data->skinName;
|
|
|
|
}
|
|
|
|
|
|
|
|
QskSkin* QskSetup::skin()
|
|
|
|
{
|
|
|
|
if ( m_data->skin == nullptr )
|
|
|
|
{
|
2018-01-16 20:34:54 +01:00
|
|
|
m_data->skin = QskSkinManager::instance()->createSkin( QString() );
|
2018-01-03 11:57:05 +01:00
|
|
|
Q_ASSERT( m_data->skin );
|
|
|
|
|
2017-07-21 18:21:34 +02:00
|
|
|
m_data->skin->setParent( this );
|
|
|
|
m_data->skinName = m_data->skin->objectName();
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_data->skin;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSetup::addGraphicProvider( const QString& providerId, QskGraphicProvider* provider )
|
|
|
|
{
|
|
|
|
m_data->graphicProviders.insert( providerId, provider );
|
2017-10-24 19:32:54 +02:00
|
|
|
}
|
2017-07-21 18:21:34 +02:00
|
|
|
|
|
|
|
QskGraphicProvider* QskSetup::graphicProvider( const QString& providerId ) const
|
|
|
|
{
|
|
|
|
if ( m_data->skin )
|
|
|
|
{
|
|
|
|
QskGraphicProvider* provider = m_data->skin->graphicProvider( providerId );
|
|
|
|
if ( provider )
|
|
|
|
return provider;
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_data->graphicProviders.provider( providerId );
|
2017-10-24 19:32:54 +02:00
|
|
|
}
|
2017-07-21 18:21:34 +02:00
|
|
|
|
2017-10-24 19:32:54 +02:00
|
|
|
bool QskSetup::eventFilter( QObject* object, QEvent* event )
|
|
|
|
{
|
2019-04-26 11:56:09 +02:00
|
|
|
if ( auto control = qskControlCast( object ) )
|
2017-10-24 19:32:54 +02:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
Qt::FocusPolicy has always been there with widgets, got lost with
|
|
|
|
Qt/Quick and has been reintroduced with Qt/Quick Controls 2 ( QC2 ).
|
|
|
|
Unfortunately this was done once more by adding code on top instead
|
|
|
|
of fixing the foundation.
|
|
|
|
|
|
|
|
But we also don't want to have how it is done in QC2 by adding
|
|
|
|
the focus management in the event handler of the base class.
|
2018-01-19 10:07:05 +01:00
|
|
|
This implementation reverts the expected default behaviour of when
|
2017-10-24 19:32:54 +02:00
|
|
|
events are accepted/ignored + is an error prone nightmare, when it
|
|
|
|
comes to overloading event handlers missing to call the base class.
|
|
|
|
|
|
|
|
That's why we prefer to do the focus management outside of the
|
|
|
|
event handlers.
|
|
|
|
*/
|
2018-08-03 08:15:28 +02:00
|
|
|
switch ( event->type() )
|
2017-10-24 19:32:54 +02:00
|
|
|
{
|
|
|
|
case QEvent::MouseButtonPress:
|
|
|
|
case QEvent::MouseButtonRelease:
|
|
|
|
{
|
|
|
|
if ( ( control->focusPolicy() & Qt::ClickFocus ) == Qt::ClickFocus )
|
|
|
|
{
|
|
|
|
const bool focusOnRelease =
|
|
|
|
QGuiApplication::styleHints()->setFocusOnTouchRelease();
|
|
|
|
|
|
|
|
if ( focusOnRelease )
|
|
|
|
{
|
|
|
|
if ( event->type() == QEvent::MouseButtonRelease )
|
|
|
|
control->forceActiveFocus( Qt::MouseFocusReason );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( event->type() == QEvent::MouseButtonPress )
|
|
|
|
control->forceActiveFocus( Qt::MouseFocusReason );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QEvent::Wheel:
|
|
|
|
{
|
|
|
|
if ( !control->isWheelEnabled() )
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
We block further processing of the event. This is in line
|
|
|
|
with not receiving any mouse event that have not been
|
|
|
|
explicitly enabled with setAcceptedMouseButtons().
|
|
|
|
|
|
|
|
*/
|
|
|
|
event->ignore();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ( control->focusPolicy() & Qt::WheelFocus ) == Qt::WheelFocus )
|
|
|
|
control->forceActiveFocus( Qt::MouseFocusReason );
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-07-21 18:21:34 +02:00
|
|
|
QskSetup* QskSetup::qmlAttachedProperties( QObject* )
|
|
|
|
{
|
|
|
|
return QskSetup::instance();
|
|
|
|
}
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE( QskSkin* )
|
|
|
|
#include "moc_QskSetup.cpp"
|