Commit bdcaae4b authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

user32: Add an items rect to the header and use it to fix scrolling down.

parent d4d0247f
...@@ -97,6 +97,7 @@ typedef struct { ...@@ -97,6 +97,7 @@ typedef struct {
BOOL bScrolling; /* Scroll arrows are active */ BOOL bScrolling; /* Scroll arrows are active */
UINT nScrollPos; /* Current scroll position */ UINT nScrollPos; /* Current scroll position */
UINT nTotalHeight; /* Total height of menu items inside menu */ UINT nTotalHeight; /* Total height of menu items inside menu */
RECT items_rect; /* Rectangle within which the items lie. Excludes margins and scroll arrows */
/* ------------ MENUINFO members ------ */ /* ------------ MENUINFO members ------ */
DWORD dwStyle; /* Extended menu style */ DWORD dwStyle; /* Extended menu style */
UINT cyMax; /* max height of the whole menu, 0 is screen height */ UINT cyMax; /* max height of the whole menu, 0 is screen height */
...@@ -1170,26 +1171,27 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop ) ...@@ -1170,26 +1171,27 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
HDC hdc; HDC hdc;
UINT start, i; UINT start, i;
BOOL textandbmp = FALSE; BOOL textandbmp = FALSE;
int orgX, orgY, maxX, maxTab, maxTabWidth, maxHeight; int orgX, orgY, maxTab, maxTabWidth, maxHeight;
lppop->Width = lppop->Height = 0; lppop->Width = lppop->Height = 0;
SetRect(&lppop->items_rect, MENU_MARGIN, MENU_MARGIN, MENU_MARGIN, MENU_MARGIN);
if (lppop->nItems == 0) return; if (lppop->nItems == 0) return;
hdc = GetDC( 0 ); hdc = GetDC( 0 );
SelectObject( hdc, get_menu_font(FALSE)); SelectObject( hdc, get_menu_font(FALSE));
start = 0; start = 0;
maxX = MENU_MARGIN;
lppop->textOffset = 0; lppop->textOffset = 0;
while (start < lppop->nItems) while (start < lppop->nItems)
{ {
lpitem = &lppop->items[start]; lpitem = &lppop->items[start];
orgX = maxX; orgX = lppop->items_rect.right;
if( lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK)) if( lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))
orgX += MENU_COL_SPACE; orgX += MENU_COL_SPACE;
orgY = MENU_MARGIN; orgY = lppop->items_rect.top;
maxTab = maxTabWidth = 0; maxTab = maxTabWidth = 0;
/* Parse items until column break or end of menu */ /* Parse items until column break or end of menu */
...@@ -1199,7 +1201,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop ) ...@@ -1199,7 +1201,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
(lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break; (lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
MENU_CalcItemSize( hdc, lpitem, lppop->hwndOwner, orgX, orgY, FALSE, lppop ); MENU_CalcItemSize( hdc, lpitem, lppop->hwndOwner, orgX, orgY, FALSE, lppop );
maxX = max( maxX, lpitem->rect.right ); lppop->items_rect.right = max( lppop->items_rect.right, lpitem->rect.right );
orgY = lpitem->rect.bottom; orgY = lpitem->rect.bottom;
if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab) if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab)
{ {
...@@ -1210,18 +1212,17 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop ) ...@@ -1210,18 +1212,17 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
} }
/* Finish the column (set all items to the largest width found) */ /* Finish the column (set all items to the largest width found) */
maxX = max( maxX, maxTab + maxTabWidth ); lppop->items_rect.right = max( lppop->items_rect.right, maxTab + maxTabWidth );
for (lpitem = &lppop->items[start]; start < i; start++, lpitem++) for (lpitem = &lppop->items[start]; start < i; start++, lpitem++)
{ {
lpitem->rect.right = maxX; lpitem->rect.right = lppop->items_rect.right;
if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab) if (IS_STRING_ITEM(lpitem->fType) && lpitem->xTab)
lpitem->xTab = maxTab; lpitem->xTab = maxTab;
} }
lppop->Height = max( lppop->Height, orgY ); lppop->items_rect.bottom = max( lppop->items_rect.bottom, orgY );
} }
lppop->Width = maxX;
/* if none of the items have both text and bitmap then /* if none of the items have both text and bitmap then
* the text and bitmaps are all aligned on the left. If there is at * the text and bitmaps are all aligned on the left. If there is at
* least one item with both text and bitmap then bitmaps are * least one item with both text and bitmap then bitmaps are
...@@ -1230,8 +1231,8 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop ) ...@@ -1230,8 +1231,8 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
if( !textandbmp) lppop->textOffset = 0; if( !textandbmp) lppop->textOffset = 0;
/* space for 3d border */ /* space for 3d border */
lppop->Height += MENU_MARGIN; lppop->Height = lppop->items_rect.bottom + MENU_MARGIN;
lppop->Width += MENU_MARGIN; lppop->Width = lppop->items_rect.right + MENU_MARGIN;
/* Adjust popup height if it exceeds maximum */ /* Adjust popup height if it exceeds maximum */
maxHeight = MENU_GetMaxPopupHeight(lppop); maxHeight = MENU_GetMaxPopupHeight(lppop);
...@@ -1239,6 +1240,8 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop ) ...@@ -1239,6 +1240,8 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
if (lppop->Height >= maxHeight) if (lppop->Height >= maxHeight)
{ {
lppop->Height = maxHeight; lppop->Height = maxHeight;
lppop->items_rect.top += get_scroll_arrow_height(lppop);
lppop->items_rect.bottom = lppop->Height - MENU_MARGIN - get_scroll_arrow_height(lppop);
lppop->bScrolling = TRUE; lppop->bScrolling = TRUE;
} }
else else
...@@ -1307,6 +1310,7 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, ...@@ -1307,6 +1310,7 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect,
lprect->bottom = maxY; lprect->bottom = maxY;
lppop->Height = lprect->bottom - lprect->top; lppop->Height = lprect->bottom - lprect->top;
lppop->items_rect = *lprect;
/* Flush right all items between the MF_RIGHTJUSTIFY and */ /* Flush right all items between the MF_RIGHTJUSTIFY and */
/* the last item (if several lines, only move the last line) */ /* the last item (if several lines, only move the last line) */
...@@ -1937,32 +1941,22 @@ MENU_EnsureMenuItemVisible(LPPOPUPMENU lppop, UINT wIndex, HDC hdc) ...@@ -1937,32 +1941,22 @@ MENU_EnsureMenuItemVisible(LPPOPUPMENU lppop, UINT wIndex, HDC hdc)
if (lppop->bScrolling) if (lppop->bScrolling)
{ {
MENUITEM *item = &lppop->items[wIndex]; MENUITEM *item = &lppop->items[wIndex];
UINT nMaxHeight = MENU_GetMaxPopupHeight(lppop);
UINT nOldPos = lppop->nScrollPos; UINT nOldPos = lppop->nScrollPos;
RECT rc; const RECT *rc = &lppop->items_rect;
UINT arrow_bitmap_height; UINT scroll_height = rc->bottom - rc->top;
BITMAP bmp;
GetClientRect(lppop->hWnd, &rc); /* NB the item rects include the MENU_MARGIN offset (so the first rect has
top == MENU_TOP_MARGIN) */
GetObjectW(get_down_arrow_bitmap(), sizeof(bmp), &bmp); if (item->rect.bottom - MENU_MARGIN > lppop->nScrollPos + scroll_height)
arrow_bitmap_height = bmp.bmHeight;
rc.top += arrow_bitmap_height;
rc.bottom -= arrow_bitmap_height + MENU_MARGIN;
nMaxHeight -= GetSystemMetrics(SM_CYBORDER) + 2 * arrow_bitmap_height;
if (item->rect.bottom > lppop->nScrollPos + nMaxHeight)
{ {
lppop->nScrollPos = item->rect.bottom - MENU_MARGIN - scroll_height;
lppop->nScrollPos = item->rect.bottom - nMaxHeight; ScrollWindow(lppop->hWnd, 0, nOldPos - lppop->nScrollPos, rc, rc);
ScrollWindow(lppop->hWnd, 0, nOldPos - lppop->nScrollPos, &rc, &rc);
MENU_DrawScrollArrows(lppop, hdc); MENU_DrawScrollArrows(lppop, hdc);
} }
else if (item->rect.top - MENU_MARGIN < lppop->nScrollPos) else if (item->rect.top - MENU_MARGIN < lppop->nScrollPos)
{ {
lppop->nScrollPos = item->rect.top - MENU_MARGIN; lppop->nScrollPos = item->rect.top - MENU_MARGIN;
ScrollWindow(lppop->hWnd, 0, nOldPos - lppop->nScrollPos, &rc, &rc); ScrollWindow(lppop->hWnd, 0, nOldPos - lppop->nScrollPos, rc, rc);
MENU_DrawScrollArrows(lppop, hdc); MENU_DrawScrollArrows(lppop, hdc);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment