Playground is now a little drawing app. Fully functional under Haiku, but with some strange defects in arc calculation within AGG.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12702 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-05-18 00:15:58 +00:00
parent 4a95e83357
commit 78c1c29baf
10 changed files with 877 additions and 277 deletions

View File

@ -2,6 +2,6 @@ SubDir OBOS_TOP src tests servers app ;
SubInclude OBOS_TOP src tests servers app copy_bits ;
SubInclude OBOS_TOP src tests servers app painter ;
SubInclude OBOS_TOP src tests servers app playground ;
SubInclude OBOS_TOP src tests servers app scrolling ;
SubInclude OBOS_TOP src tests servers app textview ;
SubInclude OBOS_TOP src tests servers app playground ;

View File

@ -3,8 +3,11 @@ SubDir OBOS_TOP src tests servers app playground ;
UseHeaders [ FDirName os app ] ;
UseHeaders [ FDirName os interface ] ;
SimpleTest Playground :
App Playground :
main.cpp
ObjectView.cpp
ObjectWindow.cpp
States.cpp
;
if ( $(TARGET_PLATFORM) = haiku ) {

View File

@ -0,0 +1,228 @@
// ObjectView.cpp
#include <stdio.h>
#include <Message.h>
#include <Window.h>
#include "States.h"
#include "ObjectView.h"
// constructor
ObjectView::ObjectView(BRect frame, const char* name,
uint32 resizeFlags, uint32 flags)
: BView(frame, name, resizeFlags, flags | B_FRAME_EVENTS),
fState(NULL),
fObjectType(OBJECT_LINE),
fStateList(20),
fColor((rgb_color){ 0, 80, 255, 100 }),
fFill(false),
fPenSize(10.0)
{
rgb_color bg = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_1_TINT);
SetViewColor(bg);
SetLowColor(bg);
}
// AttachedToWindow
void
ObjectView::AttachedToWindow()
{
}
// Draw
void
ObjectView::Draw(BRect updateRect)
{
rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR);
rgb_color shadow = tint_color(noTint, B_DARKEN_2_TINT);
rgb_color light = tint_color(noTint, B_LIGHTEN_MAX_TINT);
BRect r(Bounds());
BeginLineArray(4);
AddLine(BPoint(r.left, r.top),
BPoint(r.right, r.top), shadow);
AddLine(BPoint(r.right, r.top + 1),
BPoint(r.right, r.bottom), light);
AddLine(BPoint(r.right - 1, r.bottom),
BPoint(r.left, r.bottom), light);
AddLine(BPoint(r.left, r.bottom - 1),
BPoint(r.left, r.top + 1), shadow);
EndLineArray();
SetHighColor(255, 0, 0, 128);
const char* message = "Click and drag";
float width = StringWidth(message);
BPoint p(r.left + r.Width() / 2.0 - width / 2.0,
r.top + r.Height() / 2.0);
DrawString(message, p);
message = "to draw an object!";
width = StringWidth(message);
p.x = r.left + r.Width() / 2.0 - width / 2.0;
p.y += 20;
DrawString(message, p);
SetDrawingMode(B_OP_ALPHA);
for (int32 i = 0; State* state = (State*)fStateList.ItemAt(i); i++)
state->Draw(this);
// TODO: this should not be necessary with proper state stack
// (a new state is pushed before Draw() is called)
SetPenSize(1.0);
SetDrawingMode(B_OP_COPY);
}
// MouseDown
void
ObjectView::MouseDown(BPoint where)
{
if (!fState)
SetState(State::StateFor(fObjectType, fColor, fFill, fPenSize));
if (fState) {
Invalidate(fState->Bounds());
fState->MouseDown(where);
Invalidate(fState->Bounds());
}
}
// MouseUp
void
ObjectView::MouseUp(BPoint where)
{
if (fState) {
fState->MouseUp(where);
}
}
// MouseMoved
void
ObjectView::MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage)
{
if (fState && fState->IsTracking()) {
BRect before = fState->Bounds();
fState->MouseMoved(where);
BRect after = fState->Bounds();
BRect invalid(before | after);
Invalidate(invalid);
}
}
// SetState
void
ObjectView::SetState(State* state)
{
fState = state;
if (fState) {
Invalidate(fState->Bounds());
AddObject(fState);
}
}
// SetObjectType
void
ObjectView::SetObjectType(int32 type)
{
if (type != fObjectType) {
fObjectType = type;
SetState(NULL);
}
}
// AddObject
void
ObjectView::AddObject(State* state)
{
if (state) {
fStateList.AddItem((void*)state);
Window()->PostMessage(MSG_OBJECT_COUNT_CHANGED);
}
}
// CountObjects
int32
ObjectView::CountObjects() const
{
return fStateList.CountItems();
}
// MakeEmpty
void
ObjectView::MakeEmpty()
{
for (int32 i = 0; State* state = (State*)fStateList.ItemAt(i); i++)
delete state;
fStateList.MakeEmpty();
Window()->PostMessage(MSG_OBJECT_COUNT_CHANGED);
fState = NULL;
Invalidate();
}
// SetStateColor
void
ObjectView::SetStateColor(rgb_color color)
{
if (color.red != fColor.red ||
color.green != fColor.green ||
color.blue != fColor.blue ||
color.alpha != fColor.alpha) {
fColor = color;
if (fState) {
fState->SetColor(fColor);
Invalidate(fState->Bounds());
}
}
}
// SetStateFill
void
ObjectView::SetStateFill(bool fill)
{
if (fFill != fill) {
fFill = fill;
if (fState) {
BRect before = fState->Bounds();
fState->SetFill(fill);
BRect after = fState->Bounds();
BRect invalid(before | after);
Invalidate(invalid);
}
}
}
// SetStatePenSize
void
ObjectView::SetStatePenSize(float penSize)
{
if (fPenSize != penSize) {
fPenSize = penSize;
if (fState) {
BRect before = fState->Bounds();
fState->SetPenSize(penSize);
BRect after = fState->Bounds();
BRect invalid(before | after);
Invalidate(invalid);
}
}
}

