diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index 03e20ec355..9b172a0155 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -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 ; diff --git a/src/tests/servers/app/playground/Jamfile b/src/tests/servers/app/playground/Jamfile index a4d03f6f59..0560020189 100644 --- a/src/tests/servers/app/playground/Jamfile +++ b/src/tests/servers/app/playground/Jamfile @@ -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 ) { diff --git a/src/tests/servers/app/playground/ObjectView.cpp b/src/tests/servers/app/playground/ObjectView.cpp new file mode 100644 index 0000000000..7f690a29b5 --- /dev/null +++ b/src/tests/servers/app/playground/ObjectView.cpp @@ -0,0 +1,228 @@ +// ObjectView.cpp + +#include + +#include +#include + +#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); + } + } +} diff --git a/src/tests/servers/app/playground/ObjectView.h b/src/tests/servers/app/playground/ObjectView.h new file mode 100644 index 0000000000..7c47767773 --- /dev/null +++ b/src/tests/servers/app/playground/ObjectView.h @@ -0,0 +1,64 @@ +// ObjectView.h + +#ifndef OBJECT_VIEW_H +#define OBJECT_VIEW_H + +#include +#include + +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 diff --git a/src/tests/servers/app/playground/ObjectWindow.cpp b/src/tests/servers/app/playground/ObjectWindow.cpp new file mode 100644 index 0000000000..09878d42a2 --- /dev/null +++ b/src/tests/servers/app/playground/ObjectWindow.cpp @@ -0,0 +1,277 @@ +// main.cpp + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} + diff --git a/src/tests/servers/app/playground/ObjectWindow.h b/src/tests/servers/app/playground/ObjectWindow.h new file mode 100644 index 0000000000..b57e25875a --- /dev/null +++ b/src/tests/servers/app/playground/ObjectWindow.h @@ -0,0 +1,48 @@ +// ObjectWindow.h + +#ifndef OBJECT_WINDOW_H +#define OBJECT_WINDOW_H + +#include + +/* +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 diff --git a/src/tests/servers/app/playground/States.cpp b/src/tests/servers/app/playground/States.cpp new file mode 100644 index 0000000000..bdd726676c --- /dev/null +++ b/src/tests/servers/app/playground/States.cpp @@ -0,0 +1,194 @@ +// States.cpp + +#include + +#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; + } +} + diff --git a/src/tests/servers/app/playground/States.h b/src/tests/servers/app/playground/States.h new file mode 100644 index 0000000000..6fe3c8fea7 --- /dev/null +++ b/src/tests/servers/app/playground/States.h @@ -0,0 +1,56 @@ +// States.h + +#ifndef STATES_H +#define STATES_H + +#include +#include + +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 diff --git a/src/tests/servers/app/playground/main.cpp b/src/tests/servers/app/playground/main.cpp index c31fe5aea0..046a1d373a 100644 --- a/src/tests/servers/app/playground/main.cpp +++ b/src/tests/servers/app/playground/main.cpp @@ -1,287 +1,17 @@ // main.cpp -#include - #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -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", "", 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(); diff --git a/src/tests/servers/app/playground/run b/src/tests/servers/app/playground/run index ab366dc675..2082bc3fd4 100755 --- a/src/tests/servers/app/playground/run +++ b/src/tests/servers/app/playground/run @@ -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