From a87bf00703005530cef8bd1ea96d2e0396a035a0 Mon Sep 17 00:00:00 2001 From: Stefano Ceccherini Date: Sat, 9 Oct 2004 08:50:17 +0000 Subject: [PATCH] Bare minimum stuff to have BPopupmenu working with our own BMenu git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9269 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/Menu.cpp | 1162 ++++++++++++++++++++++------------- 1 file changed, 728 insertions(+), 434 deletions(-) diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index de84017ac8..69aeed5628 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS +// Copyright (c) 2001-2004, Haiku, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -20,33 +20,26 @@ // DEALINGS IN THE SOFTWARE. // // File Name: Menu.cpp -// Author: Marc Flerackers (mflerackers@androme.be) +// Authors: Marc Flerackers (mflerackers@androme.be) +// Stefano Ceccherini (burton666@libero.it) // Description: BMenu display a menu of selectable items. //------------------------------------------------------------------------------ - -// Standard Includes ----------------------------------------------------------- - -// System Includes ------------------------------------------------------------- -#include -#include -#include -#include -#include #include #include +#include +#include #include +#include +#include -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- +#include +#define CALLED() printf("%s\n", __PRETTY_FUNCTION__); +#ifndef COMPILE_FOR_R5 menu_info BMenu::sMenuInfo; +#endif -static property_info prop_list[] = +static property_info sPropList[] = { { "Enabled", { B_GET_PROPERTY, 0 }, { B_DIRECT_SPECIFIER, 0 }, "Returns true if menu or menu item is enabled; false " @@ -94,7 +87,7 @@ static property_info prop_list[] = {} }; -//------------------------------------------------------------------------------ +// TODO: Move this to its own file class BMenuWindow : public BWindow { public: @@ -125,7 +118,7 @@ private: BMenu *fMenu; }; -//------------------------------------------------------------------------------ + BMenu::BMenu(const char *name, menu_layout layout) : BView(BRect(), name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE), @@ -157,10 +150,10 @@ BMenu::BMenu(const char *name, menu_layout layout) fRedrawAfterSticky(true), fAttachAborted(false) { - SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR)); - SetFontSize(10); + InitData(NULL); } -//------------------------------------------------------------------------------ + + BMenu::BMenu(const char *name, float width, float height) : BView(BRect(0.0f, width, 0.0f, height), name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_NAVIGABLE), @@ -191,22 +184,24 @@ BMenu::BMenu(const char *name, float width, float height) fRedrawAfterSticky(true), fAttachAborted(false) { - SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR)); - SetFontSize(10); + InitData(NULL); } -//------------------------------------------------------------------------------ + + BMenu::~BMenu() { for (int i = 0; i < CountItems(); i++) delete ItemAt(i); } -//------------------------------------------------------------------------------ + + BMenu::BMenu(BMessage *archive) : BView(archive) { - SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR)); + InitData(archive); } -//------------------------------------------------------------------------------ + + BArchivable *BMenu::Instantiate(BMessage *data) { if (validate_instantiation(data, "BMenu")) @@ -214,16 +209,17 @@ BArchivable *BMenu::Instantiate(BMessage *data) else return NULL; } -//------------------------------------------------------------------------------ -status_t BMenu::Archive(BMessage *data, bool deep) const + + +status_t +BMenu::Archive(BMessage *data, bool deep) const { status_t err = BView::Archive(data, deep); if (err != B_OK) return err; - if (Layout() != B_ITEMS_IN_ROW) - { + if (Layout() != B_ITEMS_IN_ROW) { err = data->AddInt32("_layout", Layout()); if (err != B_OK) @@ -232,59 +228,69 @@ status_t BMenu::Archive(BMessage *data, bool deep) const err = data->AddBool("_rsize_to_fit", fResizeToFit); - if (err != B_OK) + if (err < B_OK) return err; err = data->AddBool("_disable", !IsEnabled()); - if (err != B_OK) + if (err < B_OK) return err; err = data->AddBool("_radio", IsRadioMode()); - if (err != B_OK) + if (err < B_OK) return err; err = data->AddBool("_trig_disabled", AreTriggersEnabled()); - if (err != B_OK) + if (err < B_OK) return err; err = data->AddBool("_dyn_label", fDynamicName); - if (err != B_OK) + if (err < B_OK) return err; err = data->AddFloat("_maxwidth", fMaxContentWidth); - if (err != B_OK) + if (err < B_OK) return err; - if (deep) - { + if (deep) { // TODO store items and rects } return err; } -//------------------------------------------------------------------------------ -void BMenu::AttachedToWindow() + + +void +BMenu::AttachedToWindow() { + CALLED(); BView::AttachedToWindow(); LayoutItems(0); } -//------------------------------------------------------------------------------ -void BMenu::DetachedFromWindow() + + +void +BMenu::DetachedFromWindow() { + CALLED(); + BView::DetachedFromWindow(); } -//------------------------------------------------------------------------------ -bool BMenu::AddItem(BMenuItem *item) + + +bool +BMenu::AddItem(BMenuItem *item) { return AddItem(item, CountItems()); } -//------------------------------------------------------------------------------ -bool BMenu::AddItem(BMenuItem *item, int32 index) + + +bool +BMenu::AddItem(BMenuItem *item, int32 index) { item->fSuper = this; @@ -307,31 +313,48 @@ bool BMenu::AddItem(BMenuItem *item, int32 index) return err; } -//------------------------------------------------------------------------------ -bool BMenu::AddItem(BMenuItem *item, BRect frame) + + +bool +BMenu::AddItem(BMenuItem *item, BRect frame) { + if (!item) + return false; + item->fBounds = frame; return AddItem(item, CountItems()); } -//------------------------------------------------------------------------------ -bool BMenu::AddItem(BMenu *submenu) + + +bool +BMenu::AddItem(BMenu *submenu) { BMenuItem *item = new BMenuItem(submenu); + if (!item) + return false; + submenu->fSuper = this; return AddItem(item); } -//------------------------------------------------------------------------------ -bool BMenu::AddItem(BMenu *submenu, int32 index) + + +bool +BMenu::AddItem(BMenu *submenu, int32 index) { BMenuItem *item = new BMenuItem(submenu); + if (!item) + return false; + submenu->fSuper = this; return AddItem(item, index); } -//------------------------------------------------------------------------------ -bool BMenu::AddItem(BMenu *submenu, BRect frame) + + +bool +BMenu::AddItem(BMenu *submenu, BRect frame) { BMenuItem *item = new BMenuItem(submenu); submenu->fSuper = this; @@ -339,86 +362,108 @@ bool BMenu::AddItem(BMenu *submenu, BRect frame) return AddItem(item); } -//------------------------------------------------------------------------------ -bool BMenu::AddList(BList *list, int32 index) + + +bool +BMenu::AddList(BList *list, int32 index) { return false; } -//------------------------------------------------------------------------------ -bool BMenu::AddSeparatorItem() + + +bool +BMenu::AddSeparatorItem() { BMenuItem *item = new BSeparatorItem(); item->fSuper = this; return fItems.AddItem(item); } -//------------------------------------------------------------------------------ -bool BMenu::RemoveItem(BMenuItem *item) + + +bool +BMenu::RemoveItem(BMenuItem *item) { return fItems.RemoveItem(item); } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::RemoveItem(int32 index) + + +BMenuItem * +BMenu::RemoveItem(int32 index) { - return (BMenuItem*)fItems.RemoveItem ( index ); + return static_cast(fItems.RemoveItem(index)); } -//------------------------------------------------------------------------------ -bool BMenu::RemoveItems(int32 index, int32 count, bool del) + + +bool +BMenu::RemoveItems(int32 index, int32 count, bool del) { return false; } -//------------------------------------------------------------------------------ -bool BMenu::RemoveItem(BMenu *submenu) + + +bool +BMenu::RemoveItem(BMenu *submenu) { - for (int i =0; i < fItems.CountItems(); i++) - if (((BMenuItem*)fItems.ItemAt(i))->Submenu() == submenu) - return (BMenuItem*)fItems.RemoveItem(fItems.ItemAt(i)); + for (int i = 0; i < fItems.CountItems(); i++) + if (static_cast(fItems.ItemAt(i))->Submenu() == submenu) + return fItems.RemoveItem(fItems.ItemAt(i)); return false; } -//------------------------------------------------------------------------------ -int32 BMenu::CountItems() const + + +int32 +BMenu::CountItems() const { return fItems.CountItems(); } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::ItemAt(int32 index) const + + +BMenuItem * +BMenu::ItemAt(int32 index) const { - return (BMenuItem*)fItems.ItemAt(index); + return static_cast(fItems.ItemAt(index)); } -//------------------------------------------------------------------------------ -BMenu *BMenu::SubmenuAt(int32 index) const + + +BMenu * +BMenu::SubmenuAt(int32 index) const { - return ((BMenuItem*)fItems.ItemAt(index))->Submenu(); + return static_cast(fItems.ItemAt(index))->Submenu(); } -//------------------------------------------------------------------------------ -int32 BMenu::IndexOf(BMenuItem *item) const + + +int32 +BMenu::IndexOf(BMenuItem *item) const { return fItems.IndexOf(item); } -//------------------------------------------------------------------------------ -int32 BMenu::IndexOf(BMenu *submenu) const + + +int32 +BMenu::IndexOf(BMenu *submenu) const { - for (int32 i =0; i < fItems.CountItems(); i++) - if (((BMenuItem*)fItems.ItemAt(i))->Submenu() == submenu) + for (int32 i = 0; i < fItems.CountItems(); i++) + if (static_cast(fItems.ItemAt(i))->Submenu() == submenu) return i; return -1; } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::FindItem(const char *label) const + + +BMenuItem * +BMenu::FindItem(const char *label) const { BMenuItem *item; - for (int32 i =0; i < CountItems(); i++) - { + for (int32 i = 0; i < CountItems(); i++) { item = ItemAt(i); if (item->Label() && strcmp(item->Label(), label) == 0) - return (item); + return item; - if (item->Submenu()) - { + if (item->Submenu()) { item = item->Submenu()->FindItem(label); if (item) return item; @@ -427,22 +472,43 @@ BMenuItem *BMenu::FindItem(const char *label) const return NULL; } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::FindItem(uint32 command) const + + +BMenuItem * +BMenu::FindItem(uint32 command) const { + BMenuItem *item; + + for (int32 i = 0; i < CountItems(); i++) { + item = ItemAt(i); + + if (item->Command() == command) + return item; + + if (item->Submenu()) { + item = item->Submenu()->FindItem(command); + if (item) + return item; + } + } + return NULL; } -//------------------------------------------------------------------------------ -status_t BMenu::SetTargetForItems(BHandler *handler) + + +status_t +BMenu::SetTargetForItems(BHandler *handler) { for (int32 i = 0; i < fItems.CountItems(); i++) - if (((BMenuItem*)fItems.ItemAt(i))->SetTarget(handler) != B_OK) + if (static_cast(fItems.ItemAt(i))->SetTarget(handler) != B_OK) return B_ERROR; return B_OK; } -//------------------------------------------------------------------------------ -status_t BMenu::SetTargetForItems(BMessenger messenger) + + +status_t +BMenu::SetTargetForItems(BMessenger messenger) { for (int32 i = 0; i < fItems.CountItems (); i++) if (((BMenuItem*)fItems.ItemAt(i))->SetTarget(messenger) != B_OK) @@ -450,105 +516,135 @@ status_t BMenu::SetTargetForItems(BMessenger messenger) return B_OK; } -//------------------------------------------------------------------------------ -void BMenu::SetEnabled(bool enabled) + + +void +BMenu::SetEnabled(bool enabled) { fEnabled = enabled; for (int32 i = 0; i < CountItems(); i++) ItemAt(i)->SetEnabled(enabled); } -//------------------------------------------------------------------------------ -void BMenu::SetRadioMode(bool flag) + + +void +BMenu::SetRadioMode(bool flag) { fRadioMode = flag; } -//------------------------------------------------------------------------------ -void BMenu::SetTriggersEnabled(bool flag) + + +void +BMenu::SetTriggersEnabled(bool flag) { fTriggerEnabled = flag; } -//------------------------------------------------------------------------------ -void BMenu::SetMaxContentWidth(float width) + + +void +BMenu::SetMaxContentWidth(float width) { fMaxContentWidth = width; } -//------------------------------------------------------------------------------ -void BMenu::SetLabelFromMarked(bool flag) + + +void +BMenu::SetLabelFromMarked(bool flag) { + fDynamicName = flag; } -//------------------------------------------------------------------------------ -bool BMenu::IsLabelFromMarked() + + +bool +BMenu::IsLabelFromMarked() { - return false; + return fDynamicName; } -//------------------------------------------------------------------------------ -bool BMenu::IsEnabled() const + + +bool +BMenu::IsEnabled() const { return fEnabled; } -//------------------------------------------------------------------------------ -bool BMenu::IsRadioMode() const + + +bool +BMenu::IsRadioMode() const { return fRadioMode; } -//------------------------------------------------------------------------------ -bool BMenu::AreTriggersEnabled() const + + +bool +BMenu::AreTriggersEnabled() const { return fTriggerEnabled; } -//------------------------------------------------------------------------------ -bool BMenu::IsRedrawAfterSticky() const + + +bool +BMenu::IsRedrawAfterSticky() const { return fRedrawAfterSticky; } -//------------------------------------------------------------------------------ -float BMenu::MaxContentWidth() const + + +float +BMenu::MaxContentWidth() const { return fMaxContentWidth; } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::FindMarked() + + +BMenuItem * +BMenu::FindMarked() { - for (int i =0; i < fItems.CountItems(); i++) + for (int i = 0; i < fItems.CountItems(); i++) if (((BMenuItem*)fItems.ItemAt(i))->IsMarked()) return (BMenuItem*)fItems.ItemAt(i); return NULL; } -//------------------------------------------------------------------------------ -BMenu *BMenu::Supermenu() const + + +BMenu * +BMenu::Supermenu() const { return fSuper; } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::Superitem() const + + +BMenuItem * +BMenu::Superitem() const { return fSuperitem; } -//------------------------------------------------------------------------------ -void BMenu::MessageReceived(BMessage *msg) + + +void +BMenu::MessageReceived(BMessage *msg) { BView::MessageReceived(msg); } -//------------------------------------------------------------------------------ -void BMenu::KeyDown(const char *bytes, int32 numBytes) + + +void +BMenu::KeyDown(const char *bytes, int32 numBytes) { - switch (bytes[0]) - { + switch (bytes[0]) { case B_UP_ARROW: { - if (fSelected) - { + if (fSelected) { fSelected->fSelected = false; - if ( fSelected == fItems.FirstItem()) - fSelected = (BMenuItem*)fItems.LastItem(); + if (fSelected == fItems.FirstItem()) + fSelected = static_cast(fItems.LastItem()); else fSelected = ItemAt(IndexOf(fSelected) - 1); - } - else - fSelected = (BMenuItem*)fItems.LastItem(); + } else + fSelected = static_cast(fItems.LastItem()); fSelected->fSelected = true; @@ -556,17 +652,15 @@ void BMenu::KeyDown(const char *bytes, int32 numBytes) } case B_DOWN_ARROW: { - if (fSelected) - { + if (fSelected) { fSelected->fSelected = false; if (fSelected == fItems.LastItem()) - fSelected = (BMenuItem*)fItems.FirstItem(); + fSelected = static_cast(fItems.FirstItem()); else fSelected = ItemAt(IndexOf(fSelected) + 1); - } - else - fSelected = (BMenuItem*)fItems.FirstItem(); + } else + fSelected = static_cast(fItems.FirstItem()); fSelected->fSelected = true; @@ -577,7 +671,7 @@ void BMenu::KeyDown(const char *bytes, int32 numBytes) if (fSelected) fSelected->fSelected = false; - fSelected = (BMenuItem*)fItems.FirstItem(); + fSelected = static_cast(fItems.FirstItem()); fSelected->fSelected = true; break; @@ -587,7 +681,7 @@ void BMenu::KeyDown(const char *bytes, int32 numBytes) if (fSelected) fSelected->fSelected = false; - fSelected = (BMenuItem*)fItems.LastItem(); + fSelected = static_cast(fItems.LastItem()); fSelected->fSelected = true; break; @@ -604,52 +698,64 @@ void BMenu::KeyDown(const char *bytes, int32 numBytes) BView::KeyDown(bytes, numBytes); } } -//------------------------------------------------------------------------------ -void BMenu::Draw(BRect updateRect) -{ - BRect bounds(Bounds()); - SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_4_TINT)); - StrokeRect(bounds); - SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); - StrokeLine(BPoint(bounds.left + 2, bounds.bottom - 1), - BPoint(bounds.right - 1, bounds.bottom - 1)); - StrokeLine(BPoint(bounds.right - 1, bounds.top + 1)); - SetHighColor(tint_color ( ui_color ( B_MENU_BACKGROUND_COLOR ), B_LIGHTEN_2_TINT)); - StrokeLine(BPoint(bounds.right - 2, bounds.top + 1), - BPoint(bounds.left + 1, bounds.top + 1)); - StrokeLine(BPoint(bounds.left + 1, bounds.bottom - 2)); - DrawItems(updateRect); -} -//------------------------------------------------------------------------------ -void BMenu::GetPreferredSize(float *width, float *height) +void +BMenu::Draw(BRect updateRect) { + CALLED(); + DrawBackground(updateRect); + DrawItems(Bounds()); } -//------------------------------------------------------------------------------ -void BMenu::ResizeToPreferred() + + +void +BMenu::GetPreferredSize(float *width, float *height) { + CALLED(); + ComputeLayout(0, true, false, width, height); } -//------------------------------------------------------------------------------ -void BMenu::FrameMoved(BPoint new_position) + + +void +BMenu::ResizeToPreferred() { + CALLED(); + BView::ResizeToPreferred(); } -//------------------------------------------------------------------------------ -void BMenu::FrameResized(float new_width, float new_height) + + +void +BMenu::FrameMoved(BPoint new_position) { + CALLED(); + BView::FrameMoved(new_position); } -//------------------------------------------------------------------------------ -void BMenu::InvalidateLayout() + + +void +BMenu::FrameResized(float new_width, float new_height) { + CALLED(); + BView::FrameResized(new_width, new_height); +} + + +void +BMenu::InvalidateLayout() +{ + CALLED(); CacheFontInfo(); LayoutItems(0); } -//------------------------------------------------------------------------------ -BHandler *BMenu::ResolveSpecifier(BMessage *msg, int32 index, + + +BHandler * +BMenu::ResolveSpecifier(BMessage *msg, int32 index, BMessage *specifier, int32 form, const char *property) { - BPropertyInfo propInfo(prop_list); + BPropertyInfo propInfo(sPropList); BHandler *target = NULL; switch (propInfo.FindMatch(msg, 0, specifier, form, property)) @@ -689,8 +795,10 @@ BHandler *BMenu::ResolveSpecifier(BMessage *msg, int32 index, return target; } -//------------------------------------------------------------------------------ -status_t BMenu::GetSupportedSuites(BMessage *data) + + +status_t +BMenu::GetSupportedSuites(BMessage *data) { status_t err; @@ -699,39 +807,50 @@ status_t BMenu::GetSupportedSuites(BMessage *data) err = data->AddString("suites", "suite/vnd.Be-menu"); - if (err != B_OK) + if (err < B_OK) return err; - BPropertyInfo prop_info(prop_list); + BPropertyInfo prop_info(sPropList); err = data->AddFlat("messages", &prop_info); - if (err != B_OK) + if (err < B_OK) return err; return BView::GetSupportedSuites(data); } -//------------------------------------------------------------------------------ -status_t BMenu::Perform(perform_code d, void *arg) -{ - return B_ERROR; -} -//------------------------------------------------------------------------------ -void BMenu::MakeFocus(bool focused) -{ - if (focused) - SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); + +status_t +BMenu::Perform(perform_code d, void *arg) +{ + return BView::Perform(d, arg); +} + + +void +BMenu::MakeFocus(bool focused) +{ + CALLED(); BView::MakeFocus(focused); } -//------------------------------------------------------------------------------ -void BMenu::AllAttached() + + +void +BMenu::AllAttached() { + CALLED(); + BView::AllAttached(); } -//------------------------------------------------------------------------------ -void BMenu::AllDetached() + + +void +BMenu::AllDetached() { + CALLED(); + BView::AllDetached(); } -//------------------------------------------------------------------------------ + + BMenu::BMenu(BRect frame, const char *name, uint32 resizingMode, uint32 flags, menu_layout layout, bool resizeToFit) : BView(frame, name, resizingMode, flags), @@ -762,11 +881,13 @@ BMenu::BMenu(BRect frame, const char *name, uint32 resizingMode, uint32 flags, fRedrawAfterSticky(true), fAttachAborted(false) { - SetViewColor(ui_color(B_MENU_BACKGROUND_COLOR)); - SetFontSize(10); + CALLED(); + InitData(NULL); } -//------------------------------------------------------------------------------ -BPoint BMenu::ScreenLocation() + + +BPoint +BMenu::ScreenLocation() { BMenu *superMenu = Supermenu(); @@ -789,75 +910,162 @@ BPoint BMenu::ScreenLocation() return point; } -//------------------------------------------------------------------------------ -void BMenu::SetItemMargins(float left, float top, float right, float bottom) + + +void +BMenu::SetItemMargins(float left, float top, float right, float bottom) { fPad.Set(left, top, right, bottom); } -//------------------------------------------------------------------------------ -void BMenu::GetItemMargins(float *left, float *top, float *right, + + +void +BMenu::GetItemMargins(float *left, float *top, float *right, float *bottom) const { - *left = fPad.left; - *top = fPad.top; - *right = fPad.right; - *bottom = fPad.bottom; + if (left) + *left = fPad.left; + if (top) + *top = fPad.top; + if (right) + *right = fPad.right; + if (bottom) + *bottom = fPad.bottom; } -//------------------------------------------------------------------------------ -menu_layout BMenu::Layout() const + + +menu_layout +BMenu::Layout() const { + CALLED(); return fLayout; } -//------------------------------------------------------------------------------ -void BMenu::Show() + + +void +BMenu::Show() { + CALLED(); Show(false); } -//------------------------------------------------------------------------------ -void BMenu::Show(bool selectFirst) + + +void +BMenu::Show(bool selectFirst) { + CALLED(); _show(selectFirst); } -//------------------------------------------------------------------------------ -void BMenu::Hide() + + +void +BMenu::Hide() { + CALLED(); _hide(); } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::Track(bool openAnyway, BRect *clickToOpenRect) + + +BMenuItem * +BMenu::Track(bool openAnyway, BRect *clickToOpenRect) { - return NULL; + CALLED(); + if (IsStickyPrefOn()) + openAnyway = false; + + SetStickyMode(openAnyway); + + if (LockLooper()) { + RedrawAfterSticky(Bounds()); + UnlockLooper(); + } + + int action; + return BMenu::_track(&action, -1); } -//------------------------------------------------------------------------------ -bool BMenu::AddDynamicItem(add_state s) + + +bool +BMenu::AddDynamicItem(add_state s) { + // Not implemented return false; } -//------------------------------------------------------------------------------ -void BMenu::DrawBackground(BRect update) + + +void +BMenu::DrawBackground(BRect update) { + BRect bounds(Bounds()); + + rgb_color oldColor = HighColor(); + + SetHighColor(tint_color(sMenuInfo.background_color, B_DARKEN_4_TINT)); + StrokeRect(bounds); + SetHighColor(tint_color(sMenuInfo.background_color, B_DARKEN_2_TINT)); + StrokeLine(BPoint(bounds.left + 2, bounds.bottom - 1), + BPoint(bounds.right - 1, bounds.bottom - 1)); + StrokeLine(BPoint(bounds.right - 1, bounds.top + 1)); + SetHighColor(tint_color(sMenuInfo.background_color, B_LIGHTEN_2_TINT)); + StrokeLine(BPoint(bounds.right - 2, bounds.top + 1), + BPoint(bounds.left + 1, bounds.top + 1)); + StrokeLine(BPoint(bounds.left + 1, bounds.bottom - 2)); + + SetHighColor(oldColor); } -//------------------------------------------------------------------------------ -void BMenu::SetTrackingHook(menu_tracking_hook func, void *state) + + +void +BMenu::SetTrackingHook(menu_tracking_hook func, void *state) { + CALLED(); } -//------------------------------------------------------------------------------ + + void BMenu::_ReservedMenu3() {} void BMenu::_ReservedMenu4() {} void BMenu::_ReservedMenu5() {} void BMenu::_ReservedMenu6() {} -//------------------------------------------------------------------------------ -BMenu &BMenu::operator=(const BMenu &) + + +BMenu & +BMenu::operator=(const BMenu &) { return *this; } -//------------------------------------------------------------------------------ -void BMenu::InitData(BMessage *data) + + +void +BMenu::InitData(BMessage *data) { + BFont font; + font.SetFamilyAndStyle(sMenuInfo.f_family, sMenuInfo.f_style); + font.SetSize(sMenuInfo.font_size); + SetFont(&font); + + SetDrawingMode(B_OP_COPY); + SetViewColor(sMenuInfo.background_color); + + if (data) { + data->FindInt32("_layout", (int32 *)&fLayout); + data->FindBool("_rsize_to_fit", &fResizeToFit); + data->FindBool("_disable", &fEnabled); + data->FindBool("_radio", &fRadioMode); + + bool disableTrigger = false; + data->FindBool("_trig_disabled", &disableTrigger); + fTriggerEnabled = !disableTrigger; + + data->FindBool("_dyn_label", &fDynamicName); + data->FindFloat("_maxwidth", &fMaxContentWidth); + } } -//------------------------------------------------------------------------------ -bool BMenu::_show(bool selectFirstItem) + + +bool +BMenu::_show(bool selectFirstItem) { + CALLED(); BPoint point = ScreenLocation(); BWindow *window = new BMenuWindow(BRect(point.x, point.y, @@ -867,36 +1075,71 @@ bool BMenu::_show(bool selectFirstItem) return true; } -//------------------------------------------------------------------------------ -void BMenu::_hide() + + +void +BMenu::_hide() { + CALLED(); BWindow *window = Window(); - if (window) - { + if (window) { window->RemoveChild(this); - window->Lock(); window->Quit(); } } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::_track(int *action, long start) + + +BMenuItem * +BMenu::_track(int *action, long start) { - return NULL; + CALLED(); + BPoint location; + ulong buttons; + BMenuItem *item = NULL; + + do { + if (LockLooper()) { + GetMouse(&location, &buttons); + item = HitTestItems(location); + + if (item && fSelected != item) { + SelectItem(item); + /*if (fSelected) + fSelected->Select(false); + fSelected = item; + item->Select(true); + */ + Invalidate(); + Window()->UpdateIfNeeded(); + } + + UnlockLooper(); + } + snooze(50000); + } while (buttons != 0); + + return item; } -//------------------------------------------------------------------------------ -bool BMenu::_AddItem(BMenuItem *item, int32 index) + + +bool +BMenu::_AddItem(BMenuItem *item, int32 index) { return false; } -//------------------------------------------------------------------------------ -bool BMenu::RemoveItems(int32 index, int32 count, BMenuItem *item, bool del) + + +bool +BMenu::RemoveItems(int32 index, int32 count, BMenuItem *item, bool del) { return false; } -//------------------------------------------------------------------------------ -void BMenu::LayoutItems(int32 index) + + +void +BMenu::LayoutItems(int32 index) { CalcTriggers(); @@ -906,21 +1149,21 @@ void BMenu::LayoutItems(int32 index) ResizeTo(width, height); } -//------------------------------------------------------------------------------ -void BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems, + + +void +BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems, float* width, float* height) { BRect frame; float iWidth, iHeight; BMenuItem *item; - if (fLayout == B_ITEMS_IN_COLUMN) - { + if (fLayout == B_ITEMS_IN_COLUMN) { frame = BRect(0.0f, 0.0f, 0.0f, 2.0f); - for (int i = 0; i < fItems.CountItems(); i++) - { - item = (BMenuItem*)fItems.ItemAt(i); + for (int i = 0; i < fItems.CountItems(); i++) { + item = static_cast(fItems.ItemAt(i)); item->GetContentSize(&iWidth, &iHeight); @@ -940,17 +1183,15 @@ void BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems, frame.right = (float)ceil(frame.right) + 2.0f; frame.bottom += 1.0f; - } - else if (fLayout == B_ITEMS_IN_ROW) - { + + } else if (fLayout == B_ITEMS_IN_ROW) { font_height fh; GetFontHeight(&fh); frame = BRect(0.0f, 0.0f, 0.0f, (float)ceil(fh.ascent) + (float)ceil(fh.descent) + fPad.top + fPad.bottom); - for (int i = 0; i < fItems.CountItems(); i++) - { - item = (BMenuItem*)fItems.ItemAt(i); + for (int i = 0; i < fItems.CountItems(); i++) { + item = static_cast(fItems.ItemAt(i)); item->GetContentSize(&iWidth, &iHeight); @@ -968,62 +1209,84 @@ void BMenu::ComputeLayout(int32 index, bool bestFit, bool moveItems, frame.right = (float)ceil(frame.right) + 8.0f; } - if ((ResizingMode() & B_FOLLOW_LEFT_RIGHT) == B_FOLLOW_LEFT_RIGHT) - { + if ((ResizingMode() & B_FOLLOW_LEFT_RIGHT) == B_FOLLOW_LEFT_RIGHT) { if (Parent()) *width = Parent()->Frame().Width() + 1.0f; else *width = Window()->Frame().Width() + 1.0f; *height = frame.Height(); - } - else - { + } else { *width = frame.Width(); *height = frame.Height(); } } -//------------------------------------------------------------------------------ -BRect BMenu::Bump(BRect current, BPoint extent, int32 index) const + + +BRect +BMenu::Bump(BRect current, BPoint extent, int32 index) const { + CALLED(); return BRect(); } -//------------------------------------------------------------------------------ -BPoint BMenu::ItemLocInRect(BRect frame) const + + +BPoint +BMenu::ItemLocInRect(BRect frame) const { + CALLED(); return BPoint(); } -//------------------------------------------------------------------------------ -BRect BMenu::CalcFrame(BPoint where, bool *scrollOn) + + +BRect +BMenu::CalcFrame(BPoint where, bool *scrollOn) { + CALLED(); return BRect(); } -//------------------------------------------------------------------------------ -bool BMenu::ScrollMenu(BRect bounds, BPoint loc, bool *fast) + + +bool +BMenu::ScrollMenu(BRect bounds, BPoint loc, bool *fast) { + CALLED(); return false; } -//------------------------------------------------------------------------------ -void BMenu::ScrollIntoView(BMenuItem *item) + + +void +BMenu::ScrollIntoView(BMenuItem *item) { + CALLED(); } -//------------------------------------------------------------------------------ -void BMenu::DrawItems(BRect updateRect) + + +void +BMenu::DrawItems(BRect updateRect) { - for (int i =0; i < fItems.CountItems(); i++) - { - if (ItemAt(i)->Frame().Intersects(updateRect)) + CALLED(); + for (int i = 0; i < fItems.CountItems(); i++) { + if (ItemAt(i)->Frame().Intersects(updateRect)) { ItemAt(i)->Draw(); + } } + Sync(); } -//------------------------------------------------------------------------------ -int BMenu::State(BMenuItem **item) const + + +int +BMenu::State(BMenuItem **item) const { + CALLED(); return 0; } -//------------------------------------------------------------------------------ -void BMenu::InvokeItem(BMenuItem *item, bool now) + + +void +BMenu::InvokeItem(BMenuItem *item, bool now) { + CALLED(); if (item->Submenu()) item->Submenu()->Show(); else if (IsRadioMode()) @@ -1031,63 +1294,89 @@ void BMenu::InvokeItem(BMenuItem *item, bool now) item->Invoke(); } -//------------------------------------------------------------------------------ -bool BMenu::OverSuper(BPoint loc) + + +bool +BMenu::OverSuper(BPoint loc) { + CALLED(); // TODO: we assume that loc is in screen coords if (!Supermenu()) return false; return Supermenu()->Window()->Frame().Contains(loc); } -//------------------------------------------------------------------------------ -bool BMenu::OverSubmenu(BMenuItem *item, BPoint loc) + + +bool +BMenu::OverSubmenu(BMenuItem *item, BPoint loc) { + CALLED(); // TODO: we assume that loc is in screen coords if (!item->Submenu()) return false; return item->Submenu()->Window()->Frame().Contains(loc); } -//------------------------------------------------------------------------------ -BMenuWindow *BMenu::MenuWindow() + + +BMenuWindow * +BMenu::MenuWindow() { + CALLED(); return fCachedMenuWindow; } -//------------------------------------------------------------------------------ -void BMenu::DeleteMenuWindow() + + +void +BMenu::DeleteMenuWindow() { + CALLED(); delete fCachedMenuWindow; fCachedMenuWindow = NULL; } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::HitTestItems(BPoint where, BPoint slop) const + + +BMenuItem * +BMenu::HitTestItems(BPoint where, BPoint slop) const { - for (int i =0; i < CountItems(); i++) + CALLED(); + for (int i = 0; i < CountItems(); i++) if (ItemAt(i)->fBounds.Contains(where)) return ItemAt(i); return NULL; } -//------------------------------------------------------------------------------ -BRect BMenu::Superbounds() const + + +BRect +BMenu::Superbounds() const { + CALLED(); + if (fSuper) + return fSuper->Bounds(); + return BRect(); } -//------------------------------------------------------------------------------ -void BMenu::CacheFontInfo() + + +void +BMenu::CacheFontInfo() { + CALLED(); font_height fh; GetFontHeight(&fh); fAscent = fh.ascent; fDescent = fh.descent; fFontHeight = (float)ceil(fh.ascent + fh.descent + 0.5f); } -//------------------------------------------------------------------------------ -void BMenu::ItemMarked(BMenuItem *item) + + +void +BMenu::ItemMarked(BMenuItem *item) { - if (IsRadioMode()) - { + CALLED(); + if (IsRadioMode()) { for (int32 i = 0; i < CountItems(); i++) if (ItemAt(i) != item) ItemAt(i)->SetMarked(false); @@ -1096,183 +1385,202 @@ void BMenu::ItemMarked(BMenuItem *item) if (IsLabelFromMarked() && Superitem()) Superitem()->SetLabel(item->Label()); } -//------------------------------------------------------------------------------ -void BMenu::Install(BWindow *target) + + +void +BMenu::Install(BWindow *target) { - for (int i =0; i < CountItems(); i++) + CALLED(); + for (int32 i = 0; i < CountItems(); i++) ItemAt(i)->Install(target); } -//------------------------------------------------------------------------------ -void BMenu::Uninstall() + + +void +BMenu::Uninstall() { + CALLED(); + for (int32 i = 0; i < CountItems(); i++) + ItemAt(i)->Uninstall(); } -//------------------------------------------------------------------------------ -void BMenu::SelectItem(BMenuItem *m, uint32 showSubmenu,bool selectFirstItem) + + +void +BMenu::SelectItem(BMenuItem *m, uint32 showSubmenu,bool selectFirstItem) { + CALLED(); } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::CurrentSelection() const + + +BMenuItem * +BMenu::CurrentSelection() const { + CALLED(); return fSelected; } -//------------------------------------------------------------------------------ -bool BMenu::SelectNextItem(BMenuItem *item, bool forward) + + +bool +BMenu::SelectNextItem(BMenuItem *item, bool forward) { + CALLED(); return false; } -//------------------------------------------------------------------------------ -BMenuItem *BMenu::NextItem(BMenuItem *item, bool forward) const + + +BMenuItem * +BMenu::NextItem(BMenuItem *item, bool forward) const { + CALLED(); return NULL; } -//------------------------------------------------------------------------------ -bool BMenu::IsItemVisible(BMenuItem *item) const + + +bool +BMenu::IsItemVisible(BMenuItem *item) const { + CALLED(); return false; } -//------------------------------------------------------------------------------ -void BMenu::SetIgnoreHidden(bool on) + + +void +BMenu::SetIgnoreHidden(bool on) { + CALLED(); fIgnoreHidden = on; } -//------------------------------------------------------------------------------ -void BMenu::SetStickyMode(bool on) + + +void +BMenu::SetStickyMode(bool on) { fStickyMode = on; } -//------------------------------------------------------------------------------ -bool BMenu::IsStickyMode() const + + +bool +BMenu::IsStickyMode() const { return fStickyMode; } -//------------------------------------------------------------------------------ -void BMenu::CalcTriggers() + + +void +BMenu::CalcTriggers() { + CALLED(); } -//------------------------------------------------------------------------------ -const char *BMenu::ChooseTrigger(const char *title, BList *chars) + + +const char * +BMenu::ChooseTrigger(const char *title, BList *chars) { + CALLED(); return NULL; } -//------------------------------------------------------------------------------ -void BMenu::UpdateWindowViewSize(bool upWind) + + +void +BMenu::UpdateWindowViewSize(bool upWind) { + CALLED(); } -//------------------------------------------------------------------------------ -bool BMenu::IsStickyPrefOn() + + +bool +BMenu::IsStickyPrefOn() +{ + return sMenuInfo.click_to_open; +} + + +void +BMenu::RedrawAfterSticky(BRect bounds) +{ + CALLED(); +} + + +bool +BMenu::OkToProceed(BMenuItem *) { return false; } -//------------------------------------------------------------------------------ -void BMenu::RedrawAfterSticky(BRect bounds) -{ -} -//------------------------------------------------------------------------------ -bool BMenu::OkToProceed(BMenuItem *) -{ - return false; -} -//------------------------------------------------------------------------------ -status_t BMenu::ParseMsg(BMessage *msg, int32 *sindex, BMessage *spec, + + +status_t +BMenu::ParseMsg(BMessage *msg, int32 *sindex, BMessage *spec, int32 *form, const char **prop, BMenu **tmenu, BMenuItem **titem, int32 *user_data, BMessage *reply) const { return B_ERROR; } -//------------------------------------------------------------------------------ -status_t BMenu::DoMenuMsg(BMenuItem **next, BMenu *tar, BMessage *m, + + +status_t +BMenu::DoMenuMsg(BMenuItem **next, BMenu *tar, BMessage *m, BMessage *r, BMessage *spec, int32 f) const { return B_ERROR; } -//------------------------------------------------------------------------------ -status_t BMenu::DoMenuItemMsg(BMenuItem **next, BMenu *tar, BMessage *m, + + +status_t +BMenu::DoMenuItemMsg(BMenuItem **next, BMenu *tar, BMessage *m, BMessage *r, BMessage *spec, int32 f) const { return B_ERROR; } -//------------------------------------------------------------------------------ -status_t BMenu::DoEnabledMsg(BMenuItem *ti, BMenu *tm, BMessage *m, + + +status_t +BMenu::DoEnabledMsg(BMenuItem *ti, BMenu *tm, BMessage *m, BMessage *r) const { return B_ERROR; } -//------------------------------------------------------------------------------ -status_t BMenu::DoLabelMsg(BMenuItem *ti, BMenu *tm, BMessage *m, + + +status_t +BMenu::DoLabelMsg(BMenuItem *ti, BMenu *tm, BMessage *m, BMessage *r) const { return B_ERROR; } -//------------------------------------------------------------------------------ -status_t BMenu::DoMarkMsg(BMenuItem *ti, BMenu *tm, BMessage *m, + + +status_t +BMenu::DoMarkMsg(BMenuItem *ti, BMenu *tm, BMessage *m, BMessage *r) const { return B_ERROR; } -//------------------------------------------------------------------------------ -status_t BMenu::DoDeleteMsg(BMenuItem *ti, BMenu *tm, BMessage *m, + + +status_t +BMenu::DoDeleteMsg(BMenuItem *ti, BMenu *tm, BMessage *m, BMessage *r) const { return B_ERROR; } -//------------------------------------------------------------------------------ -status_t BMenu::DoCreateMsg(BMenuItem *ti, BMenu *tm, BMessage *m, + + +status_t +BMenu::DoCreateMsg(BMenuItem *ti, BMenu *tm, BMessage *m, BMessage *r, bool menu) const { return B_ERROR; } -//------------------------------------------------------------------------------ - -// Temporary mouse hooks -#if 0 -//------------------------------------------------------------------------------ -void BMenu::MouseDown(BPoint point) +status_t +set_menu_info(menu_info *info) { - BMenuItem *item = HitTestItems(point); - - if (item) - InvokeItem(item); - - Hide(); -} -//------------------------------------------------------------------------------ -void BMenu::MouseMoved(BPoint point, uint32 transit, const BMessage *message) -{ - BMenuItem *item = HitTestItems(point); - - if (fSelected) - { - if (fSelected == item) - return; + if (!info) + return B_BAD_VALUE; - fSelected->fSelected = false; - //if (fSelected->Submenu()) - // fSelected->Submenu()->Hide(); - Invalidate(fSelected->Frame()); - } - - fSelected = item; - - if (fSelected) - { - fSelected->fSelected = true; - //if (fSelected->Submenu()) - // fSelected->Submenu()->Show(); - Invalidate(fSelected->Frame()); - } -} -//------------------------------------------------------------------------------ -void BMenu::MouseUp(BPoint point) -{ - -} -#endif -//------------------------------------------------------------------------------ -status_t set_menu_info(menu_info *info) -{ BPath path; if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) @@ -1286,34 +1594,20 @@ status_t set_menu_info(menu_info *info) return B_OK; file.Write(info, sizeof(menu_info)); + + BMenu::sMenuInfo = *info; return B_OK; } -//------------------------------------------------------------------------------ -status_t get_menu_info(menu_info *info) + + +status_t +get_menu_info(menu_info *info) { - info->font_size = 8; - memcpy(info->f_family, "Arial", 6); - memcpy(info->f_style, "Regular", 8); - info->background_color = ui_color(B_MENU_BACKGROUND_COLOR); - info->separator = 0; - info->click_to_open = true; - info->triggers_always_shown = false; - - BPath path; - - if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) - return B_OK; - - path.Append("menu_settings"); - - BFile file(path.Path(), B_READ_ONLY); - - if (file.InitCheck() != B_OK) - return B_OK; - - file.Read(info, sizeof(menu_info)); - + if (!info) + return B_BAD_VALUE; + + *info = BMenu::sMenuInfo; + return B_OK; } -//------------------------------------------------------------------------------