extras: add tools to remember gui configuration (size, position, etc) in new extras...
authorRejean Loyer <redj@ecere.com>
Thu, 21 Aug 2014 16:34:29 +0000 (12:34 -0400)
committerJerome St-Louis <jerome@ecere.com>
Thu, 15 Oct 2015 00:19:23 +0000 (20:19 -0400)
extras/gui/GuiConfigData.ec [new file with mode: 0644]

diff --git a/extras/gui/GuiConfigData.ec b/extras/gui/GuiConfigData.ec
new file mode 100644 (file)
index 0000000..4e0f126
--- /dev/null
@@ -0,0 +1,346 @@
+import "ecere"
+
+// source file line number printf (sflnprintf)
+
+#undef _DEBUG
+
+#ifdef _DEBUG
+#define sflnprintf(format,...) printf("%s:% 5d: " format, __FILE__, __LINE__, ##__VA_ARGS__)
+#define sflnPrintLn(...) PrintLn(__FILE__, ":", __LINE__, ": ", ##__VA_ARGS__)
+#else
+void DoNothing() {}
+#define sflnprintf(format,...) DoNothing()
+#define sflnPrintLn(...) DoNothing()
+#endif
+
+class GuiConfigData
+{
+   virtual bool onSave();
+   virtual void onModified()
+   {
+      modified = true;
+   }
+
+public:
+
+   Map<String, GuiDataWindow> windows;
+   Map<String, GuiDataPaneSplitter> paneSplitters;
+
+   void saveWindowInit(const char * configId, Window window)
+   {
+      sflnprintf("GuiConfigData::saveWindowInit\n");
+      applyWindowConfig(configId, window);
+      {
+         bool isNew = false;
+         GuiDataWindow guiData = insertWindowConfig(configId, true, &isNew);
+         if(guiData && isNew)
+         {
+            if(window.state != minimized)
+               guiData.state = window.state;
+            if(!(window.normalAnchor.left.distance == 0 && window.normalAnchor.top.distance == 0 &&
+                  window.normalSizeAnchor.size.w == 0 && window.normalSizeAnchor.size.h == 0))
+            {
+               recordWindowPosition(guiData, window);
+               recordWindowSize(guiData, window);
+            }
+            onModified();
+            onSave();
+         }
+      }
+   }
+
+   void saveWindowState(const char * configId, Window window, WindowState state)
+   {
+      sflnprintf("GuiConfigData::saveWindowState\n");
+      GuiDataWindow guiData = insertWindowConfig(configId, false, null);
+      if(guiData)
+      {
+         if(state != minimized)
+            guiData.state = state;
+         if(state == normal)
+            applyWindowSize(window, guiData);
+         onModified();
+      }
+   }
+
+   void saveWindowPosition(const char * configId, Window window, Point position, Size size)
+   {
+      sflnprintf("GuiConfigData::saveWindowPosition\n");
+      GuiDataWindow guiData = insertWindowConfig(configId, false, null);
+      if(guiData && window.state == normal)
+      {
+         if(!(window.normalAnchor.left.distance == 0 && window.normalAnchor.top.distance == 0 &&
+               window.normalSizeAnchor.size.w == 0 && window.normalSizeAnchor.size.h == 0))
+         {
+            recordWindowPosition(guiData, window);
+            recordWindowSize(guiData, window);
+         }
+         onModified();
+      }
+   }
+
+   void saveWindowSize(const char * configId, Window window, Size size)
+   {
+      sflnprintf("GuiConfigData::saveWindowSize\n");
+      GuiDataWindow guiData = insertWindowConfig(configId, false, null);
+      if(guiData && window.state == normal)
+      {
+         recordWindowSize(guiData, window);
+         onModified();
+      }
+   }
+
+   void saveWindowClose(const char * configId)
+   {
+      sflnprintf("GuiConfigData::saveWindowClose\n");
+      GuiDataWindow guiData = getWindowConfig(configId);
+      if(guiData)
+         guiData.saving = false;
+      if(modified)
+         onSave();
+   }
+
+   void savePaneSplitterSize(const char * configId, double scaleSplit)
+   {
+      sflnprintf("GuiConfigData::savePaneSplitterSize\n");
+      GuiDataPaneSplitter guiData = null;
+      if(!paneSplitters)
+         paneSplitters = { };
+      if(!(guiData = paneSplitters[configId]))
+         paneSplitters[configId] = guiData = { };
+      if(!guiData.loading)
+      {
+         guiData.scaleSplit = scaleSplit;
+         onModified();
+      }
+   }
+
+private:
+   bool modified;
+
+   ~GuiConfigData()
+   {
+      timer.Stop();
+   }
+
+   Timer timer
+   {
+      userData = this, delay = 2.5;
+      bool DelayExpired()
+      {
+         if(modified)
+         {
+            if(onSave())
+               modified = false;
+         }
+         return true;
+      }
+   };
+
+   GuiDataWindow getWindowConfig(const char * configId)
+   {
+      //sflnprintf("GuiConfigData::getWindowConfig\n");
+      GuiDataWindow guiData = null;
+      if(windows)
+         guiData = windows[configId];
+      return guiData;
+   }
+
+   GuiDataWindow insertWindowConfig(const char * configId, bool startSaving, bool *isNew)
+   {
+      //sflnprintf("GuiConfigData::insertWindowConfig\n");
+      GuiDataWindow guiData = null;
+      if(startSaving)
+      {
+         if(!windows)
+            windows = { };
+         if(!(guiData = windows[configId]))
+         {
+            windows[configId] = guiData = { };
+            if(isNew)
+               *isNew = true;
+         }
+         guiData.saving = true;
+      }
+      else
+         guiData = getWindowConfig(configId);
+      if(/*!startSaving && */guiData && (!guiData.saving || guiData.loading))
+         guiData = null;
+      return guiData;
+   }
+
+   void recordWindowPosition(GuiDataWindow guiData, Window window)
+   {
+      sflnprintf("GuiConfigData::recordWindowPosition\n");
+      guiData.position = { window.normalAnchor.left.distance, window.normalAnchor.top.distance };
+      sflnPrintLn("recordWindowPosition(guiData.position == ", guiData.position, ", created == ", window.created, ")");
+   }
+
+   void recordWindowSize(GuiDataWindow guiData, Window window)
+   {
+      sflnprintf("GuiConfigData::recordWindowSize\n");
+      //Size s;
+      //sflnPrintLn(guiData.size);
+      //s = window.normalSizeAnchor.size;
+      //sflnPrintLn(s);
+      guiData.size = window.normalSizeAnchor.size;
+      //sflnPrintLn(guiData.size);
+      //sflnPrintLn(window.size);
+      //sflnPrintLn("recordWindowSize(guiData.size == ", guiData.size, ", created == ", window.created, ")");
+   }
+
+   void applyWindowConfig(const char * configId, Window window)
+   {
+      sflnprintf("GuiConfigData::applyWindowConfig\n");
+      GuiDataWindow guiData = getWindowConfig(configId);
+      if(guiData)
+      {
+         guiData.loading = true;
+         window.state = normal;
+         applyWindowPosition(window, guiData);
+         applyWindowSize(window, guiData);
+         window.Move(guiData.position.x, guiData.position.y, guiData.size.w, guiData.size.h);
+         sflnPrintLn("applyWindowConfig(window.size == ", window.size, ", created == ", window.created, ")");
+         window.state = guiData.state;
+         guiData.loading = false;
+      }
+   }
+
+   void applyWindowPosition(Window window, GuiDataWindow guiData)
+   {
+      sflnprintf("GuiConfigData::applyWindowPosition\n");
+      window.position = guiData.position;
+      sflnPrintLn("applyWindowPosition(window.position == ", window.position, ", created == ", window.created, ")");
+   }
+
+   void applyWindowSize(Window window, GuiDataWindow guiData)
+   {
+      sflnprintf("GuiConfigData::applyWindowSize\n");
+      if(guiData.size.w && guiData.size.h)
+      {
+         window.size = guiData.size;
+         sflnPrintLn("applyWindowSize(window.size == ", window.size, ", created == ", window.created, ")");
+      }
+   }
+
+   void applyPaneSplitterConfig(const char * configId, PaneSplitter paneSplitter)
+   {
+      //sflnprintf("GuiConfigData::applyPaneSplitterConfig\n");
+      GuiDataPaneSplitter guiData = paneSplitters[configId];
+      if(guiData)
+      {
+         guiData.loading = true;
+         paneSplitter.scaleSplit = guiData.scaleSplit;
+         guiData.loading = false;
+      }
+   }
+}
+
+class SavedConfigWindow : Window
+{
+   virtual GuiConfigData getGuiConfigData() { return null; }
+   virtual const char * getGuiConfigInstanceId() { return _class.name; }
+
+   bool OnCreate()
+   {
+      sflnprintf("SavedConfigWindow::OnCreate\n");
+      bool result = Window::OnCreate();
+      if(result)
+      {
+         GuiConfigData data = getGuiConfigData();
+         if(data) data.saveWindowInit(getGuiConfigInstanceId(), this);
+      }
+      return result;
+   }
+
+   bool OnPostCreate()
+   {
+      sflnprintf("SavedConfigWindow::OnPostCreate\n");
+      bool result = Window::OnPostCreate();
+      if(result)
+      {
+         GuiConfigData data = getGuiConfigData();
+         data.timer.Start();
+      }
+      return result;
+   }
+
+   /*bool OnPostCreate()
+   {
+      //sflnprintf("SavedConfigWindow::OnPostCreate\n");
+      GuiConfigData data = getGuiConfigData();
+      if(data) data.saveWindowInit(getGuiConfigInstanceId(), this);
+      return true;
+   }*/
+
+   bool OnStateChange(WindowState state, Modifiers mods)
+   {
+      sflnprintf("SavedConfigWindow::OnStateChange\n");
+      GuiConfigData data = getGuiConfigData();
+      if(data) data.saveWindowState(getGuiConfigInstanceId(), this, state);
+      return true;
+   }
+
+   void OnPosition(int x, int y, int width, int height)
+   {
+      sflnprintf("SavedConfigWindow::OnPosition(%i, %i, %i, %i)\n", x, y, width, height);
+      GuiConfigData data = getGuiConfigData();
+      if(data) data.saveWindowPosition(getGuiConfigInstanceId(), this, { x, y }, clientSize);
+   }
+
+   void OnResize(int width, int height)
+   {
+      sflnprintf("SavedConfigWindow::OnResize(%i, %i) -- (%i, %i)\n", width, height, this.normalSizeAnchor.size.w, this.normalSizeAnchor.size.h);
+      GuiConfigData data = getGuiConfigData();
+      if(data) data.saveWindowSize(getGuiConfigInstanceId(), this, clientSize);
+   }
+
+   bool OnClose(bool parentClosing)
+   {
+      sflnprintf("SavedConfigWindow::OnClose\n");
+      GuiConfigData data = getGuiConfigData();
+      if(data) data.saveWindowClose(getGuiConfigInstanceId());
+      return true;
+   }
+}
+
+class GuiDataWindow : struct
+{
+public:
+   WindowState state;
+   Point position;
+   Size size;
+private:
+   bool saving;
+   bool loading;
+}
+
+class SavedConfigPaneSplitter : PaneSplitter
+{
+   virtual GuiConfigData getGuiConfigData() { return null; }
+   virtual const char * getGuiConfigInstanceId() { return _class.name; }
+
+   bool OnPostCreate()
+   {
+      //sflnprintf("SavedConfigPaneSplitter::OnPostCreate\n");
+      GuiConfigData data = getGuiConfigData();
+      if(data) data.applyPaneSplitterConfig(getGuiConfigInstanceId(), this);
+      return true;
+   }
+
+   bool NotifyResized(SavedConfigPaneSplitter splitter)
+   {
+      //sflnprintf("SavedConfigPaneSplitter::NotifyResized\n");
+      GuiConfigData data = splitter.getGuiConfigData();
+      if(data) data.savePaneSplitterSize(splitter.getGuiConfigInstanceId(), splitter.scaleSplit);
+      return true;
+   }
+}
+
+class GuiDataPaneSplitter : struct
+{
+public:
+   double scaleSplit;
+private:
+   bool loading;
+}