MenuField: Open the menu bar when the label is clicked

Fixes #6894

Private DrawLabel() method renamed to _DrawLabel() and rest of drawing
code moved to new private method _DrawMenuField(). These methods both
check to make sure that they are drawing in a valid rect that intersects
updateRect.

When label or menu is selected Draw a the label background in the selected
menu color matching the behavior of BeOS R5.

_DrawLabel() calls be_control_look->DrawLabel()

Update copyright year in MenuField.h
This commit is contained in:
John Scipione 2013-08-20 18:17:07 -04:00
parent 408c0ee4cd
commit 9422c92ea3
2 changed files with 57 additions and 30 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006-2011, Haiku, Inc. All rights reserved.
* Copyright 2006-2013, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _MENU_FIELD_H
@ -121,9 +121,12 @@ private:
BMenuField(const char* label,
BMenu* menu, BMessage* message);
void _DrawLabel(BRect updateRect);
void _DrawMenuBar(BRect updateRect);
void InitObject(const char* label);
void InitObject2();
void DrawLabel(BRect updateRect);
static void InitMenu(BMenu* menu);
int32 _MenuTask();

View File

@ -23,6 +23,7 @@
#include <LayoutUtils.h>
#include <MenuBar.h>
#include <MenuItem.h>
#include <MenuPrivate.h>
#include <Message.h>
#include <BMCPrivate.h>
#include <Window.h>
@ -139,6 +140,8 @@ static const float kMinMenuBarWidth = 20.0f;
// found by experimenting on BeOS R5
using BPrivate::MenuPrivate;
BMenuField::BMenuField(BRect frame, const char* name, const char* label,
BMenu* menu, uint32 resizingMode, uint32 flags)
:
@ -361,20 +364,8 @@ BMenuField::AllUnarchived(const BMessage* from)
void
BMenuField::Draw(BRect updateRect)
{
DrawLabel(updateRect);
BRect rect(fMenuBar->Frame());
rect.InsetBy(-kVMargin, -kVMargin);
rgb_color base = fMenuBar->LowColor();
rgb_color background = LowColor();
uint32 flags = 0;
if (!fMenuBar->IsEnabled())
flags |= BControlLook::B_DISABLED;
if (IsFocus() && Window()->IsActive())
flags |= BControlLook::B_FOCUSED;
be_control_look->DrawMenuFieldFrame(this, rect, updateRect, base,
background, flags);
_DrawLabel(updateRect);
_DrawMenuBar(updateRect);
}
@ -425,9 +416,6 @@ BMenuField::AllAttached()
void
BMenuField::MouseDown(BPoint where)
{
if (!fMenuBar->Frame().Contains(where))
return;
BRect bounds = fMenuBar->ConvertFromParent(Bounds());
fMenuBar->StartMenuBar(-1, false, true, &bounds);
@ -995,10 +983,15 @@ BMenuField::InitObject2()
void
BMenuField::DrawLabel(BRect updateRect)
BMenuField::_DrawLabel(BRect updateRect)
{
CALLED();
BRect rect(Bounds());
rect.right = fDivider;
if (!rect.IsValid() || !rect.Intersects(updateRect))
return;
_ValidateLayoutData();
font_height& fh = fLayoutData->font_info;
@ -1006,17 +999,15 @@ BMenuField::DrawLabel(BRect updateRect)
if (label == NULL)
return;
SetLowColor(ViewColor());
// horizontal alignment
float x;
switch (fAlign) {
case B_ALIGN_RIGHT:
x = fDivider - fLayoutData->label_width - 3.0;
x = fDivider - fLayoutData->label_width - 3.0f;
break;
case B_ALIGN_CENTER:
x = fDivider - fLayoutData->label_width / 2.0;
x = fDivider - roundf(fLayoutData->label_width / 2.0f);
break;
default:
@ -1025,14 +1016,47 @@ BMenuField::DrawLabel(BRect updateRect)
}
// vertical alignment
float y = Bounds().top
+ (Bounds().Height() + 1 - fh.ascent - fh.descent) / 2
float y = rect.top
+ roundf((rect.Height() + 1 - fh.ascent - fh.descent) / 2.0f)
+ fh.ascent;
y = floor(y + 0.5);
SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
IsEnabled() ? B_DARKEN_MAX_TINT : B_DISABLED_LABEL_TINT));
DrawString(label, BPoint(x, y));
const rgb_color lowColor = LowColor();
MenuPrivate menuPrivate(fMenuBar);
if (menuPrivate.State() != MENU_STATE_CLOSED)
SetLowColor(ui_color(B_MENU_SELECTED_BACKGROUND_COLOR));
BRect fillRect(rect.InsetByCopy(0, kVMargin));
fillRect.right -= kVMargin * 2;
FillRect(fillRect, B_SOLID_LOW);
uint32 flags = 0;
if (!IsEnabled())
flags |= BControlLook::B_DISABLED;
be_control_look->DrawLabel(this, label, LowColor(), flags, BPoint(x, y));
SetLowColor(lowColor);
}
void
BMenuField::_DrawMenuBar(BRect updateRect)
{
CALLED();
BRect rect(fMenuBar->Frame().InsetByCopy(-kVMargin, -kVMargin));
if (!rect.IsValid() || !rect.Intersects(updateRect))
return;
uint32 flags = 0;
if (!IsEnabled())
flags |= BControlLook::B_DISABLED;
if (IsFocus() && Window()->IsActive())
flags |= BControlLook::B_FOCUSED;
be_control_look->DrawMenuFieldFrame(this, rect, updateRect,
fMenuBar->LowColor(), LowColor(), flags);
}