1 namespace Upp { 2 3 class PlotterDragDrop; 4 5 class PlotterCtrl : public DragDropCtrl, public CtrlFrame 6 { 7 public: 8 class ViewPlot : public Plotter 9 { 10 public: 11 ViewPlot(PlotterCtrl& ctrl, int extra_gap = 0); 12 ViewPlot(PlotterCtrl& ctrl, Pointf scale, Pointf delta, int extra_gap = 0); 13 ViewPlot(PlotterCtrl& ctrl, const Matrixf& preform, int extra_gap = 0); 14 15 private: 16 ViewDraw viewdraw; 17 }; 18 friend class ViewPlot; 19 20 typedef PlotterCtrl CLASSNAME; 21 PlotterCtrl(); 22 virtual ~PlotterCtrl(); 23 24 virtual void FrameAdd(Ctrl& ctrl); 25 virtual void FrameRemove(); 26 virtual void FrameLayout(Rect& rc); 27 virtual void FrameAddSize(Size& sz); 28 29 virtual void Layout(); 30 virtual void Paint(Draw& draw); 31 // void AsyncPaint(); IsPainting()32 bool IsPainting() const { return is_painting; } 33 LostFocus()34 virtual void LostFocus() { ResetPush(); } 35 36 ImageDraw& BeginBufferPaint(); 37 virtual void EndBufferPaint(); 38 39 virtual void Plot(Plotter& plotter) = 0; AbortPlot()40 virtual void AbortPlot() {} 41 42 void BufferPaint(bool bp = true) { buffer_paint = bp; RefreshBuffer(); } IsBufferPaint()43 bool IsBufferPaint() const { return buffer_paint; } 44 void RefreshBuffer(); 45 void RefreshBuffer(const Rect& rc); 46 47 void BufferPan(bool bp = true) { buffer_pan = bp; } IsBufferPan()48 bool IsBufferPan() const { return buffer_pan; } 49 void PanOffset(Point o); ClearPanOffset()50 void ClearPanOffset() { PanOffset(Point(0, 0)); } GetPanOffset()51 Point GetPanOffset() const { return pan_offset; } 52 ShowScroll(bool ssc)53 void ShowScroll(bool ssc) { show_scroll = ssc; Layout(); } IsScrollShown()54 bool IsScrollShown() const { return show_scroll; } 55 MaxScale(double d)56 void MaxScale(double d) { max_scale.cx = max_scale.cy = d; } MaxScale(Sizef ms)57 void MaxScale(Sizef ms) { max_scale = ms; } GetMaxScale()58 Sizef GetMaxScale() const { return max_scale; } 59 Gap(Rect g)60 void Gap(Rect g) { gap = g; Layout(); } Gap(int i)61 void Gap(int i) { gap = Rect(i, i, i, i); Layout(); } GetGap()62 Rect GetGap() const { return gap; } 63 64 virtual Image CursorImage(Point pt, dword keyflags); 65 virtual bool Push(Point pt, dword keyflags); 66 virtual void Drag(Point start, Point prev, Point curr, dword keyflags); 67 virtual void Drop(Point start, Point end, dword keyflags); 68 virtual void Click(Point pt, dword keyflags); 69 virtual void Cancel(); 70 virtual bool Key(dword key, int repcnt); 71 virtual void MouseWheel(Point p, int zdelta, dword keyflags); 72 virtual void MouseMove(Point pt, dword keyflags); 73 RefreshPos()74 virtual void RefreshPos() {} RefreshDragDrop()75 virtual void RefreshDragDrop() { RefreshBuffer(); } 76 FromClient(Point pt)77 Pointf FromClient(Point pt) const { return (Pointf(pt) - delta) / scale; } FromClientNull(Point pt)78 Pointf FromClientNull(Point pt) const { return IsNull(pt) ? Pointf(Null) : FromClient(pt); } 79 Rectf FromClient(const Rect& rc) const; 80 FromPushClient(Point pt)81 Pointf FromPushClient(Point pt) const { return (Pointf(pt) - push_delta) / push_scale; } FromPushClientNull(Point pt)82 Pointf FromPushClientNull(Point pt) const { return IsNull(pt) ? Pointf(Null) : FromPushClient(pt); } 83 ToClient(Pointf pt)84 Point ToClient(Pointf pt) const { return PointfToPoint(Sizef(pt) * scale + delta); } ToClientNull(Pointf pt)85 Point ToClientNull(Pointf pt) const { return IsNull(pt) ? Point(Null) : PointfToPoint(Sizef(pt) * scale + delta); } 86 Rect ToClient(const Rectf& rc) const; 87 ToPushClient(Pointf pt)88 Point ToPushClient(Pointf pt) const { return PointfToPoint(Sizef(pt) * push_scale + push_delta); } ToPushClientNull(Pointf pt)89 Point ToPushClientNull(Pointf pt) const { return IsNull(pt) ? Point(Null) : ToPushClient(pt); } 90 91 void SyncPush(); 92 93 void SetExtent(const Rectf& extent); GetExtent()94 const Rectf& GetExtent() const { return extent; } 95 GetViewRect()96 Rectf GetViewRect() const { return FromClient(Rect(GetSize()).Deflated(gap)); } 97 98 void ScrollInto(Rectf rc); 99 void ScrollInto(Pointf pt); 100 101 void SetAspectRatio(double aspect); NoAspectRatio()102 void NoAspectRatio() { SetAspectRatio(0); } GetAspectRatio()103 double GetAspectRatio() const { return aspect; } IsAspectRatio()104 bool IsAspectRatio() const { return aspect != 0; } 105 106 void SetAspectLock(bool a = true); NoAspectLock()107 void NoAspectLock() { SetAspectLock(false); } IsAspectLock()108 bool IsAspectLock() const { return aspect_lock; } IsAspectLocked()109 bool IsAspectLocked() const { return IsAspectRatio() || IsAspectLock(); } 110 111 void EnableLock(bool e = true); DisableLock()112 void DisableLock() { EnableLock(false); } IsLockEnabled()113 bool IsLockEnabled() const { return enable_lock; }\ 114 115 void SetScale(Sizef scale); 116 void SetDelta(Pointf delta); 117 void SetZoom(Sizef scale, Pointf delta); 118 void SetZoom(double scale, Pointf delta); 119 void SetZoomSc(Sizef scale); SetZoomSc(double sx,double sy)120 void SetZoomSc(double sx, double sy) { SetZoomSc(Pointf(sx, sy)); } 121 void SetZoomSc(double z); 122 GetScale()123 Sizef GetScale() const { return scale; } GetPushScale()124 Sizef GetPushScale() const { return push_scale; } 125 double GetAvgScale() const; GetDelta()126 Pointf GetDelta() const { return delta; } GetPushDelta()127 Pointf GetPushDelta() const { return push_delta; } 128 IsReversedX()129 bool IsReversedX() const { return rev_x; } IsReversedY()130 bool IsReversedY() const { return rev_y; } 131 IsReversing()132 bool IsReversing() const { return scale.cx * scale.cy < 0; } 133 134 Sizef GetPhysicalZoom() const; 135 136 void AdjustPos(Pointf& delta, Point scpos) const; 137 Sizef AdjustScale(Sizef sc) const; 138 139 Pointf GetSc() const; 140 void SetSc(Pointf center); 141 142 void ZoomInX(); 143 void ZoomOutX(); ZoomFullX()144 void ZoomFullX() { if(extent.left < extent.right) ZoomX(extent.left, extent.right); } 145 void ZoomX(double min, double max, bool add_gap = true); 146 void ZoomInY(); 147 void ZoomOutY(); ZoomFullY()148 void ZoomFullY() { if(extent.top < extent.bottom) ZoomY(extent.right, extent.bottom); } 149 void ZoomY(double min, double max, bool add_gap = true); ZoomIn()150 void ZoomIn() { ZoomInX(); ZoomInY(); } ZoomOut()151 void ZoomOut() { ZoomOutX(); ZoomOutY(); } ZoomFull()152 void ZoomFull() { Zoom(extent, false); } 153 void Zoom(const Rectf& rc, bool keep_ratio = true, bool add_gap = true); 154 155 void UserZoomInX(); 156 void UserZoomOutX(); 157 void UserZoomFullX(); 158 void UserZoomX(double min, double max); 159 void UserZoomInY(); 160 void UserZoomOutY(); 161 void UserZoomFullY(); 162 void UserZoomY(double min, double max); 163 void UserZoomIn(); 164 void UserZoomOut(); 165 virtual void UserZoomFull(); 166 void UserAspectLock(); 167 void UserZoom(const Rectf& rc, bool keep_ratio = true); 168 169 void PickDragDrop(One<PlotterDragDrop> dd); 170 One<PlotterDragDrop> ClearDragDrop(); GetDragDrop()171 PlotterDragDrop *GetDragDrop() { return ~drag_drop; } GetDragDrop()172 const PlotterDragDrop *GetDragDrop() const { return ~drag_drop; } 173 174 void UpdateMousePos(); GetMousePos()175 Pointf GetMousePos() const { return mouse_pos; } 176 DoSetFocus()177 void DoSetFocus() { SetWantFocus(); } 178 ResetPush()179 void ResetPush() { reset_push = true; } 180 181 TOOL(View) 182 TOOL(ViewZoomInX) 183 TOOL(ViewZoomOutX) 184 TOOL(ViewZoomFullX) 185 TOOL(ViewZoomInY) 186 TOOL(ViewZoomOutY) 187 TOOL(ViewZoomFullY) 188 TOOL(ViewZoomIn) 189 TOOL(ViewZoomOut) 190 TOOL(ViewZoomFull) 191 TOOL(ViewAspectLock) 192 TOOL(ViewPan) 193 194 void PostRefresh(); 195 196 public: 197 Callback WhenRescan; 198 Callback WhenZoom; 199 Callback WhenUserZoom; 200 Callback WhenMousePos; 201 202 protected: 203 void AdjustPos(Point scpos, int xymask); // 1 = x, 2 = y 204 205 protected: 206 bool rev_x, rev_y, aspect_lock, enable_lock; 207 Rect gap; 208 Alignment halign, valign; 209 Color background; 210 Sizef scale; 211 Pointf delta; 212 Sizef push_scale; 213 Pointf push_delta; 214 Sizef max_scale; 215 Pointf mouse_pos; 216 Rectf extent; 217 double aspect; 218 219 Image paint_buffer; 220 One<ImageDraw> paint_draw; 221 bool is_painting; 222 bool abort_repaint; 223 bool buffer_paint; 224 bool buffer_pan; 225 Point pan_offset; 226 227 private: 228 void OnHScroll(); 229 void OnVScroll(); Refresh0()230 void Refresh0() { RefreshBuffer(); } 231 232 private: 233 TimeCallback tcb_refresh; 234 Size old_size; 235 One<PlotterDragDrop> drag_drop; 236 Pointf drag_start; 237 HScrollBar hscroll; 238 VScrollBar vscroll; 239 Button horz_in, horz_out, horz_full; 240 Button vert_in, vert_out, vert_full; 241 Button full; 242 bool reset_push; 243 bool show_scroll; 244 bool lock_drag_drop; 245 bool lock_short_drag_drop; 246 int drag_mode; 247 enum { DRAG_NONE, DRAG_CUSTOM, DRAG_PAN, DRAG_ZOOM_IN, DRAG_ZOOM_OUT }; 248 }; 249 250 template <class T> 251 inline const T *GetDragDrop(const PlotterCtrl *ctrl, T * = 0) 252 { 253 if(const T *p = dynamic_cast<const T *>(ctrl->GetShortDragDrop())) 254 return p; 255 return dynamic_cast<const T *>(ctrl->GetDragDrop()); 256 } 257 258 template <class T> 259 inline T *GetDragDrop(PlotterCtrl *ctrl, T * = 0) 260 { 261 return dynamic_cast<T *>(ctrl->GetDragDrop()); 262 } 263 264 template <class T> 265 inline bool IsDragDrop(const PlotterCtrl *ctrl, T * = 0) 266 { 267 return dynamic_cast<const T *>(ctrl->GetDragDrop());; 268 } 269 // make member template as soon as possible 270 271 class PlotterDragDrop 272 { 273 public: ~PlotterDragDrop()274 virtual ~PlotterDragDrop() {} 275 276 virtual PlotterCtrl& GetOwner() = 0; 277 Plot(Plotter & plotter)278 virtual void Plot(Plotter& plotter) {} Push(Pointf pt,dword keyflags)279 virtual bool Push(Pointf pt, dword keyflags) { return true; } Cursor(Pointf pt,dword keyflags,bool dragging)280 virtual Image Cursor(Pointf pt, dword keyflags, bool dragging) const { return Image::Arrow(); } 281 virtual void Drag(Pointf pt, Pointf prev, Pointf curr, dword keyflags); 282 virtual void DragRect(const Rectf& prev, const Rectf& curr, dword keyflags); 283 virtual void Drop(Pointf pt, Pointf end, dword keyflags); DropRect(const Rectf & rc,dword keyflags)284 virtual void DropRect(const Rectf& rc, dword keyflags) {} Click(Pointf pt,dword keyflags)285 virtual void Click(Pointf pt, dword keyflags) {} Key(dword key)286 virtual bool Key(dword key) { return false; } Cancel()287 virtual void Cancel() {} 288 }; 289 290 class EmptyDragDrop : public PlotterDragDrop 291 { 292 public: EmptyDragDrop(PlotterCtrl & owner)293 EmptyDragDrop(PlotterCtrl& owner) : owner(owner) {} 294 GetOwner()295 virtual PlotterCtrl& GetOwner() { return owner; } 296 Push(Pointf pt,dword keyflags)297 virtual bool Push(Pointf pt, dword keyflags) { return false; } 298 299 private: 300 PlotterCtrl& owner; 301 }; 302 303 class ZoomInDragDrop : public PlotterDragDrop 304 { 305 public: ZoomInDragDrop(PlotterCtrl & owner)306 ZoomInDragDrop(PlotterCtrl& owner) : owner(owner) {} 307 GetOwner()308 virtual PlotterCtrl& GetOwner() { return owner; } 309 310 virtual Image Cursor(Pointf pt, dword keyflags, bool dragging) const; 311 virtual void DropRect(const Rectf& rc, dword keyflags); 312 virtual void Click(Pointf pt, dword keyflags); 313 314 private: 315 PlotterCtrl& owner; 316 }; 317 318 class ZoomOutDragDrop : public PlotterDragDrop 319 { 320 public: ZoomOutDragDrop(PlotterCtrl & owner)321 ZoomOutDragDrop(PlotterCtrl& owner) : owner(owner) {} 322 GetOwner()323 virtual PlotterCtrl& GetOwner() { return owner; } 324 325 virtual Image Cursor(Pointf pt, dword keyflags, bool dragging) const; 326 virtual bool Push(Pointf pt, dword keyflags); 327 virtual void DropRect(const Rectf& rc, dword keyflags); 328 virtual void Click(Pointf pt, dword keyflags); 329 330 private: 331 PlotterCtrl& owner; 332 }; 333 334 class PanDragDrop : public PlotterDragDrop 335 { 336 public: PanDragDrop(PlotterCtrl & owner)337 PanDragDrop(PlotterCtrl& owner) : owner(owner) {} 338 GetOwner()339 virtual PlotterCtrl& GetOwner() { return owner; } 340 341 virtual Image Cursor(Pointf pt, dword keyflags, bool dragging) const; 342 virtual bool Push(Pointf pt, dword keyflags); 343 virtual void Drag(Pointf start, Pointf prev, Pointf curr, dword keyflags); 344 virtual void Drop(Pointf start, Pointf end, dword keyflags); 345 virtual void Cancel(); 346 347 private: 348 PlotterCtrl& owner; 349 }; 350 351 } 352