ecere/gui/controls/ListBox: Fixes for moving row in tree views
[sdk] / ecere / src / gui / controls / ListBox.ec
index d9ce74a..7ae0fd0 100644 (file)
@@ -489,13 +489,13 @@ public:
 
             if(!after || after.index < index)
             {
-               if(after == listBox.firstRowShown.prev)
+               if((after && after == listBox.firstRowShown.prev) || (!after && !parent && listBox.firstRowShown.prev))
                   listBox.firstRowShown = this;
 
                // All rows between AFTER (exclusive) and ROW (exclusive) are incremented by one
                // ROW is equal to AFTER's index + 1
 
-               for(search = after ? after.next : listBox.rows.first; search && search != this; search = search.GetNextRow())
+               for(search = after ? after.next : (parent ? parent.subRows.first : listBox.rows.first); search && search != this; search = search.GetNextRow())
                   search.index += ixCount;
 
                if(after && after.subRows.first && !after.collapsed)
@@ -504,7 +504,7 @@ public:
                   index = search.index + 1;
                }
                else
-                  index = after ? (after.index + 1) : 0;
+                  index = after ? (after.index + 1) : parent ? parent.index + 1 : 0;
 
                // Fix indices of sub rows
                if(!collapsed)
@@ -516,10 +516,12 @@ public:
             }
             else
             {
-               DataRow nextRow = GetNextRow();
+               DataRow nextRow;
+               int afterIXCount = 1;
+
+               nextRow = GetNextRow();
                if(this == listBox.firstRowShown)
                   listBox.firstRowShown = nextRow;
-               index = after.index;
 
                // All rows between ROW (exclusive) and AFTER (inclusive) are decremented by one
                // ROW is equal to AFTER's index
@@ -529,8 +531,33 @@ public:
                   search.index -= ixCount;
                   if(search == after) break;
                }
+
+               // Fix up's after's sub rows
+               if(after && !after.collapsed)
+               {
+                  DataRow last = after.GetLastRow();
+                  if(last != after)
+                  {
+                     int ix = after.index+1;
+                     for(search = after.GetNextRow(); search; search = search.GetNextRow())
+                     {
+                        afterIXCount++;
+                        search.index = ix++;
+                        if(search == last) break;
+                     }
+                  }
+               }
+               index = after.index + afterIXCount;
+
+               // Fix indices of sub rows
+               if(!collapsed)
+               {
+                  int c, ix = index+1;
+                  for(c = 1, search = GetNextRow(); search && c < ixCount; c++, search = search.GetNextRow())
+                     search.index = ix++;
+               }
             }
-            listBox.rows.Move(this, after);
+            (parent ? parent.subRows : listBox.rows).Move(this, after);
 
 #ifdef _DEBUG
             listBox.CheckConsistency();
@@ -1104,6 +1131,7 @@ public:
    virtual bool Window::NotifyKeyHit(ListBox listBox, DataRow row, Key key, unichar ch);
    virtual bool Window::NotifyModified(ListBox listBox, DataRow row);
    virtual bool Window::NotifyEditing(ListBox listBox, DataRow row);
+   virtual void Window::NotifyMoved(ListBox listBox, DataRow row, Modifiers mods);
 
 #ifdef _DEBUG
    private void CheckConsistency()
@@ -2493,6 +2521,10 @@ private:
                   foreground = this.background;
                }
 
+#ifdef _DEBUG
+               // surface.WriteTextf(x + 100, y,  "ix: %d", row.index);
+#endif
+
                x += width;// + EXTRA_SPACE;
 
                if(row.header) break;
@@ -2978,7 +3010,7 @@ private:
          if(!visible)
          {
             ReleaseCapture();
-            this.rolledOver = this.dragging = false;
+            rolledOver = dragging = false;
          }
          /*else
             Capture();*/
@@ -3174,16 +3206,16 @@ private:
       }
 
       // ADDED THIS CHECK FOR FieldDropBox LEAKS
