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