2017-08-22 20:50:55 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "QskSkinHintTable.h"
|
|
|
|
|
2017-10-17 17:34:00 +02:00
|
|
|
QVariant QskSkinHintTable::invalidHint;
|
|
|
|
|
|
|
|
inline const QVariant* qskResolvedHint( QskAspect::Aspect aspect,
|
|
|
|
const std::unordered_map< QskAspect::Aspect, QVariant >& hints,
|
|
|
|
QskAspect::Aspect* resolvedAspect )
|
|
|
|
{
|
|
|
|
const auto a = aspect;
|
|
|
|
|
|
|
|
Q_FOREVER
|
|
|
|
{
|
|
|
|
auto it = hints.find( aspect );
|
|
|
|
if ( it != hints.cend() )
|
|
|
|
{
|
|
|
|
if ( resolvedAspect )
|
|
|
|
*resolvedAspect = aspect;
|
|
|
|
|
|
|
|
return &it->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( const auto topState = aspect.topState() )
|
|
|
|
{
|
|
|
|
aspect.clearState( topState );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( aspect.placement() )
|
|
|
|
{
|
2019-04-17 16:33:17 +02:00
|
|
|
// clear the placement bits and restart
|
2017-10-17 17:34:00 +02:00
|
|
|
aspect = a;
|
2019-04-17 16:33:17 +02:00
|
|
|
aspect.setPlacement( QskAspect::NoPlacement );
|
2017-10-17 17:34:00 +02:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
QskSkinHintTable::QskSkinHintTable()
|
|
|
|
: m_hints( nullptr )
|
|
|
|
, m_animatorCount( 0 )
|
|
|
|
, m_hasStates( false )
|
2017-10-17 17:34:00 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-08-03 08:15:28 +02:00
|
|
|
QskSkinHintTable::QskSkinHintTable( const QskSkinHintTable& other )
|
|
|
|
: m_hints( nullptr )
|
|
|
|
, m_animatorCount( other.m_animatorCount )
|
|
|
|
, m_hasStates( other.m_hasStates )
|
2017-08-22 20:50:55 +02:00
|
|
|
{
|
2017-10-17 17:34:00 +02:00
|
|
|
if ( other.m_hints )
|
2018-08-03 08:15:28 +02:00
|
|
|
m_hints = new HintMap( *( other.m_hints ) );
|
2017-08-22 20:50:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QskSkinHintTable::~QskSkinHintTable()
|
|
|
|
{
|
|
|
|
delete m_hints;
|
|
|
|
}
|
|
|
|
|
2017-10-17 17:34:00 +02:00
|
|
|
QskSkinHintTable& QskSkinHintTable::operator=( const QskSkinHintTable& other )
|
2017-08-22 20:50:55 +02:00
|
|
|
{
|
2017-10-17 17:34:00 +02:00
|
|
|
m_animatorCount = other.m_animatorCount;
|
|
|
|
m_hasStates = other.m_hasStates;
|
|
|
|
|
|
|
|
if ( other.m_hints )
|
|
|
|
{
|
|
|
|
if ( m_hints == nullptr )
|
|
|
|
m_hints = new HintMap();
|
|
|
|
|
|
|
|
*m_hints = *other.m_hints;
|
|
|
|
}
|
|
|
|
else
|
2017-08-22 20:50:55 +02:00
|
|
|
{
|
2017-10-17 17:34:00 +02:00
|
|
|
delete m_hints;
|
|
|
|
m_hints = nullptr;
|
2017-08-22 20:50:55 +02:00
|
|
|
}
|
|
|
|
|
2017-10-17 17:34:00 +02:00
|
|
|
return *this;
|
2017-08-22 20:50:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const std::unordered_map< QskAspect::Aspect, QVariant >& QskSkinHintTable::hints() const
|
|
|
|
{
|
|
|
|
if ( m_hints )
|
|
|
|
return *m_hints;
|
|
|
|
|
|
|
|
static std::unordered_map< QskAspect::Aspect, QVariant > dummyHints;
|
|
|
|
return dummyHints;
|
|
|
|
}
|
|
|
|
|
2017-10-17 17:34:00 +02:00
|
|
|
void QskSkinHintTable::setHint( QskAspect::Aspect aspect, const QVariant& skinHint )
|
2017-08-22 20:50:55 +02:00
|
|
|
{
|
|
|
|
if ( m_hints == nullptr )
|
2017-10-17 17:34:00 +02:00
|
|
|
m_hints = new HintMap();
|
2017-08-22 20:50:55 +02:00
|
|
|
|
|
|
|
auto it = m_hints->find( aspect );
|
|
|
|
if ( it == m_hints->end() )
|
|
|
|
{
|
|
|
|
m_hints->emplace( aspect, skinHint );
|
2017-10-17 17:34:00 +02:00
|
|
|
if ( aspect.isAnimator() )
|
|
|
|
m_animatorCount++;
|
2017-08-22 20:50:55 +02:00
|
|
|
}
|
|
|
|
else if ( it->second != skinHint )
|
|
|
|
{
|
|
|
|
it->second = skinHint;
|
|
|
|
}
|
|
|
|
|
2017-10-17 17:34:00 +02:00
|
|
|
if ( aspect.state() )
|
|
|
|
m_hasStates = true;
|
2017-08-22 20:50:55 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 08:14:53 +02:00
|
|
|
bool QskSkinHintTable::removeHint( QskAspect::Aspect aspect )
|
2017-08-22 20:50:55 +02:00
|
|
|
{
|
|
|
|
if ( m_hints == nullptr )
|
2019-05-16 08:14:53 +02:00
|
|
|
return false;
|
2017-08-22 20:50:55 +02:00
|
|
|
|
2019-05-16 08:14:53 +02:00
|
|
|
const bool erased = m_hints->erase( aspect );
|
|
|
|
|
|
|
|
if ( erased )
|
2017-08-22 20:50:55 +02:00
|
|
|
{
|
2017-10-17 17:34:00 +02:00
|
|
|
if ( aspect.isAnimator() )
|
|
|
|
m_animatorCount--;
|
2018-08-03 08:15:28 +02:00
|
|
|
|
2017-10-17 17:34:00 +02:00
|
|
|
if ( m_hints->empty() )
|
2017-08-22 20:50:55 +02:00
|
|
|
{
|
2017-10-17 17:34:00 +02:00
|
|
|
delete m_hints;
|
|
|
|
m_hints = nullptr;
|
2017-08-22 20:50:55 +02:00
|
|
|
}
|
|
|
|
}
|
2019-05-16 08:14:53 +02:00
|
|
|
|
|
|
|
return erased;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant QskSkinHintTable::takeHint( QskAspect::Aspect aspect )
|
|
|
|
{
|
|
|
|
if ( m_hints )
|
|
|
|
{
|
|
|
|
auto it = m_hints->find( aspect );
|
|
|
|
if ( it != m_hints->end() )
|
|
|
|
{
|
|
|
|
const auto value = it->second;
|
|
|
|
m_hints->erase( it );
|
|
|
|
|
|
|
|
if ( aspect.isAnimator() )
|
|
|
|
m_animatorCount--;
|
|
|
|
|
|
|
|
if ( m_hints->empty() )
|
|
|
|
{
|
|
|
|
delete m_hints;
|
|
|
|
m_hints = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return QVariant();
|
2017-08-22 20:50:55 +02:00
|
|
|
}
|
|
|
|
|
2017-10-17 17:34:00 +02:00
|
|
|
void QskSkinHintTable::clear()
|
2017-08-22 20:50:55 +02:00
|
|
|
{
|
2017-10-17 17:34:00 +02:00
|
|
|
delete m_hints;
|
|
|
|
m_hints = nullptr;
|
|
|
|
|
|
|
|
m_animatorCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QVariant* QskSkinHintTable::resolvedHint(
|
|
|
|
QskAspect::Aspect aspect, QskAspect::Aspect* resolvedAspect ) const
|
|
|
|
{
|
|
|
|
if ( m_hints != nullptr )
|
|
|
|
return qskResolvedHint( aspect, *m_hints, resolvedAspect );
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
QskAspect::Aspect QskSkinHintTable::resolvedAspect( QskAspect::Aspect aspect ) const
|
|
|
|
{
|
|
|
|
QskAspect::Aspect a;
|
|
|
|
|
|
|
|
if ( m_hints != nullptr )
|
|
|
|
qskResolvedHint( aspect, *m_hints, &a );
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
QskAspect::Aspect QskSkinHintTable::resolvedAnimator(
|
|
|
|
QskAspect::Aspect aspect, QskAnimationHint& hint ) const
|
|
|
|
{
|
|
|
|
if ( m_hints && m_animatorCount > 0 )
|
2017-08-22 20:50:55 +02:00
|
|
|
{
|
2017-10-17 17:34:00 +02:00
|
|
|
Q_FOREVER
|
|
|
|
{
|
|
|
|
auto it = m_hints->find( aspect );
|
|
|
|
if ( it != m_hints->cend() )
|
|
|
|
{
|
|
|
|
hint = it->second.value< QskAnimationHint >();
|
|
|
|
return aspect;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( const auto topState = aspect.topState() )
|
|
|
|
aspect.clearState( topState );
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
2017-08-22 20:50:55 +02:00
|
|
|
}
|
|
|
|
|
2017-10-17 17:34:00 +02:00
|
|
|
return QskAspect::Aspect();
|
2017-08-22 20:50:55 +02:00
|
|
|
}
|