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

View File

@ -18,6 +18,7 @@ ObjectView::ObjectView(BRect frame, const char* name,
fObjectType(OBJECT_LINE),
fStateList(20),
fColor((rgb_color){ 0, 80, 255, 100 }),
fDrawingMode(B_OP_ALPHA),
fFill(false),
fPenSize(10.0),
fScrolling(false),
@ -67,14 +68,14 @@ ObjectView::Draw(BRect updateRect)
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);
BPoint p(r.Width() / 2.0 - width / 2.0,
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.x = r.Width() / 2.0 - width / 2.0;
p.y += 25;
DrawString(message, p);
@ -82,11 +83,6 @@ ObjectView::Draw(BRect updateRect)
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
@ -103,7 +99,8 @@ ObjectView::MouseDown(BPoint where)
fLastMousePos = where;
} else {
if (!fState)
AddObject(State::StateFor(fObjectType, fColor, fFill, fPenSize));
AddObject(State::StateFor(fObjectType, fColor, fDrawingMode,
fFill, fPenSize));
if (fState) {
// 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
void
ObjectView::SetStateFill(bool fill)
@ -239,7 +250,7 @@ ObjectView::SetStateFill(bool fill)
if (fState) {
BRect before = fState->Bounds();
fState->SetFill(fill);
fState->SetFill(fFill);
BRect after = fState->Bounds();
BRect invalid(before | after);
@ -258,7 +269,7 @@ ObjectView::SetStatePenSize(float penSize)
if (fState) {
BRect before = fState->Bounds();
fState->SetPenSize(penSize);
fState->SetPenSize(fPenSize);
BRect after = fState->Bounds();
BRect invalid(before | after);

View File

@ -14,54 +14,59 @@ enum {
class ObjectView : public BView {
public:
ObjectView(BRect frame, const char* name,
uint32 resizeFlags, uint32 flags);
ObjectView(BRect frame, const char* name,
uint32 resizeFlags, uint32 flags);
// BView
virtual void AttachedToWindow();
// BView
virtual void AttachedToWindow();
virtual void Draw(BRect updateRect);
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);
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);
// ObjectView
void SetState(State* state);
void SetObjectType(int32 type);
int32 ObjectType() const
{ return fObjectType; }
void SetObjectType(int32 type);
int32 ObjectType() const
{ return fObjectType; }
void AddObject(State* state);
int32 CountObjects() const;
void MakeEmpty();
void AddObject(State* state);
int32 CountObjects() const;
void MakeEmpty();
void SetStateColor(rgb_color color);
rgb_color StateColor() const
{ return fColor; }
void SetStateColor(rgb_color color);
rgb_color StateColor() const
{ return fColor; }
void SetStateFill(bool fill);
bool StateFill() const
{ return fFill; }
void SetStateDrawingMode(drawing_mode mode);
drawing_mode StateDrawingMode() const
{ return fDrawingMode; }
void SetStatePenSize(float penSize);
float StatePenSize() const
{ return fPenSize; }
void SetStateFill(bool fill);
bool StateFill() const
{ return fFill; }
void SetStatePenSize(float penSize);
float StatePenSize() const
{ return fPenSize; }
private:
State* fState;
int32 fObjectType;
State* fState;
int32 fObjectType;
BList fStateList;
BList fStateList;
rgb_color fColor;
bool fFill;
float fPenSize;
rgb_color fColor;
drawing_mode fDrawingMode;
bool fFill;
float fPenSize;
bool fScrolling;
BPoint fLastMousePos;
bool fScrolling;
BPoint fLastMousePos;
};
#endif // OBJECT_VIEW_H

View File

@ -13,6 +13,8 @@
#include <MenuField.h>
#include <MenuItem.h>
#include <PopUpMenu.h>
#include <ScrollBar.h>
#include <ScrollView.h>
#include <Slider.h>
#include <String.h>
#include <RadioButton.h>
@ -41,7 +43,7 @@ enum {
// constructor
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)
// : BWindow(frame, name, B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
// B_ASYNCHRONOUS_CONTROLS)
@ -67,22 +69,36 @@ ObjectWindow::ObjectWindow(BRect frame, const char* name)
b = Bounds();
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);
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);
// object view occupies the right side of the window
b.left = b.right + 1.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,
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();
// 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,
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", "",
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 mWidth = fDrawingModeMF->StringWidth(fDrawingModeMF->Label());
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;
float width = max_c(mWidth, max_c(rWidth, max_c(gWidth, max_c(bWidth, aWidth)))) + 10.0;
fDrawingModeMF->SetDivider(width);
fRedTC->SetDivider(width);
fGreenTC->SetDivider(width);
fBlueTC->SetDivider(width);
fAlphaTC->SetDivider(width);*/
fAlphaTC->SetDivider(width);
// fill check box
b.OffsetBy(0, fAlphaTC->Bounds().Height() + 5.0);
@ -316,6 +334,13 @@ ObjectWindow::MessageReceived(BMessage* message)
case MSG_SET_PEN_SIZE:
fObjectView->SetStatePenSize((float)fPenSizeS->Value());
break;
case MSG_SET_DRAWING_MODE: {
drawing_mode mode;
if (message->FindInt32("mode", (int32*)&mode) >= B_OK) {
fObjectView->SetStateDrawingMode(mode);
}
break;
}
default:
BWindow::MessageReceived(message);
}

