diff --git a/headers/private/interface/BMCPrivate.h b/headers/private/interface/BMCPrivate.h new file mode 100644 index 0000000000..a28af7ed5b --- /dev/null +++ b/headers/private/interface/BMCPrivate.h @@ -0,0 +1,109 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: BMCPrivate.h +// Author: Marc Flerackers (mflerackers@androme.be) +// Description: The BMCPrivate classes are used by BMenuField. +//------------------------------------------------------------------------------ + +#ifndef _BMC_PRIVATE_H +#define _BMC_PRIVATE_H + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- +#include +#include +#include + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +class _BMCItem_ : public BMenuItem { + +public: + _BMCItem_(BMenu *menu); + _BMCItem_(BMessage *message); +virtual ~_BMCItem_(); + +static BArchivable *Instantiate(BMessage *data); + + void Draw(); + void GetContentSize(float *width, float *height); + +private: +friend class BMenuField; + + bool fShowPopUpMarker; +}; +//------------------------------------------------------------------------------ + +/*//------------------------------------------------------------------------------ +_BMCFilter_::_BMCFilter_(BMenuField *menuField, uint32) +{ +} +//------------------------------------------------------------------------------ +_BMCFilter_::~_BMCFilter_() +{ +} +//------------------------------------------------------------------------------ +filter_result _BMCFilter_::Filter(BMessage *message, BHandler **handler) +{ +} +//------------------------------------------------------------------------------ +_BMCFilter_ &_BMCFilter_::operator=(const _BMCFilter_ &) +{ + return *this; +} +//------------------------------------------------------------------------------*/ + +//------------------------------------------------------------------------------ +class _BMCMenuBar_ : public BMenuBar { + +public: + _BMCMenuBar_(BRect frame, bool fixed_size, + BMenuField *menuField); + _BMCMenuBar_(BMessage *data); +virtual ~_BMCMenuBar_(); + +static BArchivable *Instantiate(BMessage *data); + +virtual void AttachedToWindow(); +virtual void FrameResized(float width, float height); +virtual void MessageReceived(BMessage* msg); +virtual void MakeFocus(bool focused = true); + +private: + _BMCMenuBar_&operator=(const _BMCMenuBar_ &); + + BMenuField *fMenuField; + bool fFixedSize; + BMessageRunner *fRunner; +}; +//------------------------------------------------------------------------------ + +#endif // _BMC_PRIVATE_H diff --git a/src/kits/interface/BMCPrivate.cpp b/src/kits/interface/BMCPrivate.cpp new file mode 100644 index 0000000000..3b04285cda --- /dev/null +++ b/src/kits/interface/BMCPrivate.cpp @@ -0,0 +1,237 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: BMCPrivate.cpp +// Author: Marc Flerackers (mflerackers@androme.be) +// Description: The BMCPrivate classes are used by BMenuField. +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- +#include +#include +#include +#include +#include + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + +//------------------------------------------------------------------------------ +_BMCItem_::_BMCItem_(BMenu *menu) + : BMenuItem(menu), + fShowPopUpMarker(true) +{ +} +//------------------------------------------------------------------------------ +_BMCItem_::_BMCItem_(BMessage *message) + : BMenuItem(message), + fShowPopUpMarker(true) +{ +} +//------------------------------------------------------------------------------ +_BMCItem_::~_BMCItem_() +{ +} +//------------------------------------------------------------------------------ +BArchivable *_BMCItem_::Instantiate(BMessage *data) +{ + if (validate_instantiation(data, "_BMCItem_")) + return new _BMCItem_(data); + else + return NULL; +} +//------------------------------------------------------------------------------ +void _BMCItem_::Draw() +{ + BMenuItem::Draw(); + + if (!fShowPopUpMarker) + return; + + BMenu *menu = Menu(); + BRect rect(menu->Bounds()); + + rect.right -= 4; + rect.bottom -= 5; + rect.left = rect.right - 4; + rect.top = rect.bottom - 2; + + if (IsEnabled()) + menu->SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), + B_DARKEN_4_TINT)); + else + menu->SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), + B_DARKEN_4_TINT)); + + menu->StrokeLine(BPoint(rect.left, rect.top), BPoint(rect.right, rect.top)); + menu->StrokeLine(BPoint(rect.left + 1.0f, rect.top + 1.0f), + BPoint(rect.right - 1.0f, rect.top + 1.0f)); + menu->StrokeLine(BPoint(rect.left + 2.0f, rect.bottom), + BPoint(rect.left + 2.0f, rect.bottom)); +} +//------------------------------------------------------------------------------ +void _BMCItem_::GetContentSize(float *width, float *height) +{ + BMenuItem::GetContentSize(width, height); +} +//------------------------------------------------------------------------------ +/*_BMCFilter_::_BMCFilter_(BMenuField *menuField, uint32) +{ +} +//------------------------------------------------------------------------------ +_BMCFilter_::~_BMCFilter_() +{ +} +//------------------------------------------------------------------------------ +filter_result _BMCFilter_::Filter(BMessage *message, BHandler **handler) +{ +} +//------------------------------------------------------------------------------ +_BMCFilter_ &_BMCFilter_::operator=(const _BMCFilter_ &) +{ + return *this; +}*/ +//------------------------------------------------------------------------------ +_BMCMenuBar_::_BMCMenuBar_(BRect frame, bool fixed_size, BMenuField *menuField) + : BMenuBar(frame, "_mc_mb_", B_FOLLOW_LEFT | B_FOLLOW_TOP, B_ITEMS_IN_ROW, + !fixed_size) +{ + SetFlags(Flags() | B_FRAME_EVENTS); + SetBorder(B_BORDER_CONTENTS); + + + fMenuField = menuField; + fFixedSize = fixed_size; + fRunner = NULL; + + float left, top, right, bottom; + + GetItemMargins(&left, &top, &right, &bottom); + SetItemMargins(left, top, right, bottom); // TODO: + + SetMaxContentWidth(frame.Width() - (left + right)); +} +//------------------------------------------------------------------------------ +_BMCMenuBar_::_BMCMenuBar_(BMessage *data) + : BMenuBar(data) +{ + SetFlags(Flags() | B_FRAME_EVENTS); + + bool rsize_to_fit; + + if (data->FindBool("_rsize_to_fit", &rsize_to_fit) == B_OK) + fFixedSize = !rsize_to_fit; + else + fFixedSize = true; +} +//------------------------------------------------------------------------------ +_BMCMenuBar_::~_BMCMenuBar_() +{ +} +//------------------------------------------------------------------------------ +BArchivable *_BMCMenuBar_::Instantiate(BMessage *data) +{ + if (validate_instantiation(data, "_BMCMenuBar_")) + return new _BMCMenuBar_(data); + else + return NULL; +} +//------------------------------------------------------------------------------ +void _BMCMenuBar_::AttachedToWindow() +{ + fMenuField = (BMenuField*)Parent(); + + BMenuBar *menuBar = Window()->KeyMenuBar(); + BMenuBar::AttachedToWindow(); + Window()->SetKeyMenuBar(menuBar); +} +//------------------------------------------------------------------------------ +void _BMCMenuBar_::FrameResized(float width, float height) +{ + // TODO: + BMenuBar::FrameResized(width, height); +} +//------------------------------------------------------------------------------ +void _BMCMenuBar_::MessageReceived(BMessage *msg) +{ + if (msg->what == 'TICK') + { + BMenuItem *item = ItemAt(0); + + if (item && item->Submenu() && item->Submenu()->Window()) + { + BMessage message(B_KEY_DOWN); + + message.AddInt8("byte", B_ESCAPE); + message.AddInt8("key", B_ESCAPE); + message.AddInt32("modifiers", 0); + message.AddInt8("raw_char", B_ESCAPE); + + Window()->PostMessage(&message, this, NULL); + } + } + + BMenuBar::MessageReceived(msg); +} +//------------------------------------------------------------------------------ +void _BMCMenuBar_::MakeFocus(bool focused) +{ + if (IsFocus() == focused) + return; + + BMenuBar::MakeFocus(focused); + + if (focused) + { + BMessage message('TICK'); + //fRunner = new BMessageRunner(BMessenger(this, NULL, NULL), &message, + // 50000, -1); + } + else if (fRunner) + { + //delete fRunner; + fRunner = NULL; + } + + if (focused) + return; + + fMenuField->fSelected = false; + fMenuField->fTransition = true; + + BRect bounds(fMenuField->Bounds()); + + fMenuField->Draw(BRect(bounds.left, bounds.top, fMenuField->fDivider, + bounds.bottom)); +} +//------------------------------------------------------------------------------ +_BMCMenuBar_ &_BMCMenuBar_::operator=(const _BMCMenuBar_ &) +{ + return *this; +} +//------------------------------------------------------------------------------ diff --git a/src/kits/interface/MenuField.cpp b/src/kits/interface/MenuField.cpp new file mode 100644 index 0000000000..a817719d40 --- /dev/null +++ b/src/kits/interface/MenuField.cpp @@ -0,0 +1,594 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: MenuField.cpp +// Author: Marc Flerackers (mflerackers@androme.be) +// Description: BMenuField displays a labeled pop-up menu. +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- + +// System Includes ------------------------------------------------------------- +#include +#include +#include +#include +#include + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- +static float kVMargin = 2.0f; + +//------------------------------------------------------------------------------ +BMenuField::BMenuField(BRect frame, const char *name, const char *label, + BMenu *menu, uint32 resize, uint32 flags) + : BView(frame, name, resize, flags) +{ + InitObject(label); + SetFont(be_plain_font); + fMenu = menu; + InitMenu(menu); + + frame.OffsetTo(0.0f, 0.0f); + fMenuBar = new _BMCMenuBar_(BRect(frame.left + fDivider + 2.0f, + frame.top + kVMargin, frame.right - 2.0f, frame.bottom - kVMargin), + false, this); + + AddChild(fMenuBar); + fMenuBar->AddItem(menu); + + fMenuBar->SetFont(be_plain_font); + + InitObject2(); +} +//------------------------------------------------------------------------------ +BMenuField::BMenuField(BRect frame, const char *name, const char *label, + BMenu *menu, bool fixed_size, uint32 resize, + uint32 flags) + : BView(frame, name, resize, flags) +{ + InitObject(label); + SetFont(be_plain_font); + fMenu = menu; + InitMenu(menu); + + fFixedSizeMB = fixed_size; + + frame.OffsetTo(0.0f, 0.0f); + fMenuBar = new _BMCMenuBar_(BRect(frame.left + fDivider + 2.0f, + frame.top + kVMargin, frame.right - 2.0f, frame.bottom - kVMargin), + fixed_size, this); + + AddChild(fMenuBar); + fMenuBar->AddItem(new _BMCItem_(menu)); + + fMenuBar->SetFont(be_plain_font); + + InitObject2(); +} +//------------------------------------------------------------------------------ +BMenuField::BMenuField(BMessage *data) + : BView(data) +{ + const char *label = NULL; + + data->FindString("_label", &label); + + InitObject(label); + + fMenuBar = (BMenuBar*)FindView("_mc_mb_"); + fMenu = fMenuBar->SubmenuAt(0); + + InitObject2(); + + bool disable; + + if (data->FindBool("_disable", &disable) == B_OK) + SetEnabled(!disable); + + int32 align; + + data->FindInt32("_align", &align); + SetAlignment((alignment)align); + + data->FindFloat("_divide", &fDivider); + + bool fixed; + + if (data->FindBool("be:fixeds", &fixed) == B_OK) + fFixedSizeMB = fixed; + + BMenuItem *item = fMenuBar->ItemAt(0); + + if (!item) + return; + + _BMCItem_ *bmcitem = dynamic_cast<_BMCItem_*>(item); + + if (!bmcitem) + return; + + bool dmark; + + if (data->FindBool("be:dmark", &dmark)) + bmcitem->fShowPopUpMarker = dmark; +} +//------------------------------------------------------------------------------ +BMenuField::~BMenuField() +{ + if (fLabel) + free(fLabel); + + if (fMenuTaskID >= 0) + kill_thread(fMenuTaskID); +} +//------------------------------------------------------------------------------ +BArchivable *BMenuField::Instantiate(BMessage *data) +{ + if (validate_instantiation(data, "BMenuField")) + return new BMenuField(data); + else + return NULL; +} +//------------------------------------------------------------------------------ +status_t BMenuField::Archive(BMessage *data, bool deep) const +{ + BView::Archive(data, deep); + + if (Label()) + data->AddString("_label", Label()); + + if (!IsEnabled()) + data->AddBool("_disable", true); + + data->AddInt32("_align", Alignment()); + + data->AddFloat("_divide", Divider()); + + if (fFixedSizeMB) + data->AddBool("be:fixeds", true); + + BMenuItem *item = fMenuBar->ItemAt(0); + + if (!item) + return B_OK; + + _BMCItem_ *bmcitem = dynamic_cast<_BMCItem_*>(item); + + if (bmcitem && !bmcitem->fShowPopUpMarker) + data->AddBool("be:dmark", false); + + return B_OK; +} +//------------------------------------------------------------------------------ +void BMenuField::Draw(BRect update) +{ + BRect bounds(Bounds()); + bool active = false; + + if (IsFocus()) + active = Window()->IsActive(); + + /* + SetHighColor(0, 255, 0); + FillRect(bounds); + */ + + DrawLabel(bounds, update); + + BRect frame(fMenuBar->Frame()); + //rgb_color color = HighColor(); + + if (frame.InsetByCopy(-2, -2).Intersects(update)) + { + SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); + StrokeLine(BPoint(frame.left - 1.0f, frame.top - 1.0f), + BPoint(frame.left - 1.0f, frame.bottom - 1.0f)); + StrokeLine(BPoint(frame.left - 1.0f, frame.top - 1.0f), + BPoint(frame.right - 1.0f, frame.top - 1.0f)); + + StrokeLine(BPoint(frame.left + 1.0f, frame.bottom + 1.0f), + BPoint(frame.right + 1.0f, frame.bottom + 1.0f)); + StrokeLine(BPoint(frame.right + 1.0f, frame.top + 1.0f)); + + SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_4_TINT)); + StrokeLine(BPoint(frame.left - 1.0f, frame.bottom), + BPoint(frame.left - 1.0f, frame.bottom)); + StrokeLine(BPoint(frame.right, frame.top - 1.0f), + BPoint(frame.right, frame.top - 1.0f)); + + } + + if (active || fTransition) + { + SetHighColor(active ? ui_color(B_KEYBOARD_NAVIGATION_COLOR) : + ViewColor()); + StrokeRect(frame.InsetByCopy(-kVMargin, -kVMargin)); + + fTransition = false; + } +} +//------------------------------------------------------------------------------ +void BMenuField::AttachedToWindow() +{ + if (Parent()) + { + SetViewColor(Parent()->ViewColor()); + SetLowColor(Parent()->ViewColor()); + } + + if (fLabel) + fStringWidth = StringWidth(fLabel); +} +//------------------------------------------------------------------------------ +void BMenuField::AllAttached() +{ + ResizeTo(Bounds().Width(), + fMenuBar->Bounds().Height() + kVMargin + kVMargin); +} +//------------------------------------------------------------------------------ +void BMenuField::MouseDown(BPoint where) +{ + if (where.x > fDivider && !fMenuBar->Frame().Contains(where)) + return; + + BRect bounds(Bounds()); + + fMenuBar->StartMenuBar(0, false, true, + &fMenuBar->ConvertFromParent(bounds)); + + fMenuTaskID = spawn_thread((thread_func)MenuTask, "_m_task_", + B_NORMAL_PRIORITY, this); + + if (fMenuTaskID) + resume_thread(fMenuTaskID); +} +//------------------------------------------------------------------------------ +void BMenuField::KeyDown(const char *bytes, int32 numBytes) +{ + switch (bytes[0]) + { + case B_SPACE: + case B_RIGHT_ARROW: + case B_DOWN_ARROW: + { + BRect bounds(Bounds()); + + fMenuBar->StartMenuBar(0, true, true, + &fMenuBar->ConvertFromParent(bounds)); + + fSelected = true; + fTransition = true; + + bounds = Bounds(); + bounds.right = fDivider; + + Draw(bounds); + } + default: + BView::KeyDown(bytes, numBytes); + } +} +//------------------------------------------------------------------------------ +void BMenuField::MakeFocus(bool state) +{ + if (IsFocus() == state) + return; + + BView::MakeFocus(state); + + if(Window()) + Draw(Bounds()); // TODO: use fStringWidth +} +//------------------------------------------------------------------------------ +void BMenuField::MessageReceived(BMessage *msg) +{ + BView::MessageReceived(msg); +} +//------------------------------------------------------------------------------ +void BMenuField::WindowActivated(bool state) +{ + BView::WindowActivated(state); + + if (IsFocus()) + Draw(Bounds()); +} +//------------------------------------------------------------------------------ +void BMenuField::MouseUp(BPoint pt) +{ + BView::MouseUp(pt); +} +//------------------------------------------------------------------------------ +void BMenuField::MouseMoved(BPoint pt, uint32 code, const BMessage *msg) +{ + BView::MouseMoved(pt, code, msg); +} +//------------------------------------------------------------------------------ +void BMenuField::DetachedFromWindow() +{ + BView::DetachedFromWindow(); +} +//------------------------------------------------------------------------------ +void BMenuField::AllDetached() +{ + BView::AllDetached(); +} +//------------------------------------------------------------------------------ +void BMenuField::FrameMoved(BPoint new_position) +{ + BView::FrameMoved(new_position); +} +//------------------------------------------------------------------------------ +void BMenuField::FrameResized(float new_width, float new_height) +{ + BView::FrameResized(new_width, new_height); +} +//------------------------------------------------------------------------------ +BMenu *BMenuField::Menu() const +{ + return fMenu; +} +//------------------------------------------------------------------------------ +BMenuBar *BMenuField::MenuBar() const +{ + return fMenuBar; +} +//------------------------------------------------------------------------------ +BMenuItem *BMenuField::MenuItem() const +{ + return fMenuBar->ItemAt(0); +} +//------------------------------------------------------------------------------ +void BMenuField::SetLabel(const char *label) +{ + if (fLabel) + { + if (label && strcmp(fLabel, label) == 0) + return; + + free(fLabel); + } + + fLabel = strdup(label); + + if (Window()) + { + Invalidate(); + if (fLabel) + fStringWidth = StringWidth(fLabel); + } +} +//------------------------------------------------------------------------------ +const char *BMenuField::Label() const +{ + return fLabel; +} +//------------------------------------------------------------------------------ +void BMenuField::SetEnabled(bool on) +{ + if (fEnabled == on) + return; + + fEnabled = on; + fMenuBar->SetEnabled(on); + + if (Window()) + { + fMenuBar->Invalidate(fMenuBar->Bounds()); + Invalidate(Bounds()); + } +} +//------------------------------------------------------------------------------ +bool BMenuField::IsEnabled() const +{ + return fEnabled; +} +//------------------------------------------------------------------------------ +void BMenuField::SetAlignment(alignment label) +{ + fAlign = label; +} +//------------------------------------------------------------------------------ +alignment BMenuField::Alignment() const +{ + return fAlign; +} +//------------------------------------------------------------------------------ +void BMenuField::SetDivider(float dividing_line) +{ + if (fDivider - dividing_line == 0.0f) + return; + + MenuBar()->MoveBy(dividing_line - fDivider, 0.0f); + MenuBar()->ResizeBy(fDivider - dividing_line, 0.0f); + + fDivider = dividing_line; +} +//------------------------------------------------------------------------------ +float BMenuField::Divider() const +{ + return fDivider; +} +//------------------------------------------------------------------------------ +void BMenuField::ShowPopUpMarker() +{ + // TODO: +} +//------------------------------------------------------------------------------ +void BMenuField::HidePopUpMarker() +{ + // TODO: +} +//------------------------------------------------------------------------------ +BHandler *BMenuField::ResolveSpecifier(BMessage *msg, + int32 index, + BMessage *specifier, + int32 form, + const char *property) +{ + return BView::ResolveSpecifier(msg, index, specifier, form, property); +} +//------------------------------------------------------------------------------ +status_t BMenuField::GetSupportedSuites(BMessage *data) +{ + return BView::GetSupportedSuites(data); +} +//------------------------------------------------------------------------------ +void BMenuField::ResizeToPreferred() +{ + BView::ResizeToPreferred(); +} +//------------------------------------------------------------------------------ +void BMenuField::GetPreferredSize(float *width, float *height) +{ + BView::GetPreferredSize(width, height); +} +//------------------------------------------------------------------------------ +status_t BMenuField::Perform(perform_code d, void *arg) +{ + return BView::Perform(d, arg); +} +//------------------------------------------------------------------------------ +void BMenuField::_ReservedMenuField1() {} +void BMenuField::_ReservedMenuField2() {} +void BMenuField::_ReservedMenuField3() {} +//------------------------------------------------------------------------------ +BMenuField &BMenuField::operator=(const BMenuField &) +{ + return *this; +} +//------------------------------------------------------------------------------ +void BMenuField::InitObject(const char *label) +{ + fLabel = NULL; + fMenu = NULL; + fMenuBar; + fAlign = B_ALIGN_LEFT; + fStringWidth = 0; + fEnabled = true; + fSelected = false; + fTransition = false; + fFixedSizeMB = false; + fMenuTaskID = -1; + + SetLabel(label); + + if (label) + fDivider = (float)floor(Frame().Width() / 2.0f); + else + fDivider = 0; +} +//------------------------------------------------------------------------------ +void BMenuField::InitObject2() +{ + // TODO set filter +} +//------------------------------------------------------------------------------ +void BMenuField::DrawLabel(BRect bounds, BRect update) +{ + font_height fh; + GetFontHeight(&fh); + + if (Label()) + { + SetLowColor(ViewColor()); + + float y = (float)ceil(fh.ascent + fh.descent + fh.leading) + 2.0f; + float x; + + switch (fAlign) + { + case B_ALIGN_RIGHT: + x = fDivider - StringWidth(Label()) - 3.0f; + break; + + case B_ALIGN_CENTER: + x = fDivider - StringWidth(Label()) / 2.0f; + break; + + default: + x = 3.0f; + break; + } + + SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), + IsEnabled() ? B_DARKEN_MAX_TINT : B_DISABLED_LABEL_TINT)); + DrawString(Label(), BPoint(x, y)); + } +} +//------------------------------------------------------------------------------ +void BMenuField::InitMenu(BMenu *menu) +{ + menu->SetFont(be_plain_font); + + int32 index = 0; + BMenu *subMenu; + + while (subMenu = menu->SubmenuAt(index++)) + InitMenu(subMenu); +} +//------------------------------------------------------------------------------ +long BMenuField::MenuTask(void *arg) +{ + BRect rect; + BMenuField *menuField = (BMenuField*)arg; + + if (!menuField->LockLooper()) + return 0; + + menuField->fSelected = true; + menuField->fTransition = true; + menuField->Draw(menuField->Bounds()); + + menuField->UnlockLooper(); + + bool tracking; + + do + { + snooze(20000); + + if (!menuField->LockLooper()) + return 0; + + tracking = menuField->fMenuBar->fTracking; + + menuField->UnlockLooper(); + } while (tracking); + + if (!menuField->LockLooper()) + return 0; + + menuField->fSelected = false; + menuField->fTransition = true; + menuField->Draw(menuField->Bounds()); + + menuField->UnlockLooper(); + + return 0; +} +//------------------------------------------------------------------------------ +