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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user