Loading...
Searching...
No Matches
PropertyCommand.hpp
1#pragma once
2#include <score/command/Command.hpp>
3#include <score/model/path/Path.hpp>
4#include <score/model/path/PathSerialization.hpp>
5
6#include <QString>
7#include <QVariant>
8
9namespace score
10{
20class SCORE_LIB_BASE_EXPORT PropertyCommand : public Command
21{
22public:
23 using Command::Command;
24 PropertyCommand() = default;
25
26 template <typename T, typename... Args>
27 PropertyCommand(const T& obj, QString property, QVariant newval)
28 : m_path{Path<T>(obj).unsafePath()}
29 , m_property{std::move(property)}
30 , m_old{obj.property(m_property.toUtf8().constData())}
31 , m_new{std::move(newval)}
32 {
33 }
34
35 ~PropertyCommand() override;
36
37 void undo(const score::DocumentContext& ctx) const final override;
38 void redo(const score::DocumentContext& ctx) const final override;
39
40 template <typename Path_T>
41 void update(const Path_T&, QVariant newval)
42 {
43 m_new = std::move(newval);
44 }
45
46protected:
47 void serializeImpl(DataStreamInput&) const final override;
48 void deserializeImpl(DataStreamOutput&) final override;
49
50private:
51 ObjectPath m_path;
52 QString m_property;
53 QVariant m_old, m_new;
54};
55
56template <typename T>
58{
59public:
60 using model_t = typename T::model_type;
61 using param_t = typename T::param_type;
62
63 template <typename U>
64 struct command;
65
66 using score::Command::Command;
67 PropertyCommand_T() = default;
68
69 template <typename U>
70 PropertyCommand_T(const model_t& obj, U&& newval)
71 : m_path{obj}
72 , m_old{(obj.*T::get)()}
73 , m_new{std::forward<U>(newval)}
74 {
75 }
76
77 ~PropertyCommand_T() override { }
78
79 template <typename Path_T, typename U>
80 void update(const Path_T&, U&& newval)
81 {
82 m_new = std::forward<U>(newval);
83 }
84
85 void undo(const score::DocumentContext& ctx) const final override
86 {
87 (m_path.find(ctx).*T::set)(m_old);
88 }
89
90 void redo(const score::DocumentContext& ctx) const final override
91 {
92 (m_path.find(ctx).*T::set)(m_new);
93 }
94
95private:
96 void serializeImpl(DataStreamInput& s) const final override
97 {
98 s << m_path << m_old << m_new;
99 }
100
101 void deserializeImpl(DataStreamOutput& s) final override
102 {
103 s >> m_path >> m_old >> m_new;
104 }
105
106 Path<model_t> m_path;
107 param_t m_old, m_new;
108};
109
110template <typename T>
111struct StaticPropertyCommand : score::PropertyCommand_T<T>::template command<void>::type
112{
113 using score::PropertyCommand_T<T>::template command<void>::type::type;
114};
115}
116
117#define PROPERTY_COMMAND_T(NS, Name, Property, Description) \
118 namespace NS \
119 { \
120 class Name : public score::PropertyCommand_T<Property> \
121 { \
122 SCORE_COMMAND_DECL(NS::CommandFactoryName(), Name, Description) \
123 public: \
124 using PropertyCommand_T::PropertyCommand_T; \
125 }; \
126 } \
127 \
128 namespace score \
129 { \
130 template <> \
131 template <> \
132 struct score::PropertyCommand_T<NS::Property>::command<void> \
133 { \
134 using type = NS::Name; \
135 }; \
136 }
The ObjectPath class.
Definition ObjectPath.hpp:37
The Path class is a typesafe wrapper around ObjectPath.
Definition Path.hpp:52
The Command class.
Definition Command.hpp:34
Definition PropertyCommand.hpp:58
The PropertyCommand class.
Definition PropertyCommand.hpp:21
Base toolkit upon which the software is built.
Definition Application.cpp:90
STL namespace.
Definition DataStreamHelpers.hpp:99
Definition DataStreamHelpers.hpp:103
Definition DocumentContext.hpp:18
Definition PropertyCommand.hpp:64
Definition PropertyCommand.hpp:112