1 // States.cpp 2 3 #include <View.h> 4 5 #include "States.h" 6 7 // constructor 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 22 State::~State() 23 { 24 } 25 26 // Init 27 void 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 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 58 State::MouseUp() 59 { 60 fTracking = TRACKING_NONE; 61 } 62 63 // MouseMoved 64 void 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 81 State::SetColor(rgb_color color) 82 { 83 fColor = color; 84 } 85 86 // SetDrawingMode 87 void 88 State::SetDrawingMode(drawing_mode mode) 89 { 90 fDrawingMode = mode; 91 } 92 93 // SetFill 94 void 95 State::SetFill(bool fill) 96 { 97 fFill = fill; 98 } 99 100 // SetPenSize 101 void 102 State::SetPenSize(float penSize) 103 { 104 fPenSize = penSize; 105 } 106 107 // SetEditing 108 void 109 State::SetEditing(bool editing) 110 { 111 fEditing = editing; 112 } 113 114 // Bounds 115 BRect 116 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 132 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 142 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 152 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 167 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 178 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: 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 206 class 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 225 class 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 246 class 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 265 State* 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