1// States.cpp 2 3#include <View.h> 4 5#include "States.h" 6 7// constructor 8State::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 22State::~State() 23{ 24} 25 26// Init 27void 28State::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 37void 38State::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 57void 58State::MouseUp() 59{ 60 fTracking = TRACKING_NONE; 61} 62 63// MouseMoved 64void 65State::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 80void 81State::SetColor(rgb_color color) 82{ 83 fColor = color; 84} 85 86// SetDrawingMode 87void 88State::SetDrawingMode(drawing_mode mode) 89{ 90 fDrawingMode = mode; 91} 92 93// SetFill 94void 95State::SetFill(bool fill) 96{ 97 fFill = fill; 98} 99 100// SetPenSize 101void 102State::SetPenSize(float penSize) 103{ 104 fPenSize = penSize; 105} 106 107// SetEditing 108void 109State::SetEditing(bool editing) 110{ 111 fEditing = editing; 112} 113 114// Bounds 115BRect 116State::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 131void 132State::Draw(BView* view) const 133{ 134 if (fValid && fEditing) { 135 _RenderDot(view, fStartPoint); 136 _RenderDot(view, fEndPoint); 137 } 138} 139 140// _ValidRect 141BRect 142State::_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 151void 152State::_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 166void 167State::_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 177bool 178State::_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 186class LineState : public State { 187 public: 188 LineState() 189 : State() {} 190 191 virtual void Draw(BView* view) const 192 { 193 if (fValid) { 194 _AdjustViewState(view); 195 view->StrokeLine(fStartPoint, fEndPoint); 196 } 197 State::Draw(view); 198 } 199 virtual bool SupportsFill() const 200 { 201 return false; 202 } 203}; 204 205// RectState 206class RectState : public State { 207 public: 208 RectState() 209 : State() {} 210 211 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 225class RoundRectState : public State { 226 public: 227 RoundRectState() 228 : State() {} 229 230 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 246class EllipseState : public State { 247 public: 248 EllipseState() 249 : State() {} 250 251 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 265State* 266State::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