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 BMenuWindow;
|
||||||
class ExtraMenuData;
|
class ExtraMenuData;
|
||||||
class TriggerList;
|
class TriggerList;
|
||||||
|
class MenuPrivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum menu_layout {
|
enum menu_layout {
|
||||||
@@ -159,9 +160,8 @@ public:
|
|||||||
void* state);
|
void* state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BWindow;
|
|
||||||
friend class BMenuBar;
|
friend class BMenuBar;
|
||||||
friend class BMenuItem;
|
friend class BPrivate::MenuPrivate;
|
||||||
friend status_t _init_interface_kit_();
|
friend status_t _init_interface_kit_();
|
||||||
friend status_t set_menu_info(menu_info* info);
|
friend status_t set_menu_info(menu_info* info);
|
||||||
friend status_t get_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
|
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;
|
extern const char *kEmptyMenuLabel;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2620,3 +2620,121 @@ get_menu_info(menu_info *info)
|
|||||||
|
|
||||||
return status;
|
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.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -21,6 +21,8 @@
|
|||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include <MenuPrivate.h>
|
||||||
|
|
||||||
#include "utf8_functions.h"
|
#include "utf8_functions.h"
|
||||||
|
|
||||||
const unsigned char kCtrlBits[] = {
|
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;
|
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,
|
BMenuItem::BMenuItem(const char *label, BMessage *message, char shortcut,
|
||||||
uint32 modifiers)
|
uint32 modifiers)
|
||||||
@@ -247,8 +250,10 @@ BMenuItem::SetMarked(bool state)
|
|||||||
{
|
{
|
||||||
fMark = state;
|
fMark = state;
|
||||||
|
|
||||||
if (state && Menu() != NULL)
|
if (state && Menu() != NULL) {
|
||||||
Menu()->_ItemMarked(this);
|
MenuPrivate priv(Menu());
|
||||||
|
priv.ItemMarked(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -372,14 +377,18 @@ BMenuItem::Frame() const
|
|||||||
void
|
void
|
||||||
BMenuItem::GetContentSize(float *width, float *height)
|
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);
|
fCachedWidth = fSuper->StringWidth(fLabel);
|
||||||
|
|
||||||
if (width)
|
if (width)
|
||||||
*width = (float)ceil(fCachedWidth);
|
*width = (float)ceil(fCachedWidth);
|
||||||
if (height)
|
if (height) {
|
||||||
*height = fSuper->fFontHeight;
|
*height = MenuPrivate(fSuper).FontHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -399,9 +408,9 @@ BMenuItem::TruncateLabel(float maxWidth, char *newLabel)
|
|||||||
void
|
void
|
||||||
BMenuItem::DrawContent()
|
BMenuItem::DrawContent()
|
||||||
{
|
{
|
||||||
fSuper->_CacheFontInfo();
|
MenuPrivate(fSuper).CacheFontInfo();
|
||||||
|
|
||||||
fSuper->MovePenBy(0, fSuper->fAscent);
|
fSuper->MovePenBy(0, MenuPrivate(fSuper).Ascent());
|
||||||
BPoint lineStart = fSuper->PenLocation();
|
BPoint lineStart = fSuper->PenLocation();
|
||||||
|
|
||||||
float labelWidth, labelHeight;
|
float labelWidth, labelHeight;
|
||||||
@@ -472,7 +481,8 @@ BMenuItem::Draw()
|
|||||||
DrawContent();
|
DrawContent();
|
||||||
|
|
||||||
// draw extra symbols
|
// 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())
|
if (IsMarked())
|
||||||
_DrawMarkSymbol(bgColor);
|
_DrawMarkSymbol(bgColor);
|
||||||
|
|
||||||
@@ -504,8 +514,10 @@ BMenuItem::IsSelected() const
|
|||||||
BPoint
|
BPoint
|
||||||
BMenuItem::ContentLocation() const
|
BMenuItem::ContentLocation() const
|
||||||
{
|
{
|
||||||
return BPoint(fBounds.left + Menu()->fPad.left,
|
const BRect &padding = MenuPrivate(fSuper).Padding();
|
||||||
fBounds.top + Menu()->fPad.top);
|
|
||||||
|
return BPoint(fBounds.left + padding.left,
|
||||||
|
fBounds.top + padding.top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -550,7 +562,8 @@ void
|
|||||||
BMenuItem::_InitMenuData(BMenu *menu)
|
BMenuItem::_InitMenuData(BMenu *menu)
|
||||||
{
|
{
|
||||||
fSubmenu = menu;
|
fSubmenu = menu;
|
||||||
fSubmenu->fSuperitem = this;
|
|
||||||
|
MenuPrivate(fSubmenu).SetSuperItem(this);
|
||||||
|
|
||||||
BMenuItem *item = menu->FindMarked();
|
BMenuItem *item = menu->FindMarked();
|
||||||
|
|
||||||
@@ -564,9 +577,10 @@ BMenuItem::_InitMenuData(BMenu *menu)
|
|||||||
void
|
void
|
||||||
BMenuItem::Install(BWindow *window)
|
BMenuItem::Install(BWindow *window)
|
||||||
{
|
{
|
||||||
if (fSubmenu)
|
if (fSubmenu) {
|
||||||
fSubmenu->_Install(window);
|
MenuPrivate(fSubmenu).Install(window);
|
||||||
|
}
|
||||||
|
|
||||||
fWindow = window;
|
fWindow = window;
|
||||||
|
|
||||||
if (fShortcutChar != 0 && (fModifiers & B_COMMAND_KEY) && fWindow)
|
if (fShortcutChar != 0 && (fModifiers & B_COMMAND_KEY) && fWindow)
|
||||||
@@ -619,9 +633,10 @@ BMenuItem::Invoke(BMessage *message)
|
|||||||
void
|
void
|
||||||
BMenuItem::Uninstall()
|
BMenuItem::Uninstall()
|
||||||
{
|
{
|
||||||
if (fSubmenu != NULL)
|
if (fSubmenu != NULL) {
|
||||||
fSubmenu->_Uninstall();
|
MenuPrivate(fSubmenu).Uninstall();
|
||||||
|
}
|
||||||
|
|
||||||
if (Target() == fWindow)
|
if (Target() == fWindow)
|
||||||
SetTarget(BMessenger());
|
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).");
|
debugger("Error - can't add menu or menu item to more than 1 container (either menu or menubar).");
|
||||||
|
|
||||||
if (fSubmenu != NULL) {
|
if (fSubmenu != NULL) {
|
||||||
fSubmenu->fSuper = super;
|
MenuPrivate(fSubmenu).SetSuper(super);
|
||||||
}
|
}
|
||||||
|
|
||||||
fSuper = super;
|
fSuper = super;
|
||||||
@@ -667,7 +682,7 @@ BMenuItem::_DrawMarkSymbol(rgb_color bgColor)
|
|||||||
|
|
||||||
BRect r(fBounds);
|
BRect r(fBounds);
|
||||||
float leftMargin;
|
float leftMargin;
|
||||||
fSuper->GetItemMargins(&leftMargin, NULL, NULL, NULL);
|
MenuPrivate(fSuper).GetItemMargins(&leftMargin, NULL, NULL, NULL);
|
||||||
r.right = r.left + leftMargin - 3;
|
r.right = r.left + leftMargin - 3;
|
||||||
r.left += 1;
|
r.left += 1;
|
||||||
|
|
||||||
@@ -715,28 +730,30 @@ BMenuItem::_DrawShortcutSymbol()
|
|||||||
if (fSubmenu)
|
if (fSubmenu)
|
||||||
where.x -= fBounds.Height() - 3;
|
where.x -= fBounds.Height() - 3;
|
||||||
|
|
||||||
|
const float ascent = MenuPrivate(fSuper).Ascent();
|
||||||
switch (fShortcutChar) {
|
switch (fShortcutChar) {
|
||||||
case B_DOWN_ARROW:
|
case B_DOWN_ARROW:
|
||||||
case B_UP_ARROW:
|
case B_UP_ARROW:
|
||||||
case B_LEFT_ARROW:
|
case B_LEFT_ARROW:
|
||||||
case B_RIGHT_ARROW:
|
case B_RIGHT_ARROW:
|
||||||
case B_ENTER:
|
case B_ENTER:
|
||||||
_DrawControlChar(fShortcutChar, where + BPoint(0, fSuper->fAscent));
|
_DrawControlChar(fShortcutChar, where + BPoint(0, ascent));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fSuper->DrawChar(fShortcutChar, where + BPoint(0, fSuper->fAscent));
|
fSuper->DrawChar(fShortcutChar, where + BPoint(0, ascent));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
where.y += (fBounds.Height() - 11) / 2 - 1;
|
where.y += (fBounds.Height() - 11) / 2 - 1;
|
||||||
where.x -= 4;
|
where.x -= 4;
|
||||||
|
|
||||||
|
const bool altCommandKey = MenuPrivate(fSuper).IsAltCommandKey();
|
||||||
if (fModifiers & B_COMMAND_KEY) {
|
if (fModifiers & B_COMMAND_KEY) {
|
||||||
BRect rect(0,0,16,10);
|
BRect rect(0,0,16,10);
|
||||||
BBitmap control(rect, B_CMAP8);
|
BBitmap control(rect, B_CMAP8);
|
||||||
|
|
||||||
if (BMenu::sAltAsCommandKey)
|
if (altCommandKey)
|
||||||
control.ImportBits(kAltBits, sizeof(kAltBits), 17, 0, B_CMAP8);
|
control.ImportBits(kAltBits, sizeof(kAltBits), 17, 0, B_CMAP8);
|
||||||
else
|
else
|
||||||
control.ImportBits(kCtrlBits, sizeof(kCtrlBits), 17, 0, B_CMAP8);
|
control.ImportBits(kCtrlBits, sizeof(kCtrlBits), 17, 0, B_CMAP8);
|
||||||
@@ -749,7 +766,7 @@ BMenuItem::_DrawShortcutSymbol()
|
|||||||
BRect rect(0,0,16,10);
|
BRect rect(0,0,16,10);
|
||||||
BBitmap control(rect, B_CMAP8);
|
BBitmap control(rect, B_CMAP8);
|
||||||
|
|
||||||
if (BMenu::sAltAsCommandKey)
|
if (altCommandKey)
|
||||||
control.ImportBits(kCtrlBits, sizeof(kCtrlBits), 17, 0, B_CMAP8);
|
control.ImportBits(kCtrlBits, sizeof(kCtrlBits), 17, 0, B_CMAP8);
|
||||||
else
|
else
|
||||||
control.ImportBits(kAltBits, sizeof(kAltBits), 17, 0, B_CMAP8);
|
control.ImportBits(kAltBits, sizeof(kAltBits), 17, 0, B_CMAP8);
|
||||||
@@ -774,7 +791,7 @@ BMenuItem::_DrawSubmenuSymbol(rgb_color bgColor)
|
|||||||
|
|
||||||
BRect r(fBounds);
|
BRect r(fBounds);
|
||||||
float rightMargin;
|
float rightMargin;
|
||||||
fSuper->GetItemMargins(NULL, NULL, &rightMargin, NULL);
|
MenuPrivate(fSuper).GetItemMargins(NULL, NULL, &rightMargin, NULL);
|
||||||
r.left = r.right - rightMargin + 3;
|
r.left = r.right - rightMargin + 3;
|
||||||
r.right -= 1;
|
r.right -= 1;
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ class BWindow::Shortcut {
|
|||||||
|
|
||||||
|
|
||||||
using BPrivate::gDefaultTokens;
|
using BPrivate::gDefaultTokens;
|
||||||
|
using BPrivate::MenuPrivate;
|
||||||
|
|
||||||
static property_info sWindowPropInfo[] = {
|
static property_info sWindowPropInfo[] = {
|
||||||
{
|
{
|
||||||
@@ -359,8 +360,9 @@ BWindow::BWindow(BRect frame, int32 bitmapToken)
|
|||||||
|
|
||||||
BWindow::~BWindow()
|
BWindow::~BWindow()
|
||||||
{
|
{
|
||||||
if (BMenu *menu = dynamic_cast<BMenu *>(fFocus))
|
if (BMenu *menu = dynamic_cast<BMenu *>(fFocus)) {
|
||||||
menu->QuitTracking();
|
MenuPrivate(menu).QuitTracking();
|
||||||
|
}
|
||||||
|
|
||||||
// The BWindow is locked when the destructor is called,
|
// The BWindow is locked when the destructor is called,
|
||||||
// we need to unlock because the menubar thread tries
|
// we need to unlock because the menubar thread tries
|
||||||
@@ -1052,9 +1054,10 @@ FrameMoved(origin);
|
|||||||
// Close an eventually opened menu
|
// Close an eventually opened menu
|
||||||
// unless the target is the menu itself
|
// unless the target is the menu itself
|
||||||
BMenu *menu = dynamic_cast<BMenu *>(fFocus);
|
BMenu *menu = dynamic_cast<BMenu *>(fFocus);
|
||||||
|
MenuPrivate privMenu(menu);
|
||||||
if (menu != NULL && menu != view
|
if (menu != NULL && menu != view
|
||||||
&& menu->State() != MENU_STATE_CLOSED) {
|
&& privMenu.State() != MENU_STATE_CLOSED) {
|
||||||
menu->QuitTracking();
|
privMenu.QuitTracking();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3260,8 +3263,10 @@ BWindow::_HandleKeyDown(BMessage* event)
|
|||||||
// example)
|
// example)
|
||||||
if (shortcut->MenuItem() != NULL) {
|
if (shortcut->MenuItem() != NULL) {
|
||||||
BMenu* menu = shortcut->MenuItem()->Menu();
|
BMenu* menu = shortcut->MenuItem()->Menu();
|
||||||
if (menu != NULL)
|
if (menu != NULL) {
|
||||||
menu->InvokeItem(shortcut->MenuItem(), true);
|
MenuPrivate(menu).InvokeItem(shortcut->MenuItem(),
|
||||||
|
true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
BHandler* target = shortcut->Target();
|
BHandler* target = shortcut->Target();
|
||||||
if (target == NULL)
|
if (target == NULL)
|
||||||
|
|||||||
Reference in New Issue
Block a user