Patch in part by "yourpalal":

* Set the MENU_STATE_CLOSED state upon BMenu initialization.
 * When drawing the label, use the parent bounds, including
   item margins to truncate the label, when the parent menu is
   closed.

Thanks a lot for the patch!

Changes by myself:
 * Cache the MenuPrivate instance in BMenuItem::DrawContent().
 * Use Window()->UpdateIfNeeded() to animate the flashing invoked menu item,
   which makes a lot more sense, the comment about it working in BeOS is
   probably due to item->Select() probably drawing outside of an update cycle.
 * The trigger invokation in keyboard handling didn't break out of the loop
   after invoking an item. Probably didn't matter since triggers are hopefully
   not assigned to more than one menu item. :-)
 * Use the same trick as BMenuBar to avoid interfering with keyboard navigation
   in the BMenu::_Track() hook.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35739 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2010-03-03 17:43:31 +00:00
parent b353282928
commit 2bcccf5a74
3 changed files with 34 additions and 23 deletions

View File

@ -203,7 +203,7 @@ BMenu::BMenu(const char* name, menu_layout layout)
fAscent(-1.0f),
fDescent(-1.0f),
fFontHeight(-1.0f),
fState(0),
fState(MENU_STATE_CLOSED),
fLayout(layout),
fExtraRect(NULL),
fMaxContentWidth(0.0f),
@ -272,7 +272,7 @@ BMenu::BMenu(BMessage* archive)
fAscent(-1.0f),
fDescent(-1.0f),
fFontHeight(-1.0f),
fState(0),
fState(MENU_STATE_CLOSED),
fLayout(B_ITEMS_IN_ROW),
fExtraRect(NULL),
fMaxContentWidth(0.0f),
@ -564,6 +564,7 @@ BMenu::KeyDown(const char* bytes, int32 numBytes)
continue;
_InvokeItem(item);
break;
}
break;
}
@ -1255,7 +1256,7 @@ BMenu::BMenu(BRect frame, const char* name, uint32 resizingMode, uint32 flags,
fAscent(-1.0f),
fDescent(-1.0f),
fFontHeight(-1.0f),
fState(0),
fState(MENU_STATE_CLOSED),
fLayout(layout),
fExtraRect(NULL),
fMaxContentWidth(0.0f),
@ -1657,16 +1658,20 @@ BMenu::_Track(int* action, long start)
if (fState != MENU_STATE_CLOSED) {
bigtime_t snoozeAmount = 50000;
BPoint newLocation = location;
uint32 newButtons = buttons;
// If user doesn't move the mouse, loop here,
// so we don't interfer with keyboard menu navigation
do {
snooze(snoozeAmount);
BPoint newLocation;
uint32 newButtons;
bigtime_t newPollTime = system_time();
if (LockLooper()) {
if (!LockLooper())
break;
GetMouse(&newLocation, &newButtons, true);
UnlockLooper();
}
} while (newLocation == location && newButtons == buttons);
bigtime_t newPollTime = system_time();
// mouseSpeed in px per ms
// (actually point_distance returns the square of the distance,
@ -2343,16 +2348,16 @@ BMenu::_InvokeItem(BMenuItem* item, bool now)
if (!item->Submenu() && LockLooper()) {
snooze(50000);
item->Select(true);
Sync();
Window()->UpdateIfNeeded();
snooze(50000);
item->Select(false);
Sync();
Window()->UpdateIfNeeded();
snooze(50000);
item->Select(true);
Sync();
Window()->UpdateIfNeeded();
snooze(50000);
item->Select(false);
Sync();
Window()->UpdateIfNeeded();
UnlockLooper();
}

View File

@ -644,18 +644,17 @@ BMenuBar::_Track(int32* action, int32 startIndex, bool showMenu)
window->Unlock();
if (fState != MENU_STATE_CLOSED) {
// if user doesn't move the mouse, loop here,
// If user doesn't move the mouse, loop here,
// so we don't interfer with keyboard menu navigation
BPoint newLocation;
uint32 newButtons;
BPoint newLocation = where;
uint32 newButtons = buttons;
do {
snooze(snoozeAmount);
if (!LockLooper())
break;
GetMouse(&newLocation, &newButtons, true);
UnlockLooper();
} while (newLocation == where
&& newButtons == buttons);
} while (newLocation == where && newButtons == buttons);
where = newLocation;
buttons = newButtons;

View File

@ -388,9 +388,10 @@ BMenuItem::TruncateLabel(float maxWidth, char *newLabel)
void
BMenuItem::DrawContent()
{
MenuPrivate(fSuper).CacheFontInfo();
MenuPrivate menuPrivate(fSuper);
menuPrivate.CacheFontInfo();
fSuper->MovePenBy(0, MenuPrivate(fSuper).Ascent());
fSuper->MovePenBy(0, menuPrivate.Ascent());
BPoint lineStart = fSuper->PenLocation();
float labelWidth, labelHeight;
@ -398,13 +399,19 @@ BMenuItem::DrawContent()
fSuper->SetDrawingMode(B_OP_OVER);
float frameWidth = fBounds.Width();
if (menuPrivate.State() == MENU_STATE_CLOSED) {
float rightMargin, leftMargin;
menuPrivate.GetItemMargins(&leftMargin, NULL, &rightMargin, NULL);
frameWidth = fSuper->Frame().Width() - (rightMargin + leftMargin);
}
// truncate if needed
// TODO: Actually, this is still never triggered
if (fBounds.Width() > labelWidth)
if (frameWidth > labelWidth)
fSuper->DrawString(fLabel);
else {
char *truncatedLabel = new char[strlen(fLabel) + 4];
TruncateLabel(fBounds.Width(), truncatedLabel);
TruncateLabel(frameWidth, truncatedLabel);
fSuper->DrawString(truncatedLabel);
delete[] truncatedLabel;
}