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
@@ -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;
}