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 if (_HitTest(where, fStartPoint)) { 41 fTracking = TRACKING_START; 42 fClickOffset = fStartPoint - where; 43 } else if (_HitTest(where, fEndPoint)) { 44 fTracking = TRACKING_END; 45 fClickOffset = fEndPoint - where; 46 } else if (!fValid) { 47 fTracking = TRACKING_END; 48 fStartPoint = fEndPoint = where; 49 fClickOffset.Set(0.0, 0.0); 50 } 51 } 52 53 // MouseUp 54 void 55 State::MouseUp() 56 { 57 fTracking = TRACKING_NONE; 58 } 59 60 // MouseMoved 61 void 62 State::MouseMoved(BPoint where) 63 { 64 if (fTracking == TRACKING_START) { 65 fStartPoint = where + fClickOffset; 66 fValid = true; 67 } else if (fTracking == TRACKING_END) { 68 fEndPoint = where + fClickOffset; 69 fValid = true; 70 } 71 } 72 73 // SetColor 74 void 75 State::SetColor(rgb_color color) 76 { 77 fColor = color; 78 } 79 80 // SetDrawingMode 81 void 82 State::SetDrawingMode(drawing_mode mode) 83 { 84 fDrawingMode = mode; 85 } 86 87 // SetFill 88 void 89 State::SetFill(bool fill) 90 { 91 fFill = fill; 92 } 93 94 // SetPenSize 95 void 96 State::SetPenSize(float penSize) 97 { 98 fPenSize = penSize; 99 } 100 101 // SetEditing 102 void 103 State::SetEditing(bool editing) 104 { 105 fEditing = editing; 106 } 107 108 // Bounds 109 BRect 110 State::Bounds() const 111 { 112 if (fValid) { 113 BRect r = _ValidRect(); 114 float inset = -2.0; // for the dots 115 if (!SupportsFill() || !fFill) { 116 inset = min_c(inset, -ceilf(fPenSize / 2.0)); 117 } 118 r.InsetBy(inset, inset); 119 return r; 120 } 121 return BRect(0.0, 0.0, -1.0, -1.0); 122 } 123 124 // Draw 125 void 126 State::Draw(BView* view) const 127 { 128 if (fValid && fEditing) { 129 _RenderDot(view, fStartPoint); 130 _RenderDot(view, fEndPoint); 131 } 132 } 133 134 // _ValidRect 135 BRect 136 State::_ValidRect() const 137 { 138 return BRect(min_c(fStartPoint.x, fEndPoint.x), 139 min_c(fStartPoint.y, fEndPoint.y), 140 max_c(fStartPoint.x, fEndPoint.x), 141 max_c(fStartPoint.y, fEndPoint.y)); 142 } 143 144 // _RenderDot 145 void 146 State::_RenderDot(BView* view, BPoint where) const 147 { 148 view->SetHighColor(0, 0, 0, 255); 149 view->SetPenSize(1.0); 150 view->SetDrawingMode(B_OP_COPY); 151 BRect r(where, where); 152 r.InsetBy(-2.0, -2.0); 153 view->StrokeRect(r); 154 view->SetHighColor(255, 255, 255, 255); 155 r.InsetBy(1.0, 1.0); 156 view->FillRect(r); 157 } 158 159 // _AdjustViewState 160 void 161 State::_AdjustViewState(BView* view) const 162 { 163 view->SetDrawingMode(fDrawingMode); 164 view->SetHighColor(fColor); 165 166 if (!SupportsFill() || !fFill) 167 view->SetPenSize(fPenSize); 168 } 169 170 // _HitTest 171 bool 172 State::_HitTest(BPoint where, BPoint point) const 173 { 174 BRect r(point, point); 175 r.InsetBy(-8.0, -8.0); 176 return r.Contains(where); 177 } 178 179 // LineState 180 class LineState : public State { 181 public: 182 LineState() 183 : State() {} 184 185 virtual void Draw(BView* view) const 186 { 187 if (fValid) { 188 _AdjustViewState(view); 189 view->StrokeLine(fStartPoint, fEndPoint); 190 } 191 State::Draw(view); 192 } 193 virtual bool SupportsFill() const 194 { 195 return false; 196 } 197 }; 198 199 // RectState 200 class RectState : public State { 201 public: 202 RectState() 203 : State() {} 204 205 virtual void Draw(BView* view) const 206 { 207 if (fValid) { 208 _AdjustViewState(view); 209 if (fFill) 210 view->FillRect(_ValidRect()); 211 else 212 view->StrokeRect(_ValidRect()); 213 } 214 State::Draw(view); 215 } 216 }; 217 218 // RoundRectState 219 class RoundRectState : public State { 220 public: 221 RoundRectState() 222 : State() {} 223 224 virtual void Draw(BView* view) const 225 { 226 if (fValid) { 227 _AdjustViewState(view); 228 BRect r = _ValidRect(); 229 float radius = min_c(r.Width() / 3.0, r.Height() / 3.0); 230 if (fFill) 231 view->FillRoundRect(r, radius, radius); 232 else 233 view->StrokeRoundRect(r, radius, radius); 234 } 235 State::Draw(view); 236 } 237 }; 238 239 // EllipseState 240 class EllipseState : public State { 241 public: 242 EllipseState() 243 : State() {} 244 245 virtual void Draw(BView* view) const 246 { 247 if (fValid) { 248 _AdjustViewState(view); 249 if (fFill) 250 view->FillEllipse(_ValidRect()); 251 else 252 view->StrokeEllipse(_ValidRect()); 253 } 254 State::Draw(view); 255 } 256 }; 257 258 // StateFor 259 State* 260 State::StateFor(int32 objectType, rgb_color color, drawing_mode mode, 261 bool fill, float penSize) 262 { 263 State* state = NULL; 264 switch (objectType) { 265 case OBJECT_LINE: 266 state = new LineState(); 267 break; 268 case OBJECT_RECT: 269 state = new RectState(); 270 break; 271 case OBJECT_ROUND_RECT: 272 state = new RoundRectState(); 273 break; 274 case OBJECT_ELLIPSE: 275 state = new EllipseState(); 276 break; 277 default: 278 break; 279 } 280 if (state) 281 state->Init(color, mode, fill, penSize); 282 return state; 283 } 284 285