diff --git a/headers/os/interface/Menu.h b/headers/os/interface/Menu.h index 338a1e190f..4c6d76768a 100644 --- a/headers/os/interface/Menu.h +++ b/headers/os/interface/Menu.h @@ -17,7 +17,7 @@ #include /*----------------------------------------------------------------*/ -/*----- Menu decalrations and structures -------------------------*/ +/*----- Menu declarations and structures -------------------------*/ class BMenuItem; class BMenuBar; @@ -204,6 +204,10 @@ virtual void _ReservedMenu6(); void LayoutItems(int32 index); void ComputeLayout(int32 index, bool bestFit, bool moveItems, float* width, float* height); + void _ComputeColumnLayout(int32 index, bool bestFit, bool moveItems, BRect &outRect); + void _ComputeRowLayout(int32 index, bool bestFit, bool moveItems, BRect &outRect); + void _ComputeMatrixLayout(BRect &outRect); + BRect Bump(BRect current, BPoint extent, int32 index) const; BPoint ItemLocInRect(BRect frame) const; BRect CalcFrame(BPoint where, bool *scrollOn); diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 67bf1bb903..bcbc1ef5ee 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -1530,90 +1530,19 @@ BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems, // Recalculate only the needed items, // not the whole layout every time - BRect frame(0, 0, 0, 0); - float iWidth, iHeight; - BMenuItem *item = NULL; - - BFont font; - GetFont(&font); + BRect frame(0, 0, 0, 0); switch (fLayout) { case B_ITEMS_IN_COLUMN: - { - for (int32 i = 0; i < fItems.CountItems(); i++) { - item = ItemAt(i); - if (item != NULL) { - item->GetContentSize(&iWidth, &iHeight); - - if (item->fModifiers && item->fShortcutChar) - iWidth += 2 * font.Size(); - if (item->fSubmenu != NULL) - iWidth += 2 * font.Size(); - - item->fBounds.left = 0.0f; - item->fBounds.top = frame.bottom; - item->fBounds.bottom = item->fBounds.top + iHeight + fPad.top + fPad.bottom; - - frame.right = max_c(frame.right, iWidth + fPad.left + fPad.right); - frame.bottom = item->fBounds.bottom + 1.0f; - } - } - if (fMaxContentWidth > 0) - frame.right = min_c(frame.right, fMaxContentWidth); - - if (moveItems) { - for (int32 i = 0; i < fItems.CountItems(); i++) - ItemAt(i)->fBounds.right = frame.right; - } - frame.right = ceilf(frame.right); - frame.bottom--; + _ComputeColumnLayout(index, bestFit, moveItems, frame); break; - } case B_ITEMS_IN_ROW: - { - font_height fh; - GetFontHeight(&fh); - frame = BRect(0.0f, 0.0f, 0.0f, ceilf(fh.ascent + fh.descent + fPad.top + fPad.bottom)); - - for (int32 i = 0; i < fItems.CountItems(); i++) { - item = ItemAt(i); - if (item != NULL) { - item->GetContentSize(&iWidth, &iHeight); - - item->fBounds.left = frame.right; - item->fBounds.top = 0.0f; - item->fBounds.right = item->fBounds.left + iWidth + fPad.left + fPad.right; - - frame.right = item->Frame().right + 1.0f; - frame.bottom = max_c(frame.bottom, iHeight + fPad.top + fPad.bottom); - } - } - - if (moveItems) { - for (int32 i = 0; i < fItems.CountItems(); i++) - ItemAt(i)->fBounds.bottom = frame.bottom; - } - - if (bestFit) - frame.right = ceilf(frame.right); - else - frame.right = Bounds().right; + _ComputeRowLayout(index, bestFit, moveItems, frame); break; - } case B_ITEMS_IN_MATRIX: - { - for (int32 i = 0; i < CountItems(); i++) { - item = ItemAt(i); - if (item != NULL) { - frame.left = min_c(frame.left, item->Frame().left); - frame.right = max_c(frame.right, item->Frame().right); - frame.top = min_c(frame.top, item->Frame().top); - frame.bottom = max_c(frame.bottom, item->Frame().bottom); - } - } + _ComputeMatrixLayout(frame); break; - } default: break; @@ -1640,6 +1569,99 @@ BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems, } +void +BMenu::_ComputeColumnLayout(int32 index, bool bestFit, bool moveItems, BRect &frame) +{ + BFont font; + GetFont(&font); + for (int32 i = 0; i < fItems.CountItems(); i++) { + BMenuItem *item = ItemAt(i); + if (item != NULL) { + float iWidth, iHeight; + item->GetContentSize(&iWidth, &iHeight); + + if (item->fModifiers && item->fShortcutChar) { + iWidth += font.Size(); + if (item->fModifiers & B_COMMAND_KEY) + iWidth += 15; + if (item->fModifiers & B_CONTROL_KEY) + iWidth += 15; + if (item->fModifiers & B_SHIFT_KEY) + iWidth += 20; + } + + item->fBounds.left = 0.0f; + item->fBounds.top = frame.bottom; + item->fBounds.bottom = item->fBounds.top + iHeight + fPad.top + fPad.bottom; + + if (item->fSubmenu != NULL) + iWidth += item->Frame().Height(); + + frame.right = max_c(frame.right, iWidth + fPad.left + fPad.right); + frame.bottom = item->fBounds.bottom + 1.0f; + } + } + if (fMaxContentWidth > 0) + frame.right = min_c(frame.right, fMaxContentWidth); + + if (moveItems) { + for (int32 i = 0; i < fItems.CountItems(); i++) + ItemAt(i)->fBounds.right = frame.right; + } + frame.right = ceilf(frame.right); + frame.bottom--; +} + + +void +BMenu::_ComputeRowLayout(int32 index, bool bestFit, bool moveItems, BRect &frame) +{ + font_height fh; + GetFontHeight(&fh); + frame = BRect(0.0f, 0.0f, 0.0f, ceilf(fh.ascent + fh.descent + fPad.top + fPad.bottom)); + + for (int32 i = 0; i < fItems.CountItems(); i++) { + BMenuItem *item = ItemAt(i); + float iWidth, iHeight; + if (item != NULL) { + item->GetContentSize(&iWidth, &iHeight); + + item->fBounds.left = frame.right; + item->fBounds.top = 0.0f; + item->fBounds.right = item->fBounds.left + iWidth + fPad.left + fPad.right; + + frame.right = item->Frame().right + 1.0f; + frame.bottom = max_c(frame.bottom, iHeight + fPad.top + fPad.bottom); + } + } + + if (moveItems) { + for (int32 i = 0; i < fItems.CountItems(); i++) + ItemAt(i)->fBounds.bottom = frame.bottom; + } + + if (bestFit) + frame.right = ceilf(frame.right); + else + frame.right = Bounds().right; +} + + +void +BMenu::_ComputeMatrixLayout(BRect &frame) +{ + for (int32 i = 0; i < CountItems(); i++) { + BMenuItem *item = ItemAt(i); + if (item != NULL) { + frame.left = min_c(frame.left, item->Frame().left); + frame.right = max_c(frame.right, item->Frame().right); + frame.top = min_c(frame.top, item->Frame().top); + frame.bottom = max_c(frame.bottom, item->Frame().bottom); + } + } +} + + BRect BMenu::Bump(BRect current, BPoint extent, int32 index) const { diff --git a/src/kits/interface/MenuItem.cpp b/src/kits/interface/MenuItem.cpp index c9224fa0b3..0ef3fb4c7b 100644 --- a/src/kits/interface/MenuItem.cpp +++ b/src/kits/interface/MenuItem.cpp @@ -1,11 +1,11 @@ /* - * Copyright 2001-2006, Haiku, Inc. + * Copyright 2001-2007, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * Marc Flerackers (mflerackers@androme.be) * Bill Hayden (haydentech@users.sourceforge.net) - * Stefano Ceccherini (burton666@libero.it) + * Stefano Ceccherini (stefano.ceccherini@gmail.com) * Olivier Milla */ @@ -20,7 +20,6 @@ #include #include - const uint32 kCtrlLength = 20*11; const unsigned char kCtrlBits[] = { 0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x14,0xff,0xff,0xff, @@ -709,11 +708,12 @@ BMenuItem::_DrawMarkSymbol(rgb_color bgColor) void BMenuItem::_DrawShortcutSymbol() { - // TODO: Review this + BFont font; + Menu()->GetFont(&font); BPoint where = ContentLocation(); - where.x += fBounds.Width() - 28; + where.x += fBounds.Width() - 28; if (fSubmenu) - where.x -= 12; + where.x -= fBounds.Height(); switch (fShortcutChar) { case B_DOWN_ARROW: @@ -729,7 +729,8 @@ BMenuItem::_DrawShortcutSymbol() break; } - where -= BPoint(20, -1); + where.y += (fBounds.Height() - 11) / 2 - 1; + where.x -= 5; if (fModifiers & B_COMMAND_KEY) { BRect rect(0,0,16,10); @@ -739,9 +740,9 @@ BMenuItem::_DrawShortcutSymbol() control.SetBits(kAltBits, kAltLength, 0, B_CMAP8); else control.SetBits(kCtrlBits, kCtrlLength, 0, B_CMAP8); - fSuper->DrawBitmap(&control, where); - + where.x -= rect.Width() + 1; + fSuper->DrawBitmap(&control, where); } if (fModifiers & B_CONTROL_KEY) { @@ -752,16 +753,16 @@ BMenuItem::_DrawShortcutSymbol() control.SetBits(kCtrlBits, kCtrlLength, 0, B_CMAP8); else control.SetBits(kAltBits, kAltLength, 0, B_CMAP8); - fSuper->DrawBitmap(&control, where); - where.x -= rect.Width() + 1; + fSuper->DrawBitmap(&control, where); } if (fModifiers & B_SHIFT_KEY) { BRect rect(0,0,21,10); BBitmap shift(rect, B_CMAP8); shift.SetBits(kShiftBits, kShiftLength, 0, B_CMAP8); - fSuper->DrawBitmap(&shift, where - BPoint(6, 0)); + where.x -= rect.Width() + 1; + fSuper->DrawBitmap(&shift, where); } } diff --git a/src/kits/interface/PopUpMenu.cpp b/src/kits/interface/PopUpMenu.cpp index dac665064d..9a1e3ab27e 100644 --- a/src/kits/interface/PopUpMenu.cpp +++ b/src/kits/interface/PopUpMenu.cpp @@ -16,7 +16,6 @@ #include -using std::nothrow; struct popup_menu_data { BPopUpMenu *object; @@ -267,7 +266,7 @@ BMenuItem * BPopUpMenu::_Go(BPoint where, bool autoInvoke, bool startOpened, BRect *_specialRect, bool async) { - popup_menu_data *data = new (nothrow) popup_menu_data; + popup_menu_data *data = new (std::nothrow) popup_menu_data; if (!data) return NULL;