Files
haiku-beta6/src/apps/icon-o-matic/generic/gui/Group.cpp
T
Stephan Aßmus 5ca1108776 * fixed off by one errors when calculating min size
* added setter for internal spacing 


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17916 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-06-23 23:12:18 +00:00

139 lines
3.0 KiB
C++

/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <[email protected]>
*/
#include "Group.h"
#include <stdio.h>
// constructor
Group::Group(BRect frame, const char* name, orientation direction)
: BView(frame, name, B_FOLLOW_ALL, B_FRAME_EVENTS),
fOrientation(direction),
fInset(4.0),
fSpacing(0.0)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
}
// destructor
Group::~Group()
{
}
// AttachedToWindow
void
Group::AttachedToWindow()
{
// trigger a layout
FrameResized(Bounds().Width(), Bounds().Height());
}
// FrameResized
void
Group::FrameResized(float width, float height)
{
// layout controls
BRect r(Bounds());
r.InsetBy(fInset, fInset);
_LayoutControls(r);
}
// GetPreferredSize
void
Group::GetPreferredSize(float* width, float* height)
{
BRect r(_MinFrame());
if (width)
*width = r.Width();
if (height)
*height = r.Height();
}
// #pragma mark -
void
Group::SetSpacing(float insetFromBorder, float childSpacing)
{
if (fSpacing == childSpacing && fInset == insetFromBorder)
return;
fInset = insetFromBorder;
fSpacing = childSpacing;
// trigger a layout
FrameResized(Bounds().Width(), Bounds().Height());
}
// #pragma mark -
// _LayoutControls
void
Group::_LayoutControls(BRect r) const
{
if (fOrientation == B_HORIZONTAL) {
r.left -= fSpacing;
for (int32 i = 0; BView* child = ChildAt(i); i++) {
r.right = r.left + child->Bounds().Width() + 2 * fSpacing;
_LayoutControl(child, r);
r.left = r.right + 1.0 - fSpacing;
}
} else {
r.top -= fSpacing;
for (int32 i = 0; BView* child = ChildAt(i); i++) {
r.bottom = r.top + child->Bounds().Height() + 2 * fSpacing;
_LayoutControl(child, r);
r.top = r.bottom + 1.0 - fSpacing;
}
}
}
// _MinFrame
BRect
Group::_MinFrame() const
{
float minWidth = fInset * 2.0;
float minHeight = fInset * 2.0;
if (fOrientation == B_HORIZONTAL) {
minWidth += fSpacing;
for (int32 i = 0; BView* child = ChildAt(i); i++) {
minWidth += child->Bounds().Width() + 1 + fSpacing;
minHeight = max_c(minHeight,
child->Bounds().Height() + 1 + fInset * 2.0);
}
} else {
minHeight += fSpacing;
for (int32 i = 0; BView* child = ChildAt(i); i++) {
minHeight += child->Bounds().Height() + 1 + fSpacing;
minWidth = max_c(minWidth,
child->Bounds().Width() + 1 + fInset * 2.0);
}
}
return BRect(0.0, 0.0, minWidth - 1.0, minHeight - 1.0);
}
// _LayoutControl
void
Group::_LayoutControl(BView* view, BRect frame,
bool resizeWidth, bool resizeHeight) const
{
if (!resizeHeight)
// center vertically
frame.top = (frame.top + frame.bottom) / 2.0 - view->Bounds().Height() / 2.0;
if (!resizeWidth)
// center horizontally
frame.left = (frame.left + frame.right) / 2.0 - view->Bounds().Width() / 2.0;
view->MoveTo(frame.LeftTop());
float width = resizeWidth ? frame.Width() : view->Bounds().Width();
float height = resizeHeight ? frame.Height() : view->Bounds().Height();
if (resizeWidth || resizeHeight)
view->ResizeTo(width, height);
}