Files
haiku-beta6/src/kits/interface/Box.cpp
T
Michael Lotz 76c0041c51 I suppose setting the height was forgotten?
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15092 a95241bf-73f2-0310-859d-f6bbb57e9c96
2005-11-23 17:49:38 +00:00

505 lines
8.7 KiB
C++

/*
* Copyright (c) 2001-2005, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Marc Flerackers ([email protected])
* Stephan Aßmus <[email protected]>
* DarkWyrm <[email protected]>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Box.h>
#include <Message.h>
BBox::BBox(BRect frame, const char *name, uint32 resizingMode, uint32 flags,
border_style border)
: BView(frame, name, resizingMode, flags | B_FRAME_EVENTS),
fStyle(border)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
InitObject();
}
BBox::~BBox()
{
ClearAnyLabel();
}
BBox::BBox(BMessage *archive)
: BView(archive)
{
InitObject(archive);
const char *string;
if (archive->FindString("_label", &string) == B_OK)
SetLabel(string);
bool aBool;
int32 anInt32;
if (archive->FindBool("_style", &aBool) == B_OK)
fStyle = aBool ? B_FANCY_BORDER : B_PLAIN_BORDER;
else if (archive->FindInt32("_style", &anInt32) == B_OK)
fStyle = (border_style)anInt32;
if (archive->FindBool("_lblview", &aBool) == B_OK)
fLabelView = ChildAt(0);
}
BArchivable *
BBox::Instantiate(BMessage *archive)
{
if (validate_instantiation(archive, "BBox"))
return new BBox(archive);
else
return NULL;
}
status_t
BBox::Archive(BMessage *archive, bool deep) const
{
BView::Archive(archive, deep);
if (fLabel)
archive->AddString("_label", fLabel);
if (fLabelView)
archive->AddBool("_lblview", true);
if (fStyle != B_FANCY_BORDER)
archive->AddInt32("_style", fStyle);
return B_OK;
}
void
BBox::SetBorder(border_style border)
{
fStyle = border;
if (Window() != NULL && LockLooper()) {
Invalidate();
UnlockLooper();
}
}
border_style
BBox::Border() const
{
return fStyle;
}
void
BBox::SetLabel(const char *string)
{
ClearAnyLabel();
if (string) {
// Update fBounds
fBounds = Bounds();
font_height fh;
GetFontHeight(&fh);
fBounds.top = (float)ceil((fh.ascent + fh.descent) / 2.0f);
fLabel = strdup(string);
}
if (Window())
Invalidate();
}
status_t
BBox::SetLabel(BView *viewLabel)
{
ClearAnyLabel();
if (viewLabel) {
// Update fBounds
fBounds = Bounds();
fBounds.top = ceilf(viewLabel->Bounds().Height() / 2.0f);
fLabelView = viewLabel;
fLabelView->MoveTo(10.0f, 0.0f);
AddChild(fLabelView, ChildAt(0));
}
if (Window())
Invalidate();
return B_OK;
}
const char *
BBox::Label() const
{
return fLabel;
}
BView *
BBox::LabelView() const
{
return fLabelView;
}
void
BBox::Draw(BRect updateRect)
{
switch (fStyle) {
case B_FANCY_BORDER:
DrawFancy();
break;
case B_PLAIN_BORDER:
DrawPlain();
break;
default:
break;
}
if (fLabel) {
font_height fh;
GetFontHeight(&fh);
SetHighColor(ViewColor());
FillRect(BRect(6.0f, 1.0f, 12.0f + StringWidth(fLabel),
(float)ceil(fh.ascent + fh.descent))/*, B_SOLID_LOW*/);
SetHighColor(0, 0, 0);
DrawString(fLabel, BPoint(10.0f, (float)ceil(fh.ascent - fh.descent)
+ 1.0f));
}
}
void BBox::AttachedToWindow()
{
if (Parent()) {
SetViewColor(Parent()->ViewColor());
SetLowColor(Parent()->ViewColor());
}
}
void
BBox::DetachedFromWindow()
{
BView::DetachedFromWindow();
}
void
BBox::AllAttached()
{
BView::AllAttached();
}
void
BBox::AllDetached()
{
BView::AllDetached();
}
void
BBox::FrameResized(float width, float height)
{
BRect bounds(Bounds());
// invalidate the regions that the app_server did not
// (for removing the previous or drawing the new border)
if (fStyle != B_NO_BORDER) {
int32 borderSize = fStyle == B_PLAIN_BORDER ? 0 : 1;
BRect invalid(bounds);
if (fBounds.right < bounds.right) {
// enlarging
invalid.left = fBounds.right - borderSize;
invalid.right = fBounds.right;
Invalidate(invalid);
} else if (fBounds.right > bounds.right) {
// shrinking
invalid.left = bounds.right - borderSize;
Invalidate(invalid);
}
invalid = bounds;
if (fBounds.bottom < bounds.bottom) {
// enlarging
invalid.top = fBounds.bottom - borderSize;
invalid.bottom = fBounds.bottom;
Invalidate(invalid);
} else if (fBounds.bottom > bounds.bottom) {
// shrinking
invalid.top = bounds.bottom - borderSize;
Invalidate(invalid);
}
}
fBounds.right = bounds.right;
fBounds.bottom = bounds.bottom;
}
void
BBox::MessageReceived(BMessage *message)
{
BView::MessageReceived(message);
}
void
BBox::MouseDown(BPoint point)
{
BView::MouseDown(point);
}
void
BBox::MouseUp(BPoint point)
{
BView::MouseUp(point);
}
void
BBox::WindowActivated(bool active)
{
BView::WindowActivated(active);
}
void
BBox::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
{
BView::MouseMoved(point, transit, message);
}
void
BBox::FrameMoved(BPoint newLocation)
{
BView::FrameMoved(newLocation);
}
BHandler *
BBox::ResolveSpecifier(BMessage *message, int32 index,
BMessage *specifier, int32 what,
const char *property)
{
return BView::ResolveSpecifier(message, index, specifier, what, property);
}
void
BBox::ResizeToPreferred()
{
BView::ResizeToPreferred();
}
void
BBox::GetPreferredSize(float *_width, float *_height)
{
float width, height;
bool label = true;
// acount for label
if (fLabelView) {
fLabelView->GetPreferredSize(&width, &height);
width += 10.0;
// the label view is placed 10 pixels from the left
} else if (fLabel) {
font_height fh;
GetFontHeight(&fh);
width += ceilf(StringWidth(fLabel));
height += ceilf(fh.ascent + fh.descent);
} else {
label = false;
width = 0;
height = 0;
}
// acount for border
switch (fStyle) {
case B_NO_BORDER:
break;
case B_PLAIN_BORDER:
// label: (1 pixel for border + 1 pixel for padding) * 2
// no label: (1 pixel for border) * 2 + 1 pixel for padding
width += label ? 4 : 3;
// label: 1 pixel for bottom border + 1 pixel for padding
// no label: (1 pixel for border) * 2 + 1 pixel for padding
height += label ? 2 : 3;
break;
case B_FANCY_BORDER:
// label: (2 pixel for border + 1 pixel for padding) * 2
// no label: (2 pixel for border) * 2 + 1 pixel for padding
width += label ? 6 : 5;
// label: 2 pixel for bottom border + 1 pixel for padding
// no label: (2 pixel for border) * 2 + 1 pixel for padding
height += label ? 3 : 5;
break;
}
// NOTE: children are ignored, you can use BBox::GetPreferredSize()
// to get the minimum size of this object, then add the size
// of your child(ren) plus inner padding for the final size
if (_width)
*_width = width;
if (_height)
*_height = height;
}
void
BBox::MakeFocus(bool focused)
{
BView::MakeFocus(focused);
}
status_t
BBox::GetSupportedSuites(BMessage *message)
{
return BView::GetSupportedSuites(message);
}
status_t
BBox::Perform(perform_code d, void *arg)
{
return BView::Perform(d, arg);
}
void BBox::_ReservedBox1() {}
void BBox::_ReservedBox2() {}
BBox &
BBox::operator=(const BBox &)
{
return *this;
}
void
BBox::InitObject(BMessage *data)
{
fLabel = NULL;
fBounds = Bounds();
fLabelView = NULL;
int32 flags = 0;
BFont font(be_bold_font);
if (!data || !data->HasString("_fname"))
flags = B_FONT_FAMILY_AND_STYLE;
if (!data || !data->HasFloat("_fflt"))
flags |= B_FONT_SIZE;
if (flags != 0)
SetFont(&font, flags);
}
void
BBox::DrawPlain()
{
BRect r = fBounds;
rgb_color light = tint_color(ViewColor(), B_LIGHTEN_MAX_TINT);
rgb_color shadow = tint_color(ViewColor(), B_DARKEN_3_TINT);
BeginLineArray(4);
AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.top), light);
AddLine(BPoint(r.left + 1.0f, r.top),
BPoint(r.right, r.top), light);
AddLine(BPoint(r.left + 1.0f, r.bottom),
BPoint(r.right, r.bottom), shadow);
AddLine(BPoint(r.right, r.bottom - 1.0f),
BPoint(r.right, r.top + 1.0f), shadow);
EndLineArray();
}
void
BBox::DrawFancy()
{
BRect r = fBounds;
rgb_color light = tint_color(ViewColor(), B_LIGHTEN_MAX_TINT);
rgb_color shadow = tint_color(ViewColor(), B_DARKEN_3_TINT);
BeginLineArray(8);
AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.top), shadow);
AddLine(BPoint(r.left + 1.0f, r.top),
BPoint(r.right, r.top), shadow);
AddLine(BPoint(r.left + 1.0f, r.bottom),
BPoint(r.right, r.bottom), light);
AddLine(BPoint(r.right, r.bottom - 1.0f),
BPoint(r.right, r.top + 1.0f), light);
r.InsetBy(1.0, 1.0);
AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.top), light);
AddLine(BPoint(r.left + 1.0f, r.top),
BPoint(r.right, r.top), light);
AddLine(BPoint(r.left + 1.0f, r.bottom),
BPoint(r.right, r.bottom), shadow);
AddLine(BPoint(r.right, r.bottom - 1.0f),
BPoint(r.right, r.top + 1.0f), shadow);
EndLineArray();
}
void
BBox::ClearAnyLabel()
{
fBounds.top = 0;
if (fLabel) {
free(fLabel);
fLabel = NULL;
} else if (fLabelView) {
fLabelView->RemoveSelf();
delete fLabelView;
fLabelView = NULL;
}
}