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 "QskControl.h"
#include "QskWindow.h"
2018-07-19 14:10:48 +02:00
#include <qvariant.h>
2017-07-21 18:21:34 +02:00
namespace QskObjectTree
{
class Visitor
{
2018-08-03 08:15:28 +02:00
public:
2017-12-07 17:04:05 +01:00
virtual ~Visitor() = default;
2017-07-21 18:21:34 +02:00
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
{
2018-08-03 08:15:28 +02:00
public:
ResolveVisitor( const char* propertyName )
: m_propertyName( propertyName )
2017-07-21 18:21:34 +02:00
{
}
inline const T& resolveValue() const
{
return m_value;
}
void setResolveValue( const T& value )
{
m_value = value;
}
2018-07-31 17:32:25 +02:00
bool visitDown( QObject* object ) override final
2017-07-21 18:21:34 +02:00
{
if ( auto control = qobject_cast< QskControl* >( object ) )
2017-07-21 18:21:34 +02:00
return setImplicitValue( control, m_value );
if ( auto window = qobject_cast< QskWindow* >( object ) )
2018-08-03 08:15:28 +02:00
return setImplicitValue( window, m_value );
2017-07-21 18:21:34 +02:00
return !setProperty( object, m_propertyName.constData(), m_value );
}
2018-07-31 17:32:25 +02:00
bool visitUp( const QObject* object ) override final
2017-07-21 18:21:34 +02:00
{
if ( isRoot( object ) )
return true;
if ( auto control = qobject_cast< const QskControl* >( object ) )
2017-07-21 18:21:34 +02:00
{
m_value = value( control );
return true;
}
if ( auto window = qobject_cast< const QskWindow* >( object ) )
2017-07-21 18:21:34 +02:00
{
m_value = value( window );
return true;
}
return getProperty( object, m_propertyName, m_value );
}
2018-08-03 08:15:28 +02:00
private:
inline bool getProperty( const QObject* object,
const char* name, T& value ) const
2017-07-21 18:21:34 +02:00
{
if ( !m_propertyName.isEmpty() )
{
const QVariant v = object->property( name );
if ( v.canConvert< T >() )
{
value = qvariant_cast< T >( v );
return true;
}
}
return false;
}
2018-08-03 08:15:28 +02:00
inline bool setProperty( QObject* object,
const char* name, const T& value ) const
2017-07-21 18:21:34 +02:00
{
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;
2018-08-03 08:15:28 +02:00
private:
2017-07-21 18:21:34 +02:00
const QByteArray m_propertyName;
T m_value;
};
}
#endif