xref: /haiku/src/tests/servers/app/playground/States.cpp (revision 778e3c640d3f8f0e04e15303871b7d1a7b8a86c0)
1 // States.cpp
2 
3 #include <View.h>
4 
5 #include "States.h"
6 
7 // constructor
State()8 State::State()
9 	: fValid(false),
10 	  fEditing(true),
11 	  fTracking(TRACKING_NONE),
12 	  fStartPoint(-1.0, -1.0),
13 	  fEndPoint(-1.0, -1.0),
14 	  fColor((rgb_color){ 0, 0, 0, 255 }),
15 	  fDrawingMode(B_OP_COPY),
16 	  fFill(true),
17 	  fPenSize(1.0)
18 {
19 }
20 
21 // destructor
~State()22 State::~State()
23 {
24 }
25 
26 // Init
27 void
Init(rgb_color color,drawing_mode mode,bool fill,float penSize)28 State::Init(rgb_color color, drawing_mode mode, bool fill, float penSize)
29 {
30 	fColor = color;
31 	fDrawingMode = mode;
32 	fFill = fill;
33 	fPenSize = penSize;
34 }
35 
36 // MouseDown
37 void
MouseDown(BPoint where)38 State::MouseDown(BPoint where)
39 {
40 	where.x = floorf(where.x + 0.5);
41 	where.y = floorf(where.y + 0.5);
42 
43 	if (_HitTest(where, fStartPoint)) {
44 		fTracking = TRACKING_START;
45 		fClickOffset = fStartPoint - where;
46 	} else if (_HitTest(where, fEndPoint)) {
47 		fTracking = TRACKING_END;
48 		fClickOffset = fEndPoint - where;
49 	} else if (!fValid) {
50 		fTracking = TRACKING_END;
51 		fStartPoint = fEndPoint = where;
52 		fClickOffset.Set(0.0, 0.0);
53 	}
54 }
55 
56 // MouseUp
57 void
MouseUp()58 State::MouseUp()
59 {
60 	fTracking = TRACKING_NONE;
61 }
62 
63 // MouseMoved
64 void
MouseMoved(BPoint where)65 State::MouseMoved(BPoint where)
66 {
67 	where.x = floorf(where.x + 0.5);
68 	where.y = floorf(where.y + 0.5);
69 
70 	if (fTracking == TRACKING_START) {
71 		fStartPoint = where + fClickOffset;
72 		fValid = true;
73 	} else if (fTracking == TRACKING_END) {
74 		fEndPoint = where + fClickOffset;
75 		fValid = true;
76 	}
77 }
78 
79 // SetColor
80 void
SetColor(rgb_color color)81 State::SetColor(rgb_color color)
82 {
83 	fColor = color;
84 }
85 
86 // SetDrawingMode
87 void
SetDrawingMode(drawing_mode mode)88 State::SetDrawingMode(drawing_mode mode)
89 {
90 	fDrawingMode = mode;
91 }
92 
93 // SetFill
94 void
SetFill(bool fill)95 State::SetFill(bool fill)
96 {
97 	fFill = fill;
98 }
99 
100 // SetPenSize
101 void
SetPenSize(float penSize)102 State::SetPenSize(float penSize)
103 {
104 	fPenSize = penSize;
105 }
106 
107 // SetEditing
108 void
SetEditing(bool editing)109 State::SetEditing(bool editing)
110 {
111 	fEditing = editing;
112 }
113 
114 // Bounds
115 BRect
Bounds() const116 State::Bounds() const
117 {
118 	if (fValid) {
119 		BRect r = _ValidRect();
120 		float inset = -2.0; // for the dots
121 		if (!SupportsFill() || !fFill) {
122 			inset = min_c(inset, -ceilf(fPenSize / 2.0));
123 		}
124 		r.InsetBy(inset, inset);
125 		return r;
126 	}
127 	return BRect(0.0, 0.0, -1.0, -1.0);
128 }
129 
130 // Draw
131 void
Draw(BView * view) const132 State::Draw(BView* view) const
133 {
134 	if (fValid && fEditing) {
135 		_RenderDot(view, fStartPoint);
136 		_RenderDot(view, fEndPoint);
137 	}
138 }
139 
140 // _ValidRect
141 BRect
_ValidRect() const142 State::_ValidRect() const
143 {
144 	return BRect(min_c(fStartPoint.x, fEndPoint.x),
145 				 min_c(fStartPoint.y, fEndPoint.y),
146 				 max_c(fStartPoint.x, fEndPoint.x),
147 				 max_c(fStartPoint.y, fEndPoint.y));
148 }
149 
150 // _RenderDot
151 void
_RenderDot(BView * view,BPoint where) const152 State::_RenderDot(BView* view, BPoint where) const
153 {
154 	view->SetHighColor(0, 0, 0, 255);
155 	view->SetPenSize(1.0);
156 	view->SetDrawingMode(B_OP_COPY);
157 	BRect r(where, where);
158 	r.InsetBy(-2.0, -2.0);
159 	view->StrokeRect(r);
160 	view->SetHighColor(255, 255, 255, 255);
161 	r.InsetBy(1.0, 1.0);
162 	view->FillRect(r);
163 }
164 
165 // _AdjustViewState
166 void
_AdjustViewState(BView * view) const167 State::_AdjustViewState(BView* view) const
168 {
169 	view->SetDrawingMode(fDrawingMode);
170 	view->SetHighColor(fColor);
171 
172 	if (!SupportsFill() || !fFill)
173 		view->SetPenSize(fPenSize);
174 }
175 
176 // _HitTest
177 bool
_HitTest(BPoint where,BPoint point) const178 State::_HitTest(BPoint where, BPoint point) const
179 {
180 	BRect r(point, point);
181 	r.InsetBy(-8.0, -8.0);
182 	return r.Contains(where);
183 }
184 
185 // LineState
186 class LineState : public State {
187  public:
LineState()188 					LineState()
189 						: State() {}
190 
Draw(BView * view) const191 	virtual	void	Draw(BView* view) const
192 					{
193 						if (fValid) {
194 							_AdjustViewState(view);
195 							view->StrokeLine(fStartPoint, fEndPoint);
196 						}
197 						State::Draw(view);
198 					}
SupportsFill() const199 	virtual	bool	SupportsFill() const
200 					{
201 						return false;
202 					}
203 };
204 
205 // RectState
206 class RectState : public State {
207  public:
RectState()208 					RectState()
209 						: State() {}
210 
Draw(BView * view) const211 	virtual	void	Draw(BView* view) const
212 					{
213 						if (fValid) {
214 							_AdjustViewState(view);
215 							if (fFill)
216 								view->FillRect(_ValidRect());
217 							else
218 								view->StrokeRect(_ValidRect());
219 						}
220 						State::Draw(view);
221 					}
222 };
223 
224 // RoundRectState
225 class RoundRectState : public State {
226  public:
RoundRectState()227 					RoundRectState()
228 						: State() {}
229 
Draw(BView * view) const230 	virtual	void	Draw(BView* view) const
231 					{
232 						if (fValid) {
233 							_AdjustViewState(view);
234 							BRect r = _ValidRect();
235 							float radius = min_c(r.Width() / 3.0, r.Height() / 3.0);
236 							if (fFill)
237 								view->FillRoundRect(r, radius, radius);
238 							else
239 								view->StrokeRoundRect(r, radius, radius);
240 						}
241 						State::Draw(view);
242 					}
243 };
244 
245 // EllipseState
246 class EllipseState : public State {
247  public:
EllipseState()248 					EllipseState()
249 						: State() {}
250 
Draw(BView * view) const251 	virtual	void	Draw(BView* view) const
252 					{
253 						if (fValid) {
254 							_AdjustViewState(view);
255 							if (fFill)
256 								view->FillEllipse(_ValidRect());
257 							else
258 								view->StrokeEllipse(_ValidRect());
259 						}
260 						State::Draw(view);
261 					}
262 };
263 
264 // StateFor
265 State*
StateFor(int32 objectType,rgb_color color,drawing_mode mode,bool fill,float penSize)266 State::StateFor(int32 objectType, rgb_color color, drawing_mode mode,
267 				bool fill, float penSize)
268 {
269 	State* state = NULL;
270 	switch (objectType) {
271 		case OBJECT_LINE:
272 			state = new LineState();
273 			break;
274 		case OBJECT_RECT:
275 			state = new RectState();
276 			break;
277 		case OBJECT_ROUND_RECT:
278 			state = new RoundRectState();
279 			break;
280 		case OBJECT_ELLIPSE:
281 			state = new EllipseState();
282 			break;
283 		default:
284 			break;
285 	}
286 	if (state)
287 		state->Init(color, mode, fill, penSize);
288 	return state;
289 }
290 
291