1 #ifndef FORM_EDITOR_PROPERTIES__PROPERTIES_EDITOR_H
2 #define FORM_EDITOR_PROPERTIES__PROPERTIES_EDITOR_H
3
4 #include "Property.h"
5 #include "PropertyCaller.h"
6 #include <ExpandFrame/ExpandFrame.h>
7 #include <FormEditorCommon/FormEditorCommon.h>
8
9 #define LAYOUTFILE <FormEditorProperties/FormEditorProperties.lay>
10 #include <CtrlCore/lay.h>
11
12 template <class T>
13 class PropertiesWindowBase : public WithPropertiesLayout<TopWindow>
14 {
15 typedef PropertiesWindowBase CLASSNAME;
16
17 protected:
GetProperties()18 T* GetProperties() { return _Properties; }
19 virtual void Cancel();
20 virtual void Load();
21 virtual void Save();
22
23 public:
24 PropertiesWindowBase(T* p);
25 virtual ~PropertiesWindowBase();
GetObjectWidgetClass()26 virtual String GetObjectWidgetClass() const { return String(); }
27 virtual int Execute();
28
29 private:
30 T* _Properties;
31 Array<StaticRect> _Panes;
32 };
33
34 template <class T>
PropertiesWindowBase(T * p)35 PropertiesWindowBase<T>::PropertiesWindowBase(T* p)
36 {
37 CtrlLayoutOKCancel(*this, t_("Properties"));
38 ToolWindow().Sizeable();
39 _Properties = p;
40 _Properties->InitProperties();
41 Load();
42 }
43
44 template <class T>
~PropertiesWindowBase()45 PropertiesWindowBase<T>::~PropertiesWindowBase()
46 {
47 _Properties->ClearProperties();
48 }
49
50 template <class T>
Execute()51 int PropertiesWindowBase<T>::Execute()
52 {
53 if (!_Properties->GetProperties().GetCount())
54 {
55 PromptOK(t_("No properties for object!"));
56 return IDCANCEL;
57 }
58 int r = WithPropertiesLayout<TopWindow>::Execute();
59 r == IDOK ? Save() : Cancel();
60 return r;
61 }
62
63 template <class T>
Load()64 void PropertiesWindowBase<T>::Load()
65 {
66 Vector<String> groups = _Properties->GetPropertiesGroups();
67 propGroups.Clear();
68 _Panes.Clear();
69
70 for (int i = 0; i < groups.GetCount(); ++i)
71 {
72 if (groups[i].IsEmpty())
73 groups[i] = t_("Others");
74 Array<Property*> gProps = _Properties->GetPropertiesByGroup(groups[i]);
75 StaticRect& pane = _Panes.Add();
76 int paneCY = 10;
77 for (int j = 0; j < gProps.GetCount(); ++j)
78 {
79 gProps[j]->ToPane(pane, paneCY, 5);
80 }
81 paneCY += 15;
82 propGroups.AddExpander(pane, true, paneCY).SetTitle(groups[i]);
83 }
84 }
85
86 template <class T>
Save()87 void PropertiesWindowBase<T>::Save()
88 {
89 Array<Property>& props = _Properties->GetProperties();
90 for (int i = 0; i < props.GetCount(); ++i)
91 if (props[i].IsChanged())
92 props[i].Apply();
93 Break();
94 }
95
96 template <class T>
Cancel()97 void PropertiesWindowBase<T>::Cancel()
98 {
99 Array<Property>& props = _Properties->GetProperties();
100 for (int i = 0; i < props.GetCount(); ++i)
101 if (props[i].IsChanged())
102 props[i].Restore();
103 Break();
104 }
105
106 template <class T>
107 class PropertiesWindowHistory
108 {
109 class HChangeProperty : public IHistoryItem
110 {
111 String _Name;
112 Value _Last;
113 Value _Next;
114 int _Prop;
115 T* _Ptr;
116
117 public:
HChangeProperty(T * obj,String name,int prop,Value last,Value v)118 HChangeProperty(T* obj, String name, int prop, Value last, Value v)
119 : _Ptr(obj), _Name(name), _Prop(prop), _Last(last), _Next(v) {}
~HChangeProperty()120 virtual ~HChangeProperty() {}
121
122 virtual String GetDesc() const;
123 virtual void Undo();
124 virtual void Do();
125 };
126
127 public:
PropertiesWindowHistory(T * p)128 PropertiesWindowHistory(T* p) : _Properties(p) {}
129
130 private:
131 T* _Properties;
132
133 protected:
134 virtual void Save();
135 };
136
137 template <class T>
Save()138 void PropertiesWindowHistory<T>::Save()
139 {
140 Array<Property>& props = _Properties->GetProperties();
141 for (int i = 0; i < props.GetCount(); ++i)
142 if (props[i].IsChanged())
143 {
144 T* c = _Properties->GetObject();
145 if (!c) continue;
146 Value v;
147 props[i].Get(v, Vector<Value>());
148 c->AddToHistory(new HChangeProperty(c, props[i].MetaString("Name"),
149 i, props[i].GetLast(), v));
150 }
151 }
152
153 // History: Property changes
154 template <class T>
Do()155 void PropertiesWindowHistory<T>::HChangeProperty::Do()
156 {
157 if (!_Ptr) return;
158 _Ptr->InitProperties();
159 Property& prop = _Ptr->GetProperties()[_Prop];
160 prop.Set(Vector<Value>() << _Next);
161 _Ptr->ClearProperties();
162 }
163
164 template <class T>
Undo()165 void PropertiesWindowHistory<T>::HChangeProperty::Undo()
166 {
167 if (!_Ptr) return;
168 _Ptr->InitProperties();
169 Property& prop = _Ptr->GetProperties()[_Prop];
170 prop.Set(Vector<Value>() << _Last);
171 _Ptr->ClearProperties();
172 }
173
174 template <class T>
GetDesc()175 String PropertiesWindowHistory<T>::HChangeProperty::GetDesc() const
176 {
177 if (!_Ptr) return String(t_("Unable to change the property: NULL-pointer."));
178 return NFormat(t_("Property of the object (type \"%s\"), named \"%s\", changed to: \"%s\""),
179 _Ptr->GetObjectWidgetClass(), _Name, _Next.ToString());
180 }
181
182 template <class T>
183 class PropertiesWindow : public PropertiesWindowBase<T>, public PropertiesWindowHistory<T>
184 {
185 public:
PropertiesWindow(T * p)186 PropertiesWindow(T* p) : PropertiesWindowBase<T>(p), PropertiesWindowHistory<T>(p)
187 { _useHistory = false; }
~PropertiesWindow()188 virtual ~PropertiesWindow() {}
189
Save()190 virtual void Save()
191 {
192 PropertiesWindowBase<T>::Save();
193
194 if (_useHistory)
195 PropertiesWindowHistory<T>::Save();
196 }
197
198 bool UseHistory(bool flag = true) { _useHistory = flag; }
199
200 private:
201 bool _useHistory;
202 };
203
204 #endif
205