extras/CheckListBox: Added 'IsFullyChecked()'
[sdk] / extras / gui / GuiConfigData.ec
1 import "ecere"
2
3 // source file line number printf (sflnprintf)
4
5 #undef _DEBUG
6
7 #ifdef _DEBUG
8 #define sflnprintf(format,...) printf("%s:% 5d: " format, __FILE__, __LINE__, ##__VA_ARGS__)
9 #define sflnPrintLn(...) PrintLn(__FILE__, ":", __LINE__, ": ", ##__VA_ARGS__)
10 #else
11 void DoNothing() {}
12 #define sflnprintf(format,...) DoNothing()
13 #define sflnPrintLn(...) DoNothing()
14 #endif
15
16 class GuiConfigData
17 {
18    virtual bool onSave();
19    virtual void onModified()
20    {
21       modified = true;
22    }
23
24 public:
25
26    Map<String, GuiDataWindow> windows;
27    Map<String, GuiDataPaneSplitter> paneSplitters;
28
29    void saveWindowInit(const char * configId, Window window)
30    {
31       sflnprintf("GuiConfigData::saveWindowInit\n");
32       applyWindowConfig(configId, window);
33       {
34          bool isNew = false;
35          GuiDataWindow guiData = insertWindowConfig(configId, true, &isNew);
36          if(guiData && isNew)
37          {
38             if(window.state != minimized)
39                guiData.state = window.state;
40             if(!(window.normalAnchor.left.distance == 0 && window.normalAnchor.top.distance == 0 &&
41                   window.normalSizeAnchor.size.w == 0 && window.normalSizeAnchor.size.h == 0))
42             {
43                recordWindowPosition(guiData, window);
44                recordWindowSize(guiData, window);
45             }
46             onModified();
47             onSave();
48          }
49       }
50    }
51
52    void saveWindowState(const char * configId, Window window, WindowState state)
53    {
54       sflnprintf("GuiConfigData::saveWindowState\n");
55       GuiDataWindow guiData = insertWindowConfig(configId, false, null);
56       if(guiData)
57       {
58          if(state != minimized)
59             guiData.state = state;
60          if(state == normal)
61             applyWindowSize(window, guiData);
62          onModified();
63       }
64    }
65
66    void saveWindowPosition(const char * configId, Window window, Point position, Size size)
67    {
68       sflnprintf("GuiConfigData::saveWindowPosition\n");
69       GuiDataWindow guiData = insertWindowConfig(configId, false, null);
70       if(guiData && window.state == normal)
71       {
72          if(!(window.normalAnchor.left.distance == 0 && window.normalAnchor.top.distance == 0 &&
73                window.normalSizeAnchor.size.w == 0 && window.normalSizeAnchor.size.h == 0))
74          {
75             recordWindowPosition(guiData, window);
76             recordWindowSize(guiData, window);
77          }
78          onModified();
79       }
80    }
81
82    void saveWindowSize(const char * configId, Window window, Size size)
83    {
84       sflnprintf("GuiConfigData::saveWindowSize\n");
85       GuiDataWindow guiData = insertWindowConfig(configId, false, null);
86       if(guiData && window.state == normal)
87       {
88          recordWindowSize(guiData, window);
89          onModified();
90       }
91    }
92
93    void saveWindowClose(const char * configId)
94    {
95       sflnprintf("GuiConfigData::saveWindowClose\n");
96       GuiDataWindow guiData = getWindowConfig(configId);
97       if(guiData)
98          guiData.saving = false;
99       if(modified)
100          onSave();
101    }
102
103    void savePaneSplitterSize(const char * configId, double scaleSplit)
104    {
105       sflnprintf("GuiConfigData::savePaneSplitterSize\n");
106       GuiDataPaneSplitter guiData = null;
107       if(!paneSplitters)
108          paneSplitters = { };
109       if(!(guiData = paneSplitters[configId]))
110          paneSplitters[configId] = guiData = { };
111       if(!guiData.loading)
112       {
113          guiData.scaleSplit = scaleSplit;
114          onModified();
115       }
116    }
117
118 private:
119    bool modified;
120
121    ~GuiConfigData()
122    {
123       timer.Stop();
124    }
125
126    Timer timer
127    {
128       userData = this, delay = 2.5;
129       bool DelayExpired()
130       {
131          if(modified)
132          {
133             if(onSave())
134                modified = false;
135          }
136          return true;
137       }
138    };
139
140    GuiDataWindow getWindowConfig(const char * configId)
141    {
142       //sflnprintf("GuiConfigData::getWindowConfig\n");
143       GuiDataWindow guiData = null;
144       if(windows)
145          guiData = windows[configId];
146       return guiData;
147    }
148
149    GuiDataWindow insertWindowConfig(const char * configId, bool startSaving, bool *isNew)
150    {
151       //sflnprintf("GuiConfigData::insertWindowConfig\n");
152       GuiDataWindow guiData = null;
153       if(startSaving)
154       {
155          if(!windows)
156             windows = { };
157          if(!(guiData = windows[configId]))
158          {
159             windows[configId] = guiData = { };
160             if(isNew)
161                *isNew = true;
162          }
163          guiData.saving = true;
164       }
165       else
166          guiData = getWindowConfig(configId);
167       if(/*!startSaving && */guiData && (!guiData.saving || guiData.loading))
168          guiData = null;
169       return guiData;
170    }
171
172    void recordWindowPosition(GuiDataWindow guiData, Window window)
173    {
174       sflnprintf("GuiConfigData::recordWindowPosition\n");
175       guiData.position = { window.normalAnchor.left.distance, window.normalAnchor.top.distance };
176       sflnPrintLn("recordWindowPosition(guiData.position == ", guiData.position, ", created == ", window.created, ")");
177    }
178
179    void recordWindowSize(GuiDataWindow guiData, Window window)
180    {
181       sflnprintf("GuiConfigData::recordWindowSize\n");
182       //Size s;
183       //sflnPrintLn(guiData.size);
184       //s = window.normalSizeAnchor.size;
185       //sflnPrintLn(s);
186       guiData.size = window.normalSizeAnchor.size;
187       //sflnPrintLn(guiData.size);
188       //sflnPrintLn(window.size);
189       //sflnPrintLn("recordWindowSize(guiData.size == ", guiData.size, ", created == ", window.created, ")");
190    }
191
192    void applyWindowConfig(const char * configId, Window window)
193    {
194       sflnprintf("GuiConfigData::applyWindowConfig\n");
195       GuiDataWindow guiData = getWindowConfig(configId);
196       if(guiData)
197       {
198          guiData.loading = true;
199          window.state = normal;
200          applyWindowPosition(window, guiData);
201          applyWindowSize(window, guiData);
202          window.Move(guiData.position.x, guiData.position.y, guiData.size.w, guiData.size.h);
203          sflnPrintLn("applyWindowConfig(window.size == ", window.size, ", created == ", window.created, ")");
204          window.state = guiData.state;
205          guiData.loading = false;
206       }
207    }
208
209    void applyWindowPosition(Window window, GuiDataWindow guiData)
210    {
211       sflnprintf("GuiConfigData::applyWindowPosition\n");
212       window.position = guiData.position;
213       sflnPrintLn("applyWindowPosition(window.position == ", window.position, ", created == ", window.created, ")");
214    }
215
216    void applyWindowSize(Window window, GuiDataWindow guiData)
217    {
218       sflnprintf("GuiConfigData::applyWindowSize\n");
219       if(guiData.size.w && guiData.size.h)
220       {
221          window.size = guiData.size;
222          sflnPrintLn("applyWindowSize(window.size == ", window.size, ", created == ", window.created, ")");
223       }
224    }
225
226    void applyPaneSplitterConfig(const char * configId, PaneSplitter paneSplitter)
227    {
228       //sflnprintf("GuiConfigData::applyPaneSplitterConfig\n");
229       GuiDataPaneSplitter guiData = paneSplitters[configId];
230       if(guiData)
231       {
232          guiData.loading = true;
233          paneSplitter.scaleSplit = guiData.scaleSplit;
234          guiData.loading = false;
235       }
236    }
237 }
238
239 class SavedConfigWindow : Window
240 {
241    virtual GuiConfigData getGuiConfigData() { return null; }
242    virtual const char * getGuiConfigInstanceId() { return _class.name; }
243
244    bool OnCreate()
245    {
246       sflnprintf("SavedConfigWindow::OnCreate\n");
247       bool result = Window::OnCreate();
248       if(result)
249       {
250          GuiConfigData data = getGuiConfigData();
251          if(data) data.saveWindowInit(getGuiConfigInstanceId(), this);
252       }
253       return result;
254    }
255
256    bool OnPostCreate()
257    {
258       sflnprintf("SavedConfigWindow::OnPostCreate\n");
259       bool result = Window::OnPostCreate();
260       if(result)
261       {
262          GuiConfigData data = getGuiConfigData();
263          if(data)
264             data.timer.Start();
265       }
266       return result;
267    }
268
269    /*bool OnPostCreate()
270    {
271       //sflnprintf("SavedConfigWindow::OnPostCreate\n");
272       GuiConfigData data = getGuiConfigData();
273       if(data) data.saveWindowInit(getGuiConfigInstanceId(), this);
274       return true;
275    }*/
276
277    bool OnStateChange(WindowState state, Modifiers mods)
278    {
279       sflnprintf("SavedConfigWindow::OnStateChange\n");
280       GuiConfigData data = getGuiConfigData();
281       if(data) data.saveWindowState(getGuiConfigInstanceId(), this, state);
282       return true;
283    }
284
285    void OnPosition(int x, int y, int width, int height)
286    {
287       sflnprintf("SavedConfigWindow::OnPosition(%i, %i, %i, %i)\n", x, y, width, height);
288       GuiConfigData data = getGuiConfigData();
289       if(data) data.saveWindowPosition(getGuiConfigInstanceId(), this, { x, y }, clientSize);
290    }
291
292    void OnResize(int width, int height)
293    {
294       sflnprintf("SavedConfigWindow::OnResize(%i, %i) -- (%i, %i)\n", width, height, this.normalSizeAnchor.size.w, this.normalSizeAnchor.size.h);
295       GuiConfigData data = getGuiConfigData();
296       if(data) data.saveWindowSize(getGuiConfigInstanceId(), this, clientSize);
297    }
298
299    bool OnClose(bool parentClosing)
300    {
301       sflnprintf("SavedConfigWindow::OnClose\n");
302       GuiConfigData data = getGuiConfigData();
303       if(data) data.saveWindowClose(getGuiConfigInstanceId());
304       return true;
305    }
306 }
307
308 class GuiDataWindow : struct
309 {
310 public:
311    WindowState state;
312    Point position;
313    Size size;
314 private:
315    bool saving;
316    bool loading;
317 }
318
319 class SavedConfigPaneSplitter : PaneSplitter
320 {
321    virtual GuiConfigData getGuiConfigData() { return null; }
322    virtual const char * getGuiConfigInstanceId() { return _class.name; }
323
324    bool OnPostCreate()
325    {
326       //sflnprintf("SavedConfigPaneSplitter::OnPostCreate\n");
327       GuiConfigData data = getGuiConfigData();
328       if(data) data.applyPaneSplitterConfig(getGuiConfigInstanceId(), this);
329       return true;
330    }
331
332    bool NotifyResized(SavedConfigPaneSplitter splitter)
333    {
334       //sflnprintf("SavedConfigPaneSplitter::NotifyResized\n");
335       GuiConfigData data = splitter.getGuiConfigData();
336       if(data) data.savePaneSplitterSize(splitter.getGuiConfigInstanceId(), splitter.scaleSplit);
337       return true;
338    }
339 }
340
341 class GuiDataPaneSplitter : struct
342 {
343 public:
344    double scaleSplit;
345 private:
346    bool loading;
347 }