View File

@ -0,0 +1,64 @@
// ObjectView.h
#ifndef OBJECT_VIEW_H
#define OBJECT_VIEW_H
#include <List.h>
#include <View.h>
class State;
enum {
MSG_OBJECT_COUNT_CHANGED = 'obcc',
};
class ObjectView : public BView {
public:
ObjectView(BRect frame, const char* name,
uint32 resizeFlags, uint32 flags);
// BView
virtual void AttachedToWindow();
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage);
// ObjectView
void SetState(State* state);
void SetObjectType(int32 type);
int32 ObjectType() const
{ return fObjectType; }
void AddObject(State* state);
int32 CountObjects() const;
void MakeEmpty();
void SetStateColor(rgb_color color);
rgb_color StateColor() const
{ return fColor; }
void SetStateFill(bool fill);
bool StateFill() const
{ return fFill; }
void SetStatePenSize(float penSize);
float StatePenSize() const
{ return fPenSize; }
private:
State* fState;
int32 fObjectType;
BList fStateList;
rgb_color fColor;
bool fFill;
float fPenSize;
};
#endif // OBJECT_VIEW_H

View File

@ -0,0 +1,277 @@
// main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <Application.h>
#include <Box.h>
#include <Button.h>
#include <CheckBox.h>
#include <Menu.h>
#include <MenuBar.h>
#include <MenuItem.h>
#include <String.h>
#include <RadioButton.h>
#include <TextControl.h>
#include <TextView.h>
#include "ObjectView.h"
#include "States.h"
#include "ObjectWindow.h"
enum {
MSG_SET_OBJECT_TYPE = 'stot',
MSG_SET_FILL_OR_STROKE = 'stfs',
MSG_SET_COLOR = 'stcl',
MSG_SET_PEN_SIZE = 'stps',
MSG_NEW_OBJECT = 'nobj',
MSG_UNDO = 'undo',
MSG_REDO = 'redo',
MSG_CLEAR = 'clir',
};
// constructor
ObjectWindow::ObjectWindow(BRect frame, const char* name)
: BWindow(frame, name, B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS)
{
BRect b(Bounds());
b.bottom = b.top + 8;
BMenuBar* menuBar = new BMenuBar(b, "menu bar");
AddChild(menuBar);
BMenu* menu = new BMenu("Menus");
menuBar->AddItem(menu);
BMenuItem* menuItem = new BMenuItem("Quit", NULL, 'Q');
menu->AddItem(menuItem);
menuBar->AddItem(new BMenu("don't"));
menuBar->AddItem(new BMenu("work!"));
menuBar->AddItem(new BMenu("(yet)"));
b = Bounds();
b.top = menuBar->Bounds().bottom + 1;
BBox* bg = new BBox(b, "bg box", B_FOLLOW_ALL, B_WILL_DRAW, B_PLAIN_BORDER);
AddChild(bg);
bg->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
b = bg->Bounds();
// object views occupies the right side of the window
b.Set(ceilf((b.left + b.right) / 3.0) + 3.0, b.top + 5.0, b.right - 5.0, b.bottom - 5.0);
fObjectView = new ObjectView(b, "object view", B_FOLLOW_ALL,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE);
bg->AddChild(fObjectView);
b = bg->Bounds();
// controls occupy the left side of the window
b.Set(b.left + 5.0, b.top + 5.0, ceilf((b.left + b.right) / 3.0) - 2.0, b.bottom - 5.0);
BBox* controlGroup = new BBox(b, "controls box", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
B_WILL_DRAW, B_FANCY_BORDER);
controlGroup->SetLabel("Controls");
bg->AddChild(controlGroup);
b = controlGroup->Bounds();
b.top += 10.0;
b.bottom = b.top + 25.0;
b.InsetBy(5.0, 5.0);
// new button
fNewB = new BButton(b, "new button", "New Object", new BMessage(MSG_NEW_OBJECT));
controlGroup->AddChild(fNewB);
// clear button
b.OffsetBy(0, fNewB->Bounds().Height() + 5.0);
fClearB = new BButton(b, "clear button", "Clear", new BMessage(MSG_CLEAR));
controlGroup->AddChild(fClearB);
// object type radio buttons
BMessage* message;
BRadioButton* radioButton;
b.OffsetBy(0, fClearB->Bounds().Height() + 5.0);
message = new BMessage(MSG_SET_OBJECT_TYPE);
message->AddInt32("type", OBJECT_LINE);
radioButton = new BRadioButton(b, "radio 1", "Line", message);
controlGroup->AddChild(radioButton);
radioButton->SetValue(B_CONTROL_ON);
b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
message = new BMessage(MSG_SET_OBJECT_TYPE);
message->AddInt32("type", OBJECT_RECT);
radioButton = new BRadioButton(b, "radio 2", "Rect", message);
controlGroup->AddChild(radioButton);
b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
message = new BMessage(MSG_SET_OBJECT_TYPE);
message->AddInt32("type", OBJECT_ROUND_RECT);
radioButton = new BRadioButton(b, "radio 3", "Round Rect", message);
controlGroup->AddChild(radioButton);
b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
message = new BMessage(MSG_SET_OBJECT_TYPE);
message->AddInt32("type", OBJECT_ELLIPSE);
radioButton = new BRadioButton(b, "radio 4", "Ellipse", message);
controlGroup->AddChild(radioButton);
// red text control
b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
fRedTC = new BTextControl(b, "red text control", "Red", "",
new BMessage(MSG_SET_COLOR));
controlGroup->AddChild(fRedTC);
// green text control
b.OffsetBy(0, fRedTC->Bounds().Height() + 5.0);
fGreenTC = new BTextControl(b, "green text control", "Green", "",
new BMessage(MSG_SET_COLOR));
controlGroup->AddChild(fGreenTC);
// blue text control
b.OffsetBy(0, fGreenTC->Bounds().Height() + 5.0);
fBlueTC = new BTextControl(b, "blue text control", "Blue", "",
new BMessage(MSG_SET_COLOR));
controlGroup->AddChild(fBlueTC);
// alpha text control
b.OffsetBy(0, fBlueTC->Bounds().Height() + 5.0);
fAlphaTC = new BTextControl(b, "alpha text control", "Alpha", "",
new BMessage(MSG_SET_COLOR));
controlGroup->AddChild(fAlphaTC);
/*
// TODO: while this block of code works in the Haiku app_server running under R5,
// it crashes pretty badly under Haiku. I have no idea why this happens, because
// I was doing the same thing before at other places.
// divide text controls the same
float rWidth = fRedTC->StringWidth(fRedTC->Label());
float gWidth = fGreenTC->StringWidth(fGreenTC->Label());
float bWidth = fBlueTC->StringWidth(fBlueTC->Label());
float aWidth = fAlphaTC->StringWidth(fAlphaTC->Label());
float width = max_c(rWidth, max_c(gWidth, max_c(bWidth, aWidth))) + 10.0;
fRedTC->SetDivider(width);
fGreenTC->SetDivider(width);
fBlueTC->SetDivider(width);
fAlphaTC->SetDivider(width);*/
// fill check box
b.OffsetBy(0, fAlphaTC->Bounds().Height() + 5.0);
fFillCB = new BCheckBox(b, "fill check box", "Fill",
new BMessage(MSG_SET_FILL_OR_STROKE));
controlGroup->AddChild(fFillCB);
// pen size text control
b.OffsetBy(0, radioButton->Bounds().Height() + 5.0);
fPenSizeTC = new BTextControl(b, "width text control", "Width", "",
new BMessage(MSG_SET_PEN_SIZE));
controlGroup->AddChild(fPenSizeTC);
_UpdateControls();
}
// destructor
ObjectWindow::~ObjectWindow()
{
}
// QuitRequested
bool
ObjectWindow::QuitRequested()
{
be_app->PostMessage(B_QUIT_REQUESTED);
return true;
}
// MessageReceived
void
ObjectWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_SET_OBJECT_TYPE: {
int32 type;
if (message->FindInt32("type", &type) >= B_OK) {
fObjectView->SetObjectType(type);
fFillCB->SetEnabled(type != OBJECT_LINE);
}
break;
}
case MSG_SET_FILL_OR_STROKE: {
int32 value;
if (message->FindInt32("be:value", &value) >= B_OK) {
fObjectView->SetStateFill(value);
fPenSizeTC->SetEnabled(value == B_CONTROL_OFF);
}
break;
}
case MSG_SET_COLOR:
fObjectView->SetStateColor(_GetColor());
break;
case MSG_OBJECT_COUNT_CHANGED:
fClearB->SetEnabled(fObjectView->CountObjects() > 0);
break;
case MSG_NEW_OBJECT:
fObjectView->SetState(NULL);
break;
case MSG_CLEAR:
fObjectView->MakeEmpty();
break;
case MSG_SET_PEN_SIZE:
fObjectView->SetStatePenSize(atof(fPenSizeTC->Text()));
break;
default:
BWindow::MessageReceived(message);
}
}
// _UpdateControls
void
ObjectWindow::_UpdateControls() const
{
// update color
rgb_color c = fObjectView->StateColor();
char string[32];
sprintf(string, "%d", c.red);
fRedTC->SetText(string);
sprintf(string, "%d", c.green);
fGreenTC->SetText(string);
sprintf(string, "%d", c.blue);
fBlueTC->SetText(string);
sprintf(string, "%d", c.alpha);
fAlphaTC->SetText(string);
// update buttons
fClearB->SetEnabled(fObjectView->CountObjects() > 0);
fFillCB->SetEnabled(fObjectView->ObjectType() != OBJECT_LINE);
// disable penSize if fill is on
sprintf(string, "%.1f", fObjectView->StatePenSize());
fPenSizeTC->SetText(string);
fPenSizeTC->SetEnabled(!fFillCB->IsEnabled());
}
// _GetColor
rgb_color
ObjectWindow::_GetColor() const
{
rgb_color c;
c.red = max_c(0, min_c(255, atoi(fRedTC->Text())));
c.green = max_c(0, min_c(255, atoi(fGreenTC->Text())));
c.blue = max_c(0, min_c(255, atoi(fBlueTC->Text())));
c.alpha = max_c(0, min_c(255, atoi(fAlphaTC->Text())));
return c;
}

