qskinny/src/controls/QskSkinHintTable.cpp

138 lines
3.8 KiB
C++
Raw Normal View History

/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskSkinHintTable.h"
QskSkinHintTable::QskSkinHintTable( bool extraAnimatorLookup ):
m_hints( nullptr ),
m_animatorAspects( nullptr )
{
if ( extraAnimatorLookup )
m_animatorAspects = new std::unordered_map< int, std::set< QskAspect::Aspect > >();
}
QskSkinHintTable::~QskSkinHintTable()
{
delete m_hints;
delete m_animatorAspects;
}
const std::set< QskAspect::Aspect >& QskSkinHintTable::animatorAspects(
QskAspect::Subcontrol subControl ) const
{
if ( m_animatorAspects )
{
auto it = m_animatorAspects->find( subControl );
if ( it != m_animatorAspects->cend() )
return it->second;
}
static std::set< QskAspect::Aspect > dummyAspects;
return dummyAspects;
}
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;
}
void QskSkinHintTable::setSkinHint( QskAspect::Aspect aspect, const QVariant& skinHint )
{
// For edges/corners, add all the implied assignments
if ( aspect.isBoxPrimitive() )
{
if ( aspect.boxPrimitive() == QskAspect::Radius )
{
setSkinHint( aspect | QskAspect::RadiusX, skinHint );
setSkinHint( aspect | QskAspect::RadiusY, skinHint );
return;
}
const auto edges = aspect.edge();
const auto bitcount = qPopulationCount( static_cast< quint8 >( edges ) );
if ( !bitcount || bitcount > 1 )
{
using namespace QskAspect;
auto aspectEdges = aspect;
aspectEdges.clearEdge();
if ( !bitcount || edges & TopEdge )
setSkinHint( aspectEdges | TopEdge, skinHint );
if ( !bitcount || ( edges & LeftEdge ) )
setSkinHint( aspectEdges | LeftEdge, skinHint );
if ( !bitcount || ( edges & RightEdge ) )
setSkinHint( aspectEdges | RightEdge, skinHint );
if ( !bitcount || ( edges & BottomEdge ) )
setSkinHint( aspectEdges | BottomEdge, skinHint );
}
if ( bitcount > 1 ) // Allows 0 to imply AllEdges
return;
}
if ( m_hints == nullptr )
m_hints = new std::remove_pointer< decltype( m_hints ) >::type;
auto it = m_hints->find( aspect );
if ( it == m_hints->end() )
{
m_hints->emplace( aspect, skinHint );
}
else if ( it->second != skinHint )
{
it->second = skinHint;
}
if ( m_animatorAspects && aspect.isAnimator() )
( *m_animatorAspects )[ aspect.subControl() ].insert( aspect );
}
void QskSkinHintTable::removeSkinHint( QskAspect::Aspect aspect )
{
if ( m_hints == nullptr )
return;
m_hints->erase( aspect );
if ( m_hints->empty() )
{
delete m_hints;
m_hints = nullptr;
}
if ( m_animatorAspects && aspect.isAnimator() )
{
auto it = m_animatorAspects->find( aspect.subControl() );
if ( it != m_animatorAspects->end() )
{
auto& aspects = it->second;
aspects.erase( aspect );
if ( aspects.empty() )
m_animatorAspects->erase( it );
}
}
}
const QVariant& QskSkinHintTable::skinHint( QskAspect::Aspect aspect ) const
{
if ( m_hints )
{
auto it = m_hints->find( aspect );
if ( it != m_hints->cend() )
return it->second;
}
static QVariant invalidHint;
return invalidHint;
}