extras/gui/controls/CheckListBox: Fixed for static linking
[sdk] / extras / gui / controls / CheckListBox.ec
index 223ecd6..84474d5 100644 (file)
@@ -1,4 +1,8 @@
+#ifdef ECERE_STATIC
+import static "ecere"
+#else
 import "ecere"
+#endif
 
 class CheckListBoxButton : Button
 {
@@ -31,8 +35,9 @@ class CheckListBoxButton : Button
 
 class CheckListBox : ListBox
 {
-   Map<int, CheckListBoxButton> buttonMaps { };
+   Map<uintptr, CheckListBoxButton> buttonMaps { };
    AVLTree<DataRow> rowChecks { };
+   AVLTree<DataRow> rowDisabled { };
    int checkIndent;
 
    checkIndent = 20;
@@ -53,8 +58,8 @@ class CheckListBox : ListBox
       {
          if(collapsed)
          {
-            MapIterator<int, Button> it { map = listBox.buttonMaps };
-            if(it.Index((int)r, false))
+            MapIterator<uintptr, Button> it { map = listBox.buttonMaps };
+            if(it.Index((uintptr)r, false))
             {
                Button checkBox = it.data;
                if(checkBox)
@@ -76,8 +81,9 @@ class CheckListBox : ListBox
       }
       for(r = row.GetNextRow(); r; r = r.GetNextRow())
       {
-         Button checkBox = listBox.buttonMaps[(int)r];
-         checkBox.position.y = 1 + (r.index + listBox.hasHeader) * listBox.rowHeight;
+         Button checkBox = listBox.buttonMaps[(uintptr)r];
+         if(checkBox)
+            checkBox.position.y = 1 + (r.index + listBox.hasHeader) * listBox.rowHeight;
       }
       return true;
    }
@@ -100,10 +106,10 @@ class CheckListBox : ListBox
       int indent = checkIndent;
 
       for(parent = row.parent; parent; parent = parent.parent) indent += 20;
-      button = buttonMaps[(int)row];
+      button = buttonMaps[(uintptr)row];
       if(!button) button = CheckListBoxButton { this };
       button.position = { 2 + indent, 1+(row.index + hasHeader) * rowHeight };
-      button.id = (int)row;
+      button.id = (uintptr)row;
 
       for(parent = row; parent; parent = parent.parent) if(rowChecks.Find(parent)) break;
       if(parent)
@@ -116,8 +122,10 @@ class CheckListBox : ListBox
          button.checked = CheckPartialChecks(row);
          button.buttonState = button.checked ? down : up;
       }
+      if(rowDisabled.Find(row))
+         button.disabled = true;
       button.Create();
-      buttonMaps[(int)row] = button;
+      buttonMaps[(uintptr)row] = button;
       if(recurse && !row.collapsed)
       {
          DataRow r;
@@ -150,8 +158,8 @@ class CheckListBox : ListBox
 
    void ToggleCheck(DataRow row)
    {
-      CheckListBoxButton checkBox = buttonMaps[(int)row];
-      if(checkBox)
+      CheckListBoxButton checkBox = buttonMaps[(uintptr)row];
+      if(checkBox && !checkBox.disabled)
       {
          bool checked = false;
          DataRow r;
@@ -167,40 +175,43 @@ class CheckListBox : ListBox
 
    void UncheckBoxes(DataRow row)
    {
-      CheckListBoxButton button = buttonMaps[(int)row];
-      if(button)
+      if(!row.parent || !row.parent.collapsed)
       {
-         bool wasChecked = button.checked;
-         button.checked = false;
-         button.buttonState = up;
-         if(wasChecked) NotifyChanged(master, this, row);
+         CheckListBoxButton button = buttonMaps[(uintptr)row];
+         if(button)
+         {
+            bool wasChecked = button.checked;
+            button.checked = false;
+            button.buttonState = up;
+         }
       }
-      if(!row.collapsed)
+      // if(!row.collapsed)
       {
          DataRow r;
          for(r = row.firstRow; r; r = r.next)
             UncheckBoxes(r);
       }
+      NotifyChecked(master, this, row);
    }
    
    void UnsetChildren(DataRow row)
    {
       DataRow r;
-      CheckListBoxButton button = buttonMaps[(int)row];
+      CheckListBoxButton button = buttonMaps[(uintptr)row];
       if(button)
       {
-         bool wasChecked = button.checked;
          button.checked = true;
          button.buttonState = up;
-         if(!wasChecked) NotifyChanged(master, this, row);
       }
 
       for(r = row.firstRow; r; r = r.next)
       {
          Iterator<DataRow> it { rowChecks };
+
          if(it.Find(r))
             it.Remove();
          UnsetChildren(r);
+         NotifyChecked(master, this, r);
       }      
    }
    
@@ -216,7 +227,7 @@ class CheckListBox : ListBox
       if(checked != wasChecked)
       {
          modifiedDocument = true;
-         // NotifyChanged(master, this, row);
+         // NotifyChecked(master, this, row);
          if(checked)
          {
             DataRow rr = row;
@@ -229,32 +240,34 @@ class CheckListBox : ListBox
                   if(r != rr && !rowChecks.Find(r))
                      break;
                }
-               if(r || !row.parent) break;
+               if(r || !rr.parent) break;
                rr = rr.parent;
             }
 
+            rowChecks.Add(rr);
+
             // Take out all children from rowChecks, checking them all
-            UnsetChildren(row);
+            UnsetChildren(rr);
 
-            rowChecks.Add(row);            
+            NotifyChecked(master, this, row);
 
-            for(parent = row.parent; parent; parent = parent.parent)
+            for(parent = rr.parent; parent; parent = parent.parent)
             {
-               DataRow r;
-               CheckListBoxButton button = buttonMaps[(int)parent];
+               CheckListBoxButton button = buttonMaps[(uintptr)parent];
                if(button)
                {
                   button.checked = true;
                   button.buttonState = down;
+
+                  NotifyChecked(master, this, parent);
                }
             }
          }
          else
          {
             DataRow rr = row;
-            UncheckBoxes(row);
-            parent = row.parent;
 
+            parent = rr.parent;
             while(rr)
             {
                Iterator<DataRow> it { rowChecks };
@@ -266,7 +279,7 @@ class CheckListBox : ListBox
                else
                {
                   DataRow r;
-                  for(r = row.parent.firstRow; r; r = r.next)
+                  for(r = rr.parent.firstRow; r; r = r.next)
                   {
                      if(r != rr)
                         rowChecks.Add(r);
@@ -275,9 +288,11 @@ class CheckListBox : ListBox
                }
             }
 
+            UncheckBoxes(row);
+
             for(; parent; parent = parent.parent)
             {
-               CheckListBoxButton button = buttonMaps[(int)parent];
+               CheckListBoxButton button = buttonMaps[(uintptr)parent];
                if(button)
                {
                   if(CheckPartialChecks(parent))
@@ -290,11 +305,11 @@ class CheckListBox : ListBox
                      button.checked = false;
                      button.buttonState = up;
                   }
+
+                  NotifyChecked(master, this, parent);
                }
             }
          }
-
-         NotifyChanged(master, this, row);
       }
    }
    
@@ -328,5 +343,35 @@ class CheckListBox : ListBox
       return true;
    }
 
-   // virtual void Window::NotifyChecked(CheckListBox listBox, DataRow row);
+public:
+   bool IsChecked(DataRow row)
+   {
+      CheckListBoxButton button = buttonMaps[(uintptr)row];
+      DataRow parent;
+      for(parent = row; parent; parent = parent.parent) if(rowChecks.Find(parent)) return true;
+      // For partially checked because of children:
+      if(button && button.checked)
+         return true;
+      return false;
+   }
+
+   virtual void Window::NotifyChecked(CheckListBox listBox, DataRow row);
+
+   void SetDisabled(DataRow row, bool disabled)
+   {
+      CheckListBoxButton checkBox = buttonMaps[(uintptr)row];
+      if(checkBox)
+         checkBox.disabled = disabled;
+
+      if(rowDisabled.Find(row))
+      {
+         if(!disabled)
+            rowDisabled.TakeOut(row);
+      }
+      else
+      {
+         if(disabled)
+            rowDisabled.Add(row);
+      }
+   }
 };