Visually align shortcuts in menus

In a menu, we use the right side both for submenu arrows and shortcuts.
As a result, when an entry has both a shortcut and a submenu, its
shortcut is not aligned with others, and this does not look so nice.

The spacing for the arrow appears only if there is a submenu in any of
the items in the parent menu.

Change-Id: If91fdcdad36abb0141fb05d1f59141f89540c1db
Reviewed-on: https://review.haiku-os.org/c/haiku/+/355
Reviewed-by: Adrien Destugues <[email protected]>
Reviewed-by: Ryan Leavengood <[email protected]>
This commit is contained in:
Ryan Leavengood
2020-02-04 23:06:54 +00:00
parent dcf9675793
commit e10de1ecf5
5 changed files with 27 additions and 12 deletions
+1 -1
View File
@@ -313,7 +313,7 @@ private:
bool fStickyMode; bool fStickyMode;
bool fIgnoreHidden; bool fIgnoreHidden;
bool fTriggerEnabled; bool fTriggerEnabled;
bool fRedrawAfterSticky; bool fHasSubmenus;
bool fAttachAborted; bool fAttachAborted;
}; };
+1 -1
View File
@@ -91,7 +91,7 @@ private:
rgb_color _HighColor(); rgb_color _HighColor();
void _DrawMarkSymbol(); void _DrawMarkSymbol();
void _DrawShortcutSymbol(); void _DrawShortcutSymbol(bool);
void _DrawSubmenuSymbol(); void _DrawSubmenuSymbol();
void _DrawControlChar(char shortcut, BPoint where); void _DrawControlChar(char shortcut, BPoint where);
+1
View File
@@ -56,6 +56,7 @@ public:
void SetSuperItem(BMenuItem* item); void SetSuperItem(BMenuItem* item);
void InvokeItem(BMenuItem* item, bool now = false); void InvokeItem(BMenuItem* item, bool now = false);
void QuitTracking(bool thisMenuOnly = true); void QuitTracking(bool thisMenuOnly = true);
bool HasSubmenus() { return fMenu->fHasSubmenus; }
static status_t CreateBitmaps(); static status_t CreateBitmaps();
static void DeleteBitmaps(); static void DeleteBitmaps();
+17 -6
View File
@@ -251,7 +251,7 @@ BMenu::BMenu(const char* name, menu_layout layout)
fStickyMode(false), fStickyMode(false),
fIgnoreHidden(true), fIgnoreHidden(true),
fTriggerEnabled(true), fTriggerEnabled(true),
fRedrawAfterSticky(false), fHasSubmenus(false),
fAttachAborted(false) fAttachAborted(false)
{ {
_InitData(NULL); _InitData(NULL);
@@ -286,7 +286,7 @@ BMenu::BMenu(const char* name, float width, float height)
fStickyMode(false), fStickyMode(false),
fIgnoreHidden(true), fIgnoreHidden(true),
fTriggerEnabled(true), fTriggerEnabled(true),
fRedrawAfterSticky(false), fHasSubmenus(false),
fAttachAborted(false) fAttachAborted(false)
{ {
_InitData(NULL); _InitData(NULL);
@@ -321,7 +321,7 @@ BMenu::BMenu(BMessage* archive)
fStickyMode(false), fStickyMode(false),
fIgnoreHidden(true), fIgnoreHidden(true),
fTriggerEnabled(true), fTriggerEnabled(true),
fRedrawAfterSticky(false), fHasSubmenus(false),
fAttachAborted(false) fAttachAborted(false)
{ {
_InitData(archive); _InitData(archive);
@@ -1109,7 +1109,7 @@ BMenu::AreTriggersEnabled() const
bool bool
BMenu::IsRedrawAfterSticky() const BMenu::IsRedrawAfterSticky() const
{ {
return fRedrawAfterSticky; return false;
} }
@@ -1323,7 +1323,7 @@ BMenu::BMenu(BRect frame, const char* name, uint32 resizingMode, uint32 flags,
fStickyMode(false), fStickyMode(false),
fIgnoreHidden(true), fIgnoreHidden(true),
fTriggerEnabled(true), fTriggerEnabled(true),
fRedrawAfterSticky(false), fHasSubmenus(false),
fAttachAborted(false) fAttachAborted(false)
{ {
_InitData(NULL); _InitData(NULL);
@@ -2228,6 +2228,7 @@ BMenu::_ComputeColumnLayout(int32 index, bool bestFit, bool moveItems,
bool control = false; bool control = false;
bool shift = false; bool shift = false;
bool option = false; bool option = false;
bool submenu = false;
if (index > 0) if (index > 0)
frame = ItemAt(index - 1)->Frame(); frame = ItemAt(index - 1)->Frame();
@@ -2239,6 +2240,8 @@ BMenu::_ComputeColumnLayout(int32 index, bool bestFit, bool moveItems,
BFont font; BFont font;
GetFont(&font); GetFont(&font);
// Loop over all items to set their top, bottom and left coordinates,
// all while computing the width of the menu
for (; index < fItems.CountItems(); index++) { for (; index < fItems.CountItems(); index++) {
BMenuItem* item = ItemAt(index); BMenuItem* item = ItemAt(index);
@@ -2267,12 +2270,13 @@ BMenu::_ComputeColumnLayout(int32 index, bool bestFit, bool moveItems,
+ fPad.bottom; + fPad.bottom;
if (item->fSubmenu != NULL) if (item->fSubmenu != NULL)
width += item->Frame().Height() / 2; submenu = true;
frame.right = std::max(frame.right, width + fPad.left + fPad.right); frame.right = std::max(frame.right, width + fPad.left + fPad.right);
frame.bottom = item->fBounds.bottom; frame.bottom = item->fBounds.bottom;
} }
// Compute the extra space needed for shortcuts and submenus
if (command) { if (command) {
frame.right frame.right
+= BPrivate::MenuPrivate::MenuItemCommand()->Bounds().Width() + 1; += BPrivate::MenuPrivate::MenuItemCommand()->Bounds().Width() + 1;
@@ -2289,10 +2293,17 @@ BMenu::_ComputeColumnLayout(int32 index, bool bestFit, bool moveItems,
frame.right frame.right
+= BPrivate::MenuPrivate::MenuItemShift()->Bounds().Width() + 1; += BPrivate::MenuPrivate::MenuItemShift()->Bounds().Width() + 1;
} }
if (submenu) {
frame.right += ItemAt(0)->Frame().Height() / 2;
fHasSubmenus = true;
} else {
fHasSubmenus = false;
}
if (fMaxContentWidth > 0) if (fMaxContentWidth > 0)
frame.right = std::min(frame.right, fMaxContentWidth); frame.right = std::min(frame.right, fMaxContentWidth);
// Finally update the "right" coordinate of all items
if (moveItems) { if (moveItems) {
for (int32 i = 0; i < fItems.CountItems(); i++) for (int32 i = 0; i < fItems.CountItems(); i++)
ItemAt(i)->fBounds.right = frame.right; ItemAt(i)->fBounds.right = frame.right;
+7 -4
View File
@@ -469,13 +469,14 @@ BMenuItem::Draw()
DrawContent(); DrawContent();
// draw extra symbols // draw extra symbols
const menu_layout layout = MenuPrivate(fSuper).Layout(); MenuPrivate privateAccessor(fSuper);
const menu_layout layout = privateAccessor.Layout();
if (layout == B_ITEMS_IN_COLUMN) { if (layout == B_ITEMS_IN_COLUMN) {
if (IsMarked()) if (IsMarked())
_DrawMarkSymbol(); _DrawMarkSymbol();
if (fShortcutChar) if (fShortcutChar)
_DrawShortcutSymbol(); _DrawShortcutSymbol(privateAccessor.HasSubmenus());
if (Submenu() != NULL) if (Submenu() != NULL)
_DrawSubmenuSymbol(); _DrawSubmenuSymbol();
@@ -745,15 +746,17 @@ BMenuItem::_DrawMarkSymbol()
void void
BMenuItem::_DrawShortcutSymbol() BMenuItem::_DrawShortcutSymbol(bool submenus)
{ {
BMenu* menu = fSuper; BMenu* menu = fSuper;
BFont font; BFont font;
menu->GetFont(&font); menu->GetFont(&font);
BPoint where = ContentLocation(); BPoint where = ContentLocation();
// Start from the right and walk our way back
where.x = fBounds.right - font.Size(); where.x = fBounds.right - font.Size();
if (fSubmenu != NULL) // Leave space for the submenu arrow if any item in the menu has a submenu
if (submenus)
where.x -= fBounds.Height() / 2; where.x -= fBounds.Height() / 2;
const float ascent = MenuPrivate(fSuper).Ascent(); const float ascent = MenuPrivate(fSuper).Ascent();