qskinny/src/controls/QskObjectTree.h

123 lines
3.4 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_OBJECT_TREE_H
#define QSK_OBJECT_TREE_H 1
#include "QskGlobal.h"
#include "QskControl.h"
#include "QskWindow.h"
#include <QVariant>
namespace QskObjectTree
{
class Visitor
{
public:
virtual bool visitDown( QObject* object ) = 0;
virtual bool visitUp( const QObject* object ) = 0;
};
QSK_EXPORT QObjectList childNodes( const QObject* );
QSK_EXPORT QObject* parentNode( const QObject* );
QSK_EXPORT bool isRoot( const QObject* );
void traverseDown( QObject* object, Visitor& visitor );
void traverseUp( QObject* object, Visitor& visitor );
template< class T >
class ResolveVisitor : public Visitor
{
public:
ResolveVisitor( const char* propertyName ):
m_propertyName( propertyName )
{
}
inline const T& resolveValue() const
{
return m_value;
}
void setResolveValue( const T& value )
{
m_value = value;
}
virtual bool visitDown( QObject* object ) override final
{
if ( QskControl* control = qobject_cast< QskControl* >( object ) )
return setImplicitValue( control, m_value );
if ( QskWindow* window = qobject_cast< QskWindow* >( object ) )
return setImplicitValue( window, m_value );
return !setProperty( object, m_propertyName.constData(), m_value );
}
virtual bool visitUp( const QObject* object ) override final
{
if ( isRoot( object ) )
return true;
if ( const QskControl* control = qobject_cast< const QskControl* >( object ) )
{
m_value = value( control );
return true;
}
if ( const QskWindow* window = qobject_cast< const QskWindow* >( object ) )
{
m_value = value( window );
return true;
}
return getProperty( object, m_propertyName, m_value );
}
private:
inline bool getProperty(
const QObject* object, const char* name, T& value ) const
{
if ( !m_propertyName.isEmpty() )
{
const QVariant v = object->property( name );
if ( v.canConvert< T >() )
{
value = qvariant_cast< T >( v );
return true;
}
}
return false;
}
inline bool setProperty(
QObject* object, const char* name, const T& value ) const
{
T oldValue;
if ( !getProperty( object, name, oldValue ) || oldValue == value )
return false;
object->setProperty( name, value );
return true;
}
virtual bool setImplicitValue( QskControl*, const T& ) = 0;
virtual bool setImplicitValue( QskWindow*, const T& ) = 0;
virtual T value( const QskControl* ) const = 0;
virtual T value( const QskWindow* ) const = 0;
private:
const QByteArray m_propertyName;
T m_value;
};
}
#endif