View File

@ -0,0 +1,48 @@
// ObjectWindow.h
#ifndef OBJECT_WINDOW_H
#define OBJECT_WINDOW_H
#include <Window.h>
/*
class Box;
class Button;
class CheckBox;
class Menu;
class MenuBar;
class RadioButton;
class TextView;*/
class BButton;
class BCheckBox;
class BTextControl;
class ObjectView;
class ObjectWindow : public BWindow {
public:
ObjectWindow(BRect frame, const char* name);
virtual ~ObjectWindow();
virtual bool QuitRequested();
virtual void MessageReceived(BMessage* message);
private:
void _UpdateControls() const;
rgb_color _GetColor() const;
ObjectView* fObjectView;
BButton* fNewB;
BButton* fClearB;
BTextControl* fRedTC;
BTextControl* fGreenTC;
BTextControl* fBlueTC;
BTextControl* fAlphaTC;
BCheckBox* fFillCB;
BTextControl* fPenSizeTC;
};
#endif // OBJECT_WINDOW_H

View File

@ -0,0 +1,194 @@
// States.cpp
#include <View.h>
#include "States.h"
// constructor
State::State(rgb_color color, bool fill, float penSize)
: fValid(false),
fTracking(false),
fTrackingStart(-1.0, -1.0),
fLastMousePos(-1.0, -1.0),
fColor(color),
fFill(fill),
fPenSize(penSize)
{
}
// MouseDown
void
State::MouseDown(BPoint where)
{
fTracking = true;
fTrackingStart = fLastMousePos = where;
}
// MouseUp
void
State::MouseUp(BPoint where)
{
fTracking = false;
}
// MouseMoved
void
State::MouseMoved(BPoint where)
{
if (fTracking) {
fLastMousePos = where;
fValid = true;
}
}
// SetColor
void
State::SetColor(rgb_color color)
{
fColor = color;
}
// SetFill
void
State::SetFill(bool fill)
{
fFill = fill;
}
// SetPenSize
void
State::SetPenSize(float penSize)
{
fPenSize = penSize;
}
// Bounds
BRect
State::Bounds() const
{
if (fValid) {
BRect r = _ValidRect();
if (!fFill) {
float inset = -ceilf(fPenSize / 2.0);
r.InsetBy(inset, inset);
}
return r;
}
return BRect(0.0, 0.0, -1.0, -1.0);
}
// _ValidRect
BRect
State::_ValidRect() const
{
return BRect(min_c(fTrackingStart.x, fLastMousePos.x),
min_c(fTrackingStart.y, fLastMousePos.y),
max_c(fTrackingStart.x, fLastMousePos.x),
max_c(fTrackingStart.y, fLastMousePos.y));
}
// LineState
class LineState : public State {
public:
LineState(rgb_color color, bool fill, float penSize)
: State(color, fill, penSize) {}
virtual BRect Bounds() const
{
if (fValid) {
BRect r = _ValidRect();
r.InsetBy(-fPenSize, -fPenSize);
return r;
}
return BRect(0.0, 0.0, -1.0, -1.0);
}
virtual void Draw(BView* view) const
{
if (fValid) {
view->SetHighColor(fColor);
view->SetPenSize(fPenSize);
view->StrokeLine(fTrackingStart, fLastMousePos);
}
}
};
// RectState
class RectState : public State {
public:
RectState(rgb_color color, bool fill, float penSize)
: State(color, fill, penSize) {}
virtual void Draw(BView* view) const
{
if (fValid) {
view->SetHighColor(fColor);
if (fFill)
view->FillRect(_ValidRect());
else {
view->SetPenSize(fPenSize);
view->StrokeRect(_ValidRect());
}
}
}
};
// RoundRectState
class RoundRectState : public State {
public:
RoundRectState(rgb_color color, bool fill, float penSize)
: State(color, fill, penSize) {}
virtual void Draw(BView* view) const
{
if (fValid) {
view->SetHighColor(fColor);
BRect r = _ValidRect();
float radius = min_c(r.Width() / 4.0, r.Height() / 4.0);
if (fFill)
view->FillRoundRect(r, radius, radius);
else {
view->SetPenSize(fPenSize);
view->StrokeRoundRect(r, radius, radius);
}
}
}
};
// EllipseState
class EllipseState : public State {
public:
EllipseState(rgb_color color, bool fill, float penSize)
: State(color, fill, penSize) {}
virtual void Draw(BView* view) const
{
if (fValid) {
view->SetHighColor(fColor);
if (fFill)
view->FillEllipse(_ValidRect());
else {
view->SetPenSize(fPenSize);
view->StrokeEllipse(_ValidRect());
}
}
}
};
// StateFor
State*
State::StateFor(int32 objectType, rgb_color color, bool fill, float penSize)
{
switch (objectType) {
case OBJECT_LINE:
return new LineState(color, fill, penSize);
case OBJECT_RECT:
return new RectState(color, fill, penSize);
case OBJECT_ROUND_RECT:
return new RoundRectState(color, fill, penSize);
case OBJECT_ELLIPSE:
return new EllipseState(color, fill, penSize);
default:
return NULL;
}
}

