Added a class MenuPrivate to handle access to private BMenu methods.

BMenuItem and BWindow are no longer friends of BMenu, but use this class 
instead.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24909 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2008-04-11 08:22:09 +00:00
parent df50f7a9b4
commit 10f4d0679a
5 changed files with 208 additions and 33 deletions
+2 -2
View File
@@ -19,6 +19,7 @@ namespace BPrivate {
class BMenuWindow;
class ExtraMenuData;
class TriggerList;
class MenuPrivate;
}
enum menu_layout {
@@ -159,9 +160,8 @@ public:
void* state);
private:
friend class BWindow;
friend class BMenuBar;
friend class BMenuItem;
friend class BPrivate::MenuPrivate;
friend status_t _init_interface_kit_();
friend status_t set_menu_info(menu_info* info);
friend status_t get_menu_info(menu_info* info);
+35
View File
@@ -8,6 +8,41 @@ enum menu_states {
MENU_STATE_CLOSED = 5
};
class BMenu;
class BWindow;
namespace BPrivate {
class MenuPrivate {
public:
MenuPrivate(BMenu *menu);
menu_layout Layout() const;
void ItemMarked(BMenuItem *item);
void CacheFontInfo();
float FontHeight() const;
float Ascent() const;
BRect Padding() const;
void GetItemMargins(float *, float *, float *, float *) const;
bool IsAltCommandKey() const;
int State(BMenuItem **item = NULL) const;
void Install(BWindow *window);
void Uninstall();
void SetSuper(BMenu *menu);
void SetSuperItem(BMenuItem *item);
void InvokeItem(BMenuItem *item, bool now = false);
void QuitTracking(bool thisMenuOnly = true);
private:
BMenu *fMenu;
};
};
extern const char *kEmptyMenuLabel;
+118
View File
@@ -2620,3 +2620,121 @@ get_menu_info(menu_info *info)
return status;
}
// MenuPrivate
namespace BPrivate {
MenuPrivate::MenuPrivate(BMenu *menu)
:
fMenu(menu)
{
}
menu_layout
MenuPrivate::Layout() const
{
return fMenu->Layout();
}
void
MenuPrivate::ItemMarked(BMenuItem *item)
{
fMenu->_ItemMarked(item);
}
void
MenuPrivate::CacheFontInfo()
{
fMenu->_CacheFontInfo();
}
float
MenuPrivate::FontHeight() const
{
return fMenu->fFontHeight;
}
float
MenuPrivate::Ascent() const
{
return fMenu->fAscent;
}
BRect
MenuPrivate::Padding() const
{
return fMenu->fPad;
}
void
MenuPrivate::GetItemMargins(float *left, float *top,
float *right, float *bottom) const
{
fMenu->GetItemMargins(left, top, right, bottom);
}
bool
MenuPrivate::IsAltCommandKey() const
{
return fMenu->sAltAsCommandKey;
}
int
MenuPrivate::State(BMenuItem **item) const
{
return fMenu->State(item);
}
void
MenuPrivate::Install(BWindow *window)
{
fMenu->_Install(window);
}
void
MenuPrivate::Uninstall()
{
fMenu->_Uninstall();
}
void
MenuPrivate::SetSuper(BMenu *menu)
{
fMenu->fSuper = menu;
}
void
MenuPrivate::SetSuperItem(BMenuItem *item)
{
fMenu->fSuperitem = item;
}
void
MenuPrivate::InvokeItem(BMenuItem *item, bool now)
{
fMenu->InvokeItem(item, now);
}
void
MenuPrivate::QuitTracking(bool thisMenuOnly)
{
fMenu->QuitTracking(thisMenuOnly);
}
} ;
+42 -25
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2001-2007, Haiku, Inc.
* Copyright 2001-2008, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -21,6 +21,8 @@
#include <String.h>
#include <Window.h>
#include <MenuPrivate.h>
#include "utf8_functions.h"
const unsigned char kCtrlBits[] = {
@@ -69,6 +71,7 @@ const unsigned char kShiftBits[] = {
const float kLightBGTint = (B_LIGHTEN_1_TINT + B_LIGHTEN_1_TINT + B_NO_TINT) / 3.0;
using BPrivate::MenuPrivate;
BMenuItem::BMenuItem(const char *label, BMessage *message, char shortcut,
uint32 modifiers)
@@ -247,8 +250,10 @@ BMenuItem::SetMarked(bool state)
{
fMark = state;
if (state && Menu() != NULL)
Menu()->_ItemMarked(this);
if (state && Menu() != NULL) {
MenuPrivate priv(Menu());
priv.ItemMarked(this);
}
}
@@ -372,14 +377,18 @@ BMenuItem::Frame() const
void
BMenuItem::GetContentSize(float *width, float *height)
{
fSuper->_CacheFontInfo();
// TODO: Get rid of this. BMenu should handle this
// automatically. Maybe it's not even needed, since our
// BFont::Height() caches the value locally
MenuPrivate(fSuper).CacheFontInfo();
fCachedWidth = fSuper->StringWidth(fLabel);
if (width)
*width = (float)ceil(fCachedWidth);
if (height)
*height = fSuper->fFontHeight;
if (height) {
*height = MenuPrivate(fSuper).FontHeight();
}
}
@@ -399,9 +408,9 @@ BMenuItem::TruncateLabel(float maxWidth, char *newLabel)
void
BMenuItem::DrawContent()
{
fSuper->_CacheFontInfo();
MenuPrivate(fSuper).CacheFontInfo();
fSuper->MovePenBy(0, fSuper->fAscent);
fSuper->MovePenBy(0, MenuPrivate(fSuper).Ascent());
BPoint lineStart = fSuper->PenLocation();
float labelWidth, labelHeight;
@@ -472,7 +481,8 @@ BMenuItem::Draw()
DrawContent();
// draw extra symbols
if (fSuper->Layout() == B_ITEMS_IN_COLUMN) {
const menu_layout layout = MenuPrivate(fSuper).Layout();
if (layout == B_ITEMS_IN_COLUMN) {
if (IsMarked())
_DrawMarkSymbol(bgColor);
@@ -504,8 +514,10 @@ BMenuItem::IsSelected() const
BPoint
BMenuItem::ContentLocation() const
{
return BPoint(fBounds.left + Menu()->fPad.left,
fBounds.top + Menu()->fPad.top);
const BRect &padding = MenuPrivate(fSuper).Padding();
return BPoint(fBounds.left + padding.left,
fBounds.top + padding.top);
}
@@ -550,7 +562,8 @@ void
BMenuItem::_InitMenuData(BMenu *menu)
{
fSubmenu = menu;
fSubmenu->fSuperitem = this;
MenuPrivate(fSubmenu).SetSuperItem(this);
BMenuItem *item = menu->FindMarked();
@@ -564,9 +577,10 @@ BMenuItem::_InitMenuData(BMenu *menu)
void
BMenuItem::Install(BWindow *window)
{
if (fSubmenu)
fSubmenu->_Install(window);
if (fSubmenu) {
MenuPrivate(fSubmenu).Install(window);
}
fWindow = window;
if (fShortcutChar != 0 && (fModifiers & B_COMMAND_KEY) && fWindow)
@@ -619,9 +633,10 @@ BMenuItem::Invoke(BMessage *message)
void
BMenuItem::Uninstall()
{
if (fSubmenu != NULL)
fSubmenu->_Uninstall();
if (fSubmenu != NULL) {
MenuPrivate(fSubmenu).Uninstall();
}
if (Target() == fWindow)
SetTarget(BMessenger());
@@ -640,7 +655,7 @@ BMenuItem::SetSuper(BMenu *super)
debugger("Error - can't add menu or menu item to more than 1 container (either menu or menubar).");
if (fSubmenu != NULL) {
fSubmenu->fSuper = super;
MenuPrivate(fSubmenu).SetSuper(super);
}
fSuper = super;
@@ -667,7 +682,7 @@ BMenuItem::_DrawMarkSymbol(rgb_color bgColor)
BRect r(fBounds);
float leftMargin;
fSuper->GetItemMargins(&leftMargin, NULL, NULL, NULL);
MenuPrivate(fSuper).GetItemMargins(&leftMargin, NULL, NULL, NULL);
r.right = r.left + leftMargin - 3;
r.left += 1;
@@ -715,28 +730,30 @@ BMenuItem::_DrawShortcutSymbol()
if (fSubmenu)
where.x -= fBounds.Height() - 3;
const float ascent = MenuPrivate(fSuper).Ascent();
switch (fShortcutChar) {
case B_DOWN_ARROW:
case B_UP_ARROW:
case B_LEFT_ARROW:
case B_RIGHT_ARROW:
case B_ENTER:
_DrawControlChar(fShortcutChar, where + BPoint(0, fSuper->fAscent));
_DrawControlChar(fShortcutChar, where + BPoint(0, ascent));
break;
default:
fSuper->DrawChar(fShortcutChar, where + BPoint(0, fSuper->fAscent));
fSuper->DrawChar(fShortcutChar, where + BPoint(0, ascent));
break;
}
where.y += (fBounds.Height() - 11) / 2 - 1;
where.x -= 4;
const bool altCommandKey = MenuPrivate(fSuper).IsAltCommandKey();
if (fModifiers & B_COMMAND_KEY) {
BRect rect(0,0,16,10);
BBitmap control(rect, B_CMAP8);
if (BMenu::sAltAsCommandKey)
if (altCommandKey)
control.ImportBits(kAltBits, sizeof(kAltBits), 17, 0, B_CMAP8);
else
control.ImportBits(kCtrlBits, sizeof(kCtrlBits), 17, 0, B_CMAP8);
@@ -749,7 +766,7 @@ BMenuItem::_DrawShortcutSymbol()
BRect rect(0,0,16,10);
BBitmap control(rect, B_CMAP8);
if (BMenu::sAltAsCommandKey)
if (altCommandKey)
control.ImportBits(kCtrlBits, sizeof(kCtrlBits), 17, 0, B_CMAP8);
else
control.ImportBits(kAltBits, sizeof(kAltBits), 17, 0, B_CMAP8);
@@ -774,7 +791,7 @@ BMenuItem::_DrawSubmenuSymbol(rgb_color bgColor)
BRect r(fBounds);
float rightMargin;
fSuper->GetItemMargins(NULL, NULL, &rightMargin, NULL);
MenuPrivate(fSuper).GetItemMargins(NULL, NULL, &rightMargin, NULL);
r.left = r.right - rightMargin + 3;
r.right -= 1;
+11 -6
View File
@@ -94,6 +94,7 @@ class BWindow::Shortcut {
using BPrivate::gDefaultTokens;
using BPrivate::MenuPrivate;
static property_info sWindowPropInfo[] = {
{
@@ -359,8 +360,9 @@ BWindow::BWindow(BRect frame, int32 bitmapToken)
BWindow::~BWindow()
{
if (BMenu *menu = dynamic_cast<BMenu *>(fFocus))
menu->QuitTracking();
if (BMenu *menu = dynamic_cast<BMenu *>(fFocus)) {
MenuPrivate(menu).QuitTracking();
}
// The BWindow is locked when the destructor is called,
// we need to unlock because the menubar thread tries
@@ -1052,9 +1054,10 @@ FrameMoved(origin);
// Close an eventually opened menu
// unless the target is the menu itself
BMenu *menu = dynamic_cast<BMenu *>(fFocus);
MenuPrivate privMenu(menu);
if (menu != NULL && menu != view
&& menu->State() != MENU_STATE_CLOSED) {
menu->QuitTracking();
&& privMenu.State() != MENU_STATE_CLOSED) {
privMenu.QuitTracking();
return;
}
@@ -3260,8 +3263,10 @@ BWindow::_HandleKeyDown(BMessage* event)
// example)
if (shortcut->MenuItem() != NULL) {
BMenu* menu = shortcut->MenuItem()->Menu();
if (menu != NULL)
menu->InvokeItem(shortcut->MenuItem(), true);
if (menu != NULL) {
MenuPrivate(menu).InvokeItem(shortcut->MenuItem(),
true);
}
} else {
BHandler* target = shortcut->Target();
if (target == NULL)