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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user