comctl32: toolbar: Implemented SetRows.

This commit is contained in:
Jason Edmeades 2007-08-27 21:30:16 +01:00 committed by Alexandre Julliard
parent 2d8cd767b2
commit 881c204c02
2 changed files with 150 additions and 10 deletions

View File

@ -1032,6 +1032,61 @@ static void test_dispinfo(void)
g_dwExpectedDispInfoMask = 0;
}
typedef struct
{
int nRows;
BOOL bLarger;
int expectedRows;
} tbrows_result_t;
static tbrows_result_t tbrows_results[] =
{
{1, TRUE, 1}, /* 0: Simple case 9 in a row */
{2, TRUE, 2}, /* 1: Another simple case 5 on one row, 4 on another*/
{3, FALSE, 3}, /* 2: 3 lines - should be 3 lines of 3 buttons */
{8, FALSE, 5}, /* 3: 8 lines - should be 5 lines of 2 buttons */
{8, TRUE, 9}, /* 4: 8 lines but grow - should be 9 lines */
{1, TRUE, 1} /* 5: Back to simple case */
};
static void test_setrows(void)
{
TBBUTTON buttons[9];
HWND hToolbar;
int i;
for (i=0; i<9; i++)
MakeButton(buttons+i, 1000+i, TBSTYLE_FLAT | TBSTYLE_CHECKGROUP, 0);
/* Test 1 - 9 buttons */
hToolbar = CreateToolbarEx(hMainWnd,
WS_VISIBLE | WS_CLIPCHILDREN | WS_CHILD | CCS_NORESIZE | CCS_NOPARENTALIGN
| CCS_NOMOVEY | CCS_TOP,
0,
0, NULL, (UINT)0,
buttons, sizeof(buttons)/sizeof(buttons[0]),
20, 20, 0, 0, sizeof(TBBUTTON));
ok(hToolbar != NULL, "Toolbar creation\n");
ok(SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
/* test setting rows to each of 1-10 with bLarger true and false */
for (i=0; i<(sizeof(tbrows_results) / sizeof(tbrows_result_t)); i++) {
RECT rc;
int rows;
memset(&rc, 0xCC, sizeof(rc));
SendMessageA(hToolbar, TB_SETROWS,
MAKELONG(tbrows_results[i].nRows, tbrows_results[i].bLarger),
(LONG) &rc);
rows = SendMessageA(hToolbar, TB_GETROWS, MAKELONG(0,0), MAKELONG(0,0));
ok(rows == tbrows_results[i].expectedRows,
"[%d] Unexpected number of rows %d (expected %d)\n", i, rows,
tbrows_results[i].expectedRows);
}
DestroyWindow(hToolbar);
}
START_TEST(toolbar)
{
@ -1066,6 +1121,7 @@ START_TEST(toolbar)
test_getbuttoninfo();
test_createtoolbarex();
test_dispinfo();
test_setrows();
PostQuitMessage(0);
while(GetMessageA(&msg,0,0,0)) {

View File

@ -44,7 +44,7 @@
* - TBN_GETOBJECT
* - TBN_SAVE
* - Button wrapping (under construction).
* - Fix TB_SETROWS.
* - Fix TB_SETROWS and Separators.
* - iListGap custom draw support.
*
* Testing:
@ -3637,10 +3637,7 @@ TOOLBAR_GetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
if (infoPtr->dwStyle & TBSTYLE_WRAPABLE)
return infoPtr->nRows;
else
return 1;
return infoPtr->nRows;
}
@ -4947,20 +4944,107 @@ TOOLBAR_SetRows (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr (hwnd);
LPRECT lprc = (LPRECT)lParam;
int rows = LOWORD(wParam);
BOOL bLarger = HIWORD(wParam);
TRACE("\n");
if (LOWORD(wParam) > 1) {
FIXME("multiple rows not supported!\n");
}
TRACE("Setting rows to %d (%d)\n", rows, bLarger);
if(infoPtr->nRows != LOWORD(wParam))
if(infoPtr->nRows != rows)
{
infoPtr->nRows = LOWORD(wParam);
TBUTTON_INFO *btnPtr = infoPtr->buttons;
int curColumn = 0; /* Current column */
int curRow = 0; /* Current row */
int hidden = 0; /* Number of hidden buttons */
int seps = 0; /* Number of separators */
int idealWrap = 0; /* Ideal wrap point */
int i;
BOOL wrap;
/*
Calculate new size and wrap points - Under windows, setrows will
change the dimensions if needed to show the number of requested
rows (if CCS_NORESIZE is set), or will take up the whole window
(if no CCS_NORESIZE).
Basic algorithum - If N buttons, and y rows requested, each row
contains N/y buttons.
FIXME: Handling of separators not obvious from testing results
FIXME: Take width of window into account?
*/
/* Loop through the buttons one by one counting key items */
for (i = 0; i < infoPtr->nNumButtons; i++ )
{
btnPtr[i].fsState &= ~TBSTATE_WRAP;
if (btnPtr[i].fsState & TBSTATE_HIDDEN)
hidden++;
else if (btnPtr[i].fsStyle & BTNS_SEP)
seps++;
}
/* FIXME: Separators make this quite complex */
if (seps) FIXME("Separators unhandled\n");
/* Round up so more per line, ie less rows */
idealWrap = (infoPtr->nNumButtons - hidden + (rows-1)) / rows;
/* Calculate ideal wrap point if we are allowed to grow, but cannot
achieve the requested number of rows. */
if (bLarger && idealWrap > 1)
{
int resRows = (infoPtr->nNumButtons + (idealWrap-1)) / idealWrap;
int moreRows = (infoPtr->nNumButtons + (idealWrap-2)) / (idealWrap-1);
if (resRows < rows && moreRows > rows)
{
idealWrap--;
TRACE("Changing idealWrap due to bLarger (now %d)\n", idealWrap);
}
}
curColumn = curRow = 0;
wrap = FALSE;
TRACE("Trying to wrap at %d (%d,%d,%d)\n", idealWrap,
infoPtr->nNumButtons, hidden, rows);
for (i = 0; i < infoPtr->nNumButtons; i++ )
{
if (btnPtr[i].fsState & TBSTATE_HIDDEN)
continue;
/* Step on, wrap if necessary or flag next to wrap */
if (!wrap) {
curColumn++;
} else {
wrap = FALSE;
curColumn = 1;
curRow++;
}
if (curColumn > (idealWrap-1)) {
wrap = TRUE;
btnPtr[i].fsState |= TBSTATE_WRAP;
}
}
TRACE("Result - %d rows\n", curRow + 1);
/* recalculate toolbar */
TOOLBAR_CalcToolbar (hwnd);
/* Resize if necessary (Only if NORESIZE is set - odd, but basically
if NORESIZE is NOT set, then the toolbar will always be resized to
take up the whole window. With it set, sizing needs to be manual. */
if (infoPtr->dwStyle & CCS_NORESIZE) {
SetWindowPos(hwnd, NULL, 0, 0,
infoPtr->rcBound.right - infoPtr->rcBound.left,
infoPtr->rcBound.bottom - infoPtr->rcBound.top,
SWP_NOMOVE);
}
/* repaint toolbar */
InvalidateRect(hwnd, NULL, TRUE);
}