-      if(/*!mods.isSideEffect && */(this.rolledOver || !this.dragging))
+      if(/*!mods.isSideEffect && */(rolledOver || !dragging))
       {
          int rowY = (style.header) ? rowHeight : 0;
-         DataRow row = null;
+         DataRow row = null, nextRow;
          int rowIndex;
 
          mouseX = x;
          mouseY = y;
 
-         if(this.dragging &&
+         if(dragging &&
             ((vertScroll && vertScroll.visible &&
              (y < 0 || y >= clientSize.h)) ||
              (horzScroll && horzScroll.visible &&
@@ -3206,15 +3238,20 @@ private:
          // This must be done after the scrolling took place
          rowIndex = firstRowShown ? firstRowShown.index : -1;
          y = Max(y, 0);
-         y = Min(y, clientSize.h-1);
-         for(row = firstRowShown; row; row = row.GetNextRow(), rowIndex ++)
+         y = Min(y, clientSize.h-rowHeight-1);
+         for(row = firstRowShown; row; row = nextRow, rowIndex ++)
          {
+            nextRow = row.GetNextRow();
             rowY += rowHeight;
-            if(rowY > y)
+            if(rowY > y || !nextRow)
             {
                break;
             }
          }
+         if(row && row == currentRow)
+            row = row.GetNextRow();
+         if(row && row.parent == currentRow)
+            row = row.GetNextRow();
 
          if(row && currentRow != row)
          {
@@ -3240,7 +3277,7 @@ private:
                   this.movedRow = true;
                }
             }
-            else if((style.freeSelect  || this.dragging) && ((realX>= 0 && realY >= 0 && realX< clientSize.w && realY < clientSize.h) || this.rolledOver))
+            else if((style.freeSelect  || this.dragging) && ((realX>= 0 && realY >= 0 && realX< clientSize.w && realY < clientSize.h) || rolledOver))
             {
                if(!(style.multiSelect))
                {
@@ -3298,8 +3335,8 @@ private:
 
    bool OnMouseOver(int x, int y, Modifiers mods)
    {
-      if(this.dragging)
-         this.rolledOver = true;
+      if(dragging)
+         rolledOver = true;
       return true;
    }
 
@@ -3617,6 +3654,8 @@ private:
                      this.dragRow = currentRow;
                      this.dropIndex = -1;
                      this.movedRow = false;
+
+                     Capture();
                   }
                   if(editData && editData.visible && style.alwaysEdit)
                   {
@@ -3779,11 +3818,11 @@ private:
       {
          if(!style.noDragging)
          {
-            this.dragging = true;
+            dragging = true;
             Capture();
          }
          if(x >= 0 && y >= 0 && x < clientSize.w && y < clientSize.h)
-            this.rolledOver = true;
+            rolledOver = true;
          Update(null);
       }
       else
@@ -3812,6 +3851,7 @@ private:
       {
          DataRow row, switchRow = rows.last;
          int rowY = (style.header) ? rowHeight : 0;
+         while(switchRow.lastRow) switchRow = switchRow.lastRow;
          for(row = firstRowShown; row; row = row.GetNextRow())
          {
             rowY += rowHeight;
@@ -3920,18 +3960,50 @@ private:
                   // Switch row first: move before
                   if(row == switchRow)
                   {
-                     if(NotifyMove(master, this, switchRow.prev, mods))
-                        dragRow.Move(switchRow.prev);
+                     DataRow actualMoveRow;
+
+                     if(!switchRow.prev && switchRow.parent == dragRow.parent)
+                        actualMoveRow = null;
+                     else
+                     {
+                        actualMoveRow = switchRow.prev ? switchRow.prev : switchRow;
+                        while(actualMoveRow && actualMoveRow.parent != dragRow.parent && actualMoveRow.parent)
+                           actualMoveRow = actualMoveRow.parent;
+                     }
+
+                     if(!actualMoveRow || (actualMoveRow && actualMoveRow.parent == dragRow.parent))
+                        if(NotifyMove(master, this, actualMoveRow, mods))
+                        {
+                           dragRow.Move(actualMoveRow);
+                           NotifyMoved(master, this, actualMoveRow, mods);
+                        }
                   }
                   // Dragged row first: move after
                   else
                   {
-                     if(NotifyMove(master, this, switchRow, mods))
-                        dragRow.Move(switchRow);
+                     DataRow actualMoveRow = switchRow;
+                     DataRow nextRow = switchRow.GetNextRow();
+
+                     while(nextRow && nextRow.parent != dragRow.parent)
+                        nextRow = nextRow.parent ? nextRow.parent.next : null;
+                     if(nextRow)
+                        actualMoveRow = nextRow.prev;
+
+                     if(!nextRow)
+                        actualMoveRow = dragRow.parent ? dragRow.parent.subRows.last : rows.last;
+
+                     if(!actualMoveRow || (actualMoveRow != dragRow && actualMoveRow.parent == dragRow.parent))
+                        if(NotifyMove(master, this, actualMoveRow, mods))
+                        {
+                           dragRow.Move(actualMoveRow);
+                           NotifyMoved(master, this, actualMoveRow, mods);
+                        }
                   }
                }
             }
          }
+         if(dragRow)
+            ReleaseCapture();
          dragRow = null;
          editRow = null;
          movedRow = false;
@@ -3940,11 +4012,11 @@ private:
       }
 
       timer.Stop();
-      if(this.dragging || style.freeSelect)
+      if(dragging || style.freeSelect)
       {
-         if(this.dragging)
+         if(dragging)
          {
-            this.rolledOver = this.dragging = false;
+            rolledOver = dragging = false;
          }
          if(x >= 0 && y >= 0 && x < clientSize.w && y < clientSize.h && currentRow && style.freeSelect)
          {
@@ -4098,7 +4170,7 @@ private:
       }
       else if(key == escape)
       {
-         if(resizingField || this.movingFields || (editData && editData.visible) || this.dragRow)
+         if(resizingField || this.movingFields || (editData && editData.visible) || dragRow)
          {
             if(editData && editData.visible && style.alwaysEdit && !editData.active)
                return true;
@@ -4111,10 +4183,13 @@ private:
                resizingField = null;
                ReleaseCapture();
             }
-            this.dragRow = null;
-            if(this.dragging)
+            if(dragRow)
+               ReleaseCapture();
+
+            dragRow = null;
+            if(dragging)
             {
-               this.dragging = false;
+               dragging = false;
                ReleaseCapture();
             }
 
@@ -4508,7 +4583,7 @@ private:
    int rowCount;
    int rowHeight;
    int fontH;
-   double typingTimeOut;
+   public double typingTimeOut;
    char * typedString;
 
    int mouseX, mouseY;