ecere/gui/controls/Stacker: Freeing space for scrollers when not needed
[sdk] / ecere / src / gui / controls / Stacker.ec
index 8efa028..fa89484 100644 (file)
@@ -10,92 +10,7 @@ public import "ecere"
 #endif
 #endif
 
-public class RepButton : Button
-{
-public:
-   bool pressing;
-   isRemote = true;
-   inactive = true;
-   
-   property Seconds delay { set { timer2.delay = value; } }
-   property Seconds delay0 { set { timer.delay = value; } }
-   
-   bool OnKeyHit(Key key, unichar ch)
-   {
-      return true;
-   }
-
-   bool OnKeyDown(Key key, unichar ch)
-   {
-      if(key == hotKey)
-      {
-         NotifyPushed(master, this, 0,0, key.modifiers);
-         return false;
-      }
-      return true;
-   }
-
-   bool OnKeyUp(Key key, unichar ch)
-   {
-      if(key == hotKey)
-      {
-         NotifyReleased(master, this, 0,0, key.modifiers);
-         return false;
-      }
-      return true;
-   }
-
-   bool NotifyPushed(RepButton button, int x, int y, Modifiers mods)
-   {
-      button.pressing = true;
-      button.NotifyClicked(this, button, x, y, mods);
-      button.timer.Start();
-      return true;
-   }
-
-   bool NotifyMouseLeave(RepButton button, Modifiers mods)
-   {
-      button.timer.Stop();
-      button.timer2.Stop();
-      return true;
-   }
-
-   bool NotifyReleased(RepButton button, int x, int y, Modifiers mods)
-   {
-      button.pressing = false;
-      button.NotifyMouseLeave(this, button, mods);
-      return false;
-   }
-
-   bool NotifyMouseOver(RepButton button, int x, int y, Modifiers mods)
-   {
-      if(button.pressing)
-         button.timer2.Start();
-      return true;
-   }
-
-   Timer timer
-   {
-      this, delay = 0.1;
-
-      bool DelayExpired()
-      {
-         timer.Stop();
-         timer2.Start();
-         timer2.DelayExpired(this);
-         return true;
-      }
-   };
-   Timer timer2
-   {
-      this, delay = 0.1;
-      bool DelayExpired()
-      {
-         NotifyClicked(master, this, 0, 0, 0);
-         return true;
-      }
-   };
-}
+// class RepButton WAS ALREADY DEFINED IN date.ec! The version here broke CalendarControl behavior.
 
 static define stackerScrolling = 16;
 
@@ -201,7 +116,7 @@ private:
 
    RepButton left
    {
-      nonClient = true, parent = this, visible = false, bevelOver = true, keyRepeat = true, opacity = 0;
+      nonClient = true, parent = this, visible = false, bevelOver = true, keyRepeat = true, opacity = 0; delay0 = 0.1;
 
       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
@@ -222,7 +137,7 @@ private:
    };
    RepButton right
    {
-      nonClient = true, parent = this, visible = false, bevelOver = true, keyRepeat = true, opacity = 0;
+      nonClient = true, parent = this, visible = false, bevelOver = true, keyRepeat = true, opacity = 0; delay0 = 0.1;
 
       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
       {
@@ -247,7 +162,7 @@ private:
    void GetDecorationsSize(MinMaxValue * w, MinMaxValue * h)
    {
       Window::GetDecorationsSize(w, h);
-      if(bits.scrollable && bits.endButtons)
+      if(bits.scrollable && bits.endButtons && left.visible)
       {
          if(direction == vertical) *h += left.size.h + right.size.h + 8; else *w += left.size.w + right.size.w + 8;
       }
@@ -256,7 +171,7 @@ private:
    void SetWindowArea(int * x, int * y, MinMaxValue * w, MinMaxValue * h, MinMaxValue * cw, MinMaxValue * ch)
    {
       Window::SetWindowArea(x, y, w, h, cw, ch);
-      if(bits.scrollable && bits.endButtons)
+      if(bits.scrollable && bits.endButtons && left.visible)
       {
          if(direction == vertical) *y += left.size.h + 4; else *x += left.size.w + 4;
       }
@@ -335,12 +250,12 @@ private:
    void OnChildVisibilityToggled(Window child, bool visible)
    {
       DoResize(size.w, size.h); // todo: improve with DoPartialResize(size.w, size.h, client);
-      size = size;   // TRIGGER SCROLLING UPDATE (Currently required since we aren't using Window scrollbars)
+      // size = size;   // TRIGGER SCROLLING UPDATE (Currently required since we aren't using Window scrollbars)
    }
    void OnChildResized(Window child, int x, int y, int w, int h)
    {
       DoResize(size.w, size.h); // todo: improve with DoPartialResize(size.w, size.h, client);
-      size = size;   // TRIGGER SCROLLING UPDATE (Currently required since we aren't using Window scrollbars)
+      // size = size;   // TRIGGER SCROLLING UPDATE (Currently required since we aren't using Window scrollbars)
    }
 
    /*void UpdateControls()
@@ -389,6 +304,14 @@ private:
 
    void DoResize(int width, int height)
    {
+      if(left.visible)
+      {
+         // Take into consideration the space we would gain back by getting rid of the scrolling buttons
+         if(direction == horizontal)
+            width += 2 * (left.size.w + 4);
+         else
+            height += 2 * (left.size.h + 4);
+      }
       // TOIMPROVE: this needs to maintain an order and allow for dynamically adding
       //            children. inserting in the order should also be possible.
       // TOIMPROVE: in Window.ec... it should be possible to change the order of children
@@ -515,11 +438,35 @@ private:
 
    public void DestroyChildren()
    {
-      // This is not required and will jam if the Stacker is destroyed
-      if(!destroyed)
+      // This safe loop with 'left' will jam if the Stacker is destroyed
+      if(!destroyed && created)
       {
-         while(controls.count)
-            controls[0].Destroy(0);
+         bool left = true;
+         while(left)
+         {
+            left = false;
+            for(w : controls)
+            {
+               if(!w.destroyed && w.created)
+               {
+                  w.Destroy(0);
+                  left = true;
+                  break;
+               }
+            }
+         }
+      }
+      else
+      {
+         // If the stacker is already destroyed, just clear everything
+         Iterator<Window> it { controls };
+         while(it.pointer = null, it.Next())
+         {
+            Window w = it.data;
+            it.Remove();
+            w.Destroy(0);
+            delete w;
+         }
       }
    }