View File

@ -0,0 +1,56 @@
// States.h
#ifndef STATES_H
#define STATES_H
#include <GraphicsDefs.h>
#include <Point.h>
class BView;
enum {
OBJECT_LINE = 0,
OBJECT_RECT,
OBJECT_ROUND_RECT,
OBJECT_ELLIPSE,
OBJECT_TRIANGLE,
OBJECT_SHAPE,
};
class State {
public:
State(rgb_color color,
bool fill, float penSize);
void MouseDown(BPoint where);
void MouseUp(BPoint where);
void MouseMoved(BPoint where);
bool IsTracking() const
{ return fTracking; }
void SetColor(rgb_color color);
void SetFill(bool fill);
void SetPenSize(float penSize);
virtual BRect Bounds() const;
virtual void Draw(BView* view) const = 0;
static State* StateFor(int32 objectType,
rgb_color color,
bool fill, float penSize);
protected:
BRect _ValidRect() const;
bool fValid;
bool fTracking;
BPoint fTrackingStart;
BPoint fLastMousePos;
rgb_color fColor;
bool fFill;
float fPenSize;
};
#endif // STATES_H

View File

@ -1,287 +1,17 @@
// main.cpp
#include <stdio.h>
#include <Application.h>
#include <Box.h>
#include <Button.h>
#include <CheckBox.h>
#include <Menu.h>
#include <MenuBar.h>
#include <MenuItem.h>
#include <String.h>
#include <RadioButton.h>
#include <TextControl.h>
#include <TextView.h>
#include <View.h>
#include <Window.h>
class HelloView : public BView {
public:
HelloView(BRect frame, const char* name,
uint32 resizeFlags, uint32 flags);
virtual void AttachedToWindow();
virtual void Draw(BRect updateRect);
virtual void FrameMoved(BPoint were);
virtual void FrameResized(float width, float height);
virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage);
private:
bool fTracking;
BPoint fTrackingStart;
BPoint fLastMousePos;
};
// constructor
HelloView::HelloView(BRect frame, const char* name,
uint32 resizeFlags, uint32 flags)
: BView(frame, name, resizeFlags, flags | B_FRAME_EVENTS),
fTracking(false),
fTrackingStart(-1.0, -1.0),
fLastMousePos(-1.0, -1.0)
{
// TODO: Find bug: this influences StringWidth(), but the font is not used
// SetFontSize(9);
rgb_color bg = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_LIGHTEN_1_TINT);
SetViewColor(bg);
SetLowColor(bg);
BFont font;
GetFont(&font);
BString string("ß amM öo\t");
int32 charCount = string.CountChars();
float* escapements = new float[charCount];
escapement_delta dummy;
dummy.space = 0.0;
dummy.nonspace = 0.0;
font.GetEscapements(string.String(), charCount, &dummy, escapements);
for (int32 i = 0; i < charCount; i++)
printf("escapement: %.3f\n", escapements[i]);
delete[] escapements;
}
// AttachedToWindow
void
HelloView::AttachedToWindow()
{
}
// Draw
void
HelloView::Draw(BRect updateRect)
{
rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR);
rgb_color shadow = tint_color(noTint, B_DARKEN_2_TINT);
rgb_color light = tint_color(noTint, B_LIGHTEN_MAX_TINT);
BRect r(Bounds());
BeginLineArray(4);
AddLine(BPoint(r.left, r.top),
BPoint(r.right, r.top), shadow);
AddLine(BPoint(r.right, r.top + 1),
BPoint(r.right, r.bottom), light);
AddLine(BPoint(r.right - 1, r.bottom),
BPoint(r.left, r.bottom), light);
AddLine(BPoint(r.left, r.bottom - 1),
BPoint(r.left, r.top + 1), shadow);
EndLineArray();
SetHighColor(255, 0, 0, 128);
const char* message = "Click and drag";
float width = StringWidth(message);
BPoint p(r.left + r.Width() / 2.0 - width / 2.0,
r.top + r.Height() / 2.0);
DrawString(message, p);
message = "to draw a line!";
width = StringWidth(message);
p.x = r.left + r.Width() / 2.0 - width / 2.0;
p.y += 20;
DrawString(message, p);
// SetDrawingMode(B_OP_OVER);
SetDrawingMode(B_OP_ALPHA);
SetPenSize(10.0);
SetHighColor(0, 80, 255, 100);
StrokeLine(fTrackingStart, fLastMousePos);
// TODO: this should not be necessary with proper state stack
// (a new state is pushed before Draw() is called)
SetDrawingMode(B_OP_COPY);
}
// FrameMoved
void
HelloView::FrameMoved(BPoint were)
{
printf("HelloView::FrameMoved()\n");
if (Window()) {
Window()->CurrentMessage()->PrintToStream();
}
}
// FrameResized
void
HelloView::FrameResized(float width, float height)
{
printf("HelloView::FrameResized()\n");
if (Window()) {
Window()->CurrentMessage()->PrintToStream();
}
}
// MouseDown
void
HelloView::MouseDown(BPoint where)
{
fTracking = true;
fTrackingStart = fLastMousePos = where;
Invalidate();
}
// MouseUp
void
HelloView::MouseUp(BPoint where)
{
fTracking = false;
}
// MouseMoved
void
HelloView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
{
if (fTracking) {
BRect invalidBefore(min_c(fTrackingStart.x, fLastMousePos.x),
min_c(fTrackingStart.y, fLastMousePos.y),
max_c(fTrackingStart.x, fLastMousePos.x),
max_c(fTrackingStart.y, fLastMousePos.y));
fLastMousePos = where;
BRect invalidAfter(min_c(fTrackingStart.x, fLastMousePos.x),
min_c(fTrackingStart.y, fLastMousePos.y),
max_c(fTrackingStart.x, fLastMousePos.x),
max_c(fTrackingStart.y, fLastMousePos.y));
BRect invalid(invalidBefore | invalidAfter);
invalid.InsetBy(-10.0, -10.0);
Invalidate(invalid);
}
}
// show_window
void
show_window(BRect frame, const char* name)
{
// BRect f(0, 0, frame.Width(), frame.Height());
BRect f(frame);
BWindow* window = new BWindow(f, name,
B_TITLED_WINDOW,
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE);
BRect b(window->Bounds());
b.bottom = b.top + 8;
BMenuBar* menuBar = new BMenuBar(b, "menu bar");
window->AddChild(menuBar);
BMenu* menu = new BMenu("Menus");
menuBar->AddItem(menu);
BMenuItem* menuItem = new BMenuItem("Quit", NULL, 'Q');
menu->AddItem(menuItem);
menuBar->AddItem(new BMenu("don't"));
menuBar->AddItem(new BMenu("work!"));
menuBar->AddItem(new BMenu("(yet)"));
b = window->Bounds();
b.top = menuBar->Bounds().bottom + 1;
BBox* bg = new BBox(b, "box", B_FOLLOW_ALL, B_WILL_DRAW, B_PLAIN_BORDER);
window->AddChild(bg);
b = bg->Bounds();
// occupy the right side of the window
b.Set((b.left + b.right) / 2.0 + 3.0, b.top + 5.0, b.right - 5.0, b.bottom - 5.0);
BView* view = new HelloView(b, "hello view", B_FOLLOW_ALL,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE);
bg->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
bg->AddChild(view);
b = bg->Bounds();
// occupy the left side of the window
b.Set(b.left + 5.0, b.top + 5.0, (b.left + b.right) / 2.0 - 2.0, b.bottom - 5.0);
BBox* controlGroup = new BBox(b, "controls box", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
B_WILL_DRAW, B_FANCY_BORDER);
controlGroup->SetLabel("Controls");
bg->AddChild(controlGroup);
b = controlGroup->Bounds();
b.top += 15.0;
b.bottom = b.top + 25.0;
b.InsetBy(5.0, 5.0);
BRadioButton* radioButton1 = new BRadioButton(b, "radio 1", "Choice One", NULL);
controlGroup->AddChild(radioButton1);
b.OffsetBy(0, radioButton1->Bounds().Height() + 5.0);
BRadioButton* radioButton2 = new BRadioButton(b, "radio 2", "Choice Two", NULL);
controlGroup->AddChild(radioButton2);
b.OffsetBy(0, radioButton2->Bounds().Height() + 5.0);
BRadioButton* radioButton3 = new BRadioButton(b, "radio 3", "Choice Three", NULL);
controlGroup->AddChild(radioButton3);
radioButton1->SetValue(B_CONTROL_ON);
// button
b.OffsetBy(0, radioButton3->Bounds().Height() + 5.0);
BButton* button = new BButton(b, "button", "Button", NULL);
controlGroup->AddChild(button);
// text control
b.OffsetBy(0, button->Bounds().Height() + 5.0);
BTextControl* textControl = new BTextControl(b, "text control", "Text", "<enter text here>", NULL);
textControl->SetDivider(textControl->StringWidth(textControl->Label()) + 10.0);
controlGroup->AddChild(textControl);
/* BRect textRect(b);
textRect.OffsetTo(0.0, 0.0);
BTextView* textView = new BTextView(b, "text view", textRect,
B_FOLLOW_ALL, B_WILL_DRAW);
view->AddChild(textView);
textView->SetText("This is a BTextView.");
textView->MakeFocus(true);*/
// check box
b.OffsetBy(0, textControl->Bounds().Height() + 5.0);
BCheckBox* checkBox = new BCheckBox(b, "check box", "CheckBox", NULL);
controlGroup->AddChild(checkBox);
// window->MoveTo(frame.left, frame.top);
window->Show();
}
#include "ObjectWindow.h"
// main
int
main(int argc, char** argv)
{
BApplication* app = new BApplication("application/x.vnd-Haiku.windows_test");
BApplication* app = new BApplication("application/x.vnd-Haiku.Objects");
BRect frame(80.0, 100.0, 450.0, 400.0);
show_window(frame, "Playground");
// frame.Set(50.0, 50.0, 200.0, 250.0);
// show_window(frame, "Window #2");
BRect frame(50.0, 50.0, 450.0, 430.0);
(new ObjectWindow(frame, "Playground"))->Show();
app->Run();

View File

@ -4,4 +4,4 @@
sleep 1s
../../../../../distro/x86.R1/beos/system/servers/obos_registrar &
sleep 1s
../../../../../tests/servers/app/playground/Playground
../../../../../distro/x86.R1/beos/apps/Playground