View File

@ -5,18 +5,34 @@
#include "States.h"
// constructor
State::State(rgb_color color, bool fill, float penSize)
State::State()
: fValid(false),
fEditing(true),
fTracking(TRACKING_NONE),
fStartPoint(-1.0, -1.0),
fEndPoint(-1.0, -1.0),
fColor(color),
fFill(fill),
fPenSize(penSize)
fColor((rgb_color){ 0, 0, 0, 255 }),
fDrawingMode(B_OP_COPY),
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
void
State::MouseDown(BPoint where)
@ -61,6 +77,13 @@ State::SetColor(rgb_color color)
fColor = color;
}
// SetDrawingMode
void
State::SetDrawingMode(drawing_mode mode)
{
fDrawingMode = mode;
}
// SetFill
void
State::SetFill(bool fill)
@ -137,11 +160,7 @@ State::_RenderDot(BView* view, BPoint where) const
void
State::_AdjustViewState(BView* view) const
{
if (fColor.alpha < 255)
view->SetDrawingMode(B_OP_ALPHA);
else
view->SetDrawingMode(B_OP_OVER);
view->SetDrawingMode(fDrawingMode);
view->SetHighColor(fColor);
if (!SupportsFill() || !fFill)
@ -160,8 +179,8 @@ State::_HitTest(BPoint where, BPoint point) const
// LineState
class LineState : public State {
public:
LineState(rgb_color color, bool fill, float penSize)
: State(color, fill, penSize) {}
LineState()
: State() {}
virtual void Draw(BView* view) const
{
@ -180,8 +199,8 @@ class LineState : public State {
// RectState
class RectState : public State {
public:
RectState(rgb_color color, bool fill, float penSize)
: State(color, fill, penSize) {}
RectState()
: State() {}
virtual void Draw(BView* view) const
{
@ -199,8 +218,8 @@ class RectState : public State {
// RoundRectState
class RoundRectState : public State {
public:
RoundRectState(rgb_color color, bool fill, float penSize)
: State(color, fill, penSize) {}
RoundRectState()
: State() {}
virtual void Draw(BView* view) const
{
@ -220,8 +239,8 @@ class RoundRectState : public State {
// EllipseState
class EllipseState : public State {
public:
EllipseState(rgb_color color, bool fill, float penSize)
: State(color, fill, penSize) {}
EllipseState()
: State() {}
virtual void Draw(BView* view) const
{
@ -238,19 +257,28 @@ class EllipseState : public State {
// StateFor
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) {
case OBJECT_LINE:
return new LineState(color, fill, penSize);
state = new LineState();
break;
case OBJECT_RECT:
return new RectState(color, fill, penSize);
state = new RectState();
break;
case OBJECT_ROUND_RECT:
return new RoundRectState(color, fill, penSize);
state = new RoundRectState();
break;
case OBJECT_ELLIPSE:
return new EllipseState(color, fill, penSize);
state = new EllipseState();
break;
default:
return NULL;
break;
}
if (state)
state->Init(color, mode, fill, penSize);
return state;
}

View File

@ -19,40 +19,44 @@ enum {
class State {
public:
State(rgb_color color,
bool fill, float penSize);
State();
virtual ~State();
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);
void SetEditing(bool editing);
BRect Bounds() const;
virtual void Draw(BView* view) const;
virtual bool SupportsFill() const
{ return true; }
static State* StateFor(int32 objectType,
rgb_color color,
void Init(rgb_color color, drawing_mode mode,
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 SetDrawingMode(drawing_mode mode);
void SetFill(bool fill);
void SetPenSize(float penSize);
void SetEditing(bool editing);
BRect Bounds() const;
virtual void Draw(BView* view) const;
virtual bool SupportsFill() const
{ return true; }
static State* StateFor(int32 objectType,
rgb_color color, drawing_mode mode,
bool fill, float penSize);
protected:
BRect _ValidRect() const;
void _RenderDot(BView* view, BPoint where) const;
void _AdjustViewState(BView* view) const;
BRect _ValidRect() const;
void _RenderDot(BView* view, BPoint where) const;
void _AdjustViewState(BView* view) const;
bool _HitTest(BPoint where, BPoint point) const;
bool _HitTest(BPoint where, BPoint point) const;
bool fValid;
bool fValid;
bool fEditing;
bool fEditing;
enum {
TRACKING_NONE = 0,
@ -60,15 +64,16 @@ class State {
TRACKING_END
};
uint32 fTracking;
BPoint fClickOffset;
uint32 fTracking;
BPoint fClickOffset;
BPoint fStartPoint;
BPoint fEndPoint;
BPoint fStartPoint;
BPoint fEndPoint;
rgb_color fColor;
bool fFill;
float fPenSize;
rgb_color fColor;
drawing_mode fDrawingMode;
bool fFill;
float fPenSize;
};
#endif // STATES_H