statemachine: Use new QQmlListProperty capabilities
Change-Id: Ic471ba4f82bdf1ac63953927d0a83f514d0e49d0 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
96d2c71c88
commit
053547fba7
|
@ -46,54 +46,142 @@
|
|||
#include <QQmlInfo>
|
||||
#include <QQmlListProperty>
|
||||
|
||||
template <class T>
|
||||
enum class ChildrenMode {
|
||||
None = 0x0,
|
||||
State = 0x1,
|
||||
Transition = 0x2,
|
||||
StateOrTransition = State | Transition
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static T *parentObject(QQmlListProperty<QObject> *prop) { return static_cast<T *>(prop->object); }
|
||||
|
||||
template<class T, ChildrenMode Mode>
|
||||
struct ParentHandler
|
||||
{
|
||||
static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem);
|
||||
static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ParentHandler<T, ChildrenMode::None>
|
||||
{
|
||||
static bool unparentItem(QQmlListProperty<QObject> *, QObject *) { return true; }
|
||||
static bool parentItem(QQmlListProperty<QObject> *, QObject *) { return true; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ParentHandler<T, ChildrenMode::State>
|
||||
{
|
||||
static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item)
|
||||
{
|
||||
if (QAbstractState *state = qobject_cast<QAbstractState *>(item)) {
|
||||
state->setParent(parentObject<T>(prop));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool unparentItem(QQmlListProperty<QObject> *, QObject *oldItem)
|
||||
{
|
||||
if (QAbstractState *state = qobject_cast<QAbstractState *>(oldItem)) {
|
||||
state->setParent(nullptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ParentHandler<T, ChildrenMode::Transition>
|
||||
{
|
||||
static bool parentItem(QQmlListProperty<QObject> *prop, QObject *item)
|
||||
{
|
||||
if (QAbstractTransition *trans = qobject_cast<QAbstractTransition *>(item)) {
|
||||
parentObject<T>(prop)->addTransition(trans);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
|
||||
{
|
||||
if (QAbstractTransition *trans = qobject_cast<QAbstractTransition *>(oldItem)) {
|
||||
parentObject<T>(prop)->removeTransition(trans);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct ParentHandler<T, ChildrenMode::StateOrTransition>
|
||||
{
|
||||
static bool parentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
|
||||
{
|
||||
return ParentHandler<T, ChildrenMode::State>::parentItem(prop, oldItem)
|
||||
|| ParentHandler<T, ChildrenMode::Transition>::parentItem(prop, oldItem);
|
||||
}
|
||||
|
||||
static bool unparentItem(QQmlListProperty<QObject> *prop, QObject *oldItem)
|
||||
{
|
||||
return ParentHandler<T, ChildrenMode::State>::unparentItem(prop, oldItem)
|
||||
|| ParentHandler<T, ChildrenMode::Transition>::unparentItem(prop, oldItem);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, ChildrenMode Mode>
|
||||
class ChildrenPrivate
|
||||
{
|
||||
public:
|
||||
ChildrenPrivate()
|
||||
{}
|
||||
|
||||
static void append(QQmlListProperty<QObject> *prop, QObject *item)
|
||||
{
|
||||
QAbstractState *state = qobject_cast<QAbstractState*>(item);
|
||||
if (state) {
|
||||
item->setParent(prop->object);
|
||||
} else {
|
||||
QAbstractTransition *trans = qobject_cast<QAbstractTransition*>(item);
|
||||
if (trans)
|
||||
static_cast<T *>(prop->object)->addTransition(trans);
|
||||
}
|
||||
static_cast<ChildrenPrivate<T>*>(prop->data)->children.append(item);
|
||||
emit static_cast<T *>(prop->object)->childrenChanged();
|
||||
}
|
||||
|
||||
static void appendNoTransition(QQmlListProperty<QObject> *prop, QObject *item)
|
||||
{
|
||||
QAbstractState *state = qobject_cast<QAbstractState*>(item);
|
||||
if (state) {
|
||||
item->setParent(prop->object);
|
||||
}
|
||||
static_cast<ChildrenPrivate<T>*>(prop->data)->children.append(item);
|
||||
emit static_cast<T *>(prop->object)->childrenChanged();
|
||||
Handler::parentItem(prop, item);
|
||||
static_cast<Self *>(prop->data)->children.append(item);
|
||||
emit parentObject<T>(prop)->childrenChanged();
|
||||
}
|
||||
|
||||
static int count(QQmlListProperty<QObject> *prop)
|
||||
{
|
||||
return static_cast<ChildrenPrivate<T>*>(prop->data)->children.count();
|
||||
return static_cast<Self *>(prop->data)->children.count();
|
||||
}
|
||||
|
||||
static QObject *at(QQmlListProperty<QObject> *prop, int index)
|
||||
{
|
||||
return static_cast<ChildrenPrivate<T>*>(prop->data)->children.at(index);
|
||||
return static_cast<Self *>(prop->data)->children.at(index);
|
||||
}
|
||||
|
||||
static void clear(QQmlListProperty<QObject> *prop)
|
||||
{
|
||||
static_cast<ChildrenPrivate<T>*>(prop->data)->children.clear();
|
||||
emit static_cast<T *>(prop->object)->childrenChanged();
|
||||
auto &children = static_cast<Self *>(prop->data)->children;
|
||||
for (QObject *oldItem : qAsConst(children))
|
||||
Handler::unparentItem(prop, oldItem);
|
||||
|
||||
children.clear();
|
||||
emit parentObject<T>(prop)->childrenChanged();
|
||||
}
|
||||
|
||||
static void replace(QQmlListProperty<QObject> *prop, int index, QObject *item)
|
||||
{
|
||||
auto &children = static_cast<Self *>(prop->data)->children;
|
||||
|
||||
Handler::unparentItem(prop, children.at(index));
|
||||
Handler::parentItem(prop, item);
|
||||
|
||||
children.replace(index, item);
|
||||
emit parentObject<T>(prop)->childrenChanged();
|
||||
}
|
||||
|
||||
static void removeLast(QQmlListProperty<QObject> *prop)
|
||||
{
|
||||
Handler::unparentItem(prop, static_cast<Self *>(prop->data)->children.takeLast());
|
||||
emit parentObject<T>(prop)->childrenChanged();
|
||||
}
|
||||
|
||||
private:
|
||||
using Self = ChildrenPrivate<T, Mode>;
|
||||
using Handler = ParentHandler<T, Mode>;
|
||||
|
||||
QList<QObject *> children;
|
||||
};
|
||||
|
||||
|
|
|
@ -50,7 +50,9 @@ FinalState::FinalState(QState *parent)
|
|||
|
||||
QQmlListProperty<QObject> FinalState::children()
|
||||
{
|
||||
return QQmlListProperty<QObject>(this, &m_children, m_children.appendNoTransition, m_children.count, m_children.at, m_children.clear);
|
||||
return QQmlListProperty<QObject>(this, &m_children,
|
||||
m_children.append, m_children.count, m_children.at,
|
||||
m_children.clear, m_children.replace, m_children.removeLast);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -66,7 +66,7 @@ Q_SIGNALS:
|
|||
void childrenChanged();
|
||||
|
||||
private:
|
||||
ChildrenPrivate<FinalState> m_children;
|
||||
ChildrenPrivate<FinalState, ChildrenMode::State> m_children;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -61,7 +61,9 @@ void State::componentComplete()
|
|||
|
||||
QQmlListProperty<QObject> State::children()
|
||||
{
|
||||
return QQmlListProperty<QObject>(this, &m_children, m_children.append, m_children.count, m_children.at, m_children.clear);
|
||||
return QQmlListProperty<QObject>(this, &m_children,
|
||||
m_children.append, m_children.count, m_children.at,
|
||||
m_children.clear, m_children.replace, m_children.removeLast);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -69,7 +69,7 @@ Q_SIGNALS:
|
|||
void childrenChanged();
|
||||
|
||||
private:
|
||||
ChildrenPrivate<State> m_children;
|
||||
ChildrenPrivate<State, ChildrenMode::StateOrTransition> m_children;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -90,7 +90,9 @@ void StateMachine::componentComplete()
|
|||
|
||||
QQmlListProperty<QObject> StateMachine::children()
|
||||
{
|
||||
return QQmlListProperty<QObject>(this, &m_children, m_children.append, m_children.count, m_children.at, m_children.clear);
|
||||
return QQmlListProperty<QObject>(this, &m_children,
|
||||
m_children.append, m_children.count, m_children.at,
|
||||
m_children.clear, m_children.replace, m_children.removeLast);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -82,7 +82,7 @@ Q_SIGNALS:
|
|||
void qmlRunningChanged();
|
||||
|
||||
private:
|
||||
ChildrenPrivate<StateMachine> m_children;
|
||||
ChildrenPrivate<StateMachine, ChildrenMode::StateOrTransition> m_children;
|
||||
bool m_completed;
|
||||
bool m_running;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue