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 <QQmlInfo>
|
||||||
#include <QQmlListProperty>
|
#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
|
class ChildrenPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChildrenPrivate()
|
|
||||||
{}
|
|
||||||
|
|
||||||
static void append(QQmlListProperty<QObject> *prop, QObject *item)
|
static void append(QQmlListProperty<QObject> *prop, QObject *item)
|
||||||
{
|
{
|
||||||
QAbstractState *state = qobject_cast<QAbstractState*>(item);
|
Handler::parentItem(prop, item);
|
||||||
if (state) {
|
static_cast<Self *>(prop->data)->children.append(item);
|
||||||
item->setParent(prop->object);
|
emit parentObject<T>(prop)->childrenChanged();
|
||||||
} 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int count(QQmlListProperty<QObject> *prop)
|
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)
|
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 void clear(QQmlListProperty<QObject> *prop)
|
||||||
{
|
{
|
||||||
static_cast<ChildrenPrivate<T>*>(prop->data)->children.clear();
|
auto &children = static_cast<Self *>(prop->data)->children;
|
||||||
emit static_cast<T *>(prop->object)->childrenChanged();
|
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:
|
private:
|
||||||
|
using Self = ChildrenPrivate<T, Mode>;
|
||||||
|
using Handler = ParentHandler<T, Mode>;
|
||||||
|
|
||||||
QList<QObject *> children;
|
QList<QObject *> children;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,9 @@ FinalState::FinalState(QState *parent)
|
||||||
|
|
||||||
QQmlListProperty<QObject> FinalState::children()
|
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();
|
void childrenChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChildrenPrivate<FinalState> m_children;
|
ChildrenPrivate<FinalState, ChildrenMode::State> m_children;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
|
@ -61,7 +61,9 @@ void State::componentComplete()
|
||||||
|
|
||||||
QQmlListProperty<QObject> State::children()
|
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();
|
void childrenChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChildrenPrivate<State> m_children;
|
ChildrenPrivate<State, ChildrenMode::StateOrTransition> m_children;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
|
@ -90,7 +90,9 @@ void StateMachine::componentComplete()
|
||||||
|
|
||||||
QQmlListProperty<QObject> StateMachine::children()
|
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();
|
void qmlRunningChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChildrenPrivate<StateMachine> m_children;
|
ChildrenPrivate<StateMachine, ChildrenMode::StateOrTransition> m_children;
|
||||||
bool m_completed;
|
bool m_completed;
|
||||||
bool m_running;
|
bool m_running;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue