comctl32: rebar[1/4]: rewrite the layouting code
Mikołaj Zalewski
mikolaj at zalewski.pl
Sat Feb 17 15:10:51 CST 2007
As this patch is big and will probably have to wait for the moderator I
will write a comment in the second patch
-------------- next part --------------
From 2b42e9b97b443ced2531a445b531fddc5db2dcad Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Miko=C5=82aj_Zalewski?= <mikolaj at zalewski.pl>
Date: Sat, 17 Feb 2007 19:24:25 +0100
Subject: [PATCH] comctl32: rebar: rewrite the layouting code
---
dlls/comctl32/rebar.c | 1735 +++++++++++++------------------------------
dlls/comctl32/tests/rebar.c | 421 ++++++++++-
2 files changed, 901 insertions(+), 1255 deletions(-)
diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c
index 9550eb5..9da110c 100644
--- a/dlls/comctl32/rebar.c
+++ b/dlls/comctl32/rebar.c
@@ -127,20 +127,14 @@ typedef struct
LPARAM lParam;
UINT cxHeader;
+ INT cxEffective; /* current cx for band */
UINT lcx; /* minimum cx for band */
- UINT ccx; /* current cx for band */
- UINT hcx; /* maximum cx for band */
UINT lcy; /* minimum cy for band */
- UINT ccy; /* current cy for band */
- UINT hcy; /* maximum cy for band */
- SIZE offChild; /* x,y offset if child is not FIXEDSIZE */
- UINT uMinHeight;
INT iRow; /* zero-based index of the row this band assigned to */
UINT fStatus; /* status flags, reset only by _Validate */
UINT fDraw; /* drawing flags, reset only by _Layout */
UINT uCDret; /* last return from NM_CUSTOMDRAW */
- RECT rcoldBand; /* previous calculated band rectangle */
RECT rcBand; /* calculated band rectangle */
RECT rcGripper; /* calculated gripper rectangle */
RECT rcCapImage; /* calculated caption image rectangle */
@@ -161,12 +155,8 @@ typedef struct
#define DRAW_GRIPPER 0x00000001
#define DRAW_IMAGE 0x00000002
#define DRAW_TEXT 0x00000004
-#define DRAW_RIGHTSEP 0x00000010
-#define DRAW_BOTTOMSEP 0x00000020
#define DRAW_CHEVRONHOT 0x00000040
#define DRAW_CHEVRONPUSHED 0x00000080
-#define DRAW_LAST_IN_ROW 0x00000100
-#define DRAW_FIRST_IN_ROW 0x00000200
#define NTF_INVALIDATE 0x01000000
typedef struct
@@ -250,10 +240,16 @@ typedef struct
/* Width of the chevron button if present */
#define CHEVRON_WIDTH 10
+/* the gap between the child and the next band */
+#define REBAR_POST_CHILD 4
+
/* Height of divider for Rebar if not disabled (CCS_NODIVIDER) */
/* either top or bottom */
#define REBAR_DIVIDER 2
+/* height of a rebar without a child */
+#define REBAR_NO_CHILD_HEIGHT 4
+
/* minimium vertical height of a normal bar */
/* or minimum width of a CCS_VERT bar - from experiment on Win2k */
#define REBAR_MINSIZE 23
@@ -265,29 +261,11 @@ typedef struct
#define RB_GETBANDINFO_OLD (WM_USER+5) /* obsoleted after IE3, but we have to support it anyway */
-/* The following 6 defines return the proper rcBand element */
-/* depending on whether CCS_VERT was set. */
-#define rcBlt(b) ((infoPtr->dwStyle & CCS_VERT) ? b->rcBand.top : b->rcBand.left)
-#define rcBrb(b) ((infoPtr->dwStyle & CCS_VERT) ? b->rcBand.bottom : b->rcBand.right)
-#define rcBw(b) ((infoPtr->dwStyle & CCS_VERT) ? (b->rcBand.bottom - b->rcBand.top) : \
- (b->rcBand.right - b->rcBand.left))
-#define ircBlt(b) ((infoPtr->dwStyle & CCS_VERT) ? b->rcBand.left : b->rcBand.top)
-#define ircBrb(b) ((infoPtr->dwStyle & CCS_VERT) ? b->rcBand.right : b->rcBand.bottom)
-#define ircBw(b) ((infoPtr->dwStyle & CCS_VERT) ? (b->rcBand.right - b->rcBand.left) : \
- (b->rcBand.bottom - b->rcBand.top))
-
/* The following define determines if a given band is hidden */
#define HIDDENBAND(a) (((a)->fStyle & RBBS_HIDDEN) || \
((infoPtr->dwStyle & CCS_VERT) && \
((a)->fStyle & RBBS_NOVERT)))
-/* The following defines adjust the right or left end of a rectangle */
-#define READJ(b,i) do { if(infoPtr->dwStyle & CCS_VERT) b->rcBand.bottom+=(i); \
- else b->rcBand.right += (i); } while(0)
-#define LEADJ(b,i) do { if(infoPtr->dwStyle & CCS_VERT) b->rcBand.top+=(i); \
- else b->rcBand.left += (i); } while(0)
-
-
#define REBAR_GetInfoPtr(wndPtr) ((REBAR_INFO *)GetWindowLongPtrW (hwnd, 0))
static LRESULT REBAR_NotifyFormat(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam);
@@ -429,8 +407,8 @@ REBAR_DumpBand (REBAR_INFO *iP)
if (pB->fMask & RBBIM_STYLE)
TRACE("band # %u: style=0x%08x (%s)\n",
i, pB->fStyle, REBAR_FmtStyle(pB->fStyle));
- TRACE("band # %u: uMinH=%u xHeader=%u",
- i, pB->uMinHeight, pB->cxHeader);
+ TRACE("band # %u: xHeader=%u",
+ i, pB->cxHeader);
if (pB->fMask & (RBBIM_SIZE | RBBIM_IDEALSIZE | RBBIM_LPARAM )) {
if (pB->fMask & RBBIM_SIZE)
TRACE(" cx=%u", pB->cx);
@@ -446,8 +424,8 @@ REBAR_DumpBand (REBAR_INFO *iP)
if (pB->fMask & RBBIM_TEXT)
TRACE("band # %u: text=%s\n",
i, (pB->lpText) ? debugstr_w(pB->lpText) : "(null)");
- TRACE("band # %u: lcx=%u, ccx=%u, hcx=%u, lcy=%u, ccy=%u, hcy=%u, offChild=%d,%d\n",
- i, pB->lcx, pB->ccx, pB->hcx, pB->lcy, pB->ccy, pB->hcy, pB->offChild.cx, pB->offChild.cy);
+ TRACE("band # %u: lcx=%u, cxEffective=%u, lcy=%u\n",
+ i, pB->lcx, pB->cxEffective, pB->lcy);
TRACE("band # %u: fStatus=%08x, fDraw=%08x, Band=(%d,%d)-(%d,%d), Grip=(%d,%d)-(%d,%d)\n",
i, pB->fStatus, pB->fDraw,
pB->rcBand.left, pB->rcBand.top, pB->rcBand.right, pB->rcBand.bottom,
@@ -461,6 +439,43 @@ REBAR_DumpBand (REBAR_INFO *iP)
}
+static void translate_rect(REBAR_INFO *infoPtr, RECT *dest, const RECT *src)
+{
+ if (infoPtr->dwStyle & CCS_VERT) {
+ dest->top = src->left;
+ dest->bottom = src->right;
+ dest->left = src->top;
+ dest->right = src->bottom;
+ } else {
+ *dest = *src;
+ }
+}
+
+static int get_rect_cx(REBAR_INFO *infoPtr, RECT *lpRect)
+{
+ if (infoPtr->dwStyle & CCS_VERT)
+ return lpRect->bottom - lpRect->top;
+ return lpRect->right - lpRect->left;
+}
+
+static int get_rect_cy(REBAR_INFO *infoPtr, RECT *lpRect)
+{
+ if (infoPtr->dwStyle & CCS_VERT)
+ return lpRect->right - lpRect->left;
+ return lpRect->bottom - lpRect->top;
+}
+
+static void round_child_height(REBAR_BAND *lpBand, int cyHeight)
+{
+ int cy = 0;
+ if (lpBand->cyIntegral == 0)
+ return;
+ cy = max(cyHeight - (int)lpBand->cyMinChild, 0);
+ cy = lpBand->cyMinChild + (cy/lpBand->cyIntegral) * lpBand->cyIntegral;
+ cy = min(cy, lpBand->cyMaxChild);
+ lpBand->cyChild = cy;
+}
+
static void
REBAR_DrawChevron (HDC hdc, INT left, INT top, INT colorRef)
{
@@ -544,6 +559,9 @@ REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
INT oldBkMode = 0;
NMCUSTOMDRAW nmcd;
HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
+ RECT rcBand;
+
+ translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
if (lpBand->fDraw & DRAW_TEXT) {
hOldFont = SelectObject (hdc, infoPtr->hFont);
@@ -553,7 +571,7 @@ REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
/* should test for CDRF_NOTIFYITEMDRAW here */
nmcd.dwDrawStage = CDDS_ITEMPREPAINT;
nmcd.hdc = hdc;
- nmcd.rc = lpBand->rcBand;
+ nmcd.rc = rcBand;
nmcd.rc.right = lpBand->rcCapText.right;
nmcd.rc.bottom = lpBand->rcCapText.bottom;
nmcd.dwItemSpec = lpBand->wID;
@@ -649,7 +667,7 @@ REBAR_DrawBand (HDC hdc, REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
if (lpBand->uCDret == (CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYITEMDRAW)) {
nmcd.dwDrawStage = CDDS_ITEMPOSTPAINT;
nmcd.hdc = hdc;
- nmcd.rc = lpBand->rcBand;
+ nmcd.rc = rcBand;
nmcd.rc.right = lpBand->rcCapText.right;
nmcd.rc.bottom = lpBand->rcCapText.bottom;
nmcd.dwItemSpec = lpBand->wID;
@@ -683,235 +701,14 @@ REBAR_Refresh (REBAR_INFO *infoPtr, HDC hdc)
static void
-REBAR_FixVert (REBAR_INFO *infoPtr, UINT rowstart, UINT rowend,
- INT mcy)
- /* Function: */
- /* Cycle through bands in row and fix height of each band. */
- /* Also determine whether each band has changed. */
- /* On entry: */
- /* all bands at desired size. */
- /* start and end bands are *not* hidden */
-{
- REBAR_BAND *lpBand;
- INT i;
-
- for (i = (INT)rowstart; i<=(INT)rowend; i++) {
- lpBand = &infoPtr->bands[i];
- if (HIDDENBAND(lpBand)) continue;
-
- /* adjust height of bands in row to "mcy" value */
- if (infoPtr->dwStyle & CCS_VERT) {
- if (lpBand->rcBand.right != lpBand->rcBand.left + mcy)
- lpBand->rcBand.right = lpBand->rcBand.left + mcy;
- }
- else {
- if (lpBand->rcBand.bottom != lpBand->rcBand.top + mcy)
- lpBand->rcBand.bottom = lpBand->rcBand.top + mcy;
-
- }
-
- /* mark whether we need to invalidate this band and trace */
- if ((lpBand->rcoldBand.left !=lpBand->rcBand.left) ||
- (lpBand->rcoldBand.top !=lpBand->rcBand.top) ||
- (lpBand->rcoldBand.right !=lpBand->rcBand.right) ||
- (lpBand->rcoldBand.bottom !=lpBand->rcBand.bottom)) {
- lpBand->fDraw |= NTF_INVALIDATE;
- TRACE("band %d row=%d: changed to (%d,%d)-(%d,%d) from (%d,%d)-(%d,%d)\n",
- i, lpBand->iRow,
- lpBand->rcBand.left, lpBand->rcBand.top,
- lpBand->rcBand.right, lpBand->rcBand.bottom,
- lpBand->rcoldBand.left, lpBand->rcoldBand.top,
- lpBand->rcoldBand.right, lpBand->rcoldBand.bottom);
- }
- else
- TRACE("band %d row=%d: unchanged (%d,%d)-(%d,%d)\n",
- i, lpBand->iRow,
- lpBand->rcBand.left, lpBand->rcBand.top,
- lpBand->rcBand.right, lpBand->rcBand.bottom);
- }
-}
-
-
-static void
-REBAR_AdjustBands (REBAR_INFO *infoPtr, UINT rowstart, UINT rowend,
- INT maxx, INT mcy)
- /* Function: This routine distributes the extra space in a row. */
- /* See algorithm below. */
- /* On entry: */
- /* all bands @ ->cxHeader size */
- /* start and end bands are *not* hidden */
-{
- REBAR_BAND *lpBand;
- UINT xsep, extra, curwidth, fudge;
- INT x, i, last_adjusted;
-
- TRACE("start=%u, end=%u, max x=%d, max y=%d\n",
- rowstart, rowend, maxx, mcy);
-
- /* ******************* Phase 1 ************************ */
- /* Alg: */
- /* For each visible band with valid child */
- /* a. inflate band till either all extra space used */
- /* or band's ->ccx reached. */
- /* If any band modified, add any space left to last band */
- /* adjusted. */
- /* */
- /* ****************************************************** */
- lpBand = &infoPtr->bands[rowend];
- extra = maxx - rcBrb(lpBand);
- x = 0;
- last_adjusted = -1;
- for (i=(INT)rowstart; i<=(INT)rowend; i++) {
- lpBand = &infoPtr->bands[i];
- if (HIDDENBAND(lpBand)) continue;
- xsep = (x == 0) ? 0 : SEP_WIDTH;
- curwidth = rcBw(lpBand);
-
- /* set new left/top point */
- if (infoPtr->dwStyle & CCS_VERT)
- lpBand->rcBand.top = x + xsep;
- else
- lpBand->rcBand.left = x + xsep;
-
- /* compute new width */
- if ((lpBand->hwndChild && extra) && !(lpBand->fStyle & RBBS_FIXEDSIZE)) {
- /* set to the "current" band size less the header */
- fudge = lpBand->ccx;
- last_adjusted = i;
- if ((lpBand->fMask & RBBIM_SIZE) && (lpBand->cx > 0) &&
- (fudge > curwidth)) {
- TRACE("adjusting band %d by %d, fudge=%d, curwidth=%d, extra=%d\n",
- i, fudge-curwidth, fudge, curwidth, extra);
- if ((fudge - curwidth) > extra)
- fudge = curwidth + extra;
- extra -= (fudge - curwidth);
- curwidth = fudge;
- }
- else {
- TRACE("adjusting band %d by %d, fudge=%d, curwidth=%d\n",
- i, extra, fudge, curwidth);
- curwidth += extra;
- extra = 0;
- }
- }
-
- /* set new right/bottom point */
- if (infoPtr->dwStyle & CCS_VERT)
- lpBand->rcBand.bottom = lpBand->rcBand.top + curwidth;
- else
- lpBand->rcBand.right = lpBand->rcBand.left + curwidth;
- TRACE("Phase 1 band %d, (%d,%d)-(%d,%d), orig x=%d, xsep=%d\n",
- i, lpBand->rcBand.left, lpBand->rcBand.top,
- lpBand->rcBand.right, lpBand->rcBand.bottom, x, xsep);
- x = rcBrb(lpBand);
- }
- if ((x >= maxx) || (last_adjusted != -1)) {
- if (x > maxx) {
- ERR("Phase 1 failed, x=%d, maxx=%d, start=%u, end=%u\n",
- x, maxx, rowstart, rowend);
- }
- /* done, so spread extra space */
- if (x < maxx) {
- fudge = maxx - x;
- TRACE("Need to spread %d on last adjusted band %d\n",
- fudge, last_adjusted);
- for (i=(INT)last_adjusted; i<=(INT)rowend; i++) {
- lpBand = &infoPtr->bands[i];
- if (HIDDENBAND(lpBand)) continue;
-
- /* set right/bottom point */
- if (i != last_adjusted) {
- if (infoPtr->dwStyle & CCS_VERT)
- lpBand->rcBand.top += fudge;
- else
- lpBand->rcBand.left += fudge;
- }
-
- /* set left/bottom point */
- if (infoPtr->dwStyle & CCS_VERT)
- lpBand->rcBand.bottom += fudge;
- else
- lpBand->rcBand.right += fudge;
- }
- }
- TRACE("Phase 1 succeeded, used x=%d\n", x);
- REBAR_FixVert (infoPtr, rowstart, rowend, mcy);
- return;
- }
-
- /* ******************* Phase 2 ************************ */
- /* Alg: */
- /* Find first visible band, put all */
- /* extra space there. */
- /* */
- /* ****************************************************** */
-
- x = 0;
- for (i=(INT)rowstart; i<=(INT)rowend; i++) {
- lpBand = &infoPtr->bands[i];
- if (HIDDENBAND(lpBand)) continue;
- xsep = (x == 0) ? 0 : SEP_WIDTH;
- curwidth = rcBw(lpBand);
-
- /* set new left/top point */
- if (infoPtr->dwStyle & CCS_VERT)
- lpBand->rcBand.top = x + xsep;
- else
- lpBand->rcBand.left = x + xsep;
-
- /* compute new width */
- if (extra) {
- curwidth += extra;
- extra = 0;
- }
-
- /* set new right/bottom point */
- if (infoPtr->dwStyle & CCS_VERT)
- lpBand->rcBand.bottom = lpBand->rcBand.top + curwidth;
- else
- lpBand->rcBand.right = lpBand->rcBand.left + curwidth;
- TRACE("Phase 2 band %d, (%d,%d)-(%d,%d), orig x=%d, xsep=%d\n",
- i, lpBand->rcBand.left, lpBand->rcBand.top,
- lpBand->rcBand.right, lpBand->rcBand.bottom, x, xsep);
- x = rcBrb(lpBand);
- }
- if (x >= maxx) {
- if (x > maxx) {
- ERR("Phase 2 failed, x=%d, maxx=%d, start=%u, end=%u\n",
- x, maxx, rowstart, rowend);
- }
- /* done, so spread extra space */
- TRACE("Phase 2 succeeded, used x=%d\n", x);
- REBAR_FixVert (infoPtr, rowstart, rowend, mcy);
- return;
- }
-
- /* ******************* Phase 3 ************************ */
- /* at this point everything is back to ->cxHeader values */
- /* and should not have gotten here. */
- /* ****************************************************** */
-
- lpBand = &infoPtr->bands[rowstart];
- ERR("Serious problem adjusting row %d, start band %d, end band %d\n",
- lpBand->iRow, rowstart, rowend);
- REBAR_DumpBand (infoPtr);
- return;
-}
-
-
-static void
-REBAR_CalcHorzBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
+REBAR_CalcHorzBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend)
/* Function: this routine initializes all the rectangles in */
/* each band in a row to fit in the adjusted rcBand rect. */
/* *** Supports only Horizontal bars. *** */
{
REBAR_BAND *lpBand;
UINT i, xoff, yoff;
- HWND parenthwnd;
- RECT oldChild, work;
-
- /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
- parenthwnd = GetParent (infoPtr->hwndSelf);
+ RECT work;
for(i=rstart; i<rend; i++){
lpBand = &infoPtr->bands[i];
@@ -922,8 +719,6 @@ REBAR_CalcHorzBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
continue;
}
- oldChild = lpBand->rcChild;
-
/* set initial gripper rectangle */
SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
lpBand->rcBand.left, lpBand->rcBand.bottom);
@@ -960,11 +755,6 @@ REBAR_CalcHorzBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
SetRect (&lpBand->rcCapText,
lpBand->rcCapImage.right+REBAR_POST_IMAGE, lpBand->rcBand.top+1,
lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.bottom-1);
- /* update band height
- if (lpBand->uMinHeight < infoPtr->imageSize.cy + 2) {
- lpBand->uMinHeight = infoPtr->imageSize.cy + 2;
- lpBand->rcBand.bottom = lpBand->rcBand.top + lpBand->uMinHeight;
- } */
}
else {
/* set initial caption text rectangle */
@@ -980,12 +770,12 @@ REBAR_CalcHorzBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
}
/* set initial child window rectangle if there is a child */
- if (lpBand->fMask & RBBIM_CHILD) {
- xoff = lpBand->offChild.cx;
- yoff = lpBand->offChild.cy;
+ if (lpBand->hwndChild != NULL) {
+ int cyBand = lpBand->rcBand.bottom - lpBand->rcBand.top;
+ yoff = (cyBand - lpBand->cyChild) / 2;
SetRect (&lpBand->rcChild,
- lpBand->rcBand.left+lpBand->cxHeader, lpBand->rcBand.top+yoff,
- lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
+ lpBand->rcBand.left + lpBand->cxHeader, lpBand->rcBand.top + yoff,
+ lpBand->rcBand.right - REBAR_POST_CHILD, lpBand->rcBand.top + yoff + lpBand->cyChild);
if ((lpBand->fStyle & RBBS_USECHEVRON) && (lpBand->rcChild.right - lpBand->rcChild.left < lpBand->cxIdeal))
{
lpBand->rcChild.right -= CHEVRON_WIDTH;
@@ -1001,26 +791,16 @@ REBAR_CalcHorzBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
}
/* flag if notify required and invalidate rectangle */
- if (notify &&
- ((oldChild.right-oldChild.left != lpBand->rcChild.right-lpBand->rcChild.left) ||
- (oldChild.bottom-oldChild.top != lpBand->rcChild.bottom-lpBand->rcChild.top))) {
- TRACE("Child rectangle changed for band %u\n", i);
- TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
- oldChild.left, oldChild.top,
- oldChild.right, oldChild.bottom,
- lpBand->rcChild.left, lpBand->rcChild.top,
- lpBand->rcChild.right, lpBand->rcChild.bottom);
- }
if (lpBand->fDraw & NTF_INVALIDATE) {
TRACE("invalidating (%d,%d)-(%d,%d)\n",
lpBand->rcBand.left,
lpBand->rcBand.top,
- lpBand->rcBand.right + ((lpBand->fDraw & DRAW_RIGHTSEP) ? SEP_WIDTH_SIZE : 0),
- lpBand->rcBand.bottom + ((lpBand->fDraw & DRAW_BOTTOMSEP) ? SEP_WIDTH_SIZE : 0));
+ lpBand->rcBand.right + SEP_WIDTH,
+ lpBand->rcBand.bottom + SEP_WIDTH);
lpBand->fDraw &= ~NTF_INVALIDATE;
work = lpBand->rcBand;
- if (lpBand->fDraw & DRAW_RIGHTSEP) work.right += SEP_WIDTH_SIZE;
- if (lpBand->fDraw & DRAW_BOTTOMSEP) work.bottom += SEP_WIDTH_SIZE;
+ work.right += SEP_WIDTH;
+ work.bottom += SEP_WIDTH;
InvalidateRect(infoPtr->hwndSelf, &work, TRUE);
}
@@ -1030,27 +810,24 @@ REBAR_CalcHorzBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
static VOID
-REBAR_CalcVertBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
+REBAR_CalcVertBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend)
/* Function: this routine initializes all the rectangles in */
/* each band in a row to fit in the adjusted rcBand rect. */
/* *** Supports only Vertical bars. *** */
{
REBAR_BAND *lpBand;
- UINT i, xoff, yoff;
- HWND parenthwnd;
- RECT oldChild, work;
-
- /* MS seems to use GetDlgCtrlID() for above GetWindowLong call */
- parenthwnd = GetParent (infoPtr->hwndSelf);
+ UINT i, xoff;
+ RECT work;
for(i=rstart; i<rend; i++){
- lpBand = &infoPtr->bands[i];
+ RECT rcBand;
+ lpBand = &infoPtr->bands[i];
if (HIDDENBAND(lpBand)) continue;
- oldChild = lpBand->rcChild;
- /* set initial gripper rectangle */
- SetRect (&lpBand->rcGripper, lpBand->rcBand.left, lpBand->rcBand.top,
- lpBand->rcBand.right, lpBand->rcBand.top);
+ translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
+
+ /* set initial gripper rectangle */
+ SetRect (&lpBand->rcGripper, rcBand.left, rcBand.top, rcBand.right, rcBand.top);
/* calculate gripper rectangle */
if (lpBand->fStatus & HAS_GRIPPER) {
@@ -1064,9 +841,9 @@ REBAR_CalcVertBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_HEIGHT;
/* initialize Caption image rectangle */
- SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
+ SetRect (&lpBand->rcCapImage, rcBand.left,
lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE,
- lpBand->rcBand.right,
+ rcBand.right,
lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE);
}
else {
@@ -1077,9 +854,9 @@ REBAR_CalcVertBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
lpBand->rcGripper.bottom = lpBand->rcGripper.top + GRIPPER_WIDTH;
/* initialize Caption image rectangle */
- SetRect (&lpBand->rcCapImage, lpBand->rcBand.left,
+ SetRect (&lpBand->rcCapImage, rcBand.left,
lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE,
- lpBand->rcBand.right,
+ rcBand.right,
lpBand->rcGripper.bottom + REBAR_ALWAYS_SPACE);
}
}
@@ -1090,8 +867,8 @@ REBAR_CalcVertBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
xoff = REBAR_ALWAYS_SPACE;
/* initialize Caption image rectangle */
SetRect (&lpBand->rcCapImage,
- lpBand->rcBand.left, lpBand->rcBand.top+xoff,
- lpBand->rcBand.right, lpBand->rcBand.top+xoff);
+ rcBand.left, rcBand.top+xoff,
+ rcBand.right, rcBand.top+xoff);
}
/* image is visible */
@@ -1103,19 +880,14 @@ REBAR_CalcVertBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
/* set initial caption text rectangle */
SetRect (&lpBand->rcCapText,
- lpBand->rcBand.left, lpBand->rcCapImage.bottom+REBAR_POST_IMAGE,
- lpBand->rcBand.right, lpBand->rcBand.top+lpBand->cxHeader);
- /* update band height *
- if (lpBand->uMinHeight < infoPtr->imageSize.cx + 2) {
- lpBand->uMinHeight = infoPtr->imageSize.cx + 2;
- lpBand->rcBand.right = lpBand->rcBand.left + lpBand->uMinHeight;
- } */
+ rcBand.left, lpBand->rcCapImage.bottom+REBAR_POST_IMAGE,
+ rcBand.right, rcBand.top+lpBand->cxHeader);
}
else {
/* set initial caption text rectangle */
SetRect (&lpBand->rcCapText,
- lpBand->rcBand.left, lpBand->rcCapImage.bottom,
- lpBand->rcBand.right, lpBand->rcBand.top+lpBand->cxHeader);
+ rcBand.left, lpBand->rcCapImage.bottom,
+ rcBand.right, rcBand.top+lpBand->cxHeader);
}
/* text is visible */
@@ -1126,40 +898,29 @@ REBAR_CalcVertBand (REBAR_INFO *infoPtr, UINT rstart, UINT rend, BOOL notify)
}
/* set initial child window rectangle if there is a child */
- if (lpBand->fMask & RBBIM_CHILD) {
- yoff = lpBand->offChild.cx;
- xoff = lpBand->offChild.cy;
+ if (lpBand->hwndChild != NULL) {
+ int cxBand = rcBand.right - rcBand.left;
+ xoff = (cxBand - lpBand->cyChild) / 2;
SetRect (&lpBand->rcChild,
- lpBand->rcBand.left+xoff, lpBand->rcBand.top+lpBand->cxHeader,
- lpBand->rcBand.right-xoff, lpBand->rcBand.bottom-yoff);
+ rcBand.left + xoff, rcBand.top + lpBand->cxHeader,
+ rcBand.left + xoff + lpBand->cyChild, rcBand.bottom - REBAR_POST_CHILD);
}
else {
SetRect (&lpBand->rcChild,
- lpBand->rcBand.left, lpBand->rcBand.top+lpBand->cxHeader,
- lpBand->rcBand.right, lpBand->rcBand.bottom);
+ rcBand.left, rcBand.top+lpBand->cxHeader,
+ rcBand.right, rcBand.bottom);
}
- /* flag if notify required and invalidate rectangle */
- if (notify &&
- ((oldChild.right-oldChild.left != lpBand->rcChild.right-lpBand->rcChild.left) ||
- (oldChild.bottom-oldChild.top != lpBand->rcChild.bottom-lpBand->rcChild.top))) {
- TRACE("Child rectangle changed for band %u\n", i);
- TRACE(" from (%d,%d)-(%d,%d) to (%d,%d)-(%d,%d)\n",
- oldChild.left, oldChild.top,
- oldChild.right, oldChild.bottom,
- lpBand->rcChild.left, lpBand->rcChild.top,
- lpBand->rcChild.right, lpBand->rcChild.bottom);
- }
if (lpBand->fDraw & NTF_INVALIDATE) {
TRACE("invalidating (%d,%d)-(%d,%d)\n",
- lpBand->rcBand.left,
- lpBand->rcBand.top,
- lpBand->rcBand.right + ((lpBand->fDraw & DRAW_BOTTOMSEP) ? SEP_WIDTH_SIZE : 0),
- lpBand->rcBand.bottom + ((lpBand->fDraw & DRAW_RIGHTSEP) ? SEP_WIDTH_SIZE : 0));
+ rcBand.left,
+ rcBand.top,
+ rcBand.right + SEP_WIDTH,
+ rcBand.bottom + SEP_WIDTH);
lpBand->fDraw &= ~NTF_INVALIDATE;
- work = lpBand->rcBand;
- if (lpBand->fDraw & DRAW_RIGHTSEP) work.bottom += SEP_WIDTH_SIZE;
- if (lpBand->fDraw & DRAW_BOTTOMSEP) work.right += SEP_WIDTH_SIZE;
+ work = rcBand;
+ work.bottom += SEP_WIDTH;
+ work.right += SEP_WIDTH;
InvalidateRect(infoPtr->hwndSelf, &work, TRUE);
}
@@ -1184,6 +945,9 @@ REBAR_ForceResize (REBAR_INFO *infoPtr)
infoPtr->calcSize.cx, infoPtr->calcSize.cy,
rc.right, rc.bottom);
+ if (infoPtr->dwStyle & CCS_NORESIZE)
+ return;
+
/* If we need to shrink client, then skip size test */
if ((infoPtr->calcSize.cy >= rc.bottom) &&
(infoPtr->calcSize.cx >= rc.right)) {
@@ -1236,12 +1000,12 @@ REBAR_ForceResize (REBAR_INFO *infoPtr)
break;
case CCS_LEFT:
/* _LEFT sets height to parents height */
- width += infoPtr->calcSize.cx;
+ width += infoPtr->calcSize.cx;
height += (rcPcl.bottom - rcPcl.top);
x += ((infoPtr->dwStyle & WS_BORDER) ? -xedge : 0);
x += ((infoPtr->dwStyle & CCS_NODIVIDER) ? 0 : REBAR_DIVIDER);
y += ((infoPtr->dwStyle & WS_BORDER) ? -yedge : 0);
- break;
+ break;
case CCS_RIGHT:
/* FIXME: wrong wrong wrong */
/* _RIGHT sets height to parents height */
@@ -1297,7 +1061,7 @@ REBAR_MoveChildWindows (REBAR_INFO *infoPtr, UINT start, UINT endplus)
rbcz.uBand = i;
rbcz.wID = lpBand->wID;
rbcz.rcChild = lpBand->rcChild;
- rbcz.rcBand = lpBand->rcBand;
+ translate_rect(infoPtr, &rbcz.rcBand, &lpBand->rcBand);
if (infoPtr->dwStyle & CCS_VERT)
rbcz.rcBand.top += lpBand->cxHeader;
else
@@ -1311,7 +1075,7 @@ REBAR_MoveChildWindows (REBAR_INFO *infoPtr, UINT start, UINT endplus)
rbcz.rcChild.left, rbcz.rcChild.top,
rbcz.rcChild.right, rbcz.rcChild.bottom);
lpBand->rcChild = rbcz.rcChild; /* *** ??? */
- }
+ }
/* native (IE4 in "Favorites" frame **1) does:
* SetRect (&rc, -1, -1, -1, -1)
@@ -1394,552 +1158,308 @@ REBAR_MoveChildWindows (REBAR_INFO *infoPtr, UINT start, UINT endplus)
}
-
-static VOID
-REBAR_Layout (REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify, BOOL resetclient)
- /* Function: This routine is resposible for laying out all */
- /* the bands in a rebar. It assigns each band to a row and*/
- /* determines when to start a new row. */
+static void swap_size_if_vert(REBAR_INFO *infoPtr, SIZE *size)
{
- REBAR_BAND *lpBand, *prevBand;
- RECT rcClient, rcAdj;
- INT initx, inity, x, y, cx, cxsep, mmcy, mcy, clientcx, clientcy;
- INT adjcx, adjcy, row, rightx, bottomy, origheight;
- UINT i, j, rowstart, origrows, cntonrow;
- BOOL dobreak;
-
- if (!(infoPtr->fStatus & BAND_NEEDS_LAYOUT)) {
- TRACE("no layout done. No band changed.\n");
- REBAR_DumpBand (infoPtr);
- return;
- }
- infoPtr->fStatus &= ~BAND_NEEDS_LAYOUT;
- if (!infoPtr->DoRedraw) infoPtr->fStatus |= BAND_NEEDS_REDRAW;
-
- GetClientRect (infoPtr->hwndSelf, &rcClient);
- TRACE("Client is (%d,%d)-(%d,%d)\n",
- rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
-
- if (lpRect) {
- rcAdj = *lpRect;
- TRACE("adjustment rect is (%d,%d)-(%d,%d)\n",
- rcAdj.left, rcAdj.top, rcAdj.right, rcAdj.bottom);
- }
- else {
- CopyRect (&rcAdj, &rcClient);
- }
-
- clientcx = rcClient.right - rcClient.left;
- clientcy = rcClient.bottom - rcClient.top;
- adjcx = rcAdj.right - rcAdj.left;
- adjcy = rcAdj.bottom - rcAdj.top;
- if (resetclient) {
- TRACE("window client rect will be set to adj rect\n");
- clientcx = adjcx;
- clientcy = adjcy;
- }
-
- if (!infoPtr->DoRedraw && (clientcx == 0) && (clientcy == 0)) {
- ERR("no redraw and client is zero, skip layout\n");
- infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
- return;
- }
-
- /* save height of original control */
if (infoPtr->dwStyle & CCS_VERT)
- origheight = infoPtr->calcSize.cx;
- else
- origheight = infoPtr->calcSize.cy;
- origrows = infoPtr->uNumRows;
-
- initx = 0;
- inity = 0;
-
- /* ******* Start Phase 1 - all bands on row at minimum size ******* */
-
- TRACE("band loop constants, clientcx=%d, clientcy=%d, adjcx=%d, adjcy=%d\n",
- clientcx, clientcy, adjcx, adjcy);
- x = initx;
- y = inity;
- row = 0;
- cx = 0;
- mcy = 0;
- rowstart = 0;
- prevBand = NULL;
- cntonrow = 0;
-
- for (i = 0; i < infoPtr->uNumBands; i++) {
- lpBand = &infoPtr->bands[i];
- lpBand->fDraw = 0;
- lpBand->iRow = row;
-
- SetRectEmpty(&lpBand->rcChevron);
-
- if (HIDDENBAND(lpBand)) continue;
-
- lpBand->rcoldBand = lpBand->rcBand;
+ {
+ LONG tmp = size->cx;
+ size->cx = size->cy;
+ size->cy = tmp;
+ }
+}
- /* Set the offset of the child window */
- if ((lpBand->fMask & RBBIM_CHILD) &&
- !(lpBand->fStyle & RBBS_FIXEDSIZE)) {
- lpBand->offChild.cx = ((lpBand->fStyle & RBBS_CHILDEDGE) ? 4 : 0);
- }
- lpBand->offChild.cy = ((lpBand->fStyle & RBBS_CHILDEDGE) ? 2 : 0);
+static int next_band(REBAR_INFO *infoPtr, int i)
+{
+ int n;
+ for (n = i + 1; n < infoPtr->uNumBands; n++)
+ if (!HIDDENBAND(&infoPtr->bands[n]))
+ break;
+ return n;
+}
- /* separator from previous band */
- cxsep = (cntonrow == 0) ? 0 : SEP_WIDTH;
- cx = lpBand->lcx;
+static int prev_band(REBAR_INFO *infoPtr, int i)
+{
+ int n;
+ for (n = i - 1; n >= 0; n--)
+ if (!HIDDENBAND(&infoPtr->bands[n]))
+ break;
+ return n;
+}
- /* In native, 0 as one of the coordinates means no limit */
- if (infoPtr->dwStyle & CCS_VERT)
- dobreak = (adjcy && (y + cx + cxsep > adjcy));
+static int get_row_begin_for_band(REBAR_INFO *infoPtr, INT iBand)
+{
+ int iLastBand = iBand;
+ int iRow = infoPtr->bands[iBand].iRow;
+ while ((iBand = prev_band(infoPtr, iBand)) >= 0) {
+ if (infoPtr->bands[iBand].iRow != iRow)
+ break;
else
- dobreak = (adjcx && (x + cx + cxsep > adjcx));
-
- /* This is the check for whether we need to start a new row */
- if ( ( (lpBand->fStyle & RBBS_BREAK) && (i != 0) ) ||
- ( ((infoPtr->dwStyle & CCS_VERT) ? (y != 0) : (x != 0)) && dobreak)) {
-
- for (j = rowstart; j < i; j++) {
- REBAR_BAND *lpB;
- lpB = &infoPtr->bands[j];
- if (infoPtr->dwStyle & CCS_VERT) {
- lpB->rcBand.right = lpB->rcBand.left + mcy;
- }
- else {
- lpB->rcBand.bottom = lpB->rcBand.top + mcy;
- }
- }
-
- TRACE("P1 Spliting to new row %d on band %u\n", row+1, i);
- if (infoPtr->dwStyle & CCS_VERT) {
- y = inity;
- x += (mcy + SEP_WIDTH);
- }
- else {
- x = initx;
- y += (mcy + SEP_WIDTH);
- }
-
- mcy = 0;
- cxsep = 0;
- row++;
- lpBand->iRow = row;
- prevBand = NULL;
- rowstart = i;
- cntonrow = 0;
- }
-
- if (mcy < lpBand->lcy + REBARSPACE(lpBand))
- mcy = lpBand->lcy + REBARSPACE(lpBand);
-
- /* if boundary rect specified then limit mcy */
- if (lpRect) {
- if (infoPtr->dwStyle & CCS_VERT) {
- if (adjcx && (x+mcy > adjcx)) {
- mcy = adjcx - x;
- TRACE("P1 row %u limiting mcy=%d, adjcx=%d, x=%d\n",
- i, mcy, adjcx, x);
- }
- }
- else {
- if (adjcy && (y+mcy > adjcy)) {
- mcy = adjcy - y;
- TRACE("P1 row %u limiting mcy=%d, adjcy=%d, y=%d\n",
- i, mcy, adjcy, y);
- }
- }
- }
-
- TRACE("P1 band %u, row %d, x=%d, y=%d, cxsep=%d, cx=%d\n",
- i, row,
- x, y, cxsep, cx);
- if (infoPtr->dwStyle & CCS_VERT) {
- /* bound the bottom side if we have a bounding rectangle */
- rightx = clientcx;
- bottomy = (lpRect) ? min(clientcy, y+cxsep+cx) : y+cxsep+cx;
- lpBand->rcBand.left = x;
- lpBand->rcBand.right = x + min(mcy,
- lpBand->lcy+REBARSPACE(lpBand));
- lpBand->rcBand.top = min(bottomy, y + cxsep);
- lpBand->rcBand.bottom = bottomy;
- lpBand->uMinHeight = lpBand->lcy;
- y = bottomy;
- }
- else {
- /* bound the right side if we have a bounding rectangle */
- rightx = (lpRect) ? min(clientcx, x+cxsep+cx) : x+cxsep+cx;
- bottomy = clientcy;
- lpBand->rcBand.left = min(rightx, x + cxsep);
- lpBand->rcBand.right = rightx;
- lpBand->rcBand.top = y;
- lpBand->rcBand.bottom = y + min(mcy,
- lpBand->lcy+REBARSPACE(lpBand));
- lpBand->uMinHeight = lpBand->lcy;
- x = rightx;
- }
- TRACE("P1 band %u, row %d, (%d,%d)-(%d,%d)\n",
- i, row,
- lpBand->rcBand.left, lpBand->rcBand.top,
- lpBand->rcBand.right, lpBand->rcBand.bottom);
- prevBand = lpBand;
- cntonrow++;
+ iLastBand = iBand;
+ }
+ return iLastBand;
+}
- } /* for (i = 0; i < infoPtr->uNumBands... */
+static int get_row_end_for_band(REBAR_INFO *infoPtr, INT iBand)
+{
+ int iRow = infoPtr->bands[iBand].iRow;
+ while ((iBand = next_band(infoPtr, iBand)) < infoPtr->uNumBands)
+ if (infoPtr->bands[iBand].iRow != iRow)
+ break;
+ return iBand;
+}
- if (infoPtr->dwStyle & CCS_VERT)
- x += mcy;
- else
- y += mcy;
+static void REBAR_SetRowRectsX(REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand)
+{
+ int xPos = 0, i;
+ for (i = iBeginBand; i < iEndBand; i = next_band(infoPtr, i))
+ {
+ REBAR_BAND *lpBand = &infoPtr->bands[i];
- for (j = rowstart; j < infoPtr->uNumBands; j++) {
- lpBand = &infoPtr->bands[j];
- if (infoPtr->dwStyle & CCS_VERT) {
- lpBand->rcBand.right = lpBand->rcBand.left + mcy;
- }
- else {
- lpBand->rcBand.bottom = lpBand->rcBand.top + mcy;
- }
+ lpBand = &infoPtr->bands[i];
+ if (lpBand->rcBand.left != xPos || lpBand->rcBand.right != xPos + lpBand->cxEffective) {
+ lpBand->fDraw |= NTF_INVALIDATE;
+ TRACE("Setting rect %d to %d,%d\n", i, xPos, xPos + lpBand->cxEffective);
+ lpBand->rcBand.left = xPos;
+ lpBand->rcBand.right = xPos + lpBand->cxEffective;
+ }
+ xPos += lpBand->cxEffective + SEP_WIDTH;
}
+}
- if (infoPtr->uNumBands)
- infoPtr->uNumRows = row + 1;
+/* The rationale of this function is probably as follows: if we have some space
+ * to distribute we want to add it to a band on the right. However we don't want
+ * to unminimize a minimized band so we search for a band that is big enough.
+ * For some reason "big enough" is defined as bigger than the minimum size of the
+ * first band in the row
+ */
+static REBAR_BAND *REBAR_FindBandToGrow(REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand)
+{
+ INT iLcx = 0, i;
- /* ******* End Phase 1 - all bands on row at minimum size ******* */
+ iLcx = infoPtr->bands[iBeginBand].lcx;
+ for (i = prev_band(infoPtr, iEndBand); i >= iBeginBand; i = prev_band(infoPtr, i))
+ if (infoPtr->bands[i].cxEffective > iLcx && !(infoPtr->bands[i].fStyle&RBBS_FIXEDSIZE))
+ break;
- /* ******* Start Phase 1a - Adjust heights for RBS_VARHEIGHT off ******* */
+ if (i < iBeginBand)
+ for (i = prev_band(infoPtr, iEndBand); i >= iBeginBand; i = prev_band(infoPtr, i))
+ if (infoPtr->bands[i].lcx == iLcx)
+ break;
- mmcy = 0;
- if (!(infoPtr->dwStyle & RBS_VARHEIGHT)) {
- INT xy;
+ TRACE("Extra space for row [%d..%d) should be added to band %d\n", iBeginBand, iEndBand, i);
+ return &infoPtr->bands[i];
+}
- /* get the max height of all bands */
- for (i=0; i<infoPtr->uNumBands; i++) {
- lpBand = &infoPtr->bands[i];
- if (HIDDENBAND(lpBand)) continue;
- if (infoPtr->dwStyle & CCS_VERT)
- mmcy = max(mmcy, lpBand->rcBand.right - lpBand->rcBand.left);
- else
- mmcy = max(mmcy, lpBand->rcBand.bottom - lpBand->rcBand.top);
- }
+static int REBAR_ShrinkBandsRTL(REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand, INT cxShrink, BOOL bEnforce)
+{
+ REBAR_BAND *lpBand;
+ INT width, i;
- /* now adjust all rectangles by using the height found above */
- xy = 0;
- row = 0;
- for (i=0; i<infoPtr->uNumBands; i++) {
- lpBand = &infoPtr->bands[i];
- if (HIDDENBAND(lpBand)) continue;
- if (lpBand->iRow != row)
- xy += (mmcy + SEP_WIDTH);
- if (infoPtr->dwStyle & CCS_VERT) {
- lpBand->rcBand.left = xy;
- lpBand->rcBand.right = xy + mmcy;
- }
- else {
- lpBand->rcBand.top = xy;
- lpBand->rcBand.bottom = xy + mmcy;
- }
- }
+ TRACE("Shrinking bands [%d..%d) by %d, right-to-left\n", iBeginBand, iEndBand, cxShrink);
+ for (i = prev_band(infoPtr, iEndBand); i >= iBeginBand; i = prev_band(infoPtr, i))
+ {
+ lpBand = &infoPtr->bands[i];
- /* set the x/y values to the correct maximum */
- if (infoPtr->dwStyle & CCS_VERT)
- x = xy + mmcy;
- else
- y = xy + mmcy;
+ width = max(lpBand->cxEffective - cxShrink, (int)lpBand->lcx);
+ cxShrink -= lpBand->cxEffective - width;
+ lpBand->cxEffective = width;
+ if (bEnforce && lpBand->cx > lpBand->cxEffective)
+ lpBand->cx = lpBand->cxEffective;
+ if (cxShrink == 0)
+ break;
}
-
- /* ******* End Phase 1a - Adjust heights for RBS_VARHEIGHT off ******* */
+ return cxShrink;
+}
- /* ******* Start Phase 2 - split rows till adjustment height full ******* */
+static int REBAR_ShrinkBandsLTR(REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand, INT cxShrink, BOOL bEnforce)
+{
+ REBAR_BAND *lpBand;
+ INT width, i;
- /* assumes that the following variables contain: */
- /* y/x current height/width of all rows */
- /* adjcy/adjcx adjustment height/width or 0 (as small as possible) */
- if (lpRect && ((infoPtr->dwStyle & CCS_VERT) ? adjcx : adjcy)) {
- INT i, prev_rh, new_rh, adj_rh, prev_idx, current_idx;
- REBAR_BAND *prev, *current, *walk;
- UINT j;
+ TRACE("Shrinking bands [%d..%d) by %d, left-to-right\n", iBeginBand, iEndBand, cxShrink);
+ for (i = iBeginBand; i < iEndBand; i = next_band(infoPtr, i))
+ {
+ lpBand = &infoPtr->bands[i];
-/* FIXME: problem # 2 */
- if (((infoPtr->dwStyle & CCS_VERT) ?
-#if PROBLEM2
- (x < adjcx) : (y < adjcy)
-#else
- (adjcx - x > 5) : (adjcy - y > 4)
-#endif
- ) &&
- (infoPtr->uNumBands > 1)) {
- for (i=(INT)infoPtr->uNumBands-2; i>=0; i--) {
- TRACE("P2 adjcx=%d, adjcy=%d, x=%d, y=%d\n",
- adjcx, adjcy, x, y);
-
- /* find the current band (starts at i+1) */
- current = &infoPtr->bands[i+1];
- current_idx = i+1;
- while (HIDDENBAND(current)) {
- i--;
- if (i < 0) break; /* out of bands */
- current = &infoPtr->bands[i+1];
- current_idx = i+1;
- }
- if (i < 0) break; /* out of bands */
-
- /* now find the prev band (starts at i) */
- prev = &infoPtr->bands[i];
- prev_idx = i;
- while (HIDDENBAND(prev)) {
- i--;
- if (i < 0) break; /* out of bands */
- prev = &infoPtr->bands[i];
- prev_idx = i;
- }
- if (i < 0) break; /* out of bands */
-
- prev_rh = ircBw(prev);
- if (prev->iRow == current->iRow) {
- new_rh = (infoPtr->dwStyle & RBS_VARHEIGHT) ?
- current->lcy + REBARSPACE(current) :
- mmcy;
- adj_rh = new_rh + SEP_WIDTH;
- infoPtr->uNumRows++;
- current->fDraw |= NTF_INVALIDATE;
- current->iRow++;
- if (infoPtr->dwStyle & CCS_VERT) {
- current->rcBand.top = inity;
- current->rcBand.bottom = clientcy;
- current->rcBand.left += (prev_rh + SEP_WIDTH);
- current->rcBand.right = current->rcBand.left + new_rh;
- x += adj_rh;
- }
- else {
- current->rcBand.left = initx;
- current->rcBand.right = clientcx;
- current->rcBand.top += (prev_rh + SEP_WIDTH);
- current->rcBand.bottom = current->rcBand.top + new_rh;
- y += adj_rh;
- }
- TRACE("P2 moving band %d to own row at (%d,%d)-(%d,%d)\n",
- current_idx,
- current->rcBand.left, current->rcBand.top,
- current->rcBand.right, current->rcBand.bottom);
- TRACE("P2 prev band %d at (%d,%d)-(%d,%d)\n",
- prev_idx,
- prev->rcBand.left, prev->rcBand.top,
- prev->rcBand.right, prev->rcBand.bottom);
- TRACE("P2 values: prev_rh=%d, new_rh=%d, adj_rh=%d\n",
- prev_rh, new_rh, adj_rh);
- /* for bands below current adjust row # and top/bottom */
- for (j = current_idx+1; j<infoPtr->uNumBands; j++) {
- walk = &infoPtr->bands[j];
- if (HIDDENBAND(walk)) continue;
- walk->fDraw |= NTF_INVALIDATE;
- walk->iRow++;
- if (infoPtr->dwStyle & CCS_VERT) {
- walk->rcBand.left += adj_rh;
- walk->rcBand.right += adj_rh;
- }
- else {
- walk->rcBand.top += adj_rh;
- walk->rcBand.bottom += adj_rh;
- }
- }
- if ((infoPtr->dwStyle & CCS_VERT) ? (x >= adjcx) : (y >= adjcy))
- break; /* all done */
- }
- }
- }
+ width = max(lpBand->cxEffective - cxShrink, (int)lpBand->lcx);
+ cxShrink -= lpBand->cxEffective - width;
+ lpBand->cxEffective = width;
+ if (bEnforce)
+ lpBand->cx = lpBand->cxEffective;
+ if (cxShrink == 0)
+ break;
}
+ return cxShrink;
+}
- /* ******* End Phase 2 - split rows till adjustment height full ******* */
-
-
- /* ******* Start Phase 2a - mark first and last band in each ******* */
+static int REBAR_SetBandsHeight(REBAR_INFO *infoPtr, INT iBeginBand, INT iEndBand, INT yStart)
+{
+ REBAR_BAND *lpBand;
+ int yMaxHeight = 0;
+ int yPos = yStart;
+ int row = infoPtr->bands[iBeginBand].iRow;
+ int i;
+ for (i = iBeginBand; i < iEndBand; i = next_band(infoPtr, i))
+ {
+ lpBand = &infoPtr->bands[i];
+ yMaxHeight = max(yMaxHeight, lpBand->lcy);
+ }
+ TRACE("Bands [%d; %d) height: %d\n", iBeginBand, iEndBand, yMaxHeight);
- prevBand = NULL;
- for (i = 0; i < infoPtr->uNumBands; i++) {
- lpBand = &infoPtr->bands[i];
- if (HIDDENBAND(lpBand))
- continue;
- if( !prevBand ) {
- lpBand->fDraw |= DRAW_FIRST_IN_ROW;
- prevBand = lpBand;
+ for (i = iBeginBand; i < iEndBand; i = next_band(infoPtr, i))
+ {
+ lpBand = &infoPtr->bands[i];
+ /* we may be called for multiple rows if RBS_VARHEIGHT not set */
+ if (lpBand->iRow != row) {
+ yPos += yMaxHeight + SEP_WIDTH;
+ row = lpBand->iRow;
}
- else if( prevBand->iRow == lpBand->iRow )
- prevBand = lpBand;
- else {
- prevBand->fDraw |= DRAW_LAST_IN_ROW;
- lpBand->fDraw |= DRAW_FIRST_IN_ROW;
- prevBand = lpBand;
+
+ if (lpBand->rcBand.top != yPos || lpBand->rcBand.bottom != yPos + yMaxHeight) {
+ lpBand->fDraw |= NTF_INVALIDATE;
+ lpBand->rcBand.top = yPos;
+ lpBand->rcBand.bottom = yPos + yMaxHeight;
+ TRACE("Band %d: %s\n", i, wine_dbgstr_rect(&lpBand->rcBand));
}
}
- if( prevBand )
- prevBand->fDraw |= DRAW_LAST_IN_ROW;
-
- /* ******* End Phase 2a - mark first and last band in each ******* */
-
-
- /* ******* Start Phase 2b - adjust all bands for height full ******* */
- /* assumes that the following variables contain: */
- /* y/x current height/width of all rows */
- /* clientcy/clientcx height/width of client area */
+ return yPos + yMaxHeight;
+}
- if (((infoPtr->dwStyle & CCS_VERT) ? clientcx > x : clientcy > y) &&
- infoPtr->uNumBands) {
- INT diff, i;
- UINT j;
+static void REBAR_LayoutRow(REBAR_INFO *infoPtr, int iBeginBand, int iEndBand, int cx, int *piRow, int *pyPos)
+{
+ REBAR_BAND *lpBand;
+ int i, extra;
+ int width = 0;
- diff = (infoPtr->dwStyle & CCS_VERT) ? clientcx - x : clientcy - y;
+ TRACE("Adjusting row [%d;%d). Width: %d\n", iBeginBand, iEndBand, cx);
+ for (i = iBeginBand; i < iEndBand; i++)
+ infoPtr->bands[i].iRow = *piRow;
- /* iterate backwards thru the rows */
- for (i = infoPtr->uNumBands-1; i>=0; i--) {
- lpBand = &infoPtr->bands[i];
- if(HIDDENBAND(lpBand)) continue;
-
- /* if row has more than 1 band, ignore it */
- if( !(lpBand->fDraw&DRAW_FIRST_IN_ROW) )
- continue;
- if( !(lpBand->fDraw&DRAW_LAST_IN_ROW) )
- continue;
-
- /* FIXME: this next line is wrong, but fixing it to be inverted causes IE's sidebars to be the wrong size */
- if (lpBand->fMask & RBBS_VARIABLEHEIGHT) continue;
- if (((INT)lpBand->cyMaxChild < 1) ||
- ((INT)lpBand->cyIntegral < 1)) {
- if (lpBand->cyMaxChild + lpBand->cyIntegral == 0) continue;
- ERR("P2b band %u RBBS_VARIABLEHEIGHT set but cyMax=%d, cyInt=%d\n",
- i, lpBand->cyMaxChild, lpBand->cyIntegral);
- continue;
- }
- /* j is now the maximum height/width in the client area */
- j = ((diff / lpBand->cyIntegral) * lpBand->cyIntegral) +
- ircBw(lpBand);
- if (j > lpBand->cyMaxChild + REBARSPACE(lpBand))
- j = lpBand->cyMaxChild + REBARSPACE(lpBand);
- diff -= (j - ircBw(lpBand));
- if (infoPtr->dwStyle & CCS_VERT)
- lpBand->rcBand.right = lpBand->rcBand.left + j;
- else
- lpBand->rcBand.bottom = lpBand->rcBand.top + j;
- TRACE("P2b band %d, row %d changed to (%d,%d)-(%d,%d)\n",
- i, lpBand->iRow,
- lpBand->rcBand.left, lpBand->rcBand.top,
- lpBand->rcBand.right, lpBand->rcBand.bottom);
- if (diff <= 0) break;
- }
- if (diff < 0) {
- ERR("P2b allocated more than available, diff=%d\n", diff);
- diff = 0;
- }
- if (infoPtr->dwStyle & CCS_VERT)
- x = clientcx - diff;
- else
- y = clientcy - diff;
+ /* compute the extra space */
+ for (i = iBeginBand; i < iEndBand; i = next_band(infoPtr, i))
+ {
+ lpBand = &infoPtr->bands[i];
+ if (i > iBeginBand)
+ width += SEP_WIDTH;
+ lpBand->cxEffective = max(lpBand->lcx, lpBand->cx);
+ width += lpBand->cxEffective;
+ }
+
+ extra = cx - width;
+ TRACE("Extra space: %d\n", extra);
+ if (extra < 0) {
+ int ret = REBAR_ShrinkBandsRTL(infoPtr, iBeginBand, iEndBand, -extra, FALSE);
+ if (ret > 0 && next_band(infoPtr, iBeginBand) != iEndBand) /* one band may be longer than expected... */
+ ERR("Error layouting row %d - couldn't shrink for %d pixels (%d total shrink)\n", *piRow, ret, -extra);
+ } else
+ if (extra > 0) {
+ lpBand = REBAR_FindBandToGrow(infoPtr, iBeginBand, iEndBand);
+ lpBand->cxEffective += extra;
+ }
+
+ REBAR_SetRowRectsX(infoPtr, iBeginBand, iEndBand);
+ if (infoPtr->dwStyle & RBS_VARHEIGHT)
+ {
+ if (*piRow > 0)
+ *pyPos += SEP_WIDTH;
+ *pyPos = REBAR_SetBandsHeight(infoPtr, iBeginBand, iEndBand, *pyPos);
}
+ (*piRow)++;
+}
- /* ******* End Phase 2b - adjust all bands for height full ******* */
-
-
- /* ******* Start Phase 3 - adjust all bands for width full ******* */
-
- if (infoPtr->uNumBands) {
- int startband;
-
- /* If RBS_BANDBORDERS set then indicate to draw bottom separator */
- /* on all bands in all rows but last row. */
- /* Also indicate to draw the right separator for each band in */
- /* each row but the rightmost band. */
- if (infoPtr->dwStyle & RBS_BANDBORDERS) {
-
- for (i=0; i<infoPtr->uNumBands; i++) {
- lpBand = &infoPtr->bands[i];
- if (HIDDENBAND(lpBand))
- continue;
-
- /* not righthand bands */
- if( !(lpBand->fDraw & DRAW_LAST_IN_ROW) )
- lpBand->fDraw |= DRAW_RIGHTSEP;
+static VOID
+REBAR_Layout(REBAR_INFO *infoPtr, LPRECT lpRect, BOOL notify)
+{
+ REBAR_BAND *lpBand;
+ RECT rcAdj;
+ INT adjcx, adjcy, i;
+ INT rowstart = 0;
+ INT row = 0;
+ INT xMin, yPos;
+ INT cyTarget;
+ const INT yInit = 0;
- /* not the last row */
- if( lpBand->iRow != infoPtr->uNumRows )
- lpBand->fDraw |= DRAW_BOTTOMSEP;
- }
- }
+ if (!(infoPtr->fStatus & BAND_NEEDS_LAYOUT)) {
+ TRACE("no layout done. No band changed.\n");
+ REBAR_DumpBand (infoPtr);
+ return;
+ }
- /* Distribute the extra space on the horizontal and adjust */
- /* all bands in row to same height. */
- mcy = 0;
- startband = -1;
- for (i=0; i<infoPtr->uNumBands; i++) {
+ infoPtr->fStatus &= ~BAND_NEEDS_LAYOUT;
+ if (!infoPtr->DoRedraw) infoPtr->fStatus |= BAND_NEEDS_REDRAW;
- lpBand = &infoPtr->bands[i];
+ cyTarget = 0;
+ if (lpRect) {
+ rcAdj = *lpRect;
+ cyTarget = get_rect_cy(infoPtr, lpRect);
+ } else if (infoPtr->dwStyle & CCS_NORESIZE || GetParent(infoPtr->hwndSelf) == NULL)
+ GetClientRect(infoPtr->hwndSelf, &rcAdj);
+ else
+ GetClientRect(GetParent(infoPtr->hwndSelf), &rcAdj);
+ TRACE("adjustment rect is (%d,%d)-(%d,%d)\n", rcAdj.left, rcAdj.top, rcAdj.right, rcAdj.bottom);
- if( lpBand->fDraw & DRAW_FIRST_IN_ROW )
- {
- startband = i;
- mcy = 0;
- }
+ adjcx = get_rect_cx(infoPtr, &rcAdj);
+ adjcy = get_rect_cy(infoPtr, &rcAdj);
- if ( (mcy < ircBw(lpBand)) && !HIDDENBAND(lpBand) )
- mcy = ircBw(lpBand);
+ if (infoPtr->uNumBands == 0) {
+ TRACE("No bands - setting size to (0,%d), vert: %lx\n", adjcx, infoPtr->dwStyle & CCS_VERT);
+ infoPtr->oldSize = infoPtr->calcSize;
+ infoPtr->calcSize.cx = adjcx;
+ infoPtr->calcSize.cy = 0;
+ swap_size_if_vert(infoPtr, &infoPtr->calcSize);
+ infoPtr->uNumRows = 0;
+ REBAR_ForceResize(infoPtr);
+ return;
+ }
+
+ yPos = yInit;
+ xMin = 0;
+ /* divide rows */
+ i = 0;
+ for (i = 0; i < infoPtr->uNumBands; i++)
+ {
+ lpBand = &infoPtr->bands[i];
+ if (HIDDENBAND(lpBand)) continue;
- if( lpBand->fDraw & DRAW_LAST_IN_ROW )
- {
- TRACE("P3 processing row %d, starting band %d, ending band %d\n",
- lpBand->iRow, startband, i);
- if( startband < 0 )
- ERR("Last band %d with no first, row %d\n", i, lpBand->iRow);
-
- REBAR_AdjustBands (infoPtr, startband, i,
- (infoPtr->dwStyle & CCS_VERT) ?
- clientcy : clientcx, mcy);
- }
- }
+ if (i > rowstart && (lpBand->fStyle & RBBS_BREAK || xMin + lpBand->lcx > adjcx)) {
+ TRACE("%s break on band %d\n", (lpBand->fStyle & RBBS_BREAK ? "Hard" : "Soft"), i - 1);
+ REBAR_LayoutRow(infoPtr, rowstart, i, adjcx, &row, &yPos);
+ rowstart = i;
+ xMin = 0;
+ }
+ else
+ xMin += SEP_WIDTH;
- /* Calculate the other rectangles in each band */
- if (infoPtr->dwStyle & CCS_VERT) {
- REBAR_CalcVertBand (infoPtr, 0, infoPtr->uNumBands,
- notify);
- }
- else {
- REBAR_CalcHorzBand (infoPtr, 0, infoPtr->uNumBands,
- notify);
- }
+ xMin += lpBand->lcx;
}
+ REBAR_LayoutRow(infoPtr, rowstart, infoPtr->uNumBands, adjcx, &row, &yPos);
+
+ if (!(infoPtr->dwStyle & RBS_VARHEIGHT))
+ yPos = REBAR_SetBandsHeight(infoPtr, 0, infoPtr->uNumBands, yInit);
- /* ******* End Phase 3 - adjust all bands for width full ******* */
+ infoPtr->uNumRows = row;
+ if (infoPtr->dwStyle & CCS_VERT)
+ REBAR_CalcVertBand(infoPtr, 0, infoPtr->uNumBands);
+ else
+ REBAR_CalcHorzBand(infoPtr, 0, infoPtr->uNumBands);
/* now compute size of Rebar itself */
infoPtr->oldSize = infoPtr->calcSize;
- if (infoPtr->uNumBands == 0) {
- /* we have no bands, so make size the size of client */
- x = clientcx;
- y = clientcy;
- }
- if (infoPtr->dwStyle & CCS_VERT) {
- if( infoPtr->uNumBands != 0 && x < REBAR_MINSIZE )
- x = REBAR_MINSIZE;
- infoPtr->calcSize.cx = x;
- infoPtr->calcSize.cy = clientcy;
- TRACE("vert, notify=%d, x=%d, origheight=%d\n",
- notify, x, origheight);
- if (notify && (x != origheight)) infoPtr->fStatus |= NTF_HGHTCHG;
- }
- else {
- if( infoPtr->uNumBands != 0 && y < REBAR_MINSIZE )
- y = REBAR_MINSIZE;
- infoPtr->calcSize.cx = clientcx;
- infoPtr->calcSize.cy = y;
- TRACE("horz, notify=%d, y=%d, origheight=%d\n",
- notify, y, origheight);
- if (notify && (y != origheight)) infoPtr->fStatus |= NTF_HGHTCHG;
- }
- REBAR_DumpBand (infoPtr);
+ infoPtr->calcSize.cx = adjcx;
+ infoPtr->calcSize.cy = yPos;
+ swap_size_if_vert(infoPtr, &infoPtr->calcSize);
+ if (infoPtr->calcSize.cx != infoPtr->oldSize.cx || infoPtr->calcSize.cy != infoPtr->oldSize.cy)
+ if (notify && (yPos != infoPtr->calcSize.cy)) infoPtr->fStatus |= NTF_HGHTCHG;
- REBAR_MoveChildWindows (infoPtr, 0, infoPtr->uNumBands);
+ TRACE("calcsize notify=%d, size=(%d, %d), origheight=(%d,%d)\n", notify,
+ infoPtr->calcSize.cx, infoPtr->calcSize.cy,
+ infoPtr->oldSize.cx, infoPtr->oldSize.cy);
+ REBAR_DumpBand (infoPtr);
+ REBAR_MoveChildWindows (infoPtr, 0, infoPtr->uNumBands);
REBAR_ForceResize (infoPtr);
}
@@ -1958,10 +1478,6 @@ REBAR_ValidateBand (REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
lpBand->fStatus = 0;
lpBand->lcx = 0;
lpBand->lcy = 0;
- lpBand->ccx = 0;
- lpBand->ccy = 0;
- lpBand->hcx = 0;
- lpBand->hcy = 0;
/* Data coming in from users into the cx... and cy... fields */
/* may be bad, just garbage, because the user never clears */
@@ -1977,7 +1493,6 @@ REBAR_ValidateBand (REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
if (lpBand->cyMinChild > 65535) lpBand->cyMinChild = 0;
if (lpBand->cx > 65535) lpBand->cx = 0;
if (lpBand->cyChild > 65535) lpBand->cyChild = 0;
- if (lpBand->cyMaxChild > 65535) lpBand->cyMaxChild = 0;
if (lpBand->cyIntegral > 65535) lpBand->cyIntegral = 0;
if (lpBand->cxIdeal > 65535) lpBand->cxIdeal = 0;
if (lpBand->cxHeader > 65535) lpBand->cxHeader = 0;
@@ -2057,38 +1572,18 @@ REBAR_ValidateBand (REBAR_INFO *infoPtr, REBAR_BAND *lpBand)
/* Now compute minimum size of child window */
- lpBand->offChild.cx = 0;
- lpBand->offChild.cy = 0;
lpBand->lcy = textheight;
- lpBand->ccy = lpBand->lcy;
- if (lpBand->fMask & RBBIM_CHILDSIZE) {
- lpBand->lcx = lpBand->cxMinChild;
-
+ if (lpBand->hwndChild != NULL) {
/* Set the .cy values for CHILDSIZE case */
- lpBand->lcy = max(lpBand->lcy, lpBand->cyMinChild);
- lpBand->ccy = lpBand->lcy;
- lpBand->hcy = lpBand->lcy;
- if (lpBand->cyMaxChild != 0xffffffff) {
- lpBand->hcy = lpBand->cyMaxChild;
- }
- if (lpBand->cyChild != 0xffffffff)
- lpBand->ccy = max (lpBand->cyChild, lpBand->lcy);
-
+ lpBand->lcy = max(lpBand->lcy, lpBand->cyChild + REBARSPACE(lpBand));
TRACE("_CHILDSIZE\n");
}
- if (lpBand->fMask & RBBIM_SIZE) {
- lpBand->hcx = max (lpBand->cx-lpBand->cxHeader, lpBand->lcx);
- TRACE("_SIZE\n");
- }
else
- lpBand->hcx = lpBand->lcx;
- lpBand->ccx = lpBand->hcx;
-
- /* make ->.cx include header size for _Layout */
- lpBand->lcx += lpBand->cxHeader;
- lpBand->ccx += lpBand->cxHeader;
- lpBand->hcx += lpBand->cxHeader;
+ lpBand->lcy = max(lpBand->lcy, REBAR_NO_CHILD_HEIGHT);
+ lpBand->lcx = lpBand->cxMinChild + lpBand->cxHeader + REBAR_POST_CHILD;
+ if (lpBand->fStyle & RBBS_USECHEVRON && lpBand->cxMinChild < lpBand->cxIdeal)
+ lpBand->lcx += CHEVRON_WIDTH;
}
static BOOL
@@ -2158,15 +1653,17 @@ REBAR_CommonSetupBand(HWND hwnd, LPREBARBANDINFOW lprbbi, REBAR_BAND *lpBand)
{
lpBand->cxMinChild = lprbbi->cxMinChild;
lpBand->cyMinChild = lprbbi->cyMinChild;
- if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
- lpBand->cyChild = lprbbi->cyChild;
+ /* These fields where added in WIN32_IE == 0x400 and are set only for RBBS_VARIABLEHEIGHT bands */
+ if (lprbbi->cbSize >= sizeof (REBARBANDINFOA) && (lprbbi->fStyle & RBBS_VARIABLEHEIGHT)) {
lpBand->cyMaxChild = lprbbi->cyMaxChild;
- lpBand->cyIntegral = lprbbi->cyIntegral;
- }
- else { /* special case - these should be zeroed out since */
- /* RBBIM_CHILDSIZE added these in WIN32_IE >= 0x0400 */
- lpBand->cyChild = 0;
- lpBand->cyMaxChild = 0;
+ lpBand->cyIntegral = lprbbi->cyIntegral;
+
+ lpBand->cyChild = lpBand->cyMinChild;
+ round_child_height(lpBand, lprbbi->cyChild); /* try to increase cyChild */
+ }
+ else {
+ lpBand->cyChild = lpBand->cyMinChild;
+ lpBand->cyMaxChild = 0x7fffffff;
lpBand->cyIntegral = 0;
}
bChanged = TRUE;
@@ -2232,7 +1729,7 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
UINT i;
INT oldrow;
HDC hdc = (HDC)wParam;
- RECT rect, cr;
+ RECT cr;
COLORREF old = CLR_NONE, new;
HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
@@ -2240,15 +1737,17 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
oldrow = -1;
for(i=0; i<infoPtr->uNumBands; i++) {
+ RECT rcBand;
lpBand = &infoPtr->bands[i];
if (HIDDENBAND(lpBand)) continue;
+ translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
/* draw band separator between rows */
if (lpBand->iRow != oldrow) {
oldrow = lpBand->iRow;
- if (lpBand->fDraw & DRAW_BOTTOMSEP) {
+ if (infoPtr->dwStyle & RBS_BANDBORDERS) {
RECT rcRowSep;
- rcRowSep = lpBand->rcBand;
+ rcRowSep = rcBand;
if (infoPtr->dwStyle & CCS_VERT) {
rcRowSep.right += SEP_WIDTH_SIZE;
rcRowSep.bottom = infoPtr->calcSize.cy;
@@ -2272,18 +1771,20 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
}
/* draw band separator between bands in a row */
- if (lpBand->fDraw & DRAW_RIGHTSEP) {
+ if (infoPtr->dwStyle & RBS_BANDBORDERS && lpBand->rcBand.left > 0) {
RECT rcSep;
- rcSep = lpBand->rcBand;
+ rcSep = rcBand;
if (infoPtr->dwStyle & CCS_VERT) {
- rcSep.bottom += SEP_WIDTH_SIZE;
+ rcSep.bottom = rcSep.top;
+ rcSep.top -= SEP_WIDTH_SIZE;
if (theme)
DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_BOTTOM, NULL);
else
DrawEdge (hdc, &rcSep, EDGE_ETCHED, BF_BOTTOM);
}
else {
- rcSep.right += SEP_WIDTH_SIZE;
+ rcSep.right = rcSep.left;
+ rcSep.left -= SEP_WIDTH_SIZE;
if (theme)
DrawThemeEdge (theme, hdc, RP_BAND, 0, &rcSep, EDGE_ETCHED, BF_RIGHT, NULL);
else
@@ -2314,13 +1815,11 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
#endif
}
- rect = lpBand->rcBand;
-
if (theme)
{
/* When themed, the background color is ignored (but not a
* background bitmap */
- DrawThemeBackground (theme, hdc, 0, 0, &cr, &rect);
+ DrawThemeBackground (theme, hdc, 0, 0, &cr, &rcBand);
}
else
{
@@ -2329,11 +1828,11 @@ REBAR_InternalEraseBkGnd (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, REC
(lpBand->clrBack == CLR_NONE) ? "none" :
((lpBand->clrBack == CLR_DEFAULT) ? "dft" : ""),
GetBkColor(hdc),
- lpBand->rcBand.left,lpBand->rcBand.top,
- lpBand->rcBand.right,lpBand->rcBand.bottom,
+ rcBand.left,rcBand.top,
+ rcBand.right,rcBand.bottom,
clip->left, clip->top,
clip->right, clip->bottom);
- ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, 0);
+ ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rcBand, NULL, 0, 0);
if (lpBand->clrBack != CLR_NONE)
SetBkColor (hdc, old);
}
@@ -2363,9 +1862,11 @@ REBAR_InternalHitTest (REBAR_INFO *infoPtr, const LPPOINT lpPt, UINT *pFlags, IN
else {
/* somewhere inside */
for (iCount = 0; iCount < infoPtr->uNumBands; iCount++) {
+ RECT rcBand;
lpBand = &infoPtr->bands[iCount];
- if (HIDDENBAND(lpBand)) continue;
- if (PtInRect (&lpBand->rcBand, *lpPt)) {
+ translate_rect(infoPtr, &rcBand, &lpBand->rcBand);
+ if (HIDDENBAND(lpBand)) continue;
+ if (PtInRect (&rcBand, *lpPt)) {
if (pBand)
*pBand = iCount;
if (PtInRect (&lpBand->rcGripper, *lpPt)) {
@@ -2418,76 +1919,6 @@ REBAR_InternalHitTest (REBAR_INFO *infoPtr, const LPPOINT lpPt, UINT *pFlags, IN
}
}
-
-static INT
-REBAR_Shrink (REBAR_INFO *infoPtr, REBAR_BAND *band, INT movement, INT i)
- /* Function: This attempts to shrink the given band by the */
- /* the amount in "movement". A shrink to the left is indi- */
- /* cated by "movement" being negative. "i" is merely the */
- /* band index for trace messages. */
-{
- INT Leadjust, Readjust, avail, ret;
-
- /* Note: a left drag is indicated by "movement" being negative. */
- /* Similarly, a right drag is indicated by "movement" */
- /* being positive. "movement" should never be 0, but if */
- /* it is then the band does not move. */
-
- avail = rcBw(band) - band->lcx;
-
- /* now compute the Left End adjustment factor and Right End */
- /* adjustment factor. They may be different if shrinking. */
- if (avail <= 0) {
- /* if this band is not shrinkable, then just move it */
- Leadjust = Readjust = movement;
- ret = movement;
- }
- else {
- if (movement < 0) {
- /* Drag to left */
- if (avail <= abs(movement)) {
- Readjust = movement;
- Leadjust = movement + avail;
- ret = Leadjust;
- }
- else {
- Readjust = movement;
- Leadjust = 0;
- ret = 0;
- }
- }
- else {
- /* Drag to right */
- if (avail <= abs(movement)) {
- Leadjust = movement;
- Readjust = movement - avail;
- ret = Readjust;
- }
- else {
- Leadjust = movement;
- Readjust = 0;
- ret = 0;
- }
- }
- }
-
- /* Reasonability Check */
- if (rcBlt(band) + Leadjust < 0) {
- ERR("adjustment will fail, band %d: left=%d, right=%d, move=%d, rtn=%d\n",
- i, Leadjust, Readjust, movement, ret);
- }
-
- LEADJ(band, Leadjust);
- READJ(band, Readjust);
-
- TRACE("band %d: left=%d, right=%d, move=%d, rtn=%d, rcBand=(%d,%d)-(%d,%d)\n",
- i, Leadjust, Readjust, movement, ret,
- band->rcBand.left, band->rcBand.top,
- band->rcBand.right, band->rcBand.bottom);
- return ret;
-}
-
-
static void
REBAR_HandleLRDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
/* Function: This will implement the functionality of a */
@@ -2497,14 +1928,11 @@ REBAR_HandleLRDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
/* **** FIXME Switching order of bands in a row not **** */
/* **** yet implemented. **** */
{
- REBAR_BAND *hitBand, *band, *mindBand, *maxdBand;
- RECT newrect;
- INT imindBand = -1, imaxdBand, ihitBand, i, movement;
- INT RHeaderSum = 0, LHeaderSum = 0;
- INT compress;
+ REBAR_BAND *hitBand;
+ INT iHitBand, iRowBegin, iRowEnd;
+ INT movement, xBand;
/* on first significant mouse movement, issue notify */
-
if (!(infoPtr->fStatus & BEGIN_DRAG_ISSUED)) {
if (REBAR_Notify_NMREBAR (infoPtr, -1, RBN_BEGINDRAG)) {
/* Notify returned TRUE - abort drag */
@@ -2518,126 +1946,32 @@ REBAR_HandleLRDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
infoPtr->fStatus |= BEGIN_DRAG_ISSUED;
}
- ihitBand = infoPtr->iGrabbedBand;
- hitBand = &infoPtr->bands[ihitBand];
- imaxdBand = ihitBand; /* to suppress warning message */
+ iHitBand = infoPtr->iGrabbedBand;
+ iRowBegin = get_row_begin_for_band(infoPtr, iHitBand);
+ iRowEnd = get_row_end_for_band(infoPtr, iHitBand);
+ hitBand = &infoPtr->bands[iHitBand];
- /* find all the bands in the row of the one whose Gripper was seized */
- for (i=0; i<infoPtr->uNumBands; i++) {
- band = &infoPtr->bands[i];
- if (HIDDENBAND(band)) continue;
- if (band->iRow == hitBand->iRow) {
- imaxdBand = i;
- if (imindBand == -1) imindBand = i;
- /* minimum size of each band is size of header plus */
- /* size of minimum child plus offset of child from header plus */
- /* one to separate each band. */
- if (i < ihitBand)
- LHeaderSum += (band->lcx + SEP_WIDTH);
- else
- RHeaderSum += (band->lcx + SEP_WIDTH);
+ xBand = hitBand->rcBand.left;
+ movement = (infoPtr->dwStyle&CCS_VERT ? ptsmove->y : ptsmove->x)
+ - (xBand + REBAR_PRE_GRIPPER - infoPtr->ihitoffset);
- }
+ if (movement < 0) {
+ int cxLeft = REBAR_ShrinkBandsRTL(infoPtr, iRowBegin, iHitBand, -movement, TRUE);
+ hitBand->cxEffective += -movement - cxLeft;
+ hitBand->cx = hitBand->cxEffective;
+ } else if (movement > 0) {
+ int cxLeft = REBAR_ShrinkBandsLTR(infoPtr, iHitBand, iRowEnd, movement, TRUE);
+ REBAR_BAND *lpPrev = &infoPtr->bands[prev_band(infoPtr, iHitBand)];
+ lpPrev->cxEffective += movement - cxLeft;
+ lpPrev->cx = lpPrev->cxEffective;
}
- if (RHeaderSum) RHeaderSum -= SEP_WIDTH; /* no separator after last band */
-
- mindBand = &infoPtr->bands[imindBand];
- maxdBand = &infoPtr->bands[imaxdBand];
-
- if (imindBand == imaxdBand) return; /* nothing to drag against */
- if (imindBand == ihitBand) return; /* first band in row, can't drag */
-
- /* limit movement to inside adjustable bands - Left */
- if ( (ptsmove->x < mindBand->rcBand.left) ||
- (ptsmove->x > maxdBand->rcBand.right) ||
- (ptsmove->y < mindBand->rcBand.top) ||
- (ptsmove->y > maxdBand->rcBand.bottom))
- return; /* should swap bands */
+ REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
if (infoPtr->dwStyle & CCS_VERT)
- movement = ptsmove->y - ((hitBand->rcBand.top+REBAR_PRE_GRIPPER) -
- infoPtr->ihitoffset);
+ REBAR_CalcVertBand(infoPtr, 0, infoPtr->uNumBands);
else
- movement = ptsmove->x - ((hitBand->rcBand.left+REBAR_PRE_GRIPPER) -
- infoPtr->ihitoffset);
- infoPtr->dragNow = *ptsmove;
-
- TRACE("before: movement=%d (%d,%d), imindBand=%d, ihitBand=%d, imaxdBand=%d, LSum=%d, RSum=%d\n",
- movement, ptsmove->x, ptsmove->y, imindBand, ihitBand,
- imaxdBand, LHeaderSum, RHeaderSum);
- REBAR_DumpBand (infoPtr);
-
- if (movement < 0) {
-
- /* *** Drag left/up *** */
- compress = rcBlt(hitBand) - rcBlt(mindBand) -
- LHeaderSum;
- if (compress < abs(movement)) {
- TRACE("limiting left drag, was %d changed to %d\n",
- movement, -compress);
- movement = -compress;
- }
-
- for (i=ihitBand; i>=imindBand; i--) {
- band = &infoPtr->bands[i];
- if (HIDDENBAND(band)) continue;
- if (i == ihitBand) {
- LEADJ(band, movement);
- }
- else
- movement = REBAR_Shrink (infoPtr, band, movement, i);
- band->ccx = rcBw(band);
- }
- }
- else {
- BOOL first = TRUE;
-
- /* *** Drag right/down *** */
- compress = rcBrb(maxdBand) - rcBlt(hitBand) -
- RHeaderSum;
- if (compress < abs(movement)) {
- TRACE("limiting right drag, was %d changed to %d\n",
- movement, compress);
- movement = compress;
- }
- for (i=ihitBand-1; i<=imaxdBand; i++) {
- band = &infoPtr->bands[i];
- if (HIDDENBAND(band)) continue;
- if (first) {
- first = FALSE;
- READJ(band, movement);
- }
- else
- movement = REBAR_Shrink (infoPtr, band, movement, i);
- band->ccx = rcBw(band);
- }
- }
-
- /* recompute all rectangles */
- if (infoPtr->dwStyle & CCS_VERT) {
- REBAR_CalcVertBand (infoPtr, imindBand, imaxdBand+1,
- FALSE);
- }
- else {
- REBAR_CalcHorzBand (infoPtr, imindBand, imaxdBand+1,
- FALSE);
- }
-
- TRACE("bands after adjustment, see band # %d, %d\n",
- imindBand, imaxdBand);
- REBAR_DumpBand (infoPtr);
-
- SetRect (&newrect,
- mindBand->rcBand.left,
- mindBand->rcBand.top,
- maxdBand->rcBand.right,
- maxdBand->rcBand.bottom);
-
- REBAR_MoveChildWindows (infoPtr, imindBand, imaxdBand+1);
-
- InvalidateRect (infoPtr->hwndSelf, &newrect, TRUE);
- UpdateWindow (infoPtr->hwndSelf);
-
+ REBAR_CalcHorzBand(infoPtr, 0, infoPtr->uNumBands);
+ REBAR_MoveChildWindows(infoPtr, iRowBegin, iRowEnd);
}
@@ -2677,7 +2011,7 @@ REBAR_DeleteBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
TRACE("setting NEEDS_LAYOUT\n");
infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
infoPtr->fStatus |= RESIZE_ANYHOW;
- REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
+ REBAR_Layout(infoPtr, NULL, TRUE);
return TRUE;
}
@@ -2779,7 +2113,9 @@ REBAR_GetBandInfoT(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnic
if (lprbbi->fMask & RBBIM_CHILDSIZE) {
lprbbi->cxMinChild = lpBand->cxMinChild;
lprbbi->cyMinChild = lpBand->cyMinChild;
- if (lprbbi->cbSize >= sizeof (REBARBANDINFOA)) {
+ /* to make tests pass we follow Windows behaviour and allow to read these fields only
+ * for RBBS_VARIABLEHEIGHTS bands */
+ if (lprbbi->cbSize >= sizeof (REBARBANDINFOA) && (lpBand->fStyle & RBBS_VARIABLEHEIGHT)) {
lprbbi->cyChild = lpBand->cyChild;
lprbbi->cyMaxChild = lpBand->cyMaxChild;
lprbbi->cyIntegral = lpBand->cyIntegral;
@@ -2882,12 +2218,13 @@ REBAR_GetRect (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
LPRECT lprc = (LPRECT)lParam;
REBAR_BAND *lpBand;
- if ((iBand < 0) && ((UINT)iBand >= infoPtr->uNumBands))
+ if ((iBand < 0) || ((UINT)iBand >= infoPtr->uNumBands))
return FALSE;
if (!lprc)
return FALSE;
lpBand = &infoPtr->bands[iBand];
+ /* For CCS_VERT the coordintes will be swapped - like on Windows */
CopyRect (lprc, &lpBand->rcBand);
TRACE("band %d, (%d,%d)-(%d,%d)\n", iBand,
@@ -2918,10 +2255,7 @@ REBAR_GetRowHeight (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
lpBand = &infoPtr->bands[i];
if (HIDDENBAND(lpBand)) continue;
if (lpBand->iRow != iRow) continue;
- if (infoPtr->dwStyle & CCS_VERT)
- j = lpBand->rcBand.right - lpBand->rcBand.left;
- else
- j = lpBand->rcBand.bottom - lpBand->rcBand.top;
+ j = lpBand->rcBand.bottom - lpBand->rcBand.top;
if (j > ret) ret = j;
}
@@ -3051,7 +2385,7 @@ REBAR_InsertBandT(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnico
REBAR_DumpBand (infoPtr);
- REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
+ REBAR_Layout(infoPtr, NULL, TRUE);
InvalidateRect(infoPtr->hwndSelf, 0, TRUE);
return TRUE;
@@ -3063,6 +2397,9 @@ REBAR_MaximizeBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
REBAR_BAND *lpBand;
UINT uBand = (UINT) wParam;
+ int iRowBegin, iRowEnd;
+ int cxDesired, extra, extraOrig;
+ int cxIdealBand;
/* Validate */
if ((infoPtr->uNumBands == 0) ||
@@ -3075,21 +2412,29 @@ REBAR_MaximizeBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
lpBand = &infoPtr->bands[uBand];
- if (lParam && (lpBand->fMask & RBBIM_IDEALSIZE)) {
- /* handle setting ideal size */
- lpBand->ccx = lpBand->cxIdeal;
- }
- else {
- /* handle setting to max */
- FIXME("(uBand = %u fIdeal = %s) case not coded\n",
- (UINT)wParam, lParam ? "TRUE" : "FALSE");
- return FALSE;
- }
-
- infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
- REBAR_Layout (infoPtr, 0, TRUE, TRUE);
- InvalidateRect (infoPtr->hwndSelf, 0, TRUE);
+ cxIdealBand = lpBand->cxIdeal + lpBand->cxHeader + REBAR_POST_CHILD;
+ if (lParam && (lpBand->cxEffective < cxIdealBand))
+ cxDesired = cxIdealBand;
+ else
+ cxDesired = (infoPtr->dwStyle&CCS_VERT ? infoPtr->calcSize.cy : infoPtr->calcSize.cx);
+
+ iRowBegin = get_row_begin_for_band(infoPtr, uBand);
+ iRowEnd = get_row_end_for_band(infoPtr, uBand);
+ extraOrig = extra = cxDesired - lpBand->cxEffective;
+ if (extra > 0)
+ extra = REBAR_ShrinkBandsRTL(infoPtr, iRowBegin, uBand, extra, TRUE);
+ if (extra > 0)
+ extra = REBAR_ShrinkBandsLTR(infoPtr, next_band(infoPtr, uBand), iRowEnd, extra, TRUE);
+ lpBand->cxEffective += extraOrig - extra;
+ lpBand->cx = lpBand->cxEffective;
+ TRACE("(%d, %ld): Wanted size %d, obtained %d (shrink %d, %d)\n", wParam, lParam, cxDesired, lpBand->cx, extraOrig, extra);
+ REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
+ if (infoPtr->dwStyle & CCS_VERT)
+ REBAR_CalcVertBand(infoPtr, iRowBegin, iRowEnd);
+ else
+ REBAR_CalcHorzBand(infoPtr, iRowBegin, iRowEnd);
+ REBAR_MoveChildWindows(infoPtr, iRowBegin, iRowEnd);
return TRUE;
}
@@ -3098,11 +2443,9 @@ REBAR_MaximizeBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
static LRESULT
REBAR_MinimizeBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
- REBAR_BAND *band, *lpBand;
+ REBAR_BAND *lpBand;
UINT uBand = (UINT) wParam;
- RECT newrect;
- INT imindBand, imaxdBand, iprevBand, startBand, endBand;
- INT movement, i;
+ int iPrev, iRowBegin, iRowEnd;
/* A "minimize" band is equivalent to "dragging" the gripper
* of than band to the right till the band is only the size
@@ -3120,110 +2463,32 @@ REBAR_MinimizeBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
/* compute amount of movement and validate */
lpBand = &infoPtr->bands[uBand];
-
- if (infoPtr->dwStyle & CCS_VERT)
- movement = lpBand->rcBand.bottom - lpBand->rcBand.top -
- lpBand->cxHeader;
- else
- movement = lpBand->rcBand.right - lpBand->rcBand.left -
- lpBand->cxHeader;
- if (movement < 0) {
- ERR("something is wrong, band=(%d,%d)-(%d,%d), cxheader=%d\n",
- lpBand->rcBand.left, lpBand->rcBand.top,
- lpBand->rcBand.right, lpBand->rcBand.bottom,
- lpBand->cxHeader);
- return FALSE;
- }
-
- imindBand = -1;
- imaxdBand = -1;
- iprevBand = -1; /* to suppress warning message */
-
- /* find the first band in row of the one whose is being minimized */
- for (i=0; i<infoPtr->uNumBands; i++) {
- band = &infoPtr->bands[i];
- if (HIDDENBAND(band)) continue;
- if (band->iRow == lpBand->iRow) {
- imaxdBand = i;
- if (imindBand == -1) imindBand = i;
- }
- }
-
- /* if the selected band is first in row then need to expand */
- /* next visible band */
- if (imindBand == uBand) {
- band = NULL;
- movement = -movement;
- /* find the first visible band to the right of the selected band */
- for (i=uBand+1; i<=imaxdBand; i++) {
- band = &infoPtr->bands[i];
- if (!HIDDENBAND(band)) {
- iprevBand = i;
- LEADJ(band, movement);
- band->ccx = rcBw(band);
- break;
- }
- }
- /* what case is this */
- if (iprevBand == -1) {
- ERR("no previous visible band\n");
- return FALSE;
- }
- startBand = uBand;
- endBand = iprevBand;
- SetRect (&newrect,
- lpBand->rcBand.left,
- lpBand->rcBand.top,
- band->rcBand.right,
- band->rcBand.bottom);
- }
- /* otherwise expand previous visible band */
- else {
- band = NULL;
- /* find the first visible band to the left of the selected band */
- for (i=uBand-1; i>=imindBand; i--) {
- band = &infoPtr->bands[i];
- if (!HIDDENBAND(band)) {
- iprevBand = i;
- READJ(band, movement);
- band->ccx = rcBw(band);
- break;
- }
- }
- /* what case is this */
- if (iprevBand == -1) {
- ERR("no previous visible band\n");
- return FALSE;
- }
- startBand = iprevBand;
- endBand = uBand;
- SetRect (&newrect,
- band->rcBand.left,
- band->rcBand.top,
- lpBand->rcBand.right,
- lpBand->rcBand.bottom);
- }
-
- REBAR_Shrink (infoPtr, lpBand, movement, uBand);
-
- /* recompute all rectangles */
- if (infoPtr->dwStyle & CCS_VERT) {
- REBAR_CalcVertBand (infoPtr, startBand, endBand+1,
- FALSE);
- }
- else {
- REBAR_CalcHorzBand (infoPtr, startBand, endBand+1,
- FALSE);
+ iPrev = prev_band(infoPtr, uBand);
+ /* if first band in row */
+ if (iPrev < 0 || infoPtr->bands[iPrev].iRow != lpBand->iRow) {
+ int iNext = next_band(infoPtr, uBand);
+ if (iNext < infoPtr->uNumBands && infoPtr->bands[iNext].iRow == lpBand->iRow) {
+ TRACE("(%d): Minimizing the first band in row is by maximizing the second\n", wParam);
+ REBAR_MaximizeBand(infoPtr, iNext, FALSE);
+ }
+ else
+ TRACE("(%d): Only one band in row - nothing to do\n", wParam);
+ return TRUE;
}
- TRACE("bands after minimize, see band # %d, %d\n",
- startBand, endBand);
- REBAR_DumpBand (infoPtr);
+ infoPtr->bands[iPrev].cxEffective += lpBand->cxEffective - lpBand->lcx;
+ infoPtr->bands[iPrev].cx = infoPtr->bands[iPrev].cxEffective;
+ lpBand->cx = lpBand->cxEffective = lpBand->lcx;
- REBAR_MoveChildWindows (infoPtr, startBand, endBand+1);
+ iRowBegin = get_row_begin_for_band(infoPtr, uBand);
+ iRowEnd = get_row_end_for_band(infoPtr, uBand);
+ REBAR_SetRowRectsX(infoPtr, iRowBegin, iRowEnd);
- InvalidateRect (infoPtr->hwndSelf, &newrect, TRUE);
- UpdateWindow (infoPtr->hwndSelf);
+ if (infoPtr->dwStyle & CCS_VERT)
+ REBAR_CalcVertBand(infoPtr, iRowBegin, iRowEnd);
+ else
+ REBAR_CalcHorzBand(infoPtr, iRowBegin, iRowEnd);
+ REBAR_MoveChildWindows(infoPtr, iRowBegin, iRowEnd);
return FALSE;
}
@@ -3341,8 +2606,8 @@ REBAR_SetBandInfoT(REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam, BOOL bUnic
REBAR_DumpBand (infoPtr);
- if (bChanged && (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE))) {
- REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
+ if (bChanged && (lprbbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE))) {
+ REBAR_Layout(infoPtr, NULL, TRUE);
InvalidateRect(infoPtr->hwndSelf, 0, 1);
}
@@ -3492,7 +2757,7 @@ REBAR_ShowBand (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
}
infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
- REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
+ REBAR_Layout(infoPtr, NULL, TRUE);
InvalidateRect(infoPtr->hwndSelf, 0, 1);
return TRUE;
@@ -3522,7 +2787,7 @@ REBAR_SizeToRect (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
/* force full _Layout processing */
TRACE("setting NEEDS_LAYOUT\n");
infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
- REBAR_Layout (infoPtr, lpRect, TRUE, FALSE);
+ REBAR_Layout(infoPtr, lpRect, TRUE);
InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
return TRUE;
}
@@ -3678,9 +2943,9 @@ REBAR_LButtonDown (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
infoPtr->dragStart.y = (short)HIWORD(lParam);
infoPtr->dragNow = infoPtr->dragStart;
if (infoPtr->dwStyle & CCS_VERT)
- infoPtr->ihitoffset = infoPtr->dragStart.y - (lpBand->rcBand.top+REBAR_PRE_GRIPPER);
+ infoPtr->ihitoffset = infoPtr->dragStart.y - (lpBand->rcBand.left + REBAR_PRE_GRIPPER);
else
- infoPtr->ihitoffset = infoPtr->dragStart.x - (lpBand->rcBand.left+REBAR_PRE_GRIPPER);
+ infoPtr->ihitoffset = infoPtr->dragStart.x - (lpBand->rcBand.left + REBAR_PRE_GRIPPER);
}
return 0;
}
@@ -3745,6 +3010,7 @@ REBAR_MouseMove (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
if (infoPtr->iGrabbedBand >= 0)
{
REBAR_BAND *band1, *band2;
+ int yPtMove = (infoPtr->dwStyle & CCS_VERT ? ptMove.x : ptMove.y);
if (GetCapture() != infoPtr->hwndSelf)
ERR("We are dragging but haven't got capture?!?\n");
@@ -3757,25 +3023,13 @@ REBAR_MouseMove (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
(abs(ptMove.y - infoPtr->dragNow.y) <= mindragy)) return 0;
/* Test for valid drag case - must not be first band in row */
- if (infoPtr->dwStyle & CCS_VERT) {
- if ((ptMove.x < band2->rcBand.left) ||
- (ptMove.x > band2->rcBand.right) ||
+ if ((yPtMove < band2->rcBand.top) ||
+ (yPtMove > band2->rcBand.bottom) ||
((infoPtr->iGrabbedBand > 0) && (band1->iRow != band2->iRow))) {
- FIXME("Cannot drag to other rows yet!!\n");
- }
- else {
- REBAR_HandleLRDrag (infoPtr, &ptMove);
- }
+ FIXME("Cannot drag to other rows yet!!\n");
}
else {
- if ((ptMove.y < band2->rcBand.top) ||
- (ptMove.y > band2->rcBand.bottom) ||
- ((infoPtr->iGrabbedBand > 0) && (band1->iRow != band2->iRow))) {
- FIXME("Cannot drag to other rows yet!!\n");
- }
- else {
- REBAR_HandleLRDrag (infoPtr, &ptMove);
- }
+ REBAR_HandleLRDrag (infoPtr, &ptMove);
}
}
else
@@ -4114,7 +3368,7 @@ REBAR_SetFont (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
if (LOWORD(lParam)) {
GetClientRect (infoPtr->hwndSelf, &rcClient);
- REBAR_Layout (infoPtr, &rcClient, FALSE, TRUE);
+ REBAR_Layout(infoPtr, &rcClient, FALSE);
}
return 0;
@@ -4203,6 +3457,9 @@ REBAR_Size (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
LOWORD(lParam), HIWORD(lParam),
rcClient.right, rcClient.bottom);
}
+ infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
+ REBAR_Layout(infoPtr, &rcClient, TRUE);
+ return 0;
}
else {
if ((INT)wParam != SIZE_RESTORED) {
@@ -4245,11 +3502,11 @@ REBAR_Size (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
autosize.rcTarget.right, autosize.rcTarget.bottom, lParam);
}
- if ((infoPtr->calcSize.cx != rcClient.right) ||
- (infoPtr->calcSize.cy != rcClient.bottom))
- infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
-
- REBAR_Layout (infoPtr, &rcClient, TRUE, TRUE);
+ if (((infoPtr->calcSize.cx != rcClient.right) || (infoPtr->calcSize.cy != rcClient.bottom)))
+ {
+ infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
+ REBAR_Layout(infoPtr, &rcClient, TRUE);
+ }
return 0;
}
@@ -4259,12 +3516,18 @@ static LRESULT
REBAR_StyleChanged (REBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
STYLESTRUCT *ss = (STYLESTRUCT *)lParam;
-
+
TRACE("current style=%08x, styleOld=%08x, style being set to=%08x\n",
infoPtr->dwStyle, ss->styleOld, ss->styleNew);
infoPtr->orgStyle = infoPtr->dwStyle = ss->styleNew;
if (GetWindowTheme (infoPtr->hwndSelf))
infoPtr->dwStyle &= ~WS_BORDER;
+ /* maybe it should be COMMON_STYLES like in toolbar */
+ if ((ss->styleNew ^ ss->styleOld) & CCS_VERT)
+ {
+ infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
+ REBAR_Layout(infoPtr, NULL, TRUE);
+ }
return FALSE;
}
diff --git a/dlls/comctl32/tests/rebar.c b/dlls/comctl32/tests/rebar.c
index 23497ef..2633dcb 100644
--- a/dlls/comctl32/tests/rebar.c
+++ b/dlls/comctl32/tests/rebar.c
@@ -29,6 +29,13 @@
static HWND hMainWnd;
static HWND hRebar;
+
+#define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \
+ val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \
+ val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom);
+
+#define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp));
+
#define expect_eq(expr, value, type, format) { type ret = expr; ok((value) == ret, #expr " expected " format " got " format "\n", (value), (ret)); }
static void rebuild_rebar(HWND *hRebar)
@@ -41,15 +48,390 @@ static void rebuild_rebar(HWND *hRebar)
SendMessageA(*hRebar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0);
}
+static HWND build_toolbar(int nr, HWND hParent)
+{
+ TBBUTTON btns[8];
+ HWND hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | CCS_NORESIZE, 0, 0, 0, 0,
+ hParent, (HMENU)5, GetModuleHandle(NULL), NULL);
+ int iBitmapId = 0;
+ int i;
+
+ ok(hToolbar != NULL, "Toolbar creation problem\n");
+ ok(SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n");
+ ok(SendMessage(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
+ ok(SendMessage(hToolbar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0)==1, "WM_SETFONT\n");
+
+ for (i=0; i<5+nr; i++)
+ {
+ btns[i].iBitmap = i;
+ btns[i].idCommand = i;
+ btns[i].fsStyle = BTNS_BUTTON;
+ btns[i].fsState = TBSTATE_ENABLED;
+ }
+
+ switch (nr)
+ {
+ case 0: iBitmapId = IDB_HIST_SMALL_COLOR; break;
+ case 1: iBitmapId = IDB_VIEW_SMALL_COLOR; break;
+ case 2: iBitmapId = IDB_STD_SMALL_COLOR; break;
+ }
+ ok(SendMessage(hToolbar, TB_LOADIMAGES, iBitmapId, (LPARAM)HINST_COMMCTRL) == 0, "TB_LOADIMAGE failed\n");
+ ok(SendMessage(hToolbar, TB_ADDBUTTONS, 5+nr, (LPARAM)btns), "TB_ADDBUTTONS failed\n");
+ return hToolbar;
+}
+
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProcA(hWnd, msg, wParam, lParam);
}
+#if 0 /* use this to generate more tests*/
+
+static void dump_sizes(HWND hRebar)
+{
+ SIZE sz;
+ RECT r;
+ int count;
+ int i, h;
+
+ GetClientRect(hRebar, &r);
+ count = SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0);
+ printf(" { {%d, %d, %d, %d}, %d, %d, {", r.left, r.top, r.right, r.bottom,
+ SendMessageA(hRebar, RB_GETBARHEIGHT, 0, 0), count);
+ if (count == 0)
+ printf("0, ");
+ for (i = 0; i < count; i++) /* rows */
+ printf("%d, ", SendMessageA(hRebar, RB_GETROWHEIGHT, i, 0));
+ printf("}, ");
+
+ count = SendMessageA(hRebar, RB_GETBANDCOUNT, 0, 0);
+ printf("%d, {", count);
+ if (count == 0)
+ printf("{{0, 0, 0, 0}, 0, 0},");
+ for (i=0; i<count; i++)
+ {
+ REBARBANDINFO rbi;
+ rbi.cbSize = sizeof(REBARBANDINFO);
+ rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE;
+ ok(SendMessageA(hRebar, RB_GETBANDINFOA, i, (LPARAM)&rbi), "RB_GETBANDINFO failed\n");
+ ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&r), "RB_GETRECT failed\n");
+ printf("%s{ {%3d, %3d, %3d, %3d}, 0x%02x, %d}, ", (i%2==0 ? "\n " : ""), r.left, r.top, r.right, r.bottom,
+ rbi.fStyle, rbi.cx);
+ }
+ printf("\n }, }, \n");
+}
+
+#define check_sizes() dump_sizes(hRebar);
+#define check_sizes_todo(todomask) dump_sizes(hRebar);
+
+#else
+
+typedef struct {
+ RECT rc;
+ DWORD fStyle;
+ INT cx;
+} rbband_result_t;
+
+typedef struct {
+ RECT rcClient;
+ int cyBarHeight;
+ int nRows;
+ int cyRowHeights[50];
+ int nBands;
+ rbband_result_t bands[50];
+} rbsize_result_t;
+
+rbsize_result_t rbsize_results[] = {
+ { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
+ }, },
+ { {0, 0, 672, 4}, 4, 1, {4, }, 1, {
+ { { 0, 0, 672, 4}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 4}, 4, 1, {4, }, 2, {
+ { { 0, 0, 200, 4}, 0x00, 200}, { {200, 0, 672, 4}, 0x04, 200},
+ }, },
+ { {0, 0, 672, 30}, 30, 1, {30, }, 3, {
+ { { 0, 0, 200, 30}, 0x00, 200}, { {200, 0, 400, 30}, 0x04, 200},
+ { {400, 0, 672, 30}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
+ { { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200},
+ { {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68},
+ }, },
+ { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
+ { { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200},
+ { {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68},
+ }, },
+ { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
+ { { 0, 0, 200, 34}, 0x00, 200}, { {202, 0, 402, 34}, 0x04, 200},
+ { {404, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
+ }, },
+ { {0, 0, 672, 70}, 70, 2, {34, 34, }, 5, {
+ { { 0, 0, 142, 34}, 0x00, 200}, { {144, 0, 557, 34}, 0x00, 200},
+ { {559, 0, 672, 34}, 0x04, 200}, { { 0, 36, 200, 70}, 0x00, 200},
+ { {202, 36, 672, 70}, 0x04, 66},
+ }, },
+ { {0, 0, 672, 34}, 34, 1, {34, }, 5, {
+ { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
+ { {559, 0, 759, 34}, 0x08, 200}, { {584, 0, 627, 34}, 0x00, 200},
+ { {629, 0, 672, 34}, 0x04, 66},
+ }, },
+ { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
+ { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
+ { {584, 0, 627, 34}, 0x00, 200}, { {629, 0, 672, 34}, 0x04, 66},
+ }, },
+ { {0, 0, 672, 34}, 34, 1, {34, }, 3, {
+ { { 0, 0, 413, 34}, 0x00, 200}, { {415, 0, 615, 34}, 0x00, 200},
+ { {617, 0, 672, 34}, 0x04, 66},
+ }, },
+ { {0, 0, 672, 34}, 34, 1, {34, }, 2, {
+ { { 0, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
+ }, },
+ { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
+ { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 184, 20}, 0x00, 70},
+ { {184, 0, 424, 20}, 0x00, 240}, { {424, 0, 672, 20}, 0x00, 60},
+ { { 0, 20, 672, 40}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
+ { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 227, 20}, 0x00, 113},
+ { {227, 0, 424, 20}, 0x00, 197}, { {424, 0, 672, 20}, 0x00, 60},
+ { { 0, 20, 672, 40}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
+ { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
+ { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
+ { { 0, 20, 672, 40}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
+ { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 167, 20}, 0x00, 53},
+ { {167, 0, 511, 20}, 0x00, 344}, { {511, 0, 672, 20}, 0x00, 161},
+ { { 0, 20, 672, 40}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
+ { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
+ { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
+ { { 0, 20, 672, 40}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
+ { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
+ { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
+ { { 0, 20, 672, 40}, 0x00, 200},
+ }, },
+ { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
+ }, },
+ { {0, 0, 672, 65}, 65, 1, {65, }, 3, {
+ { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 180, 65}, 0x40, 90},
+ { {180, 0, 672, 65}, 0x40, 90},
+ }, },
+ { {0, 0, 0, 226}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
+ }, },
+ { {0, 0, 65, 226}, 65, 1, {65, }, 1, {
+ { { 0, 0, 226, 65}, 0x40, 90},
+ }, },
+ { {0, 0, 65, 226}, 65, 1, {65, }, 2, {
+ { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 226, 65}, 0x40, 90},
+ }, },
+ { {0, 0, 65, 226}, 65, 1, {65, }, 3, {
+ { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 163, 65}, 0x40, 90},
+ { {163, 0, 226, 65}, 0x40, 90},
+ }, },
+};
+
+static int rbsize_numtests = 0;
+
+#define check_sizes_todo(todomask) { \
+ RECT rc; \
+ REBARBANDINFO rbi; \
+ int count, i/*, mask=(todomask)*/; \
+ rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \
+ assert(rbsize_numtests < sizeof(rbsize_results)/sizeof(rbsize_results[0])); \
+ GetClientRect(hRebar, &rc); \
+ check_rect("client", rc, res->rcClient); \
+ count = SendMessage(hRebar, RB_GETROWCOUNT, 0, 0); \
+ compare(count, res->nRows, "%d"); \
+ for (i=0; i<min(count, res->nRows); i++) { \
+ int height = SendMessageA(hRebar, RB_GETROWHEIGHT, 0, 0);\
+ ok(height == res->cyRowHeights[i], "Height mismatch for row %d - %d vs %d\n", i, res->cyRowHeights[i], height); \
+ } \
+ count = SendMessage(hRebar, RB_GETBANDCOUNT, 0, 0); \
+ compare(count, res->nBands, "%d"); \
+ for (i=0; i<min(count, res->nBands); i++) { \
+ ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_ITEMRECT\n"); \
+ if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
+ check_rect("band", rc, res->bands[i].rc); \
+ rbi.cbSize = sizeof(REBARBANDINFO); \
+ rbi.fMask = RBBIM_STYLE | RBBIM_SIZE; \
+ ok(SendMessageA(hRebar, RB_GETBANDINFO, i, (LPARAM)&rbi) == 1, "RB_GETBANDINFO\n"); \
+ compare(rbi.fStyle, res->bands[i].fStyle, "%x"); \
+ compare(rbi.cx, res->bands[i].cx, "%d"); \
+ } \
+ rbsize_numtests++; \
+ }
+
+#define check_sizes() check_sizes_todo(0)
+
+#endif
+
+static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int cxIdeal)
+{
+ CHAR buffer[MAX_PATH];
+ REBARBANDINFO rbi;
+
+ if (lpszText != NULL)
+ strcpy(buffer, lpszText);
+ rbi.cbSize = sizeof(rbi);
+ rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_TEXT;
+ rbi.cx = cx;
+ rbi.cxMinChild = cxMinChild;
+ rbi.cxIdeal = cxIdeal;
+ rbi.cyMinChild = 20;
+ rbi.hwndChild = build_toolbar(1, hRebar);
+ rbi.lpText = (lpszText ? buffer : NULL);
+ SendMessage(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+}
+
+static void layout_test()
+{
+ HWND hRebar = NULL;
+ REBARBANDINFO rbi;
+
+ rebuild_rebar(&hRebar);
+ check_sizes();
+ rbi.cbSize = sizeof(rbi);
+ rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
+ rbi.cx = 200;
+ rbi.cxMinChild = 100;
+ rbi.cyMinChild = 30;
+ rbi.hwndChild = NULL;
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+ check_sizes();
+
+ rbi.fMask |= RBBIM_STYLE;
+ rbi.fStyle = RBBS_CHILDEDGE;
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+ check_sizes();
+
+ rbi.fStyle = 0;
+ rbi.cx = 200;
+ rbi.cxMinChild = 30;
+ rbi.cyMinChild = 30;
+ rbi.hwndChild = build_toolbar(0, hRebar);
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+ check_sizes();
+
+ rbi.fStyle = RBBS_CHILDEDGE;
+ rbi.cx = 68;
+ rbi.hwndChild = build_toolbar(0, hRebar);
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+ check_sizes();
+
+ SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_BANDBORDERS);
+ check_sizes(); /* a style change won't start a relayout */
+ rbi.fMask = RBBIM_SIZE;
+ rbi.cx = 66;
+ SendMessageA(hRebar, RB_SETBANDINFO, 3, (LPARAM)&rbi);
+ check_sizes(); /* here it will be relayouted */
+
+ /* this will force a new row */
+ rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
+ rbi.cx = 200;
+ rbi.cxMinChild = 400;
+ rbi.cyMinChild = 30;
+ rbi.hwndChild = build_toolbar(0, hRebar);
+ SendMessageA(hRebar, RB_INSERTBAND, 1, (LPARAM)&rbi);
+ check_sizes();
+
+ rbi.fMask = RBBIM_STYLE;
+ rbi.fStyle = RBBS_HIDDEN;
+ SendMessageA(hRebar, RB_SETBANDINFO, 2, (LPARAM)&rbi);
+ check_sizes();
+
+ SendMessageA(hRebar, RB_DELETEBAND, 2, 0);
+ check_sizes();
+ SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
+ check_sizes();
+ SendMessageA(hRebar, RB_DELETEBAND, 1, 0);
+ check_sizes();
+
+ rebuild_rebar(&hRebar);
+ add_band_w(hRebar, "ABC", 70, 40, 100);
+ add_band_w(hRebar, NULL, 40, 70, 100);
+ add_band_w(hRebar, NULL, 170, 240, 100);
+ add_band_w(hRebar, "MMMMMMM", 60, 60, 100);
+ add_band_w(hRebar, NULL, 200, 200, 100);
+ check_sizes();
+ SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
+ check_sizes();
+ SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
+ check_sizes();
+ SendMessageA(hRebar, RB_MAXIMIZEBAND, 2, FALSE);
+ check_sizes();
+ SendMessageA(hRebar, RB_MINIMIZEBAND, 2, 0);
+ check_sizes();
+ SendMessageA(hRebar, RB_MINIMIZEBAND, 0, 0);
+ check_sizes();
+
+ /* VARHEIGHT resizing test on a horizontal rebar */
+ rebuild_rebar(&hRebar);
+ SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
+ check_sizes();
+ rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
+ rbi.fStyle = RBBS_VARIABLEHEIGHT;
+ rbi.cxMinChild = 50;
+ rbi.cyMinChild = 10;
+ rbi.cyIntegral = 11;
+ rbi.cyChild = 70;
+ rbi.cyMaxChild = 200;
+ rbi.cx = 90;
+ rbi.hwndChild = build_toolbar(0, hRebar);
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+
+ rbi.cyChild = 50;
+ rbi.hwndChild = build_toolbar(0, hRebar);
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+
+ rbi.cyMinChild = 40;
+ rbi.cyChild = 50;
+ rbi.cyIntegral = 5;
+ rbi.hwndChild = build_toolbar(0, hRebar);
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+ check_sizes();
+
+ /* VARHEIGHT resizing on a vertical rebar */
+ rebuild_rebar(&hRebar);
+ SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE);
+ check_sizes();
+ rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
+ rbi.fStyle = RBBS_VARIABLEHEIGHT;
+ rbi.cxMinChild = 50;
+ rbi.cyMinChild = 10;
+ rbi.cyIntegral = 11;
+ rbi.cyChild = 70;
+ rbi.cyMaxChild = 90;
+ rbi.cx = 90;
+ rbi.hwndChild = build_toolbar(0, hRebar);
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+ check_sizes();
+
+ rbi.cyChild = 50;
+ rbi.hwndChild = build_toolbar(0, hRebar);
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+ check_sizes();
+
+ rbi.cyMinChild = 40;
+ rbi.cyChild = 50;
+ rbi.cyIntegral = 5;
+ rbi.hwndChild = build_toolbar(0, hRebar);
+ SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
+ check_sizes();
+
+ DestroyWindow(hRebar);
+}
+
static void expect_band_content(UINT uBand, UINT fStyle, COLORREF clrFore,
COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild,
UINT cxMinChild, UINT cyMinChild, UINT cx, HBITMAP hbmBack, UINT wID,
- /*UINT cyChild, UINT cyMaxChild, UINT cyIntegral,*/ UINT cxIdeal, LPARAM lParam,
+ UINT cyChild, UINT cyMaxChild, UINT cyIntegral, UINT cxIdeal, LPARAM lParam,
UINT cxHeader)
{
CHAR buf[MAX_PATH] = "abc";
@@ -74,12 +456,12 @@ static void expect_band_content(UINT uBand, UINT fStyle, COLORREF clrFore,
expect_eq(rb.cx, cx, int, "%d");
expect_eq(rb.hbmBack, hbmBack, HBITMAP, "%p");
expect_eq(rb.wID, wID, int, "%d");
- /* in Windows the values of cyChild, cyMaxChild and cyIntegral can't be read */
- todo_wine expect_eq(rb.cyChild, 0xdddddddd, int, "%x");
- todo_wine expect_eq(rb.cyMaxChild, 0xdddddddd, int, "%x");
- todo_wine expect_eq(rb.cyIntegral, 0xdddddddd, int, "%x");
+ /* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */
+ expect_eq(rb.cyChild, cyChild, int, "%x");
+ expect_eq(rb.cyMaxChild, cyMaxChild, int, "%x");
+ expect_eq(rb.cyIntegral, cyIntegral, int, "%x");
expect_eq(rb.cxIdeal, cxIdeal, int, "%d");
- expect_eq(rb.lParam, lParam, LPARAM, "%lx");
+ expect_eq(rb.lParam, lParam, LPARAM, "%ld");
expect_eq(rb.cxHeader, cxHeader, int, "%d");
}
@@ -93,7 +475,7 @@ static void bandinfo_test()
rb.cbSize = sizeof(REBARBANDINFO);
rb.fMask = 0;
ok(SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
- expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0, 0, 0);
+ expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
rb.fMask = RBBIM_CHILDSIZE;
rb.cxMinChild = 15;
@@ -102,37 +484,37 @@ static void bandinfo_test()
rb.cyMaxChild = 20;
rb.cyIntegral = 10;
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
- expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0, 0, 0);
+ expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
rb.fMask = RBBIM_TEXT;
rb.lpText = szABC;
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
- expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0, 0, 35);
+ expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35);
rb.cbSize = sizeof(REBARBANDINFO);
rb.fMask = 0;
ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBAND failed\n");
- expect_band_content(1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0, 0, 9);
- expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0, 0, 40);
+ expect_band_content(1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9);
+ expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40);
rb.fMask = RBBIM_HEADERSIZE;
rb.cxHeader = 50;
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
- expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0, 0, 50);
+ expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50);
rb.cxHeader = 5;
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
- expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0, 0, 5);
+ expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
rb.fMask = RBBIM_TEXT;
rb.lpText = szABCD;
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
- expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0, 0, 5);
+ expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
rb.fMask = RBBIM_STYLE | RBBIM_TEXT;
- rb.fStyle = 0;
+ rb.fStyle = RBBS_VARIABLEHEIGHT;
rb.lpText = szABC;
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
- expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0, 0, 40);
+ expect_band_content(0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40);
DestroyWindow(hRebar);
}
@@ -159,13 +541,14 @@ START_TEST(rebar)
wc.lpszClassName = "MyTestWnd";
wc.lpfnWndProc = MyWndProc;
RegisterClassA(&wc);
-
- hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
+ hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, 680, 226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
+ NULL, NULL, GetModuleHandleA(NULL), 0);
GetClientRect(hMainWnd, &rc);
ShowWindow(hMainWnd, SW_SHOW);
bandinfo_test();
+ layout_test();
PostQuitMessage(0);
while(GetMessageA(&msg,0,0,0)) {
TranslateMessage(&msg);
--
1.4.4.2
More information about the wine-patches
mailing list