git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14812 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-11-09 22:25:34 +00:00
parent 2f48d972f7
commit 789f68f07a
+206 -179
View File
@@ -1,54 +1,29 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2002, OpenBeOS * Copyright 2001-2005, Haiku, Inc.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Marc Flerackers ([email protected])
// 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 ([email protected])
// Description: BMenuField displays a labeled pop-up menu.
//------------------------------------------------------------------------------
// Standard Includes -----------------------------------------------------------
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
// System Includes -------------------------------------------------------------
#include <MenuBar.h> #include <MenuBar.h>
#include <MenuField.h> #include <MenuField.h>
#include <Message.h> #include <Message.h>
#include <BMCPrivate.h> #include <BMCPrivate.h>
#include <Window.h> #include <Window.h>
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
static float kVMargin = 2.0f; static float kVMargin = 2.0f;
//------------------------------------------------------------------------------
BMenuField::BMenuField(BRect frame, const char *name, const char *label, BMenuField::BMenuField(BRect frame, const char *name, const char *label,
BMenu *menu, uint32 resize, uint32 flags) BMenu *menu, uint32 resize, uint32 flags)
: BView(frame, name, resize, flags) : BView(frame, name, resize, flags)
{ {
InitObject(label); InitObject(label);
SetFont(be_plain_font); SetFont(be_plain_font);
@@ -67,23 +42,23 @@ BMenuField::BMenuField(BRect frame, const char *name, const char *label,
InitObject2(); InitObject2();
} }
//------------------------------------------------------------------------------
BMenuField::BMenuField(BRect frame, const char *name, const char *label, BMenuField::BMenuField(BRect frame, const char *name, const char *label,
BMenu *menu, bool fixed_size, uint32 resize, BMenu *menu, bool fixedSize, uint32 resize, uint32 flags)
uint32 flags) : BView(frame, name, resize, flags)
: BView(frame, name, resize, flags)
{ {
InitObject(label); InitObject(label);
SetFont(be_plain_font); SetFont(be_plain_font);
fMenu = menu; fMenu = menu;
InitMenu(menu); InitMenu(menu);
fFixedSizeMB = fixed_size; fFixedSizeMB = fixedSize;
frame.OffsetTo(0.0f, 0.0f); frame.OffsetTo(0.0f, 0.0f);
fMenuBar = new _BMCMenuBar_(BRect(frame.left + fDivider + 1.0, fMenuBar = new _BMCMenuBar_(BRect(frame.left + fDivider + 1.0,
frame.top + kVMargin, frame.right - 2.0f, frame.bottom - kVMargin), frame.top + kVMargin, frame.right - 2.0f, frame.bottom - kVMargin),
fixed_size, this); fixedSize, this);
AddChild(fMenuBar); AddChild(fMenuBar);
fMenuBar->AddItem(new _BMCItem_(menu)); fMenuBar->AddItem(new _BMCItem_(menu));
@@ -92,14 +67,14 @@ BMenuField::BMenuField(BRect frame, const char *name, const char *label,
InitObject2(); InitObject2();
} }
//------------------------------------------------------------------------------
BMenuField::BMenuField(BMessage *data) BMenuField::BMenuField(BMessage *data)
: BView(data) : BView(data)
{ {
const char *label = NULL; const char *label = NULL;
data->FindString("_label", &label); data->FindString("_label", &label);
InitObject(label); InitObject(label);
fMenuBar = (BMenuBar*)FindView("_mc_mb_"); fMenuBar = (BMenuBar*)FindView("_mc_mb_");
@@ -108,56 +83,54 @@ BMenuField::BMenuField(BMessage *data)
InitObject2(); InitObject2();
bool disable; bool disable;
if (data->FindBool("_disable", &disable) == B_OK) if (data->FindBool("_disable", &disable) == B_OK)
SetEnabled(!disable); SetEnabled(!disable);
int32 align; int32 align;
data->FindInt32("_align", &align); data->FindInt32("_align", &align);
SetAlignment((alignment)align); SetAlignment((alignment)align);
data->FindFloat("_divide", &fDivider); data->FindFloat("_divide", &fDivider);
bool fixed; bool fixed;
if (data->FindBool("be:fixeds", &fixed) == B_OK) if (data->FindBool("be:fixeds", &fixed) == B_OK)
fFixedSizeMB = fixed; fFixedSizeMB = fixed;
BMenuItem *item = fMenuBar->ItemAt(0); BMenuItem *item = fMenuBar->ItemAt(0);
if (!item) if (!item)
return; return;
_BMCItem_ *bmcitem = dynamic_cast<_BMCItem_*>(item); _BMCItem_ *bmcitem = dynamic_cast<_BMCItem_*>(item);
if (!bmcitem) if (!bmcitem)
return; return;
bool dmark;
bool dmark;
if (data->FindBool("be:dmark", &dmark)) if (data->FindBool("be:dmark", &dmark))
bmcitem->fShowPopUpMarker = dmark; bmcitem->fShowPopUpMarker = dmark;
} }
//------------------------------------------------------------------------------
BMenuField::~BMenuField() BMenuField::~BMenuField()
{ {
if (fLabel) free(fLabel);
free(fLabel);
if (fMenuTaskID >= 0) if (fMenuTaskID >= 0)
kill_thread(fMenuTaskID); kill_thread(fMenuTaskID);
} }
//------------------------------------------------------------------------------
BArchivable *BMenuField::Instantiate(BMessage *data)
BArchivable *
BMenuField::Instantiate(BMessage *data)
{ {
if (validate_instantiation(data, "BMenuField")) if (validate_instantiation(data, "BMenuField"))
return new BMenuField(data); return new BMenuField(data);
else
return NULL; return NULL;
} }
//------------------------------------------------------------------------------
status_t BMenuField::Archive(BMessage *data, bool deep) const
status_t
BMenuField::Archive(BMessage *data, bool deep) const
{ {
BView::Archive(data, deep); BView::Archive(data, deep);
@@ -168,26 +141,25 @@ status_t BMenuField::Archive(BMessage *data, bool deep) const
data->AddBool("_disable", true); data->AddBool("_disable", true);
data->AddInt32("_align", Alignment()); data->AddInt32("_align", Alignment());
data->AddFloat("_divide", Divider()); data->AddFloat("_divide", Divider());
if (fFixedSizeMB) if (fFixedSizeMB)
data->AddBool("be:fixeds", true); data->AddBool("be:fixeds", true);
BMenuItem *item = fMenuBar->ItemAt(0); BMenuItem *item = fMenuBar->ItemAt(0);
if (!item) if (!item)
return B_OK; return B_OK;
_BMCItem_ *bmcitem = dynamic_cast<_BMCItem_*>(item); _BMCItem_ *bmcitem = dynamic_cast<_BMCItem_*>(item);
if (bmcitem && !bmcitem->fShowPopUpMarker) if (bmcitem && !bmcitem->fShowPopUpMarker)
data->AddBool("be:dmark", false); data->AddBool("be:dmark", false);
return B_OK; return B_OK;
} }
//------------------------------------------------------------------------------
void BMenuField::Draw(BRect update)
void
BMenuField::Draw(BRect update)
{ {
BRect bounds(Bounds()); BRect bounds(Bounds());
bool active = false; bool active = false;
@@ -195,16 +167,11 @@ void BMenuField::Draw(BRect update)
if (IsFocus()) if (IsFocus())
active = Window()->IsActive(); active = Window()->IsActive();
//SetHighColor(255, 0, 0);
//FillRect(bounds);
DrawLabel(bounds, update); DrawLabel(bounds, update);
BRect frame(fMenuBar->Frame()); BRect frame(fMenuBar->Frame());
//rgb_color color = HighColor();
if (frame.InsetByCopy(-2, -2).Intersects(update)) if (frame.InsetByCopy(-2, -2).Intersects(update)) {
{
SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT));
StrokeLine(BPoint(frame.left - 1.0f, frame.top - 1.0f), StrokeLine(BPoint(frame.left - 1.0f, frame.top - 1.0f),
BPoint(frame.left - 1.0f, frame.bottom - 1.0f)); BPoint(frame.left - 1.0f, frame.bottom - 1.0f));
@@ -220,11 +187,9 @@ void BMenuField::Draw(BRect update)
BPoint(frame.left - 1.0f, frame.bottom)); BPoint(frame.left - 1.0f, frame.bottom));
StrokeLine(BPoint(frame.right, frame.top - 1.0f), StrokeLine(BPoint(frame.right, frame.top - 1.0f),
BPoint(frame.right, frame.top - 1.0f)); BPoint(frame.right, frame.top - 1.0f));
} }
if (active || fTransition) if (active || fTransition) {
{
SetHighColor(active ? ui_color(B_KEYBOARD_NAVIGATION_COLOR) : SetHighColor(active ? ui_color(B_KEYBOARD_NAVIGATION_COLOR) :
ViewColor()); ViewColor());
StrokeRect(frame.InsetByCopy(-kVMargin, -kVMargin)); StrokeRect(frame.InsetByCopy(-kVMargin, -kVMargin));
@@ -232,26 +197,31 @@ void BMenuField::Draw(BRect update)
fTransition = false; fTransition = false;
} }
} }
//------------------------------------------------------------------------------
void BMenuField::AttachedToWindow()
void
BMenuField::AttachedToWindow()
{ {
if (Parent()) if (Parent()) {
{
SetViewColor(Parent()->ViewColor()); SetViewColor(Parent()->ViewColor());
SetLowColor(Parent()->ViewColor()); SetLowColor(Parent()->ViewColor());
} }
if (fLabel) if (fLabel)
fStringWidth = StringWidth(fLabel); fStringWidth = StringWidth(fLabel);
} }
//------------------------------------------------------------------------------
void BMenuField::AllAttached()
void
BMenuField::AllAttached()
{ {
ResizeTo(Bounds().Width(), ResizeTo(Bounds().Width(),
fMenuBar->Bounds().Height() + kVMargin + kVMargin); fMenuBar->Bounds().Height() + kVMargin + kVMargin);
} }
//------------------------------------------------------------------------------
void BMenuField::MouseDown(BPoint where)
void
BMenuField::MouseDown(BPoint where)
{ {
if (where.x > fDivider && !fMenuBar->Frame().Contains(where)) if (where.x > fDivider && !fMenuBar->Frame().Contains(where))
return; return;
@@ -262,15 +232,15 @@ void BMenuField::MouseDown(BPoint where)
fMenuTaskID = spawn_thread((thread_func)MenuTask, "_m_task_", fMenuTaskID = spawn_thread((thread_func)MenuTask, "_m_task_",
B_NORMAL_PRIORITY, this); B_NORMAL_PRIORITY, this);
if (fMenuTaskID) if (fMenuTaskID)
resume_thread(fMenuTaskID); resume_thread(fMenuTaskID);
} }
//------------------------------------------------------------------------------
void BMenuField::KeyDown(const char *bytes, int32 numBytes)
void
BMenuField::KeyDown(const char *bytes, int32 numBytes)
{ {
switch (bytes[0]) switch (bytes[0]) {
{
case B_SPACE: case B_SPACE:
case B_RIGHT_ARROW: case B_RIGHT_ARROW:
case B_DOWN_ARROW: case B_DOWN_ARROW:
@@ -287,12 +257,15 @@ void BMenuField::KeyDown(const char *bytes, int32 numBytes)
Invalidate(bounds); Invalidate(bounds);
} }
default: default:
BView::KeyDown(bytes, numBytes); BView::KeyDown(bytes, numBytes);
} }
} }
//------------------------------------------------------------------------------
void BMenuField::MakeFocus(bool state)
void
BMenuField::MakeFocus(bool state)
{ {
if (IsFocus() == state) if (IsFocus() == state)
return; return;
@@ -302,69 +275,92 @@ void BMenuField::MakeFocus(bool state)
if (Window()) if (Window())
Invalidate(); // TODO: use fStringWidth Invalidate(); // TODO: use fStringWidth
} }
//------------------------------------------------------------------------------
void BMenuField::MessageReceived(BMessage *msg)
void
BMenuField::MessageReceived(BMessage *msg)
{ {
BView::MessageReceived(msg); BView::MessageReceived(msg);
} }
//------------------------------------------------------------------------------
void BMenuField::WindowActivated(bool state)
void
BMenuField::WindowActivated(bool state)
{ {
BView::WindowActivated(state); BView::WindowActivated(state);
if (IsFocus()) if (IsFocus())
Invalidate(); Invalidate();
} }
//------------------------------------------------------------------------------
void BMenuField::MouseUp(BPoint pt)
void
BMenuField::MouseUp(BPoint point)
{ {
BView::MouseUp(pt); BView::MouseUp(point);
} }
//------------------------------------------------------------------------------
void BMenuField::MouseMoved(BPoint pt, uint32 code, const BMessage *msg)
void
BMenuField::MouseMoved(BPoint point, uint32 code, const BMessage *message)
{ {
BView::MouseMoved(pt, code, msg); BView::MouseMoved(point, code, message);
} }
//------------------------------------------------------------------------------
void BMenuField::DetachedFromWindow()
void
BMenuField::DetachedFromWindow()
{ {
BView::DetachedFromWindow(); BView::DetachedFromWindow();
} }
//------------------------------------------------------------------------------
void BMenuField::AllDetached()
void
BMenuField::AllDetached()
{ {
BView::AllDetached(); BView::AllDetached();
} }
//------------------------------------------------------------------------------
void BMenuField::FrameMoved(BPoint new_position)
void
BMenuField::FrameMoved(BPoint newPosition)
{ {
BView::FrameMoved(new_position); BView::FrameMoved(newPosition);
} }
//------------------------------------------------------------------------------
void BMenuField::FrameResized(float new_width, float new_height)
void
BMenuField::FrameResized(float newWidth, float newHeight)
{ {
BView::FrameResized(new_width, new_height); BView::FrameResized(newWidth, newHeight);
} }
//------------------------------------------------------------------------------
BMenu *BMenuField::Menu() const
BMenu *
BMenuField::Menu() const
{ {
return fMenu; return fMenu;
} }
//------------------------------------------------------------------------------
BMenuBar *BMenuField::MenuBar() const
BMenuBar *
BMenuField::MenuBar() const
{ {
return fMenuBar; return fMenuBar;
} }
//------------------------------------------------------------------------------
BMenuItem *BMenuField::MenuItem() const
BMenuItem *
BMenuField::MenuItem() const
{ {
return fMenuBar->ItemAt(0); return fMenuBar->ItemAt(0);
} }
//------------------------------------------------------------------------------
void BMenuField::SetLabel(const char *label)
void
BMenuField::SetLabel(const char *label)
{ {
if (fLabel) if (fLabel) {
{
if (label && strcmp(fLabel, label) == 0) if (label && strcmp(fLabel, label) == 0)
return; return;
@@ -373,20 +369,23 @@ void BMenuField::SetLabel(const char *label)
fLabel = strdup(label); fLabel = strdup(label);
if (Window()) if (Window()) {
{
Invalidate(); Invalidate();
if (fLabel) if (fLabel)
fStringWidth = StringWidth(fLabel); fStringWidth = StringWidth(fLabel);
} }
} }
//------------------------------------------------------------------------------
const char *BMenuField::Label() const
const char *
BMenuField::Label() const
{ {
return fLabel; return fLabel;
} }
//------------------------------------------------------------------------------
void BMenuField::SetEnabled(bool on)
void
BMenuField::SetEnabled(bool on)
{ {
if (fEnabled == on) if (fEnabled == on)
return; return;
@@ -394,29 +393,36 @@ void BMenuField::SetEnabled(bool on)
fEnabled = on; fEnabled = on;
fMenuBar->SetEnabled(on); fMenuBar->SetEnabled(on);
if (Window()) if (Window()) {
{
fMenuBar->Invalidate(fMenuBar->Bounds()); fMenuBar->Invalidate(fMenuBar->Bounds());
Invalidate(Bounds()); Invalidate(Bounds());
} }
} }
//------------------------------------------------------------------------------
bool BMenuField::IsEnabled() const
bool
BMenuField::IsEnabled() const
{ {
return fEnabled; return fEnabled;
} }
//------------------------------------------------------------------------------
void BMenuField::SetAlignment(alignment label)
void
BMenuField::SetAlignment(alignment label)
{ {
fAlign = label; fAlign = label;
} }
//------------------------------------------------------------------------------
alignment BMenuField::Alignment() const
alignment
BMenuField::Alignment() const
{ {
return fAlign; return fAlign;
} }
//------------------------------------------------------------------------------
void BMenuField::SetDivider(float divider)
void
BMenuField::SetDivider(float divider)
{ {
divider = floorf(divider + 0.5); divider = floorf(divider + 0.5);
@@ -430,41 +436,51 @@ void BMenuField::SetDivider(float divider)
MenuBar()->MoveBy(-dx, 0.0f); MenuBar()->MoveBy(-dx, 0.0f);
MenuBar()->ResizeBy(dx, 0.0f); MenuBar()->ResizeBy(dx, 0.0f);
} }
//------------------------------------------------------------------------------
float BMenuField::Divider() const
float
BMenuField::Divider() const
{ {
return fDivider; return fDivider;
} }
//------------------------------------------------------------------------------
void BMenuField::ShowPopUpMarker()
void
BMenuField::ShowPopUpMarker()
{ {
// TODO: // TODO:
} }
//------------------------------------------------------------------------------
void BMenuField::HidePopUpMarker()
void
BMenuField::HidePopUpMarker()
{ {
// TODO: // TODO:
} }
//------------------------------------------------------------------------------
BHandler *BMenuField::ResolveSpecifier(BMessage *msg,
int32 index, BHandler *
BMessage *specifier, BMenuField::ResolveSpecifier(BMessage *message, int32 index,
int32 form, BMessage *specifier, int32 form, const char *property)
const char *property)
{ {
return BView::ResolveSpecifier(msg, index, specifier, form, property); return BView::ResolveSpecifier(message, index, specifier, form, property);
} }
//------------------------------------------------------------------------------
status_t BMenuField::GetSupportedSuites(BMessage *data)
status_t
BMenuField::GetSupportedSuites(BMessage *data)
{ {
return BView::GetSupportedSuites(data); return BView::GetSupportedSuites(data);
} }
//------------------------------------------------------------------------------
void BMenuField::ResizeToPreferred()
void
BMenuField::ResizeToPreferred()
{ {
BView::ResizeToPreferred(); BView::ResizeToPreferred();
} }
//------------------------------------------------------------------------------
void void
BMenuField::GetPreferredSize(float *_width, float *_height) BMenuField::GetPreferredSize(float *_width, float *_height)
{ {
@@ -499,22 +515,29 @@ BMenuField::GetPreferredSize(float *_width, float *_height)
*_height = fMenuBar->Bounds().Height(); *_height = fMenuBar->Bounds().Height();
} }
//------------------------------------------------------------------------------
status_t BMenuField::Perform(perform_code d, void *arg)
status_t
BMenuField::Perform(perform_code d, void *arg)
{ {
return BView::Perform(d, arg); return BView::Perform(d, arg);
} }
//------------------------------------------------------------------------------
void BMenuField::_ReservedMenuField1() {} void BMenuField::_ReservedMenuField1() {}
void BMenuField::_ReservedMenuField2() {} void BMenuField::_ReservedMenuField2() {}
void BMenuField::_ReservedMenuField3() {} void BMenuField::_ReservedMenuField3() {}
//------------------------------------------------------------------------------
BMenuField &BMenuField::operator=(const BMenuField &)
BMenuField &
BMenuField::operator=(const BMenuField &)
{ {
return *this; return *this;
} }
//------------------------------------------------------------------------------
void BMenuField::InitObject(const char *label)
void
BMenuField::InitObject(const char *label)
{ {
fLabel = NULL; fLabel = NULL;
fMenu = NULL; fMenu = NULL;
@@ -534,8 +557,10 @@ void BMenuField::InitObject(const char *label)
else else
fDivider = 0; fDivider = 0;
} }
//------------------------------------------------------------------------------
void BMenuField::InitObject2()
void
BMenuField::InitObject2()
{ {
// TODO set filter // TODO set filter
@@ -548,21 +573,21 @@ void BMenuField::InitObject2()
fMenuBar->ResizeTo(Bounds().Width() - fDivider, height); fMenuBar->ResizeTo(Bounds().Width() - fDivider, height);
} }
//------------------------------------------------------------------------------
void BMenuField::DrawLabel(BRect bounds, BRect update)
void
BMenuField::DrawLabel(BRect bounds, BRect update)
{ {
font_height fh; font_height fh;
GetFontHeight(&fh); GetFontHeight(&fh);
if (Label()) if (Label()) {
{
SetLowColor(ViewColor()); SetLowColor(ViewColor());
float y = (float)ceil(fh.ascent + fh.descent + fh.leading) + 2.0f; float y = (float)ceil(fh.ascent + fh.descent + fh.leading) + 2.0f;
float x; float x;
switch (fAlign) switch (fAlign) {
{
case B_ALIGN_RIGHT: case B_ALIGN_RIGHT:
x = fDivider - StringWidth(Label()) - 3.0f; x = fDivider - StringWidth(Label()) - 3.0f;
break; break;
@@ -575,14 +600,16 @@ void BMenuField::DrawLabel(BRect bounds, BRect update)
x = 3.0f; x = 3.0f;
break; break;
} }
SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
IsEnabled() ? B_DARKEN_MAX_TINT : B_DISABLED_LABEL_TINT)); IsEnabled() ? B_DARKEN_MAX_TINT : B_DISABLED_LABEL_TINT));
DrawString(Label(), BPoint(x, y)); DrawString(Label(), BPoint(x, y));
} }
} }
//------------------------------------------------------------------------------
void BMenuField::InitMenu(BMenu *menu)
void
BMenuField::InitMenu(BMenu *menu)
{ {
menu->SetFont(be_plain_font); menu->SetFont(be_plain_font);
@@ -592,8 +619,10 @@ void BMenuField::InitMenu(BMenu *menu)
while ((subMenu = menu->SubmenuAt(index++)) != NULL) while ((subMenu = menu->SubmenuAt(index++)) != NULL)
InitMenu(subMenu); InitMenu(subMenu);
} }
//------------------------------------------------------------------------------
long BMenuField::MenuTask(void *arg)
long
BMenuField::MenuTask(void *arg)
{ {
BMenuField *menuField = (BMenuField*)arg; BMenuField *menuField = (BMenuField*)arg;
@@ -627,8 +656,6 @@ long BMenuField::MenuTask(void *arg)
menuField->Invalidate(); menuField->Invalidate();
menuField->UnlockLooper(); menuField->UnlockLooper();
return 0; return 0;
} }
//------------------------------------------------------------------------------