compiler/libec; eda, extras: const fixes for DB apps
[sdk] / extras / gui / controls / CheckListBox.ec
index 049e26a..a88d97a 100644 (file)
@@ -1,4 +1,8 @@
-import "ecere"
+#ifdef ECERE_STATIC
+public import static "ecere"
+#else
+public import "ecere"
+#endif
 
 class CheckListBoxButton : Button
 {
@@ -31,13 +35,14 @@ class CheckListBoxButton : Button
 
 class CheckListBox : ListBox
 {
-   Map<int, CheckListBoxButton> buttonMaps { };
+   Map<uintptr, CheckListBoxButton> buttonMaps { };
    AVLTree<DataRow> rowChecks { };
+   AVLTree<DataRow> rowDisabled { };
    int checkIndent;
 
    checkIndent = 20;
 
-   fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true, 
+   fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
    noDragging = true;
    // rowHeight = 18;
 
@@ -45,7 +50,7 @@ class CheckListBox : ListBox
    {
       buttonMaps.RemoveAll();
    }
-   
+
    bool NotifyCollapse(CheckListBox listBox, DataRow row, bool collapsed)
    {
       DataRow r;
@@ -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)
@@ -68,15 +73,15 @@ class CheckListBox : ListBox
          {
             listBox.SetupButtons(r, false);
          }
-         if(r.firstRow && !r.collapsed) 
+         if(r.firstRow && !r.collapsed)
             r = r.firstRow;
-         else 
+         else
             for(; r != row; r = r.parent)
                if(r.next) { r = r.next; break; }
       }
       for(r = row.GetNextRow(); r; r = r.GetNextRow())
       {
-         Button checkBox = listBox.buttonMaps[(int)r];
+         Button checkBox = listBox.buttonMaps[(uintptr)r];
          if(checkBox)
             checkBox.position.y = 1 + (r.index + listBox.hasHeader) * listBox.rowHeight;
       }
@@ -93,7 +98,7 @@ class CheckListBox : ListBox
       }
       return false;
    }
-   
+
    void SetupButtons(DataRow row, bool recurse)
    {
       DataRow parent;
@@ -101,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)
@@ -117,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;
@@ -139,7 +146,7 @@ class CheckListBox : ListBox
       if(ListBox::OnCreate())
       {
          DataRow row;
-         
+
          buttonMaps.RemoveAll();
 
          for(row = firstRow; row; row = row.next)
@@ -151,17 +158,17 @@ 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;
          for(r = row; r; r = r.parent)
             if(rowChecks.Find(r))
-            { 
+            {
                checked = true;
                break;
-            }         
+            }
          SetCheck(row, !checked);
       }
    }
@@ -170,10 +177,9 @@ class CheckListBox : ListBox
    {
       if(!row.parent || !row.parent.collapsed)
       {
-         CheckListBoxButton button = buttonMaps[(int)row];
+         CheckListBoxButton button = buttonMaps[(uintptr)row];
          if(button)
          {
-            bool wasChecked = button.checked;
             button.checked = false;
             button.buttonState = up;
          }
@@ -184,16 +190,15 @@ class CheckListBox : ListBox
          for(r = row.firstRow; r; r = r.next)
             UncheckBoxes(r);
       }
-      NotifyChanged(master, this, row);
+      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;
       }
@@ -205,10 +210,10 @@ class CheckListBox : ListBox
          if(it.Find(r))
             it.Remove();
          UnsetChildren(r);
-         NotifyChanged(master, this, r);
-      }      
+         NotifyChecked(master, this, r);
+      }
    }
-   
+
    void SetCheck(DataRow row, bool checked)
    {
       DataRow parent;
@@ -221,7 +226,7 @@ class CheckListBox : ListBox
       if(checked != wasChecked)
       {
          modifiedDocument = true;
-         // NotifyChanged(master, this, row);
+         // NotifyChecked(master, this, row);
          if(checked)
          {
             DataRow rr = row;
@@ -234,25 +239,26 @@ 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(row);
+            rowChecks.Add(rr);
 
             // Take out all children from rowChecks, checking them all
-            UnsetChildren(row);
+            UnsetChildren(rr);
+
+            NotifyChecked(master, this, rr);
 
-            for(parent = row.parent; parent; parent = parent.parent)
+            for(parent = rr.parent; parent; parent = parent.parent)
             {
-               CheckListBoxButton button = buttonMaps[(int)parent];
+               CheckListBoxButton button = buttonMaps[(uintptr)parent];
                if(button)
                {
-                  // Partial Check
                   button.checked = true;
                   button.buttonState = down;
 
-                  NotifyChanged(master, this, parent);
+                  NotifyChecked(master, this, parent);
                }
             }
          }
@@ -260,6 +266,7 @@ class CheckListBox : ListBox
          {
             DataRow rr = row;
 
+            parent = rr.parent;
             while(rr)
             {
                Iterator<DataRow> it { rowChecks };
@@ -271,7 +278,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);
@@ -279,11 +286,12 @@ class CheckListBox : ListBox
                   rr = rr.parent;
                }
             }
+
             UncheckBoxes(row);
 
-            for(parent = row.parent; parent; parent = parent.parent)
+            for(; parent; parent = parent.parent)
             {
-               CheckListBoxButton button = buttonMaps[(int)parent];
+               CheckListBoxButton button = buttonMaps[(uintptr)parent];
                if(button)
                {
                   if(CheckPartialChecks(parent))
@@ -297,15 +305,13 @@ class CheckListBox : ListBox
                      button.buttonState = up;
                   }
 
-                  NotifyChanged(master, this, parent);
+                  NotifyChecked(master, this, parent);
                }
             }
          }
-
-         NotifyChanged(master, this, row);
       }
    }
-   
+
    bool NotifyKeyDown(CheckListBox listBox, DataRow row, Key key, unichar ch)
    {
       if(key == space)
@@ -339,7 +345,7 @@ class CheckListBox : ListBox
 public:
    bool IsChecked(DataRow row)
    {
-      CheckListBoxButton button = buttonMaps[(int)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:
@@ -348,5 +354,23 @@ public:
       return false;
    }
 
-   // virtual void Window::NotifyChecked(CheckListBox listBox, DataRow row);
+   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);
+      }
+   }
 };