Joel Holdsworth : comctl32/rebar: Implemented dragging between rows.

Alexandre Julliard julliard at winehq.org
Mon Jan 10 10:55:21 CST 2011


Module: wine
Branch: master
Commit: 90a8e3f37f1ca1778cdb415d5809c0ccc3f76993
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=90a8e3f37f1ca1778cdb415d5809c0ccc3f76993

Author: Joel Holdsworth <joel at airwebreathe.org.uk>
Date:   Sun Jan  9 09:40:23 2011 +0000

comctl32/rebar: Implemented dragging between rows.

---

 dlls/comctl32/rebar.c |   96 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c
index 6549638..8e9c38b 100644
--- a/dlls/comctl32/rebar.c
+++ b/dlls/comctl32/rebar.c
@@ -1264,18 +1264,33 @@ static int REBAR_ShrinkBandsLTR(const REBAR_INFO *infoPtr, INT iBeginBand, INT i
 
 /* Tries to move a band to a given offset within a row. */
 static int REBAR_MoveBandToRowOffset(REBAR_INFO *infoPtr, INT iBand, INT iFirstBand,
-    INT iLastBand, INT xOff)
+    INT iLastBand, INT xOff, BOOL reorder)
 {
     REBAR_BAND *insertBand = REBAR_GetBand(infoPtr, iBand);
     int xPos = 0, i;
     const BOOL setBreak = REBAR_GetBand(infoPtr, iFirstBand)->fStyle & RBBS_BREAK;
 
     /* Find the band's new position */
-    for (i = iFirstBand; i < iLastBand; i = next_visible(infoPtr, i))
+    if(reorder)
     {
-        if(xPos > xOff)
-            break;
-        xPos += REBAR_GetBand(infoPtr, i)->cxEffective + SEP_WIDTH;
+        /* Used during an LR band reorder drag */
+        for (i = iFirstBand; i < iLastBand; i = next_visible(infoPtr, i))
+        {
+            if(xPos > xOff)
+                break;
+            xPos += REBAR_GetBand(infoPtr, i)->cxEffective + SEP_WIDTH;
+        }
+    }
+    else
+    {
+        /* Used during a UD band insertion drag */
+        for (i = iFirstBand; i < iLastBand; i = next_visible(infoPtr, i))
+        {
+            const REBAR_BAND *band = REBAR_GetBand(infoPtr, i);
+            if(xPos + band->cxMinBand / 2 > xOff)
+                break;
+            xPos += band->cxEffective + SEP_WIDTH;
+        }
     }
 
     /* Move the band to its new position */
@@ -2036,8 +2051,6 @@ REBAR_HandleLRDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
      /*  Gripper drag within a row. It will not implement "out-   */
      /*  of-row" drags. (They are detected and handled in         */
      /*  REBAR_MouseMove.)                                        */
-     /*  **** FIXME Switching order of bands in a row not   ****  */
-     /*  ****       yet implemented.                        ****  */
 {
     REBAR_BAND *hitBand;
     INT iHitBand, iRowBegin, iRowEnd;
@@ -2088,7 +2101,7 @@ REBAR_HandleLRDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
         /* It was not possible to move the band by shrinking bands.
          * Try relocating the band instead. */
         REBAR_MoveBandToRowOffset(infoPtr, iHitBand, iRowBegin,
-            iRowEnd, xBand + movement);
+            iRowEnd, xBand + movement, TRUE);
     }
 
     REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
@@ -2099,6 +2112,71 @@ REBAR_HandleLRDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
     REBAR_MoveChildWindows(infoPtr, iRowBegin, iRowEnd);
 }
 
+static void
+REBAR_HandleUDDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
+{
+    INT yOff = (infoPtr->dwStyle & CCS_VERT) ? ptsmove->x : ptsmove->y;
+    INT iHitBand, iRowBegin, iNextRowBegin;
+    REBAR_BAND *hitBand, *rowBeginBand;
+
+    if(infoPtr->uNumBands <= 0)
+        ERR("There are no bands in this rebar");
+
+    /* Up/down dragging can only occur when there is more than one
+     * band in the rebar */
+    if(infoPtr->uNumBands <= 1)
+        return;
+
+    iHitBand = infoPtr->iGrabbedBand;
+    hitBand = REBAR_GetBand(infoPtr, iHitBand);
+
+    /* If we're taking a band that has the RBBS_BREAK style set, this
+     * style needs to be reapplied to the band that is going to become
+     * the new start of the row. */
+    if((hitBand->fStyle & RBBS_BREAK) &&
+        (iHitBand < infoPtr->uNumBands - 1))
+        REBAR_GetBand(infoPtr, iHitBand + 1)->fStyle |= RBBS_BREAK;
+
+    if(yOff < 0)
+    {
+        /* Place the band above the current top row */
+        DPA_DeletePtr(infoPtr->bands, iHitBand);
+        hitBand->fStyle &= RBBS_BREAK;
+        REBAR_GetBand(infoPtr, 0)->fStyle |= RBBS_BREAK;
+        infoPtr->iGrabbedBand = DPA_InsertPtr(
+            infoPtr->bands, 0, hitBand);
+    }
+    else if(yOff > REBAR_GetBand(infoPtr, infoPtr->uNumBands - 1)->rcBand.bottom)
+    {
+        /* Place the band below the current bottom row */
+        DPA_DeletePtr(infoPtr->bands, iHitBand);
+        hitBand->fStyle |= RBBS_BREAK;
+        infoPtr->iGrabbedBand = DPA_InsertPtr(
+            infoPtr->bands, infoPtr->uNumBands - 1, hitBand);
+    }
+    else
+    {
+        /* Place the band in the prexisting row the mouse is hovering over */
+        iRowBegin = first_visible(infoPtr);
+        while(iRowBegin < infoPtr->uNumBands)
+        {
+            iNextRowBegin = get_row_end_for_band(infoPtr, iRowBegin);
+            rowBeginBand = REBAR_GetBand(infoPtr, iRowBegin);
+            if(rowBeginBand->rcBand.bottom > yOff)
+            {
+                REBAR_MoveBandToRowOffset(
+                    infoPtr, iHitBand, iRowBegin, iNextRowBegin,
+                    ((infoPtr->dwStyle & CCS_VERT) ? ptsmove->y : ptsmove->x)
+                        - REBAR_PRE_GRIPPER - infoPtr->ihitoffset, FALSE);
+                break;
+            }
+
+            iRowBegin = iNextRowBegin;
+        }
+    }
+
+    REBAR_Layout(infoPtr);
+}
 
 
 /* << REBAR_BeginDrag >> */
@@ -3098,7 +3176,7 @@ REBAR_MouseMove (REBAR_INFO *infoPtr, LPARAM lParam)
         /* Test for valid drag case - must not be first band in row */
         if ((yPtMove < band->rcBand.top) ||
               (yPtMove > band->rcBand.bottom)) {
-            FIXME("Cannot drag to other rows yet!!\n");
+            REBAR_HandleUDDrag (infoPtr, &ptMove);
         }
         else {
             REBAR_HandleLRDrag (infoPtr, &ptMove);




More information about the wine-cvs mailing list