embedding ObjectView into a BScrollView to show off scrolling, drawing mode selection actually works, simplified States

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13444 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-07-05 15:40:59 +00:00
parent f4b64fa6c8
commit 8e05e376ac
5 changed files with 186 additions and 112 deletions
+22 -11
View File
@@ -18,6 +18,7 @@ ObjectView::ObjectView(BRect frame, const char* name,
fObjectType(OBJECT_LINE), fObjectType(OBJECT_LINE),
fStateList(20), fStateList(20),
fColor((rgb_color){ 0, 80, 255, 100 }), fColor((rgb_color){ 0, 80, 255, 100 }),
fDrawingMode(B_OP_ALPHA),
fFill(false), fFill(false),
fPenSize(10.0), fPenSize(10.0),
fScrolling(false), fScrolling(false),
@@ -67,14 +68,14 @@ ObjectView::Draw(BRect updateRect)
const char* message = "Click and drag"; const char* message = "Click and drag";
float width = StringWidth(message); float width = StringWidth(message);
BPoint p(r.left + r.Width() / 2.0 - width / 2.0, BPoint p(r.Width() / 2.0 - width / 2.0,
r.top + r.Height() / 2.0); r.Height() / 2.0);
DrawString(message, p); DrawString(message, p);
message = "to draw an object!"; message = "to draw an object!";
width = StringWidth(message); width = StringWidth(message);
p.x = r.left + r.Width() / 2.0 - width / 2.0; p.x = r.Width() / 2.0 - width / 2.0;
p.y += 25; p.y += 25;
DrawString(message, p); DrawString(message, p);
@@ -82,11 +83,6 @@ ObjectView::Draw(BRect updateRect)
SetDrawingMode(B_OP_ALPHA); SetDrawingMode(B_OP_ALPHA);
for (int32 i = 0; State* state = (State*)fStateList.ItemAt(i); i++) for (int32 i = 0; State* state = (State*)fStateList.ItemAt(i); i++)
state->Draw(this); 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 // MouseDown
@@ -103,7 +99,8 @@ ObjectView::MouseDown(BPoint where)
fLastMousePos = where; fLastMousePos = where;
} else { } else {
if (!fState) if (!fState)
AddObject(State::StateFor(fObjectType, fColor, fFill, fPenSize)); AddObject(State::StateFor(fObjectType, fColor, fDrawingMode,
fFill, fPenSize));
if (fState) { if (fState) {
// Invalidate(fState->Bounds()); // Invalidate(fState->Bounds());
@@ -229,6 +226,20 @@ ObjectView::SetStateColor(rgb_color color)
} }
} }
// SetStateDrawingMode
void
ObjectView::SetStateDrawingMode(drawing_mode mode)
{
if (fDrawingMode != mode) {
fDrawingMode = mode;
if (fState) {
fState->SetDrawingMode(fDrawingMode);
Invalidate(fState->Bounds());
}
}
}
// SetStateFill // SetStateFill
void void
ObjectView::SetStateFill(bool fill) ObjectView::SetStateFill(bool fill)
@@ -239,7 +250,7 @@ ObjectView::SetStateFill(bool fill)
if (fState) { if (fState) {
BRect before = fState->Bounds(); BRect before = fState->Bounds();
fState->SetFill(fill); fState->SetFill(fFill);
BRect after = fState->Bounds(); BRect after = fState->Bounds();
BRect invalid(before | after); BRect invalid(before | after);
@@ -258,7 +269,7 @@ ObjectView::SetStatePenSize(float penSize)
if (fState) { if (fState) {
BRect before = fState->Bounds(); BRect before = fState->Bounds();
fState->SetPenSize(penSize); fState->SetPenSize(fPenSize);
BRect after = fState->Bounds(); BRect after = fState->Bounds();
BRect invalid(before | after); BRect invalid(before | after);
@@ -42,6 +42,10 @@ class ObjectView : public BView {
rgb_color StateColor() const rgb_color StateColor() const
{ return fColor; } { return fColor; }
void SetStateDrawingMode(drawing_mode mode);
drawing_mode StateDrawingMode() const
{ return fDrawingMode; }
void SetStateFill(bool fill); void SetStateFill(bool fill);
bool StateFill() const bool StateFill() const
{ return fFill; } { return fFill; }
@@ -57,6 +61,7 @@ class ObjectView : public BView {
BList fStateList; BList fStateList;
rgb_color fColor; rgb_color fColor;
drawing_mode fDrawingMode;
bool fFill; bool fFill;
float fPenSize; float fPenSize;
@@ -13,6 +13,8 @@
#include <MenuField.h> #include <MenuField.h>
#include <MenuItem.h> #include <MenuItem.h>
#include <PopUpMenu.h> #include <PopUpMenu.h>
#include <ScrollBar.h>
#include <ScrollView.h>
#include <Slider.h> #include <Slider.h>
#include <String.h> #include <String.h>
#include <RadioButton.h> #include <RadioButton.h>
@@ -41,7 +43,7 @@ enum {
// constructor // constructor
ObjectWindow::ObjectWindow(BRect frame, const char* name) ObjectWindow::ObjectWindow(BRect frame, const char* name)
: BWindow(frame, name, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, : BWindow(frame, name, B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS) B_ASYNCHRONOUS_CONTROLS)
// : BWindow(frame, name, B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, // : BWindow(frame, name, B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
// B_ASYNCHRONOUS_CONTROLS) // B_ASYNCHRONOUS_CONTROLS)
@@ -67,22 +69,36 @@ ObjectWindow::ObjectWindow(BRect frame, const char* name)
b = Bounds(); b = Bounds();
b.top = menuBar->Bounds().bottom + 1; b.top = menuBar->Bounds().bottom + 1;
BBox* bg = new BBox(b, "bg box", B_FOLLOW_ALL, B_WILL_DRAW, B_PLAIN_BORDER); b.right = ceilf((b.left + b.right) / 3.0);
BBox* bg = new BBox(b, "bg box", B_FOLLOW_TOP_BOTTOM, B_WILL_DRAW, B_PLAIN_BORDER);
AddChild(bg); AddChild(bg);
bg->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); bg->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
b = bg->Bounds(); // object view occupies the right side of the window
// object views occupies the right side of the window b.left = b.right + 1.0;
b.Set(ceilf((b.left + b.right) / 3.0) + 3.0, b.top + 5.0, b.right - 5.0, b.bottom - 5.0); b.right = Bounds().right - B_V_SCROLL_BAR_WIDTH;
b.bottom -= B_H_SCROLL_BAR_HEIGHT;
fObjectView = new ObjectView(b, "object view", B_FOLLOW_ALL, fObjectView = new ObjectView(b, "object view", B_FOLLOW_ALL,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE); B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE);
// wrap a scroll view around the object view
BScrollView* scrollView = new BScrollView("object scroller", fObjectView,
B_FOLLOW_ALL, 0, true, true,
B_NO_BORDER);
bg->AddChild(fObjectView); if (BScrollBar* scrollBar = fObjectView->ScrollBar(B_VERTICAL)) {
scrollBar->SetRange(0.0, fObjectView->Bounds().Height());
scrollBar->SetProportion(0.5);
}
if (BScrollBar* scrollBar = fObjectView->ScrollBar(B_HORIZONTAL)) {
scrollBar->SetRange(0.0, fObjectView->Bounds().Width());
scrollBar->SetProportion(0.5);
}
AddChild(scrollView);
b = bg->Bounds(); b = bg->Bounds();
// controls occupy the left side of the window // 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); b.InsetBy(5.0, 5.0);
BBox* controlGroup = new BBox(b, "controls box", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, BBox* controlGroup = new BBox(b, "controls box", B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
B_WILL_DRAW, B_FANCY_BORDER); B_WILL_DRAW, B_FANCY_BORDER);
@@ -211,21 +227,23 @@ ObjectWindow::ObjectWindow(BRect frame, const char* name)
fAlphaTC = new BTextControl(b, "alpha text control", "Alpha", "", fAlphaTC = new BTextControl(b, "alpha text control", "Alpha", "",
new BMessage(MSG_SET_COLOR)); new BMessage(MSG_SET_COLOR));
controlGroup->AddChild(fAlphaTC); controlGroup->AddChild(fAlphaTC);
/*
// TODO: while this block of code works in the Haiku app_server running under R5, // 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 // it crashes pretty badly under Haiku. I have no idea why this happens, because
// I was doing the same thing before at other places. // I was doing the same thing before at other places.
// divide text controls the same // divide text controls the same
float mWidth = fDrawingModeMF->StringWidth(fDrawingModeMF->Label());
float rWidth = fRedTC->StringWidth(fRedTC->Label()); float rWidth = fRedTC->StringWidth(fRedTC->Label());
float gWidth = fGreenTC->StringWidth(fGreenTC->Label()); float gWidth = fGreenTC->StringWidth(fGreenTC->Label());
float bWidth = fBlueTC->StringWidth(fBlueTC->Label()); float bWidth = fBlueTC->StringWidth(fBlueTC->Label());
float aWidth = fAlphaTC->StringWidth(fAlphaTC->Label()); float aWidth = fAlphaTC->StringWidth(fAlphaTC->Label());
float width = max_c(rWidth, max_c(gWidth, max_c(bWidth, aWidth))) + 10.0; float width = max_c(mWidth, max_c(rWidth, max_c(gWidth, max_c(bWidth, aWidth)))) + 10.0;
fDrawingModeMF->SetDivider(width);
fRedTC->SetDivider(width); fRedTC->SetDivider(width);
fGreenTC->SetDivider(width); fGreenTC->SetDivider(width);
fBlueTC->SetDivider(width); fBlueTC->SetDivider(width);
fAlphaTC->SetDivider(width);*/ fAlphaTC->SetDivider(width);
// fill check box // fill check box
b.OffsetBy(0, fAlphaTC->Bounds().Height() + 5.0); b.OffsetBy(0, fAlphaTC->Bounds().Height() + 5.0);
@@ -316,6 +334,13 @@ ObjectWindow::MessageReceived(BMessage* message)
case MSG_SET_PEN_SIZE: case MSG_SET_PEN_SIZE:
fObjectView->SetStatePenSize((float)fPenSizeS->Value()); fObjectView->SetStatePenSize((float)fPenSizeS->Value());
break; break;
case MSG_SET_DRAWING_MODE: {
drawing_mode mode;
if (message->FindInt32("mode", (int32*)&mode) >= B_OK) {
fObjectView->SetStateDrawingMode(mode);
}
break;
}
default: default:
BWindow::MessageReceived(message); BWindow::MessageReceived(message);
} }
+51 -23
View File
@@ -5,18 +5,34 @@
#include "States.h" #include "States.h"
// constructor // constructor
State::State(rgb_color color, bool fill, float penSize) State::State()
: fValid(false), : fValid(false),
fEditing(true), fEditing(true),
fTracking(TRACKING_NONE), fTracking(TRACKING_NONE),
fStartPoint(-1.0, -1.0), fStartPoint(-1.0, -1.0),
fEndPoint(-1.0, -1.0), fEndPoint(-1.0, -1.0),
fColor(color), fColor((rgb_color){ 0, 0, 0, 255 }),
fFill(fill), fDrawingMode(B_OP_COPY),
fPenSize(penSize) fFill(true),
fPenSize(1.0)
{ {
} }
// destructor
State::~State()
{
}
// Init
void
State::Init(rgb_color color, drawing_mode mode, bool fill, float penSize)
{
fColor = color;
fDrawingMode = mode;
fFill = fill;
fPenSize = penSize;
}
// MouseDown // MouseDown
void void
State::MouseDown(BPoint where) State::MouseDown(BPoint where)
@@ -61,6 +77,13 @@ State::SetColor(rgb_color color)
fColor = color; fColor = color;
} }
// SetDrawingMode
void
State::SetDrawingMode(drawing_mode mode)
{
fDrawingMode = mode;
}
// SetFill // SetFill
void void
State::SetFill(bool fill) State::SetFill(bool fill)
@@ -137,11 +160,7 @@ State::_RenderDot(BView* view, BPoint where) const
void void
State::_AdjustViewState(BView* view) const State::_AdjustViewState(BView* view) const
{ {
if (fColor.alpha < 255) view->SetDrawingMode(fDrawingMode);
view->SetDrawingMode(B_OP_ALPHA);
else
view->SetDrawingMode(B_OP_OVER);
view->SetHighColor(fColor); view->SetHighColor(fColor);
if (!SupportsFill() || !fFill) if (!SupportsFill() || !fFill)
@@ -160,8 +179,8 @@ State::_HitTest(BPoint where, BPoint point) const
// LineState // LineState
class LineState : public State { class LineState : public State {
public: public:
LineState(rgb_color color, bool fill, float penSize) LineState()
: State(color, fill, penSize) {} : State() {}
virtual void Draw(BView* view) const virtual void Draw(BView* view) const
{ {
@@ -180,8 +199,8 @@ class LineState : public State {
// RectState // RectState
class RectState : public State { class RectState : public State {
public: public:
RectState(rgb_color color, bool fill, float penSize) RectState()
: State(color, fill, penSize) {} : State() {}
virtual void Draw(BView* view) const virtual void Draw(BView* view) const
{ {
@@ -199,8 +218,8 @@ class RectState : public State {
// RoundRectState // RoundRectState
class RoundRectState : public State { class RoundRectState : public State {
public: public:
RoundRectState(rgb_color color, bool fill, float penSize) RoundRectState()
: State(color, fill, penSize) {} : State() {}
virtual void Draw(BView* view) const virtual void Draw(BView* view) const
{ {
@@ -220,8 +239,8 @@ class RoundRectState : public State {
// EllipseState // EllipseState
class EllipseState : public State { class EllipseState : public State {
public: public:
EllipseState(rgb_color color, bool fill, float penSize) EllipseState()
: State(color, fill, penSize) {} : State() {}
virtual void Draw(BView* view) const virtual void Draw(BView* view) const
{ {
@@ -238,19 +257,28 @@ class EllipseState : public State {
// StateFor // StateFor
State* State*
State::StateFor(int32 objectType, rgb_color color, bool fill, float penSize) State::StateFor(int32 objectType, rgb_color color, drawing_mode mode,
bool fill, float penSize)
{ {
State* state = NULL;
switch (objectType) { switch (objectType) {
case OBJECT_LINE: case OBJECT_LINE:
return new LineState(color, fill, penSize); state = new LineState();
break;
case OBJECT_RECT: case OBJECT_RECT:
return new RectState(color, fill, penSize); state = new RectState();
break;
case OBJECT_ROUND_RECT: case OBJECT_ROUND_RECT:
return new RoundRectState(color, fill, penSize); state = new RoundRectState();
break;
case OBJECT_ELLIPSE: case OBJECT_ELLIPSE:
return new EllipseState(color, fill, penSize); state = new EllipseState();
break;
default: default:
return NULL; break;
} }
if (state)
state->Init(color, mode, fill, penSize);
return state;
} }
+7 -2
View File
@@ -19,7 +19,10 @@ enum {
class State { class State {
public: public:
State(rgb_color color, State();
virtual ~State();
void Init(rgb_color color, drawing_mode mode,
bool fill, float penSize); bool fill, float penSize);
void MouseDown(BPoint where); void MouseDown(BPoint where);
@@ -29,6 +32,7 @@ class State {
{ return fTracking; } { return fTracking; }
void SetColor(rgb_color color); void SetColor(rgb_color color);
void SetDrawingMode(drawing_mode mode);
void SetFill(bool fill); void SetFill(bool fill);
void SetPenSize(float penSize); void SetPenSize(float penSize);
@@ -40,7 +44,7 @@ class State {
{ return true; } { return true; }
static State* StateFor(int32 objectType, static State* StateFor(int32 objectType,
rgb_color color, rgb_color color, drawing_mode mode,
bool fill, float penSize); bool fill, float penSize);
protected: protected:
@@ -67,6 +71,7 @@ class State {
BPoint fEndPoint; BPoint fEndPoint;
rgb_color fColor; rgb_color fColor;
drawing_mode fDrawingMode;
bool fFill; bool fFill;
float fPenSize; float fPenSize;
}; };