Some work on menu layouts:

- Menus are generally a bit wider (BeIDE ones didn't look nice)
- The modifiers bitmap are drawn more centered vertically
- Splitted BMenu::ComputeLayout() into three methods
- Various minor changes.
The menuitems still don't look nice with bigger font sizes, but we'll 
try to fix this...


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21394 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2007-06-12 09:10:08 +00:00
parent c233a5b78d
commit fbe2f227ca
4 changed files with 116 additions and 90 deletions
+5 -1
View File
@@ -17,7 +17,7 @@
#include <View.h> #include <View.h>
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
/*----- Menu decalrations and structures -------------------------*/ /*----- Menu declarations and structures -------------------------*/
class BMenuItem; class BMenuItem;
class BMenuBar; class BMenuBar;
@@ -204,6 +204,10 @@ virtual void _ReservedMenu6();
void LayoutItems(int32 index); void LayoutItems(int32 index);
void ComputeLayout(int32 index, bool bestFit, bool moveItems, void ComputeLayout(int32 index, bool bestFit, bool moveItems,
float* width, float* height); 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; BRect Bump(BRect current, BPoint extent, int32 index) const;
BPoint ItemLocInRect(BRect frame) const; BPoint ItemLocInRect(BRect frame) const;
BRect CalcFrame(BPoint where, bool *scrollOn); BRect CalcFrame(BPoint where, bool *scrollOn);
+97 -75
View File
@@ -1530,90 +1530,19 @@ BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems,
// Recalculate only the needed items, // Recalculate only the needed items,
// not the whole layout every time // not the whole layout every time
BRect frame(0, 0, 0, 0); BRect frame(0, 0, 0, 0);
float iWidth, iHeight;
BMenuItem *item = NULL;
BFont font;
GetFont(&font);
switch (fLayout) { switch (fLayout) {
case B_ITEMS_IN_COLUMN: case B_ITEMS_IN_COLUMN:
{ _ComputeColumnLayout(index, bestFit, moveItems, frame);
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--;
break; break;
}
case B_ITEMS_IN_ROW: case B_ITEMS_IN_ROW:
{ _ComputeRowLayout(index, bestFit, moveItems, 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++) {
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;
break; break;
}
case B_ITEMS_IN_MATRIX: case B_ITEMS_IN_MATRIX:
{ _ComputeMatrixLayout(frame);
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);
}
}
break; break;
}
default: default:
break; 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 BRect
BMenu::Bump(BRect current, BPoint extent, int32 index) const BMenu::Bump(BRect current, BPoint extent, int32 index) const
{ {
+13 -12
View File
@@ -1,11 +1,11 @@
/* /*
* Copyright 2001-2006, Haiku, Inc. * Copyright 2001-2007, Haiku, Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Marc Flerackers (mflerackers@androme.be) * Marc Flerackers (mflerackers@androme.be)
* Bill Hayden (haydentech@users.sourceforge.net) * Bill Hayden (haydentech@users.sourceforge.net)
* Stefano Ceccherini (burton666@libero.it) * Stefano Ceccherini (stefano.ceccherini@gmail.com)
* Olivier Milla * Olivier Milla
*/ */
@@ -20,7 +20,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
const uint32 kCtrlLength = 20*11; const uint32 kCtrlLength = 20*11;
const unsigned char kCtrlBits[] = { const unsigned char kCtrlBits[] = {
0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x1d,0x14,0xff,0xff,0xff, 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 void
BMenuItem::_DrawShortcutSymbol() BMenuItem::_DrawShortcutSymbol()
{ {
// TODO: Review this BFont font;
Menu()->GetFont(&font);
BPoint where = ContentLocation(); BPoint where = ContentLocation();
where.x += fBounds.Width() - 28; where.x += fBounds.Width() - 28;
if (fSubmenu) if (fSubmenu)
where.x -= 12; where.x -= fBounds.Height();
switch (fShortcutChar) { switch (fShortcutChar) {
case B_DOWN_ARROW: case B_DOWN_ARROW:
@@ -729,7 +729,8 @@ BMenuItem::_DrawShortcutSymbol()
break; break;
} }
where -= BPoint(20, -1); where.y += (fBounds.Height() - 11) / 2 - 1;
where.x -= 5;
if (fModifiers & B_COMMAND_KEY) { if (fModifiers & B_COMMAND_KEY) {
BRect rect(0,0,16,10); BRect rect(0,0,16,10);
@@ -739,9 +740,9 @@ BMenuItem::_DrawShortcutSymbol()
control.SetBits(kAltBits, kAltLength, 0, B_CMAP8); control.SetBits(kAltBits, kAltLength, 0, B_CMAP8);
else else
control.SetBits(kCtrlBits, kCtrlLength, 0, B_CMAP8); control.SetBits(kCtrlBits, kCtrlLength, 0, B_CMAP8);
fSuper->DrawBitmap(&control, where);
where.x -= rect.Width() + 1; where.x -= rect.Width() + 1;
fSuper->DrawBitmap(&control, where);
} }
if (fModifiers & B_CONTROL_KEY) { if (fModifiers & B_CONTROL_KEY) {
@@ -752,16 +753,16 @@ BMenuItem::_DrawShortcutSymbol()
control.SetBits(kCtrlBits, kCtrlLength, 0, B_CMAP8); control.SetBits(kCtrlBits, kCtrlLength, 0, B_CMAP8);
else else
control.SetBits(kAltBits, kAltLength, 0, B_CMAP8); control.SetBits(kAltBits, kAltLength, 0, B_CMAP8);
fSuper->DrawBitmap(&control, where);
where.x -= rect.Width() + 1; where.x -= rect.Width() + 1;
fSuper->DrawBitmap(&control, where);
} }
if (fModifiers & B_SHIFT_KEY) { if (fModifiers & B_SHIFT_KEY) {
BRect rect(0,0,21,10); BRect rect(0,0,21,10);
BBitmap shift(rect, B_CMAP8); BBitmap shift(rect, B_CMAP8);
shift.SetBits(kShiftBits, kShiftLength, 0, 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);
} }
} }
+1 -2
View File
@@ -16,7 +16,6 @@
#include <new> #include <new>
using std::nothrow;
struct popup_menu_data { struct popup_menu_data {
BPopUpMenu *object; BPopUpMenu *object;
@@ -267,7 +266,7 @@ BMenuItem *
BPopUpMenu::_Go(BPoint where, bool autoInvoke, bool startOpened, BPopUpMenu::_Go(BPoint where, bool autoInvoke, bool startOpened,
BRect *_specialRect, bool async) 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) if (!data)
return NULL; return NULL;