Refactoring.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21145 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e8113cabe0
commit
a5b50d1fad
122
src/tests/kits/interface/layout/widget_layout_test/CheckBox.cpp
Normal file
122
src/tests/kits/interface/layout/widget_layout_test/CheckBox.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "CheckBox.h"
|
||||
|
||||
#include <View.h>
|
||||
|
||||
|
||||
CheckBox::CheckBox(BMessage* message, BMessenger target)
|
||||
: View(BRect(0, 0, 12, 12)),
|
||||
BInvoker(message, target),
|
||||
fSelected(false),
|
||||
fPressed(false)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckBox::SetSelected(bool selected)
|
||||
{
|
||||
if (selected != fSelected) {
|
||||
fSelected = selected;
|
||||
Invalidate();
|
||||
|
||||
// send the message
|
||||
if (Message()) {
|
||||
BMessage message(*Message());
|
||||
message.AddBool("selected", IsSelected());
|
||||
InvokeNotify(&message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CheckBox::IsSelected() const
|
||||
{
|
||||
return fSelected;
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
CheckBox::MinSize()
|
||||
{
|
||||
return BSize(12, 12);
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
CheckBox::MaxSize()
|
||||
{
|
||||
return MinSize();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckBox::Draw(BView* container, BRect updateRect)
|
||||
{
|
||||
BRect rect(Bounds());
|
||||
|
||||
if (fPressed)
|
||||
container->SetHighColor((rgb_color){ 120, 0, 0, 255 });
|
||||
else
|
||||
container->SetHighColor((rgb_color){ 0, 0, 0, 255 });
|
||||
|
||||
container->StrokeRect(rect);
|
||||
|
||||
if (fPressed ? fPressedSelected : fSelected) {
|
||||
rect.InsetBy(2, 2);
|
||||
container->StrokeLine(rect.LeftTop(), rect.RightBottom());
|
||||
container->StrokeLine(rect.RightTop(), rect.LeftBottom());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckBox::MouseDown(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
if (fPressed)
|
||||
return;
|
||||
|
||||
fPressed = true;
|
||||
fPressedSelected = fSelected;
|
||||
_PressedUpdate(where);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckBox::MouseUp(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
if (!fPressed || (buttons & B_PRIMARY_MOUSE_BUTTON))
|
||||
return;
|
||||
|
||||
_PressedUpdate(where);
|
||||
fPressed = false;
|
||||
SetSelected(fPressedSelected);
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckBox::MouseMoved(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
if (!fPressed)
|
||||
return;
|
||||
|
||||
_PressedUpdate(where);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CheckBox::_PressedUpdate(BPoint where)
|
||||
{
|
||||
bool pressedSelected = Bounds().Contains(where) ^ fSelected;
|
||||
if (pressedSelected != fPressedSelected) {
|
||||
fPressedSelected = pressedSelected;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WIDGET_LAYOUT_TEST_CHECK_BOX_H
|
||||
#define WIDGET_LAYOUT_TEST_CHECK_BOX_H
|
||||
|
||||
|
||||
#include <Invoker.h>
|
||||
|
||||
#include "View.h"
|
||||
|
||||
|
||||
class CheckBox : public View, public BInvoker {
|
||||
public:
|
||||
CheckBox(BMessage* message = NULL,
|
||||
BMessenger target = BMessenger());
|
||||
|
||||
void SetSelected(bool selected);
|
||||
bool IsSelected() const;
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
|
||||
virtual void Draw(BView* container, BRect updateRect);
|
||||
|
||||
virtual void MouseDown(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
virtual void MouseUp(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
virtual void MouseMoved(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
|
||||
private:
|
||||
void _PressedUpdate(BPoint where);
|
||||
|
||||
private:
|
||||
bool fSelected;
|
||||
bool fPressed;
|
||||
bool fPressedSelected;
|
||||
};
|
||||
|
||||
|
||||
#endif // WIDGET_LAYOUT_TEST_CHECK_BOX_H
|
410
src/tests/kits/interface/layout/widget_layout_test/GroupView.cpp
Normal file
410
src/tests/kits/interface/layout/widget_layout_test/GroupView.cpp
Normal file
@ -0,0 +1,410 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "GroupView.h"
|
||||
|
||||
#include <LayoutUtils.h>
|
||||
|
||||
|
||||
// #pragma mark - GroupView
|
||||
|
||||
|
||||
struct GroupView::LayoutInfo {
|
||||
int32 min;
|
||||
int32 max;
|
||||
int32 preferred;
|
||||
int32 size;
|
||||
|
||||
LayoutInfo()
|
||||
: min(0),
|
||||
max(B_SIZE_UNLIMITED),
|
||||
preferred(0)
|
||||
{
|
||||
}
|
||||
|
||||
void AddConstraints(float addMin, float addMax, float addPreferred)
|
||||
{
|
||||
if (addMin >= min)
|
||||
min = (int32)addMin + 1;
|
||||
if (addMax <= max)
|
||||
max = (int32)addMax + 1;
|
||||
if (addPreferred >= preferred)
|
||||
preferred = (int32)addPreferred + 1;
|
||||
}
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
if (max > min)
|
||||
max = min;
|
||||
if (preferred < min)
|
||||
preferred = min;
|
||||
if (preferred > max)
|
||||
preferred = max;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
GroupView::GroupView(enum orientation orientation, int32 lineCount)
|
||||
: View(BRect(0, 0, 0, 0)),
|
||||
fOrientation(orientation),
|
||||
fLineCount(lineCount),
|
||||
fColumnSpacing(0),
|
||||
fRowSpacing(0),
|
||||
fInsets(0, 0, 0, 0),
|
||||
fMinMaxValid(false),
|
||||
fColumnInfos(NULL),
|
||||
fRowInfos(NULL)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
if (fLineCount < 1)
|
||||
fLineCount = 1;
|
||||
}
|
||||
|
||||
|
||||
GroupView::~GroupView()
|
||||
{
|
||||
delete fColumnInfos;
|
||||
delete fRowInfos;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GroupView::SetSpacing(float horizontal, float vertical)
|
||||
{
|
||||
if (horizontal != fColumnSpacing || vertical != fRowSpacing) {
|
||||
fColumnSpacing = horizontal;
|
||||
fRowSpacing = vertical;
|
||||
|
||||
InvalidateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GroupView::SetInsets(float left, float top, float right, float bottom)
|
||||
{
|
||||
BRect newInsets(left, top, right, bottom);
|
||||
if (newInsets != fInsets) {
|
||||
fInsets = newInsets;
|
||||
InvalidateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
GroupView::MinSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
return _AddInsetsAndSpacing(BSize(fMinWidth - 1, fMinHeight - 1));
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
GroupView::MaxSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
return _AddInsetsAndSpacing(BSize(fMaxWidth - 1, fMaxHeight - 1));
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
GroupView::PreferredSize()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
return _AddInsetsAndSpacing(BSize(fPreferredWidth - 1,
|
||||
fPreferredHeight - 1));
|
||||
}
|
||||
|
||||
|
||||
BAlignment
|
||||
GroupView::Alignment()
|
||||
{
|
||||
return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GroupView::Layout()
|
||||
{
|
||||
_ValidateMinMax();
|
||||
// actually a little late already
|
||||
|
||||
BSize size = _SubtractInsetsAndSpacing(Size());
|
||||
_LayoutLine(size.IntegerWidth() + 1, fColumnInfos, fColumnCount);
|
||||
_LayoutLine(size.IntegerHeight() + 1, fRowInfos, fRowCount);
|
||||
|
||||
// layout children
|
||||
BPoint location = fInsets.LeftTop();
|
||||
for (int32 column = 0; column < fColumnCount; column++) {
|
||||
LayoutInfo& columnInfo = fColumnInfos[column];
|
||||
location.y = fInsets.top;
|
||||
for (int32 row = 0; row < fRowCount; row++) {
|
||||
View* child = _ChildAt(column, row);
|
||||
if (!child)
|
||||
continue;
|
||||
|
||||
// get the grid cell frame
|
||||
BRect cellFrame(location,
|
||||
BSize(columnInfo.size - 1, fRowInfos[row].size - 1));
|
||||
|
||||
// align the child frame in the grid cell
|
||||
BRect childFrame = BLayoutUtils::AlignInFrame(cellFrame,
|
||||
child->MaxSize(), child->Alignment());
|
||||
|
||||
// layout child
|
||||
child->SetFrame(childFrame);
|
||||
|
||||
location.y += fRowInfos[row].size + fRowSpacing;
|
||||
}
|
||||
|
||||
location.x += columnInfo.size + fColumnSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GroupView::_ValidateMinMax()
|
||||
{
|
||||
if (fMinMaxValid)
|
||||
return;
|
||||
|
||||
delete fColumnInfos;
|
||||
delete fRowInfos;
|
||||
|
||||
fColumnCount = _ColumnCount();
|
||||
fRowCount = _RowCount();
|
||||
|
||||
fColumnInfos = new LayoutInfo[fColumnCount];
|
||||
fRowInfos = new LayoutInfo[fRowCount];
|
||||
|
||||
// collect the children's min/max constraints
|
||||
for (int32 column = 0; column < fColumnCount; column++) {
|
||||
for (int32 row = 0; row < fRowCount; row++) {
|
||||
View* child = _ChildAt(column, row);
|
||||
if (!child)
|
||||
continue;
|
||||
|
||||
BSize min = child->MinSize();
|
||||
BSize max = child->MaxSize();
|
||||
BSize preferred = child->PreferredSize();
|
||||
|
||||
// apply constraints to column/row info
|
||||
fColumnInfos[column].AddConstraints(min.width, max.width,
|
||||
preferred.width);
|
||||
fRowInfos[row].AddConstraints(min.height, max.height,
|
||||
preferred.height);
|
||||
}
|
||||
}
|
||||
|
||||
// normalize the column/row constraints and compute sum min/max
|
||||
fMinWidth = 0;
|
||||
fMinHeight = 0;
|
||||
fMaxWidth = 0;
|
||||
fMaxHeight = 0;
|
||||
fPreferredWidth = 0;
|
||||
fPreferredHeight = 0;
|
||||
|
||||
for (int32 column = 0; column < fColumnCount; column++) {
|
||||
fColumnInfos[column].Normalize();
|
||||
fMinWidth = BLayoutUtils::AddSizesInt32(fMinWidth,
|
||||
fColumnInfos[column].min);
|
||||
fMaxWidth = BLayoutUtils::AddSizesInt32(fMaxWidth,
|
||||
fColumnInfos[column].max);
|
||||
fPreferredWidth = BLayoutUtils::AddSizesInt32(fPreferredWidth,
|
||||
fColumnInfos[column].preferred);
|
||||
}
|
||||
|
||||
for (int32 row = 0; row < fRowCount; row++) {
|
||||
fRowInfos[row].Normalize();
|
||||
fMinHeight = BLayoutUtils::AddSizesInt32(fMinHeight,
|
||||
fRowInfos[row].min);
|
||||
fMaxHeight = BLayoutUtils::AddSizesInt32(fMaxHeight,
|
||||
fRowInfos[row].max);
|
||||
fPreferredHeight = BLayoutUtils::AddSizesInt32(fPreferredHeight,
|
||||
fRowInfos[row].preferred);
|
||||
}
|
||||
|
||||
fMinMaxValid = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GroupView::_LayoutLine(int32 size, LayoutInfo* infos, int32 infoCount)
|
||||
{
|
||||
BList infosToLayout;
|
||||
for (int32 i = 0; i < infoCount; i++) {
|
||||
infos[i].size = 0;
|
||||
infosToLayout.AddItem(infos + i);
|
||||
}
|
||||
|
||||
// Distribute the available space over the infos. Each iteration we
|
||||
// try to distribute the remaining space evenly. We respect min and
|
||||
// max constraints, though, add up the space we failed to assign
|
||||
// due to the constraints, and use the sum as remaining space for the
|
||||
// next iteration (can be negative). Then we ignore infos that can't
|
||||
// shrink or grow anymore (depending on what would be needed).
|
||||
while (!infosToLayout.IsEmpty()) {
|
||||
BList canShrinkInfos;
|
||||
BList canGrowInfos;
|
||||
|
||||
int32 sizeDiff = 0;
|
||||
int32 infosToLayoutCount = infosToLayout.CountItems();
|
||||
for (int32 i = 0; i < infosToLayoutCount; i++) {
|
||||
LayoutInfo* info = (LayoutInfo*)infosToLayout.ItemAt(i);
|
||||
info->size += (i + 1) * size / infosToLayoutCount
|
||||
- i * size / infosToLayoutCount;
|
||||
if (info->size < info->min) {
|
||||
sizeDiff -= info->min - info->size;
|
||||
info->size = info->min;
|
||||
} else if (info->size > info->max) {
|
||||
sizeDiff += info->size - info->max;
|
||||
info->size = info->max;
|
||||
}
|
||||
|
||||
if (info->size > info->min)
|
||||
canShrinkInfos.AddItem(info);
|
||||
if (info->size < info->max)
|
||||
canGrowInfos.AddItem(info);
|
||||
}
|
||||
|
||||
size = sizeDiff;
|
||||
if (size == 0)
|
||||
break;
|
||||
|
||||
if (size > 0)
|
||||
infosToLayout = canGrowInfos;
|
||||
else
|
||||
infosToLayout = canShrinkInfos;
|
||||
}
|
||||
|
||||
// If unassigned space is remaining, that means, that the group has
|
||||
// been resized beyond its max size. We distribute the excess space
|
||||
// evenly.
|
||||
if (size > 0) {
|
||||
for (int32 i = 0; i < infoCount; i++) {
|
||||
infos[i].size += (i + 1) * size / infoCount
|
||||
- i * size / infoCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
GroupView::_AddInsetsAndSpacing(BSize size)
|
||||
{
|
||||
size.width = BLayoutUtils::AddDistances(size.width,
|
||||
fInsets.left + fInsets.right - 1
|
||||
+ (fColumnCount - 1) * fColumnSpacing);
|
||||
size.height = BLayoutUtils::AddDistances(size.height,
|
||||
fInsets.top + fInsets.bottom - 1
|
||||
+ (fRowCount - 1) * fRowSpacing);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
GroupView::_SubtractInsetsAndSpacing(BSize size)
|
||||
{
|
||||
size.width = BLayoutUtils::SubtractDistances(size.width,
|
||||
fInsets.left + fInsets.right - 1
|
||||
+ (fColumnCount - 1) * fColumnSpacing);
|
||||
size.height = BLayoutUtils::SubtractDistances(size.height,
|
||||
fInsets.top + fInsets.bottom - 1
|
||||
+ (fRowCount - 1) * fRowSpacing);
|
||||
return size;
|
||||
}
|
||||
|
||||
int32
|
||||
GroupView::_RowCount() const
|
||||
{
|
||||
int32 childCount = CountChildren();
|
||||
int32 count;
|
||||
if (fOrientation == B_HORIZONTAL)
|
||||
count = min_c(fLineCount, childCount);
|
||||
else
|
||||
count = (childCount + fLineCount - 1) / fLineCount;
|
||||
|
||||
return max_c(count, 1);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
GroupView::_ColumnCount() const
|
||||
{
|
||||
int32 childCount = CountChildren();
|
||||
int32 count;
|
||||
if (fOrientation == B_HORIZONTAL)
|
||||
count = (childCount + fLineCount - 1) / fLineCount;
|
||||
else
|
||||
count = min_c(fLineCount, childCount);
|
||||
|
||||
return max_c(count, 1);
|
||||
}
|
||||
|
||||
|
||||
View*
|
||||
GroupView::_ChildAt(int32 column, int32 row) const
|
||||
{
|
||||
if (fOrientation == B_HORIZONTAL)
|
||||
return ChildAt(column * fLineCount + row);
|
||||
else
|
||||
return ChildAt(row * fLineCount + column);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Glue
|
||||
|
||||
|
||||
Glue::Glue()
|
||||
: View()
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Strut
|
||||
|
||||
|
||||
Strut::Strut(float pixelWidth, float pixelHeight)
|
||||
: View(),
|
||||
fSize(pixelWidth >= 0 ? pixelWidth - 1 : B_SIZE_UNSET,
|
||||
pixelHeight >= 0 ? pixelHeight - 1 : B_SIZE_UNSET)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
Strut::MinSize()
|
||||
{
|
||||
return BLayoutUtils::ComposeSize(fSize, BSize(-1, -1));
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
Strut::MaxSize()
|
||||
{
|
||||
return BLayoutUtils::ComposeSize(fSize,
|
||||
BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - HStrut
|
||||
|
||||
|
||||
HStrut::HStrut(float width)
|
||||
: Strut(width, -1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - VStrut
|
||||
|
||||
|
||||
VStrut::VStrut(float height)
|
||||
: Strut(-1, height)
|
||||
{
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WIDGET_LAYOUT_TEST_GROUP_VIEW_H
|
||||
#define WIDGET_LAYOUT_TEST_GROUP_VIEW_H
|
||||
|
||||
|
||||
#include "View.h"
|
||||
|
||||
|
||||
// GroupView
|
||||
class GroupView : public View {
|
||||
public:
|
||||
GroupView(enum orientation orientation,
|
||||
int32 lineCount = 1);
|
||||
virtual ~GroupView();
|
||||
|
||||
void SetSpacing(float horizontal, float vertical);
|
||||
void SetInsets(float left, float top, float right,
|
||||
float bottom);
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
virtual BSize PreferredSize();
|
||||
virtual BAlignment Alignment();
|
||||
|
||||
virtual void Layout();
|
||||
|
||||
private:
|
||||
struct LayoutInfo;
|
||||
|
||||
private:
|
||||
void _ValidateMinMax();
|
||||
void _LayoutLine(int32 size, LayoutInfo* infos,
|
||||
int32 infoCount);
|
||||
|
||||
BSize _AddInsetsAndSpacing(BSize size);
|
||||
BSize _SubtractInsetsAndSpacing(BSize size);
|
||||
|
||||
int32 _RowCount() const;
|
||||
int32 _ColumnCount() const;
|
||||
View* _ChildAt(int32 column, int32 row) const;
|
||||
|
||||
private:
|
||||
enum orientation fOrientation;
|
||||
int32 fLineCount;
|
||||
float fColumnSpacing;
|
||||
float fRowSpacing;
|
||||
BRect fInsets;
|
||||
bool fMinMaxValid;
|
||||
int32 fMinWidth;
|
||||
int32 fMinHeight;
|
||||
int32 fMaxWidth;
|
||||
int32 fMaxHeight;
|
||||
int32 fPreferredWidth;
|
||||
int32 fPreferredHeight;
|
||||
LayoutInfo* fColumnInfos;
|
||||
LayoutInfo* fRowInfos;
|
||||
int32 fColumnCount;
|
||||
int32 fRowCount;
|
||||
};
|
||||
|
||||
|
||||
// Glue
|
||||
class Glue : public View {
|
||||
public:
|
||||
Glue();
|
||||
};
|
||||
|
||||
|
||||
// Strut
|
||||
class Strut : public View {
|
||||
public:
|
||||
Strut(float pixelWidth, float pixelHeight);
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
|
||||
private:
|
||||
BSize fSize;
|
||||
};
|
||||
|
||||
|
||||
// HStrut
|
||||
class HStrut : public Strut {
|
||||
public:
|
||||
HStrut(float width);
|
||||
};
|
||||
|
||||
|
||||
// VStrut
|
||||
class VStrut : public Strut {
|
||||
public:
|
||||
VStrut(float height);
|
||||
};
|
||||
|
||||
|
||||
#endif // WIDGET_LAYOUT_TEST_GROUP_VIEW_H
|
@ -4,6 +4,14 @@ SetSubDirSupportedPlatforms haiku libbe_test ;
|
||||
|
||||
SimpleTest WidgetLayoutTest :
|
||||
WidgetLayoutTest.cpp
|
||||
|
||||
CheckBox.cpp
|
||||
GroupView.cpp
|
||||
StringView.cpp
|
||||
TwoDimensionalSliderView.cpp
|
||||
View.cpp
|
||||
ViewContainer.cpp
|
||||
WrapperView.cpp
|
||||
:
|
||||
be
|
||||
;
|
||||
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "StringView.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <View.h>
|
||||
|
||||
|
||||
StringView::StringView(const char* string)
|
||||
: View(),
|
||||
fString(string),
|
||||
fAlignment(B_ALIGN_LEFT),
|
||||
fStringAscent(0),
|
||||
fStringDescent(0),
|
||||
fStringWidth(0),
|
||||
fExplicitMinSize(B_SIZE_UNSET, B_SIZE_UNSET)
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
fTextColor = (rgb_color){ 0, 0, 0, 255 };
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringView::SetString(const char* string)
|
||||
{
|
||||
fString = string;
|
||||
|
||||
_UpdateStringMetrics();
|
||||
Invalidate();
|
||||
InvalidateLayout();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringView::SetAlignment(alignment align)
|
||||
{
|
||||
if (align != fAlignment) {
|
||||
fAlignment = align;
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringView::SetTextColor(rgb_color color)
|
||||
{
|
||||
fTextColor = color;
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
StringView::MinSize()
|
||||
{
|
||||
BSize size(fExplicitMinSize);
|
||||
if (!size.IsWidthSet())
|
||||
size.width = fStringWidth - 1;
|
||||
if (!size.IsHeightSet())
|
||||
size.height = fStringAscent + fStringDescent - 1;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringView::SetExplicitMinSize(BSize size)
|
||||
{
|
||||
fExplicitMinSize = size;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringView::AddedToContainer()
|
||||
{
|
||||
_UpdateStringMetrics();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringView::Draw(BView* container, BRect updateRect)
|
||||
{
|
||||
BSize size(Size());
|
||||
int widthDiff = (int)size.width + 1 - (int)fStringWidth;
|
||||
int heightDiff = (int)size.height + 1
|
||||
- (int)(fStringAscent + (int)fStringDescent);
|
||||
BPoint base;
|
||||
|
||||
// horizontal alignment
|
||||
switch (fAlignment) {
|
||||
case B_ALIGN_RIGHT:
|
||||
base.x = widthDiff;
|
||||
break;
|
||||
case B_ALIGN_LEFT:
|
||||
default:
|
||||
base.x = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
base.y = heightDiff / 2 + fStringAscent;
|
||||
|
||||
container->SetHighColor(fTextColor);
|
||||
container->DrawString(fString.String(), base);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StringView::_UpdateStringMetrics()
|
||||
{
|
||||
BView* container = Container();
|
||||
if (!container)
|
||||
return;
|
||||
|
||||
BFont font;
|
||||
container->GetFont(&font);
|
||||
|
||||
font_height fh;
|
||||
font.GetHeight(&fh);
|
||||
|
||||
fStringAscent = ceilf(fh.ascent);
|
||||
fStringDescent = ceilf(fh.descent);
|
||||
fStringWidth = font.StringWidth(fString.String());
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WIDGET_LAYOUT_TEST_STRING_VIEW_H
|
||||
#define WIDGET_LAYOUT_TEST_STRING_VIEW_H
|
||||
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include "View.h"
|
||||
|
||||
|
||||
class StringView : public View {
|
||||
public:
|
||||
StringView(const char* string);
|
||||
|
||||
void SetString(const char* string);
|
||||
void SetAlignment(alignment align);
|
||||
void SetTextColor(rgb_color color);
|
||||
|
||||
virtual BSize MinSize();
|
||||
|
||||
void SetExplicitMinSize(BSize size);
|
||||
|
||||
virtual void AddedToContainer();
|
||||
|
||||
virtual void Draw(BView* container, BRect updateRect);
|
||||
|
||||
private:
|
||||
void _UpdateStringMetrics();
|
||||
|
||||
private:
|
||||
BString fString;
|
||||
alignment fAlignment;
|
||||
rgb_color fTextColor;
|
||||
float fStringAscent;
|
||||
float fStringDescent;
|
||||
float fStringWidth;
|
||||
BSize fExplicitMinSize;
|
||||
};
|
||||
|
||||
|
||||
#endif // WIDGET_LAYOUT_TEST_STRING_VIEW_H
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "TwoDimensionalSliderView.h"
|
||||
|
||||
#include <View.h>
|
||||
|
||||
|
||||
TwoDimensionalSliderView::TwoDimensionalSliderView(BMessage* message,
|
||||
BMessenger target)
|
||||
: View(BRect(0, 0, 4, 4)),
|
||||
BInvoker(message, target),
|
||||
fMinLocation(0, 0),
|
||||
fMaxLocation(0, 0),
|
||||
fDragging(false)
|
||||
{
|
||||
SetViewColor((rgb_color){0, 120, 0, 255});
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwoDimensionalSliderView::SetLocationRange(BPoint minLocation,
|
||||
BPoint maxLocation)
|
||||
{
|
||||
if (maxLocation.x < minLocation.x)
|
||||
maxLocation.x = minLocation.x;
|
||||
if (maxLocation.y < minLocation.y)
|
||||
maxLocation.y = minLocation.y;
|
||||
|
||||
fMinLocation = minLocation;
|
||||
fMaxLocation = maxLocation;
|
||||
|
||||
// force valid value
|
||||
SetValue(Value());
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
TwoDimensionalSliderView::MinLocation() const
|
||||
{
|
||||
return fMinLocation;
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
TwoDimensionalSliderView::MaxLocation() const
|
||||
{
|
||||
return fMaxLocation;
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
TwoDimensionalSliderView::Value() const
|
||||
{
|
||||
return Location() - fMinLocation;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwoDimensionalSliderView::SetValue(BPoint value)
|
||||
{
|
||||
BPoint location = fMinLocation + value;
|
||||
if (location.x < fMinLocation.x)
|
||||
location.x = fMinLocation.x;
|
||||
if (location.y < fMinLocation.y)
|
||||
location.y = fMinLocation.y;
|
||||
if (location.x > fMaxLocation.x)
|
||||
location.x = fMaxLocation.x;
|
||||
if (location.y > fMaxLocation.y)
|
||||
location.y = fMaxLocation.y;
|
||||
|
||||
if (location != Location()) {
|
||||
SetFrame(Frame().OffsetToCopy(location));
|
||||
|
||||
// send the message
|
||||
if (Message()) {
|
||||
BMessage message(*Message());
|
||||
message.AddPoint("value", Value());
|
||||
InvokeNotify(&message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwoDimensionalSliderView::MouseDown(BPoint where, uint32 buttons,
|
||||
int32 modifiers)
|
||||
{
|
||||
if (fDragging)
|
||||
return;
|
||||
|
||||
fOriginalLocation = Frame().LeftTop();
|
||||
fOriginalPoint = ConvertToContainer(where);
|
||||
fDragging = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwoDimensionalSliderView::MouseUp(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
if (!fDragging || (buttons & B_PRIMARY_MOUSE_BUTTON))
|
||||
return;
|
||||
|
||||
fDragging = false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TwoDimensionalSliderView::MouseMoved(BPoint where, uint32 buttons,
|
||||
int32 modifiers)
|
||||
{
|
||||
if (!fDragging)
|
||||
return;
|
||||
|
||||
BPoint moved = ConvertToContainer(where) - fOriginalPoint;
|
||||
SetValue(fOriginalLocation - fMinLocation + moved);
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WIDGET_LAYOUT_TEST_TWO_DIMENSIONAL_SLIDER_VIEW_H
|
||||
#define WIDGET_LAYOUT_TEST_TWO_DIMENSIONAL_SLIDER_VIEW_H
|
||||
|
||||
|
||||
#include <Invoker.h>
|
||||
|
||||
#include "View.h"
|
||||
|
||||
|
||||
class TwoDimensionalSliderView : public View, public BInvoker {
|
||||
public:
|
||||
TwoDimensionalSliderView(
|
||||
BMessage* message = NULL,
|
||||
BMessenger target = BMessenger());
|
||||
|
||||
void SetLocationRange(BPoint minLocation,
|
||||
BPoint maxLocation);
|
||||
|
||||
BPoint MinLocation() const;
|
||||
BPoint MaxLocation() const;
|
||||
|
||||
BPoint Value() const;
|
||||
void SetValue(BPoint value);
|
||||
|
||||
virtual void MouseDown(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
virtual void MouseUp(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
virtual void MouseMoved(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
|
||||
private:
|
||||
BPoint fMinLocation;
|
||||
BPoint fMaxLocation;
|
||||
bool fDragging;
|
||||
BPoint fOriginalPoint;
|
||||
BPoint fOriginalLocation;
|
||||
};
|
||||
|
||||
#endif // WIDGET_LAYOUT_TEST_TWO_DIMENSIONAL_SLIDER_VIEW_H
|
487
src/tests/kits/interface/layout/widget_layout_test/View.cpp
Normal file
487
src/tests/kits/interface/layout/widget_layout_test/View.cpp
Normal file
@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "View.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Region.h>
|
||||
#include <View.h>
|
||||
|
||||
|
||||
View::View()
|
||||
: fFrame(0, 0, 0, 0),
|
||||
fContainer(NULL),
|
||||
fParent(NULL),
|
||||
fChildren(),
|
||||
fViewColor(B_TRANSPARENT_32_BIT),
|
||||
fLayoutValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
View::View(BRect frame)
|
||||
: fFrame(frame),
|
||||
fContainer(NULL),
|
||||
fParent(NULL),
|
||||
fChildren(),
|
||||
fViewColor(B_TRANSPARENT_32_BIT),
|
||||
fLayoutValid(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
View::~View()
|
||||
{
|
||||
// delete children
|
||||
for (int32 i = CountChildren() - 1; i >= 0; i--)
|
||||
delete RemoveChild(i);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::SetFrame(BRect frame)
|
||||
{
|
||||
if (frame != fFrame && frame.IsValid()) {
|
||||
BRect oldFrame(frame);
|
||||
Invalidate();
|
||||
fFrame = frame;
|
||||
Invalidate();
|
||||
|
||||
FrameChanged(oldFrame, frame);
|
||||
}
|
||||
|
||||
// relayout if necessary
|
||||
if (!fLayoutValid) {
|
||||
Layout();
|
||||
fLayoutValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
View::Frame() const
|
||||
{
|
||||
return fFrame;
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
View::Bounds() const
|
||||
{
|
||||
return BRect(fFrame).OffsetToCopy(B_ORIGIN);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::SetLocation(BPoint location)
|
||||
{
|
||||
SetFrame(fFrame.OffsetToCopy(location));
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
View::Location() const
|
||||
{
|
||||
return fFrame.LeftTop();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::SetSize(BSize size)
|
||||
{
|
||||
BRect frame(fFrame);
|
||||
frame.right = frame.left + size.width;
|
||||
frame.bottom = frame.top + size.height;
|
||||
SetFrame(frame);
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
View::Size() const
|
||||
{
|
||||
return Frame().Size();
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
View::MinSize()
|
||||
{
|
||||
return BSize(-1, -1);
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
View::MaxSize()
|
||||
{
|
||||
return BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED);
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
View::PreferredSize()
|
||||
{
|
||||
return MinSize();
|
||||
}
|
||||
|
||||
|
||||
BAlignment
|
||||
View::Alignment()
|
||||
{
|
||||
return BAlignment(B_ALIGN_HORIZONTAL_CENTER, B_ALIGN_VERTICAL_CENTER);
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
View::LocationInContainer() const
|
||||
{
|
||||
BPoint location = fFrame.LeftTop();
|
||||
return (fParent ? fParent->LocationInContainer() + location : location);
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
View::FrameInContainer() const
|
||||
{
|
||||
BRect frame(fFrame);
|
||||
return frame.OffsetToCopy(LocationInContainer());
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
View::ConvertFromContainer(BPoint point) const
|
||||
{
|
||||
return point - LocationInContainer();
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
View::ConvertFromContainer(BRect rect) const
|
||||
{
|
||||
return rect.OffsetBySelf(-LocationInContainer());
|
||||
}
|
||||
|
||||
|
||||
BPoint
|
||||
View::ConvertToContainer(BPoint point) const
|
||||
{
|
||||
return point + LocationInContainer();
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
View::ConvertToContainer(BRect rect) const
|
||||
{
|
||||
return rect.OffsetBySelf(LocationInContainer());
|
||||
}
|
||||
|
||||
|
||||
View*
|
||||
View::Parent() const
|
||||
{
|
||||
return fParent;
|
||||
}
|
||||
|
||||
|
||||
BView*
|
||||
View::Container() const
|
||||
{
|
||||
return fContainer;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
View::AddChild(View* child)
|
||||
{
|
||||
if (!child)
|
||||
return false;
|
||||
|
||||
if (child->Parent() || child->Container()) {
|
||||
fprintf(stderr, "View::AddChild(): view %p already has a parent "
|
||||
"or is the container view\n", child);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fChildren.AddItem(child))
|
||||
return false;
|
||||
|
||||
child->_AddedToParent(this);
|
||||
|
||||
child->Invalidate();
|
||||
InvalidateLayout();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
View::RemoveChild(View* child)
|
||||
{
|
||||
if (!child)
|
||||
return false;
|
||||
|
||||
return RemoveChild(IndexOfChild(child));
|
||||
}
|
||||
|
||||
|
||||
View*
|
||||
View::RemoveChild(int32 index)
|
||||
{
|
||||
if (index < 0 || index >= fChildren.CountItems())
|
||||
return NULL;
|
||||
|
||||
View* child = ChildAt(index);
|
||||
child->Invalidate();
|
||||
child->_RemovingFromParent();
|
||||
fChildren.RemoveItem(index);
|
||||
|
||||
InvalidateLayout();
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
View::CountChildren() const
|
||||
{
|
||||
return fChildren.CountItems();
|
||||
}
|
||||
|
||||
|
||||
View*
|
||||
View::ChildAt(int32 index) const
|
||||
{
|
||||
return (View*)fChildren.ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
View*
|
||||
View::ChildAt(BPoint point) const
|
||||
{
|
||||
for (int32 i = 0; View* child = ChildAt(i); i++) {
|
||||
if (child->Frame().Contains(point))
|
||||
return child;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
View*
|
||||
View::AncestorAt(BPoint point, BPoint* localPoint) const
|
||||
{
|
||||
if (!Bounds().Contains(point))
|
||||
return NULL;
|
||||
|
||||
View* view = const_cast<View*>(this);
|
||||
|
||||
// Iterate deeper down the hierarchy, until we reach a view that
|
||||
// doesn't have a child at the location.
|
||||
while (true) {
|
||||
View* child = view->ChildAt(point);
|
||||
if (!child) {
|
||||
if (localPoint)
|
||||
*localPoint = point;
|
||||
return view;
|
||||
}
|
||||
|
||||
view = child;
|
||||
point -= view->Frame().LeftTop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
View::IndexOfChild(View* child) const
|
||||
{
|
||||
return (child ? fChildren.IndexOf(child) : -1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::Invalidate(BRect rect)
|
||||
{
|
||||
if (fContainer) {
|
||||
rect = rect & Bounds();
|
||||
fContainer->Invalidate(rect.OffsetByCopy(LocationInContainer()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::Invalidate()
|
||||
{
|
||||
Invalidate(Bounds());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::InvalidateLayout()
|
||||
{
|
||||
if (fLayoutValid) {
|
||||
fLayoutValid = false;
|
||||
if (fParent)
|
||||
fParent->InvalidateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
View::IsLayoutValid() const
|
||||
{
|
||||
return fLayoutValid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::SetViewColor(rgb_color color)
|
||||
{
|
||||
fViewColor = color;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::Draw(BView* container, BRect updateRect)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::MouseDown(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::MouseUp(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::MouseMoved(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::AddedToContainer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::RemovingFromContainer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::FrameChanged(BRect oldFrame, BRect newFrame)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::Layout()
|
||||
{
|
||||
// simply trigger relayouting the children
|
||||
for (int32 i = 0; View* child = ChildAt(i); i++)
|
||||
child->SetFrame(child->Frame());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::_AddedToParent(View* parent)
|
||||
{
|
||||
fParent = parent;
|
||||
|
||||
if (parent->Container()) {
|
||||
Invalidate();
|
||||
_AddedToContainer(parent->Container());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::_RemovingFromParent()
|
||||
{
|
||||
if (fContainer)
|
||||
_RemovingFromContainer();
|
||||
|
||||
fParent = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::_AddedToContainer(BView* container)
|
||||
{
|
||||
fContainer = container;
|
||||
|
||||
AddedToContainer();
|
||||
|
||||
for (int32 i = 0; View* child = ChildAt(i); i++)
|
||||
child->_AddedToContainer(fContainer);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::_RemovingFromContainer()
|
||||
{
|
||||
for (int32 i = 0; View* child = ChildAt(i); i++)
|
||||
child->_RemovingFromContainer();
|
||||
|
||||
RemovingFromContainer();
|
||||
|
||||
fContainer = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
View::_Draw(BView* container, BRect updateRect)
|
||||
{
|
||||
// compute the clipping region
|
||||
BRegion region(Bounds());
|
||||
for (int32 i = 0; View* child = ChildAt(i); i++)
|
||||
region.Exclude(child->Frame());
|
||||
|
||||
if (region.Frame().IsValid()) {
|
||||
// set the clipping region
|
||||
container->ConstrainClippingRegion(®ion);
|
||||
|
||||
// draw the background, if it isn't transparent
|
||||
if (fViewColor.alpha != 0) {
|
||||
container->SetLowColor(fViewColor);
|
||||
container->FillRect(updateRect, B_SOLID_LOW);
|
||||
}
|
||||
|
||||
// draw this view
|
||||
Draw(container, updateRect);
|
||||
|
||||
// revert the clipping region
|
||||
region.Set(Bounds());
|
||||
container->ConstrainClippingRegion(®ion);
|
||||
}
|
||||
|
||||
// draw the children
|
||||
if (CountChildren() > 0) {
|
||||
container->PushState();
|
||||
|
||||
for (int32 i = 0; View* child = ChildAt(i); i++) {
|
||||
BRect childFrame = child->Frame();
|
||||
BRect childUpdateRect = updateRect & childFrame;
|
||||
if (childUpdateRect.IsValid()) {
|
||||
// set origin
|
||||
childUpdateRect.OffsetBy(-childFrame.LeftTop());
|
||||
container->SetOrigin(childFrame.LeftTop());
|
||||
|
||||
// draw
|
||||
child->_Draw(container, childUpdateRect);
|
||||
}
|
||||
}
|
||||
|
||||
container->PopState();
|
||||
}
|
||||
}
|
101
src/tests/kits/interface/layout/widget_layout_test/View.h
Normal file
101
src/tests/kits/interface/layout/widget_layout_test/View.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WIDGET_LAYOUT_TEST_VIEW_H
|
||||
#define WIDGET_LAYOUT_TEST_VIEW_H
|
||||
|
||||
|
||||
#include <Alignment.h>
|
||||
#include <List.h>
|
||||
#include <Rect.h>
|
||||
|
||||
|
||||
class BView;
|
||||
|
||||
|
||||
class View {
|
||||
public:
|
||||
View();
|
||||
View(BRect frame);
|
||||
virtual ~View();
|
||||
|
||||
virtual void SetFrame(BRect frame);
|
||||
BRect Frame() const;
|
||||
BRect Bounds() const;
|
||||
|
||||
void SetLocation(BPoint location);
|
||||
BPoint Location() const;
|
||||
|
||||
void SetSize(BSize size);
|
||||
BSize Size() const;
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
virtual BSize PreferredSize();
|
||||
virtual BAlignment Alignment();
|
||||
|
||||
BPoint LocationInContainer() const;
|
||||
BRect FrameInContainer() const;
|
||||
|
||||
BPoint ConvertFromContainer(BPoint point) const;
|
||||
BRect ConvertFromContainer(BRect rect) const;
|
||||
BPoint ConvertToContainer(BPoint point) const;
|
||||
BRect ConvertToContainer(BRect rect) const;
|
||||
|
||||
View* Parent() const;
|
||||
BView* Container() const;
|
||||
|
||||
bool AddChild(View* child);
|
||||
bool RemoveChild(View* child);
|
||||
View* RemoveChild(int32 index);
|
||||
|
||||
int32 CountChildren() const;
|
||||
View* ChildAt(int32 index) const;
|
||||
View* ChildAt(BPoint point) const;
|
||||
View* AncestorAt(BPoint point,
|
||||
BPoint* localPoint = NULL) const;
|
||||
int32 IndexOfChild(View* child) const;
|
||||
|
||||
void Invalidate(BRect rect);
|
||||
void Invalidate();
|
||||
virtual void InvalidateLayout();
|
||||
bool IsLayoutValid() const;
|
||||
|
||||
void SetViewColor(rgb_color color);
|
||||
|
||||
virtual void Draw(BView* container, BRect updateRect);
|
||||
|
||||
virtual void MouseDown(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
virtual void MouseUp(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
virtual void MouseMoved(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
|
||||
virtual void AddedToContainer();
|
||||
virtual void RemovingFromContainer();
|
||||
|
||||
virtual void FrameChanged(BRect oldFrame, BRect newFrame);
|
||||
|
||||
virtual void Layout();
|
||||
|
||||
protected:
|
||||
void _AddedToParent(View* parent);
|
||||
void _RemovingFromParent();
|
||||
|
||||
void _AddedToContainer(BView* container);
|
||||
void _RemovingFromContainer();
|
||||
|
||||
void _Draw(BView* container, BRect updateRect);
|
||||
|
||||
private:
|
||||
BRect fFrame;
|
||||
BView* fContainer;
|
||||
View* fParent;
|
||||
BList fChildren;
|
||||
rgb_color fViewColor;
|
||||
bool fLayoutValid;
|
||||
};
|
||||
|
||||
#endif // WIDGET_LAYOUT_TEST_VIEW_H
|
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "ViewContainer.h"
|
||||
|
||||
#include <Message.h>
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
// internal messages
|
||||
enum {
|
||||
MSG_LAYOUT_CONTAINER = 'layc',
|
||||
};
|
||||
|
||||
|
||||
ViewContainer::ViewContainer(BRect frame)
|
||||
: BView(frame, "view container", B_FOLLOW_NONE, B_WILL_DRAW),
|
||||
View(frame.OffsetToCopy(B_ORIGIN)),
|
||||
fMouseFocus(NULL)
|
||||
{
|
||||
BView::SetViewColor(B_TRANSPARENT_32_BIT);
|
||||
_AddedToContainer(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case MSG_LAYOUT_CONTAINER:
|
||||
View::Layout();
|
||||
break;
|
||||
default:
|
||||
BView::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::AllAttached()
|
||||
{
|
||||
Window()->PostMessage(MSG_LAYOUT_CONTAINER, this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::Draw(BRect updateRect)
|
||||
{
|
||||
View::_Draw(this, updateRect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::MouseDown(BPoint where)
|
||||
{
|
||||
// get mouse buttons and modifiers
|
||||
uint32 buttons;
|
||||
int32 modifiers;
|
||||
_GetButtonsAndModifiers(buttons, modifiers);
|
||||
|
||||
// get mouse focus
|
||||
if (!fMouseFocus && (buttons & B_PRIMARY_MOUSE_BUTTON)) {
|
||||
fMouseFocus = AncestorAt(where);
|
||||
if (fMouseFocus)
|
||||
SetMouseEventMask(B_POINTER_EVENTS);
|
||||
}
|
||||
|
||||
// call hook
|
||||
if (fMouseFocus) {
|
||||
fMouseFocus->MouseDown(fMouseFocus->ConvertFromContainer(where),
|
||||
buttons, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::MouseUp(BPoint where)
|
||||
{
|
||||
if (!fMouseFocus)
|
||||
return;
|
||||
|
||||
// get mouse buttons and modifiers
|
||||
uint32 buttons;
|
||||
int32 modifiers;
|
||||
_GetButtonsAndModifiers(buttons, modifiers);
|
||||
|
||||
// call hook
|
||||
if (fMouseFocus) {
|
||||
fMouseFocus->MouseUp(fMouseFocus->ConvertFromContainer(where),
|
||||
buttons, modifiers);
|
||||
}
|
||||
|
||||
// unset the mouse focus when the primary button has been released
|
||||
if (!(buttons & B_PRIMARY_MOUSE_BUTTON))
|
||||
fMouseFocus = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::MouseMoved(BPoint where, uint32 code, const BMessage* message)
|
||||
{
|
||||
if (!fMouseFocus)
|
||||
return;
|
||||
|
||||
// get mouse buttons and modifiers
|
||||
uint32 buttons;
|
||||
int32 modifiers;
|
||||
_GetButtonsAndModifiers(buttons, modifiers);
|
||||
|
||||
// call hook
|
||||
if (fMouseFocus) {
|
||||
fMouseFocus->MouseMoved(fMouseFocus->ConvertFromContainer(where),
|
||||
buttons, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::InvalidateLayout()
|
||||
{
|
||||
if (View::IsLayoutValid()) {
|
||||
View::InvalidateLayout();
|
||||
|
||||
// trigger asynchronous re-layout
|
||||
if (Window())
|
||||
Window()->PostMessage(MSG_LAYOUT_CONTAINER, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::Draw(BView* container, BRect updateRect)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::MouseDown(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::MouseUp(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::MouseMoved(BPoint where, uint32 buttons, int32 modifiers)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ViewContainer::_GetButtonsAndModifiers(uint32& buttons, int32& modifiers)
|
||||
{
|
||||
buttons = 0;
|
||||
modifiers = 0;
|
||||
|
||||
if (BMessage* message = Window()->CurrentMessage()) {
|
||||
if (message->FindInt32("buttons", (int32*)&buttons) != B_OK)
|
||||
buttons = 0;
|
||||
if (message->FindInt32("modifiers", modifiers) != B_OK)
|
||||
modifiers = 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WIDGET_LAYOUT_TEST_VIEW_CONTAINER_H
|
||||
#define WIDGET_LAYOUT_TEST_VIEW_CONTAINER_H
|
||||
|
||||
|
||||
#include <View.h>
|
||||
|
||||
#include "View.h"
|
||||
|
||||
|
||||
class ViewContainer : public BView, public View {
|
||||
public:
|
||||
ViewContainer(BRect frame);
|
||||
|
||||
// BView hooks
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
virtual void AllAttached();
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MouseUp(BPoint where);
|
||||
virtual void MouseMoved(BPoint where, uint32 code,
|
||||
const BMessage* message);
|
||||
|
||||
// View hooks
|
||||
|
||||
virtual void InvalidateLayout();
|
||||
|
||||
virtual void Draw(BView* container, BRect updateRect);
|
||||
|
||||
virtual void MouseDown(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
virtual void MouseUp(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
virtual void MouseMoved(BPoint where, uint32 buttons,
|
||||
int32 modifiers);
|
||||
|
||||
private:
|
||||
void _GetButtonsAndModifiers(uint32& buttons,
|
||||
int32& modifiers);
|
||||
|
||||
private:
|
||||
View* fMouseFocus;
|
||||
};
|
||||
|
||||
#endif // WIDGET_LAYOUT_TEST_VIEW_CONTAINER_H
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "WrapperView.h"
|
||||
|
||||
#include <LayoutUtils.h>
|
||||
#include <View.h>
|
||||
|
||||
|
||||
WrapperView::WrapperView(BView* view)
|
||||
: View(),
|
||||
fView(view),
|
||||
fInsets(1, 1, 1, 1)
|
||||
{
|
||||
SetViewColor((rgb_color){255, 0, 0, 255});
|
||||
}
|
||||
|
||||
|
||||
BView*
|
||||
WrapperView::GetView() const
|
||||
{
|
||||
return fView;
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
WrapperView::MinSize()
|
||||
{
|
||||
return _FromViewSize(fView->MinSize());
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
WrapperView::MaxSize()
|
||||
{
|
||||
return _FromViewSize(fView->MaxSize());
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
WrapperView::PreferredSize()
|
||||
{
|
||||
return _FromViewSize(fView->PreferredSize());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WrapperView::AddedToContainer()
|
||||
{
|
||||
_UpdateViewFrame();
|
||||
|
||||
Container()->AddChild(fView);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WrapperView::RemovingFromContainer()
|
||||
{
|
||||
Container()->RemoveChild(fView);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WrapperView::FrameChanged(BRect oldFrame, BRect newFrame)
|
||||
{
|
||||
_UpdateViewFrame();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WrapperView::_UpdateViewFrame()
|
||||
{
|
||||
BRect frame(_ViewFrameInContainer());
|
||||
fView->MoveTo(frame.LeftTop());
|
||||
fView->ResizeTo(frame.Width(), frame.Height());
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
WrapperView::_ViewFrame() const
|
||||
{
|
||||
BRect viewFrame(Bounds());
|
||||
viewFrame.left += fInsets.left;
|
||||
viewFrame.top += fInsets.top;
|
||||
viewFrame.right -= fInsets.right;
|
||||
viewFrame.bottom -= fInsets.bottom;
|
||||
|
||||
return viewFrame;
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
WrapperView::_ViewFrameInContainer() const
|
||||
{
|
||||
return ConvertToContainer(_ViewFrame());
|
||||
}
|
||||
|
||||
|
||||
BSize
|
||||
WrapperView::_FromViewSize(BSize size) const
|
||||
{
|
||||
float horizontalInsets = fInsets.left + fInsets.right - 1;
|
||||
float verticalInsets = fInsets.top + fInsets.bottom - 1;
|
||||
return BSize(BLayoutUtils::AddDistances(size.width, horizontalInsets),
|
||||
BLayoutUtils::AddDistances(size.height, verticalInsets));
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WIDGET_LAYOUT_TEST_WRAPPER_VIEW_H
|
||||
#define WIDGET_LAYOUT_TEST_WRAPPER_VIEW_H
|
||||
|
||||
|
||||
#include "View.h"
|
||||
|
||||
|
||||
class BView;
|
||||
|
||||
|
||||
class WrapperView : public View {
|
||||
public:
|
||||
WrapperView(BView* view);
|
||||
|
||||
BView* GetView() const;
|
||||
|
||||
virtual BSize MinSize();
|
||||
virtual BSize MaxSize();
|
||||
virtual BSize PreferredSize();
|
||||
|
||||
virtual void AddedToContainer();
|
||||
virtual void RemovingFromContainer();
|
||||
|
||||
virtual void FrameChanged(BRect oldFrame, BRect newFrame);
|
||||
|
||||
private:
|
||||
void _UpdateViewFrame();
|
||||
BRect _ViewFrame() const;
|
||||
BRect _ViewFrameInContainer() const;
|
||||
|
||||
BSize _FromViewSize(BSize size) const;
|
||||
|
||||
private:
|
||||
BView* fView;
|
||||
BRect fInsets;
|
||||
};
|
||||
|
||||
|
||||
#endif // WIDGET_LAYOUT_TEST_WRAPPER_VIEW_H
|
Loading…
Reference in New Issue
Block a user