* Indentation cleanup.

* 80 chars limit
* Copyright fixed.
* Better grouping of methods.

+alphabranch


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32701 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2009-08-26 12:08:09 +00:00
parent 0a5897b71f
commit 13e50c47a2
2 changed files with 540 additions and 484 deletions
+190 -177
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright 2007, Haiku, Inc. All Rights Reserved. * Copyright 2007-2009, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT license.
*/ */
#ifndef _MENU_H #ifndef _MENU_H
#define _MENU_H #define _MENU_H
@@ -46,106 +46,113 @@ typedef bool (*menu_tracking_hook)(BMenu* menu, void* state);
class BMenu : public BView { class BMenu : public BView {
public: public:
BMenu(const char* title, BMenu(const char* title,
menu_layout layout = B_ITEMS_IN_COLUMN); menu_layout layout = B_ITEMS_IN_COLUMN);
BMenu(const char* title, float width, float height); BMenu(const char* title, float width,
virtual ~BMenu(); float height);
BMenu(BMessage* archive);
BMenu(BMessage* archive); virtual ~BMenu();
static BArchivable* Instantiate(BMessage* archive);
virtual status_t Archive(BMessage* archive, bool deep = true) const;
virtual void AttachedToWindow(); static BArchivable* Instantiate(BMessage* archive);
virtual void DetachedFromWindow(); virtual status_t Archive(BMessage* archive,
bool deep = true) const;
bool AddItem(BMenuItem* item); virtual void AttachedToWindow();
bool AddItem(BMenuItem* item, int32 index); virtual void DetachedFromWindow();
bool AddItem(BMenuItem* item, BRect frame); virtual void AllAttached();
bool AddItem(BMenu* menu); virtual void AllDetached();
bool AddItem(BMenu* menu, int32 index);
bool AddItem(BMenu* menu, BRect frame);
bool AddList(BList* list, int32 index);
bool AddSeparatorItem(); virtual void Draw(BRect updateRect);
bool RemoveItem(BMenuItem* item); virtual void MessageReceived(BMessage* message);
BMenuItem* RemoveItem(int32 index); virtual void KeyDown(const char* bytes, int32 numBytes);
bool RemoveItems(int32 index, int32 count,
bool deleteItems = false);
bool RemoveItem(BMenu* menu);
BMenuItem* ItemAt(int32 index) const; virtual BSize MinSize();
BMenu* SubmenuAt(int32 index) const; virtual BSize MaxSize();
int32 CountItems() const; virtual BSize PreferredSize();
int32 IndexOf(BMenuItem* item) const; virtual void GetPreferredSize(float* _width,
int32 IndexOf(BMenu* menu) const; float* _height);
BMenuItem* FindItem(uint32 command) const; virtual void ResizeToPreferred();
BMenuItem* FindItem(const char* name) const; virtual void DoLayout();
virtual void FrameMoved(BPoint newPosition);
virtual void FrameResized(float newWidth, float newHeight);
void InvalidateLayout();
virtual void InvalidateLayout(bool descendants);
virtual status_t SetTargetForItems(BHandler* target); virtual void MakeFocus(bool focus = true);
virtual status_t SetTargetForItems(BMessenger messenger);
virtual void SetEnabled(bool state);
virtual void SetRadioMode(bool state);
virtual void SetTriggersEnabled(bool state);
virtual void SetMaxContentWidth(float maxWidth);
void SetLabelFromMarked(bool state); bool AddItem(BMenuItem* item);
bool IsLabelFromMarked(); bool AddItem(BMenuItem* item, int32 index);
bool IsEnabled() const; bool AddItem(BMenuItem* item, BRect frame);
bool IsRadioMode() const; bool AddItem(BMenu* menu);
bool AreTriggersEnabled() const; bool AddItem(BMenu* menu, int32 index);
bool IsRedrawAfterSticky() const; bool AddItem(BMenu* menu, BRect frame);
float MaxContentWidth() const; bool AddList(BList* list, int32 index);
BMenuItem* FindMarked(); bool AddSeparatorItem();
BMenu* Supermenu() const; bool RemoveItem(BMenuItem* item);
BMenuItem* Superitem() const; BMenuItem* RemoveItem(int32 index);
bool RemoveItems(int32 index, int32 count,
bool deleteItems = false);
bool RemoveItem(BMenu* menu);
virtual void MessageReceived(BMessage* message); BMenuItem* ItemAt(int32 index) const;
virtual void KeyDown(const char* bytes, int32 numBytes); BMenu* SubmenuAt(int32 index) const;
virtual void Draw(BRect updateRect); int32 CountItems() const;
virtual BSize MinSize(); int32 IndexOf(BMenuItem* item) const;
virtual BSize MaxSize(); int32 IndexOf(BMenu* menu) const;
virtual BSize PreferredSize(); BMenuItem* FindItem(uint32 command) const;
virtual void GetPreferredSize(float* _width, float* _height); BMenuItem* FindItem(const char* name) const;
virtual void ResizeToPreferred();
virtual void DoLayout();
virtual void FrameMoved(BPoint newPosition);
virtual void FrameResized(float newWidth, float newHeight);
void InvalidateLayout();
virtual void InvalidateLayout(bool descendants);
virtual BHandler* ResolveSpecifier(BMessage* message, int32 index, virtual status_t SetTargetForItems(BHandler* target);
BMessage* specifier, int32 form, virtual status_t SetTargetForItems(BMessenger messenger);
const char* property); virtual void SetEnabled(bool state);
virtual status_t GetSupportedSuites(BMessage* data); virtual void SetRadioMode(bool state);
virtual void SetTriggersEnabled(bool state);
virtual void SetMaxContentWidth(float maxWidth);
virtual status_t Perform(perform_code d, void* arg); void SetLabelFromMarked(bool state);
bool IsLabelFromMarked();
bool IsEnabled() const;
bool IsRadioMode() const;
bool AreTriggersEnabled() const;
bool IsRedrawAfterSticky() const;
float MaxContentWidth() const;
virtual void MakeFocus(bool focus = true); BMenuItem* FindMarked();
virtual void AllAttached();
virtual void AllDetached(); BMenu* Supermenu() const;
BMenuItem* Superitem() const;
virtual BHandler* ResolveSpecifier(BMessage* message,
int32 index, BMessage* specifier,
int32 form, const char* property);
virtual status_t GetSupportedSuites(BMessage* data);
virtual status_t Perform(perform_code d, void* arg);
protected: protected:
BMenu(BRect frame, const char* name, BMenu(BRect frame, const char* name,
uint32 resizeMask, uint32 flags, uint32 resizeMask, uint32 flags,
menu_layout layout, bool resizeToFit); menu_layout layout, bool resizeToFit);
virtual BPoint ScreenLocation(); virtual BPoint ScreenLocation();
void SetItemMargins(float left, float top, float right, void SetItemMargins(float left, float top,
float bottom); float right, float bottom);
void GetItemMargins(float* left, float* top, void GetItemMargins(float* _left, float* _top,
float* right, float* bottom) const; float* _right, float* _bottom) const;
menu_layout Layout() const; menu_layout Layout() const;
virtual void Show(); virtual void Show();
void Show(bool selectFirstItem); void Show(bool selectFirstItem);
void Hide(); void Hide();
BMenuItem* Track(bool startOpened = false, BMenuItem* Track(bool startOpened = false,
BRect* specialRect = NULL); BRect* specialRect = NULL);
public: public:
enum add_state { enum add_state {
@@ -153,11 +160,11 @@ public:
B_PROCESSING, B_PROCESSING,
B_ABORT B_ABORT
}; };
virtual bool AddDynamicItem(add_state state); virtual bool AddDynamicItem(add_state state);
virtual void DrawBackground(BRect update); virtual void DrawBackground(BRect update);
void SetTrackingHook(menu_tracking_hook hook, void SetTrackingHook(menu_tracking_hook hook,
void* state); void* state);
private: private:
friend class BMenuBar; friend class BMenuBar;
@@ -168,117 +175,123 @@ private:
struct LayoutData; struct LayoutData;
virtual void _ReservedMenu3(); virtual void _ReservedMenu3();
virtual void _ReservedMenu4(); virtual void _ReservedMenu4();
virtual void _ReservedMenu5(); virtual void _ReservedMenu5();
virtual void _ReservedMenu6(); virtual void _ReservedMenu6();
BMenu& operator=(const BMenu& other); BMenu& operator=(const BMenu& other);
void _InitData(BMessage* archive); void _InitData(BMessage* archive);
bool _Show(bool selectFirstItem = false); bool _Show(bool selectFirstItem = false);
void _Hide(); void _Hide();
BMenuItem* _Track(int* action, long start = -1); BMenuItem* _Track(int* action, long start = -1);
void _UpdateNavigationArea(BPoint position, void _UpdateNavigationArea(BPoint position,
BRect& navAreaRectAbove, BRect& navAreaBelow); BRect& navAreaRectAbove,
BRect& navAreaBelow);
void _UpdateStateOpenSelect(BMenuItem* item, void _UpdateStateOpenSelect(BMenuItem* item,
BPoint position, BRect& navAreaRectAbove, BPoint position, BRect& navAreaRectAbove,
BRect& navAreaBelow, bigtime_t& selectedTime, BRect& navAreaBelow,
bigtime_t& navigationAreaTime); bigtime_t& selectedTime,
void _UpdateStateClose(BMenuItem* item, const BPoint& where, bigtime_t& navigationAreaTime);
const uint32& buttons); void _UpdateStateClose(BMenuItem* item,
const BPoint& where,
const uint32& buttons);
bool _AddItem(BMenuItem* item, int32 index); bool _AddItem(BMenuItem* item, int32 index);
bool _RemoveItems(int32 index, int32 count, bool _RemoveItems(int32 index, int32 count,
BMenuItem* item, bool deleteItems = false); BMenuItem* item, bool deleteItems = false);
bool _RelayoutIfNeeded(); bool _RelayoutIfNeeded();
void _LayoutItems(int32 index); void _LayoutItems(int32 index);
BSize _ValidatePreferredSize(); BSize _ValidatePreferredSize();
void _ComputeLayout(int32 index, bool bestFit, void _ComputeLayout(int32 index, bool bestFit,
bool moveItems, float* width, float* height); bool moveItems, float* width,
void _ComputeColumnLayout(int32 index, bool bestFit, float* height);
bool moveItems, BRect& outRect); void _ComputeColumnLayout(int32 index, bool bestFit,
void _ComputeRowLayout(int32 index, bool bestFit, bool moveItems, BRect& outRect);
bool moveItems, BRect& outRect); void _ComputeRowLayout(int32 index, bool bestFit,
void _ComputeMatrixLayout(BRect& outRect); bool moveItems, BRect& outRect);
void _ComputeMatrixLayout(BRect& outRect);
BRect _CalcFrame(BPoint where, bool* scrollOn); BRect _CalcFrame(BPoint where, bool* scrollOn);
protected: protected:
void _DrawItems(BRect updateRect); void _DrawItems(BRect updateRect);
private: private:
bool _OverSuper(BPoint loc); bool _OverSuper(BPoint loc);
bool _OverSubmenu(BMenuItem* item, BPoint loc); bool _OverSubmenu(BMenuItem* item, BPoint loc);
BPrivate::BMenuWindow* _MenuWindow(); BPrivate::BMenuWindow* _MenuWindow();
void _DeleteMenuWindow(); void _DeleteMenuWindow();
BMenuItem* _HitTestItems(BPoint where, BMenuItem* _HitTestItems(BPoint where,
BPoint slop = B_ORIGIN) const; BPoint slop = B_ORIGIN) const;
BRect _Superbounds() const; BRect _Superbounds() const;
void _CacheFontInfo(); void _CacheFontInfo();
void _ItemMarked(BMenuItem* item); void _ItemMarked(BMenuItem* item);
void _Install(BWindow* target); void _Install(BWindow* target);
void _Uninstall(); void _Uninstall();
void _SelectItem(BMenuItem* item, void _SelectItem(BMenuItem* item,
bool showSubmenu = true, bool showSubmenu = true,
bool selectFirstItem = false); bool selectFirstItem = false);
bool _SelectNextItem(BMenuItem* item, bool forward); bool _SelectNextItem(BMenuItem* item, bool forward);
BMenuItem* _NextItem(BMenuItem* item, bool forward) const; BMenuItem* _NextItem(BMenuItem* item, bool forward) const;
void _SetIgnoreHidden(bool on); void _SetIgnoreHidden(bool on);
void _SetStickyMode(bool on); void _SetStickyMode(bool on);
bool _IsStickyMode() const; bool _IsStickyMode() const;
void _CalcTriggers(); void _CalcTriggers();
bool _ChooseTrigger(const char* title, int32& index, bool _ChooseTrigger(const char* title, int32& index,
uint32& trigger, BPrivate::TriggerList& triggers); uint32& trigger,
void _UpdateWindowViewSize(bool updatePosition = true); BPrivate::TriggerList& triggers);
bool _OkToProceed(BMenuItem* item); void _UpdateWindowViewSize(
bool updatePosition = true);
bool _OkToProceed(BMenuItem* item);
bool _CustomTrackingWantsToQuit(); bool _CustomTrackingWantsToQuit();
int _State(BMenuItem** _item = NULL) const; int _State(BMenuItem** _item = NULL) const;
void _InvokeItem(BMenuItem* item, bool now = false); void _InvokeItem(BMenuItem* item, bool now = false);
void _QuitTracking(bool onlyThis = true); void _QuitTracking(bool onlyThis = true);
static menu_info sMenuInfo; static menu_info sMenuInfo;
static bool sAltAsCommandKey; static bool sAltAsCommandKey;
BMenuItem* fChosenItem; BMenuItem* fChosenItem;
BList fItems; BList fItems;
BRect fPad; BRect fPad;
BMenuItem* fSelected; BMenuItem* fSelected;
BPrivate::BMenuWindow* fCachedMenuWindow; BPrivate::BMenuWindow* fCachedMenuWindow;
BMenu* fSuper; BMenu* fSuper;
BMenuItem* fSuperitem; BMenuItem* fSuperitem;
BRect fSuperbounds; BRect fSuperbounds;
float fAscent; float fAscent;
float fDescent; float fDescent;
float fFontHeight; float fFontHeight;
uint32 fState; uint32 fState;
menu_layout fLayout; menu_layout fLayout;
BRect* fExtraRect; BRect* fExtraRect;
float fMaxContentWidth; float fMaxContentWidth;
BPoint* fInitMatrixSize; BPoint* fInitMatrixSize;
BPrivate::ExtraMenuData* fExtraMenuData; BPrivate::ExtraMenuData* fExtraMenuData;
LayoutData* fLayoutData; LayoutData* fLayoutData;
int32 _reserved; int32 _reserved;
char fTrigger; char fTrigger;
bool fResizeToFit; bool fResizeToFit;
bool fUseCachedMenuLayout; bool fUseCachedMenuLayout;
bool fEnabled; bool fEnabled;
bool fDynamicName; bool fDynamicName;
bool fRadioMode; bool fRadioMode;
bool fTrackNewBounds; bool fTrackNewBounds;
bool fStickyMode; bool fStickyMode;
bool fIgnoreHidden; bool fIgnoreHidden;
bool fTriggerEnabled; bool fTriggerEnabled;
bool fRedrawAfterSticky; bool fRedrawAfterSticky;
bool fAttachAborted; bool fAttachAborted;
}; };
#endif // _MENU_H #endif // _MENU_H
+350 -307
View File
@@ -1,11 +1,12 @@
/* /*
* Copyright 2001-2009, Haiku, Inc. * Copyright 2001-2009, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT license.
* *
* Authors: * Authors:
* Marc Flerackers ([email protected]) * Marc Flerackers ([email protected])
* Stefano Ceccherini ([email protected]) * Stefano Ceccherini ([email protected])
* Rene Gollent ([email protected]) * Rene Gollent ([email protected])
* Stephan Aßmus <[email protected]>
*/ */
@@ -86,8 +87,8 @@ bool BMenu::sAltAsCommandKey;
static property_info sPropList[] = { static property_info sPropList[] = {
{ "Enabled", { B_GET_PROPERTY, 0 }, { "Enabled", { B_GET_PROPERTY, 0 },
{ B_DIRECT_SPECIFIER, 0 }, "Returns true if menu or menu item is enabled; false " { B_DIRECT_SPECIFIER, 0 }, "Returns true if menu or menu item is "
"otherwise.", "enabled; false otherwise.",
0, { B_BOOL_TYPE } 0, { B_BOOL_TYPE }
}, },
@@ -97,31 +98,34 @@ static property_info sPropList[] = {
}, },
{ "Label", { B_GET_PROPERTY, 0 }, { "Label", { B_GET_PROPERTY, 0 },
{ B_DIRECT_SPECIFIER, 0 }, "Returns the string label of the menu or menu item.", { B_DIRECT_SPECIFIER, 0 }, "Returns the string label of the menu or "
"menu item.",
0, { B_STRING_TYPE } 0, { B_STRING_TYPE }
}, },
{ "Label", { B_SET_PROPERTY, 0 }, { "Label", { B_SET_PROPERTY, 0 },
{ B_DIRECT_SPECIFIER, 0 }, "Sets the string label of the menu or menu item.", { B_DIRECT_SPECIFIER, 0 }, "Sets the string label of the menu or menu "
"item.",
0, { B_STRING_TYPE } 0, { B_STRING_TYPE }
}, },
{ "Mark", { B_GET_PROPERTY, 0 }, { "Mark", { B_GET_PROPERTY, 0 },
{ B_DIRECT_SPECIFIER, 0 }, "Returns true if the menu item or the menu's superitem " { B_DIRECT_SPECIFIER, 0 }, "Returns true if the menu item or the "
"is marked; false otherwise.", "menu's superitem is marked; false otherwise.",
0, { B_BOOL_TYPE } 0, { B_BOOL_TYPE }
}, },
{ "Mark", { B_SET_PROPERTY, 0 }, { "Mark", { B_SET_PROPERTY, 0 },
{ B_DIRECT_SPECIFIER, 0 }, "Marks or unmarks the menu item or the menu's superitem.", { B_DIRECT_SPECIFIER, 0 }, "Marks or unmarks the menu item or the "
"menu's superitem.",
0, { B_BOOL_TYPE } 0, { B_BOOL_TYPE }
}, },
{ "Menu", { B_CREATE_PROPERTY, 0 }, { "Menu", { B_CREATE_PROPERTY, 0 },
{ B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 }, { B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 },
"Adds a new menu item at the specified index with the text label found in \"data\" " "Adds a new menu item at the specified index with the text label "
"and the int32 command found in \"what\" (used as the what field in the CMessage " "found in \"data\" and the int32 command found in \"what\" (used as "
"sent by the item)." , 0, {}, "the what field in the BMessage sent by the item)." , 0, {},
{ {{{"data", B_STRING_TYPE}}} { {{{"data", B_STRING_TYPE}}}
} }
}, },
@@ -133,20 +137,21 @@ static property_info sPropList[] = {
{ "Menu", { }, { "Menu", { },
{ B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 }, { B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 },
"Directs scripting message to the specified menu, first popping the current " "Directs scripting message to the specified menu, first popping the "
"specifier off the stack.", 0, {} "current specifier off the stack.", 0, {}
}, },
{ "MenuItem", { B_COUNT_PROPERTIES, 0 }, { "MenuItem", { B_COUNT_PROPERTIES, 0 },
{ B_DIRECT_SPECIFIER, 0 }, "Counts the number of menu items in the specified menu.", { B_DIRECT_SPECIFIER, 0 }, "Counts the number of menu items in the "
"specified menu.",
0, { B_INT32_TYPE } 0, { B_INT32_TYPE }
}, },
{ "MenuItem", { B_CREATE_PROPERTY, 0 }, { "MenuItem", { B_CREATE_PROPERTY, 0 },
{ B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 }, { B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 },
"Adds a new menu item at the specified index with the text label found in \"data\" " "Adds a new menu item at the specified index with the text label "
"and the int32 command found in \"what\" (used as the what field in the CMessage " "found in \"data\" and the int32 command found in \"what\" (used as "
"sent by the item).", 0, {}, "the what field in the BMessage sent by the item).", 0, {},
{ { {{"data", B_STRING_TYPE }, { { {{"data", B_STRING_TYPE },
{"be:invoke_message", B_MESSAGE_TYPE}, {"be:invoke_message", B_MESSAGE_TYPE},
{"what", B_INT32_TYPE}, {"what", B_INT32_TYPE},
@@ -166,8 +171,8 @@ static property_info sPropList[] = {
{ "MenuItem", { }, { "MenuItem", { },
{ B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 }, { B_NAME_SPECIFIER, B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 0 },
"Directs scripting message to the specified menu, first popping the current " "Directs scripting message to the specified menu, first popping the "
"specifier off the stack." "current specifier off the stack."
}, },
{} {}
@@ -183,6 +188,9 @@ struct BMenu::LayoutData {
}; };
// #pragma mark -
BMenu::BMenu(const char* name, menu_layout layout) BMenu::BMenu(const char* name, menu_layout layout)
: :
BView(BRect(0, 0, 0, 0), name, 0, B_WILL_DRAW), BView(BRect(0, 0, 0, 0), name, 0, B_WILL_DRAW),
@@ -252,18 +260,6 @@ BMenu::BMenu(const char* name, float width, float height)
} }
BMenu::~BMenu()
{
_DeleteMenuWindow();
RemoveItems(0, CountItems(), true);
delete fInitMatrixSize;
delete fExtraMenuData;
delete fLayoutData;
}
BMenu::BMenu(BMessage* archive) BMenu::BMenu(BMessage* archive)
: :
BView(archive), BView(archive),
@@ -299,6 +295,21 @@ BMenu::BMenu(BMessage* archive)
} }
BMenu::~BMenu()
{
_DeleteMenuWindow();
RemoveItems(0, CountItems(), true);
delete fInitMatrixSize;
delete fExtraMenuData;
delete fLayoutData;
}
// #pragma mark -
BArchivable* BArchivable*
BMenu::Instantiate(BMessage* archive) BMenu::Instantiate(BMessage* archive)
{ {
@@ -347,6 +358,9 @@ BMenu::Archive(BMessage* data, bool deep) const
} }
// #pragma mark -
void void
BMenu::AttachedToWindow() BMenu::AttachedToWindow()
{ {
@@ -393,6 +407,279 @@ BMenu::DetachedFromWindow()
} }
void
BMenu::AllAttached()
{
BView::AllAttached();
}
void
BMenu::AllDetached()
{
BView::AllDetached();
}
// #pragma mark -
void
BMenu::Draw(BRect updateRect)
{
if (_RelayoutIfNeeded()) {
Invalidate();
return;
}
DrawBackground(updateRect);
_DrawItems(updateRect);
}
void
BMenu::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case B_MOUSE_WHEEL_CHANGED:
{
float deltaY = 0;
msg->FindFloat("be:wheel_delta_y", &deltaY);
if (deltaY == 0)
return;
BMenuWindow* window = dynamic_cast<BMenuWindow*>(Window());
if (window == NULL)
return;
float largeStep;
float smallStep;
window->GetSteps(&smallStep, &largeStep);
// pressing the option/command/control key scrolls faster
if (modifiers() & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY))
deltaY *= largeStep;
else
deltaY *= smallStep;
window->TryScrollBy(deltaY);
break;
}
default:
BView::MessageReceived(msg);
break;
}
}
void
BMenu::KeyDown(const char* bytes, int32 numBytes)
{
// TODO: Test how it works on beos and implement it correctly
switch (bytes[0]) {
case B_UP_ARROW:
if (fLayout == B_ITEMS_IN_COLUMN)
_SelectNextItem(fSelected, false);
break;
case B_DOWN_ARROW:
if (fLayout == B_ITEMS_IN_COLUMN)
_SelectNextItem(fSelected, true);
break;
case B_LEFT_ARROW:
if (fLayout == B_ITEMS_IN_ROW)
_SelectNextItem(fSelected, false);
else {
// this case has to be handled a bit specially.
BMenuItem* item = Superitem();
if (item) {
if (dynamic_cast<BMenuBar*>(Supermenu())) {
// If we're at the top menu below the menu bar, pass
// the keypress to the menu bar so we can move to
// another top level menu.
BMessenger msgr(Supermenu());
msgr.SendMessage(Window()->CurrentMessage());
} else
Supermenu()->_SelectItem(item, false, false);
}
}
break;
case B_RIGHT_ARROW:
if (fLayout == B_ITEMS_IN_ROW)
_SelectNextItem(fSelected, true);
else {
if (fSelected && fSelected->Submenu()) {
_SelectItem(fSelected, true, true);
} else if (dynamic_cast<BMenuBar*>(Supermenu())) {
// if we have no submenu and we're an
// item in the top menu below the menubar,
// pass the keypress to the menubar
// so you can use the keypress to switch menus.
BMessenger msgr(Supermenu());
msgr.SendMessage(Window()->CurrentMessage());
}
}
break;
case B_PAGE_UP:
case B_PAGE_DOWN:
{
BMenuWindow* window = dynamic_cast<BMenuWindow*>(Window());
if (window == NULL || !window->HasScrollers())
break;
int32 deltaY = bytes[0] == B_PAGE_UP ? -1 : 1;
float largeStep;
window->GetSteps(NULL, &largeStep);
window->TryScrollBy(deltaY * largeStep);
break;
}
case B_ENTER:
case B_SPACE:
if (fSelected) {
_InvokeItem(fSelected);
_QuitTracking(false);
}
break;
case B_ESCAPE:
_QuitTracking();
break;
default:
{
uint32 trigger = UTF8ToCharCode(&bytes);
for (uint32 i = CountItems(); i-- > 0;) {
BMenuItem* item = ItemAt(i);
if (item->fTriggerIndex < 0 || item->fTrigger != trigger)
continue;
_InvokeItem(item);
}
break;
}
}
}
// #pragma mark -
BSize
BMenu::MinSize()
{
_ValidatePreferredSize();
BSize size = (GetLayout() ? GetLayout()->MinSize()
: fLayoutData->preferred);
return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
}
BSize
BMenu::MaxSize()
{
_ValidatePreferredSize();
BSize size = (GetLayout() ? GetLayout()->MaxSize()
: fLayoutData->preferred);
return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size);
}
BSize
BMenu::PreferredSize()
{
_ValidatePreferredSize();
BSize size = (GetLayout() ? GetLayout()->PreferredSize()
: fLayoutData->preferred);
return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size);
}
void
BMenu::GetPreferredSize(float* _width, float* _height)
{
_ValidatePreferredSize();
if (_width)
*_width = fLayoutData->preferred.width;
if (_height)
*_height = fLayoutData->preferred.height;
}
void
BMenu::ResizeToPreferred()
{
BView::ResizeToPreferred();
}
void
BMenu::DoLayout()
{
// If the user set a layout, we let the base class version call its
// hook.
if (GetLayout()) {
BView::DoLayout();
return;
}
if (_RelayoutIfNeeded())
Invalidate();
}
void
BMenu::FrameMoved(BPoint new_position)
{
BView::FrameMoved(new_position);
}
void
BMenu::FrameResized(float new_width, float new_height)
{
BView::FrameResized(new_width, new_height);
}
void
BMenu::InvalidateLayout()
{
InvalidateLayout(false);
}
void
BMenu::InvalidateLayout(bool descendants)
{
fUseCachedMenuLayout = false;
fLayoutData->preferred.Set(B_SIZE_UNSET, B_SIZE_UNSET);
BView::InvalidateLayout(descendants);
}
// #pragma mark -
void
BMenu::MakeFocus(bool focused)
{
BView::MakeFocus(focused);
}
bool bool
BMenu::AddItem(BMenuItem* item) BMenu::AddItem(BMenuItem* item)
{ {
@@ -589,8 +876,10 @@ bool
BMenu::RemoveItem(BMenu* submenu) BMenu::RemoveItem(BMenu* submenu)
{ {
for (int32 i = 0; i < fItems.CountItems(); i++) { for (int32 i = 0; i < fItems.CountItems(); i++) {
if (static_cast<BMenuItem*>(fItems.ItemAtFast(i))->Submenu() == submenu) if (static_cast<BMenuItem*>(fItems.ItemAtFast(i))->Submenu()
== submenu) {
return _RemoveItems(i, 1, NULL, false); return _RemoveItems(i, 1, NULL, false);
}
} }
return false; return false;
@@ -827,246 +1116,7 @@ BMenu::Superitem() const
} }
void // #pragma mark -
BMenu::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case B_MOUSE_WHEEL_CHANGED:
{
float deltaY = 0;
msg->FindFloat("be:wheel_delta_y", &deltaY);
if (deltaY == 0)
return;
BMenuWindow* window = dynamic_cast<BMenuWindow*>(Window());
if (window == NULL)
return;
float largeStep;
float smallStep;
window->GetSteps(&smallStep, &largeStep);
// pressing the option/command/control key scrolls faster
if (modifiers() & (B_OPTION_KEY | B_COMMAND_KEY | B_CONTROL_KEY))
deltaY *= largeStep;
else
deltaY *= smallStep;
window->TryScrollBy(deltaY);
break;
}
default:
BView::MessageReceived(msg);
break;
}
}
void
BMenu::KeyDown(const char* bytes, int32 numBytes)
{
// TODO: Test how it works on beos and implement it correctly
switch (bytes[0]) {
case B_UP_ARROW:
if (fLayout == B_ITEMS_IN_COLUMN)
_SelectNextItem(fSelected, false);
break;
case B_DOWN_ARROW:
if (fLayout == B_ITEMS_IN_COLUMN)
_SelectNextItem(fSelected, true);
break;
case B_LEFT_ARROW:
if (fLayout == B_ITEMS_IN_ROW)
_SelectNextItem(fSelected, false);
else {
// this case has to be handled a bit specially.
BMenuItem* item = Superitem();
if (item) {
if (dynamic_cast<BMenuBar*>(Supermenu())) {
// if we're at the top menu below the menu bar, pass the keypress to
// the menu bar so we can move to another top level menu
BMessenger msgr(Supermenu());
msgr.SendMessage(Window()->CurrentMessage());
} else
Supermenu()->_SelectItem(item, false, false);
}
}
break;
case B_RIGHT_ARROW:
if (fLayout == B_ITEMS_IN_ROW)
_SelectNextItem(fSelected, true);
else {
if (fSelected && fSelected->Submenu()) {
_SelectItem(fSelected, true, true);
} else if (dynamic_cast<BMenuBar*>(Supermenu())) {
// if we have no submenu and we're an
// item in the top menu below the menubar,
// pass the keypress to the menubar
// so you can use the keypress to switch menus.
BMessenger msgr(Supermenu());
msgr.SendMessage(Window()->CurrentMessage());
}
}
break;
case B_PAGE_UP:
case B_PAGE_DOWN:
{
BMenuWindow* window = dynamic_cast<BMenuWindow*>(Window());
if (window == NULL || !window->HasScrollers())
break;
int32 deltaY = bytes[0] == B_PAGE_UP ? -1 : 1;
float largeStep;
window->GetSteps(NULL, &largeStep);
window->TryScrollBy(deltaY * largeStep);
break;
}
case B_ENTER:
case B_SPACE:
if (fSelected) {
_InvokeItem(fSelected);
_QuitTracking(false);
}
break;
case B_ESCAPE:
_QuitTracking();
break;
default:
{
uint32 trigger = UTF8ToCharCode(&bytes);
for (uint32 i = CountItems(); i-- > 0;) {
BMenuItem* item = ItemAt(i);
if (item->fTriggerIndex < 0 || item->fTrigger != trigger)
continue;
_InvokeItem(item);
}
break;
}
}
}
void
BMenu::Draw(BRect updateRect)
{
if (_RelayoutIfNeeded()) {
Invalidate();
return;
}
DrawBackground(updateRect);
_DrawItems(updateRect);
}
BSize
BMenu::MinSize()
{
_ValidatePreferredSize();
BSize size = (GetLayout() ? GetLayout()->MinSize()
: fLayoutData->preferred);
return BLayoutUtils::ComposeSize(ExplicitMinSize(), size);
}
BSize
BMenu::MaxSize()
{
_ValidatePreferredSize();
BSize size = (GetLayout() ? GetLayout()->MaxSize()
: fLayoutData->preferred);
return BLayoutUtils::ComposeSize(ExplicitMaxSize(), size);
}
BSize
BMenu::PreferredSize()
{
_ValidatePreferredSize();
BSize size = (GetLayout() ? GetLayout()->PreferredSize()
: fLayoutData->preferred);
return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), size);
}
void
BMenu::GetPreferredSize(float* _width, float* _height)
{
_ValidatePreferredSize();
if (_width)
*_width = fLayoutData->preferred.width;
if (_height)
*_height = fLayoutData->preferred.height;
}
void
BMenu::ResizeToPreferred()
{
BView::ResizeToPreferred();
}
void
BMenu::DoLayout()
{
// If the user set a layout, we let the base class version call its
// hook.
if (GetLayout()) {
BView::DoLayout();
return;
}
if (_RelayoutIfNeeded())
Invalidate();
}
void
BMenu::FrameMoved(BPoint new_position)
{
BView::FrameMoved(new_position);
}
void
BMenu::FrameResized(float new_width, float new_height)
{
BView::FrameResized(new_width, new_height);
}
void
BMenu::InvalidateLayout()
{
InvalidateLayout(false);
}
void
BMenu::InvalidateLayout(bool descendants)
{
fUseCachedMenuLayout = false;
fLayoutData->preferred.Set(B_SIZE_UNSET, B_SIZE_UNSET);
BView::InvalidateLayout(descendants);
}
BHandler* BHandler*
@@ -1191,30 +1241,10 @@ BMenu::Perform(perform_code code, void* _data)
} }
void
BMenu::MakeFocus(bool focused)
{
BView::MakeFocus(focused);
}
void
BMenu::AllAttached()
{
BView::AllAttached();
}
void
BMenu::AllDetached()
{
BView::AllDetached();
}
BMenu::BMenu(BRect frame, const char* name, uint32 resizingMode, uint32 flags, BMenu::BMenu(BRect frame, const char* name, uint32 resizingMode, uint32 flags,
menu_layout layout, bool resizeToFit) menu_layout layout, bool resizeToFit)
: BView(frame, name, resizingMode, flags), :
BView(frame, name, resizingMode, flags),
fChosenItem(NULL), fChosenItem(NULL),
fSelected(NULL), fSelected(NULL),
fCachedMenuWindow(NULL), fCachedMenuWindow(NULL),
@@ -1467,7 +1497,8 @@ BMenu::_Show(bool selectFirstItem)
// Menu didn't have the time to add its items: aborting... // Menu didn't have the time to add its items: aborting...
if (fAttachAborted) { if (fAttachAborted) {
window->DetachMenu(); window->DetachMenu();
// TODO: Probably not needed, we can just let _hide() quit the window // TODO: Probably not needed, we can just let _hide() quit the
// window.
if (ourWindow) if (ourWindow)
window->Quit(); window->Quit();
else else
@@ -1518,7 +1549,8 @@ BMenu::_Hide()
const static bigtime_t kOpenSubmenuDelay = 225000; const static bigtime_t kOpenSubmenuDelay = 225000;
const static bigtime_t kNavigationAreaTimeout = 1000000; const static bigtime_t kNavigationAreaTimeout = 1000000;
const static bigtime_t kHysteresis = 200000; // TODO: Test and reduce if needed. const static bigtime_t kHysteresis = 200000;
// TODO: Test and reduce if needed.
const static int32 kMouseMotionThreshold = 15; const static int32 kMouseMotionThreshold = 15;
// TODO: Same as above. Actually, we could get rid of the kHysteresis // TODO: Same as above. Actually, we could get rid of the kHysteresis
@@ -1795,7 +1827,8 @@ BMenu::_UpdateStateOpenSelect(BMenuItem* item, BPoint position,
float yOffset = navAreaRectBelow.bottom - position.y; float yOffset = navAreaRectBelow.bottom - position.y;
float ratio = navAreaRectBelow.Width() / navAreaRectBelow.Height(); float ratio = navAreaRectBelow.Width() / navAreaRectBelow.Height();
inNavArea = yOffset >= (navAreaRectBelow.Height() - xOffset / ratio); inNavArea = yOffset >= (navAreaRectBelow.Height() - xOffset
/ ratio);
} }
bigtime_t systime = system_time(); bigtime_t systime = system_time();
@@ -1823,7 +1856,8 @@ BMenu::_UpdateStateOpenSelect(BMenuItem* item, BPoint position,
if (!navAreaRectAbove.IsValid() && !navAreaRectBelow.IsValid()) { if (!navAreaRectAbove.IsValid() && !navAreaRectBelow.IsValid()) {
position = ConvertToScreen(position); position = ConvertToScreen(position);
_UpdateNavigationArea(position, navAreaRectAbove, navAreaRectBelow); _UpdateNavigationArea(position, navAreaRectAbove,
navAreaRectBelow);
} }
} }
@@ -1896,7 +1930,8 @@ BMenu::_AddItem(BMenuItem* item, int32 index)
bool bool
BMenu::_RemoveItems(int32 index, int32 count, BMenuItem* item, bool deleteItems) BMenu::_RemoveItems(int32 index, int32 count, BMenuItem* item,
bool deleteItems)
{ {
bool success = false; bool success = false;
bool invalidateLayout = false; bool invalidateLayout = false;
@@ -2229,8 +2264,10 @@ BMenu::_CalcFrame(BPoint where, bool* scrollOn)
else if (frame.left < screenFrame.left) else if (frame.left < screenFrame.left)
frame.OffsetBy(-frame.left, 0); frame.OffsetBy(-frame.left, 0);
} else if (superMenu->Layout() == B_ITEMS_IN_COLUMN) { } else if (superMenu->Layout() == B_ITEMS_IN_COLUMN) {
if (frame.right > screenFrame.right) if (frame.right > screenFrame.right) {
frame.OffsetBy(-superItem->Frame().Width() - frame.Width() - 2, 0); frame.OffsetBy(-superItem->Frame().Width() - frame.Width() - 2,
0);
}
if (frame.left < 0) if (frame.left < 0)
frame.OffsetBy(-frame.left + 6, 0); frame.OffsetBy(-frame.left + 6, 0);
@@ -2244,7 +2281,8 @@ BMenu::_CalcFrame(BPoint where, bool* scrollOn)
&& frame.top < (screenFrame.bottom - 80)) { && frame.top < (screenFrame.bottom - 80)) {
scroll = true; scroll = true;
} else { } else {
frame.OffsetBy(0, -superItem->Frame().Height() - frame.Height() - 3); frame.OffsetBy(0, -superItem->Frame().Height()
- frame.Height() - 3);
} }
} }
@@ -2531,8 +2569,10 @@ BMenu::_NextItem(BMenuItem* item, bool forward) const
index = 0; index = 0;
} while (!ItemAt(index)->IsEnabled() && index != startIndex); } while (!ItemAt(index)->IsEnabled() && index != startIndex);
if (index == startIndex) // we are back where we started and no item was enabled if (index == startIndex) {
// We are back where we started and no item was enabled.
return NULL; return NULL;
}
return ItemAt(index); return ItemAt(index);
} }
@@ -2698,7 +2738,8 @@ BMenu::_OkToProceed(BMenuItem* item)
// or releases the mouse button in nonsticky mode // or releases the mouse button in nonsticky mode
// or moves the pointer over another item // or moves the pointer over another item
// TODO: I added the check for BMenuBar to solve a problem with Deskbar. // TODO: I added the check for BMenuBar to solve a problem with Deskbar.
// BeOS seems to do something similar. This could also be a bug in Deskbar, though. // BeOS seems to do something similar. This could also be a bug in
// Deskbar, though.
if ((buttons != 0 && stickyMode) if ((buttons != 0 && stickyMode)
|| ((dynamic_cast<BMenuBar*>(this) == NULL || ((dynamic_cast<BMenuBar*>(this) == NULL
&& (buttons == 0 && !stickyMode)) || _HitTestItems(where) != item)) && (buttons == 0 && !stickyMode)) || _HitTestItems(where) != item))
@@ -2713,7 +2754,8 @@ BMenu::_CustomTrackingWantsToQuit()
{ {
if (fExtraMenuData != NULL && fExtraMenuData->trackingHook != NULL if (fExtraMenuData != NULL && fExtraMenuData->trackingHook != NULL
&& fExtraMenuData->trackingState != NULL) { && fExtraMenuData->trackingState != NULL) {
return fExtraMenuData->trackingHook(this, fExtraMenuData->trackingState); return fExtraMenuData->trackingHook(this,
fExtraMenuData->trackingState);
} }
return false; return false;
@@ -2741,7 +2783,8 @@ BMenu::_QuitTracking(bool onlyThis)
// #pragma mark - // #pragma mark -
// TODO: Maybe the following two methods would fit better into InterfaceDefs.cpp // TODO: Maybe the following two methods would fit better into
// InterfaceDefs.cpp
// In R5, they do all the work client side, we let the app_server handle the // In R5, they do all the work client side, we let the app_server handle the
// details. // details.
status_t status_t