1 #ifndef _ScatterCtrl_ScatterCtrl_h
2 #define _ScatterCtrl_ScatterCtrl_h
3
4 #include <ScatterDraw/ScatterDraw.h>
5 #include <plugin/jpg/jpg.h>
6 #include <PdfDraw/PdfDraw.h>
7 #include <GridCtrl/GridCtrl.h>
8 #include <plugin/Eigen/Eigen.h>
9 #include <ScatterDraw/Histogram.h>
10
11 #include "PopUpText.h"
12
13 namespace Upp {
14
15 class EditDoubleLostFocus : public EditDouble {
16 public:
17 Event<> WhenLostFocus;
18
LostFocus()19 virtual void LostFocus() {
20 WhenLostFocus();
21 EditDouble::LostFocus();
22 }
23 };
24
25 typedef WithSpin<double, EditDoubleLostFocus> EditDoubleLostFocusSpin;
26
27 class CtrlScroll : public StaticRect {
28 public:
29 CtrlScroll();
30
31 CtrlScroll &AddPane(Ctrl& c, bool scrollH = true, bool scrollV = true);
AddPaneH(Ctrl & c)32 CtrlScroll &AddPaneH(Ctrl& c) {return AddPane(c, true, false);}
AddPaneV(Ctrl & c)33 CtrlScroll &AddPaneV(Ctrl& c) {return AddPane(c, false, true);}
HasPane()34 inline bool HasPane() const {return (~pane != NULL);}
35
36 Event<> WhenScrolled;
37
38 private:
39 virtual void Layout();
40 virtual void MouseWheel(Point p, int zdelta, dword keyflags);
41
42 void Scroll(const Point& p);
43 void OnScroll();
44
45 ScrollBars scroll;
46
47 Ptr<Ctrl> pane;
48 bool hsizepos, vsizepos;
49 };
50
51 class ArrayCtrlSource : public DataSource {
52 private:
53 ArrayCtrl *data;
54 bool useCols;
55 Vector<int> ids;
56 int beginData;
57 int64 numData;
58
59 public:
ArrayCtrlSource()60 ArrayCtrlSource() : data(0), useCols(true), beginData(0), numData(Null) {ids << 0 << 1;}
61 ArrayCtrlSource(ArrayCtrl &_data, bool _useCols = true, int _idX = 0, int _idY = 1, int _beginData = 0, int _numData = Null) {
62 Init(_data, _idY, _idX, _useCols, _beginData, _numData);
63 }
64 void Init(ArrayCtrl &_data, Vector<int> &_ids, bool _useCols = true, int _beginData = 0, int _numData = Null) {
65 data = &_data;
66 useCols = _useCols;
67
68 ids = clone(_ids);
69 beginData = _beginData;
70 if (IsNull(_numData)) {
71 if (!useCols)
72 numData = data->GetColumnCount();
73 else
74 numData = data->GetCount();
75 } else {
76 if (!useCols)
77 numData = min(_numData, data->GetColumnCount());
78 else
79 numData = min(_numData, data->GetCount());
80 }
81 numData -= beginData;
82 }
83 void Init(ArrayCtrl &_data, int idY, int idX, bool _useCols = true, int _beginData = 0, int _numData = Null) {
84 ids << idY << idX;
85 Init(_data, ids, _useCols, _beginData, _numData);
86 }
y(int64 id)87 virtual inline double y(int64 id) {return useCols ? data->Get(beginData + int(id), ids[0]) : data->Get(ids[0], beginData + int(id));};
x(int64 id)88 virtual inline double x(int64 id) {
89 if (IsNull(ids[1]))
90 return double(id);
91 else
92 return useCols ? data->Get(beginData + int(id), ids[1]) : data->Get(ids[1], beginData + int(id));
93 }
xn(int n,int64 id)94 virtual inline double xn(int n, int64 id) {return useCols ? data->Get(beginData + int(id), ids[n]) : data->Get(ids[n], beginData + int(id));}
GetCount()95 virtual inline int64 GetCount() const {return numData;};
96 };
97
98 class GridCtrlSource : public DataSource {
99 private:
100 GridCtrl *data;
101 bool useCols;
102 Vector<int> ids;
103 int beginData;
104 int64 numData;
105
106 public:
GridCtrlSource()107 GridCtrlSource() : data(0), useCols(true), beginData(0), numData(Null) {ids << 0 << 1;}
108 GridCtrlSource(GridCtrl &_data, bool _useCols = true, int idX = 0, int idY = 1, int _beginData = 0, int _numData = Null) {
109 ids << idY << idX;
110 Init(_data, ids, _useCols, _beginData, _numData);
111 }
112 GridCtrlSource(GridCtrl &_data, Vector<int> &_ids, bool _useCols = true, int _beginData = 0, int _numData = Null) {
113 Init(_data, _ids, _useCols, _beginData, _numData);
114 }
115 void Init(GridCtrl &_data, Vector<int> &_ids, bool _useCols = true, int _beginData = 0, int _numData = Null) {
116 data = &_data;
117 useCols = _useCols;
118
119 ids = clone(_ids);
120 beginData = _beginData;
121 if (IsNull(_numData)) {
122 if (!useCols)
123 numData = data->GetColumnCount();
124 else
125 numData = data->GetRowCount();
126 } else {
127 if (!useCols)
128 numData = min(_numData, data->GetColumnCount());
129 else
130 numData = min(_numData, data->GetRowCount());
131 }
132 numData -= beginData;
133 }
134 void Init(GridCtrl &_data, int idY, int idX, bool _useCols = true, int _beginData = 0, int _numData = Null) {
135 Vector<int> _ids;
136 _ids << idY << idX;
137 Init(_data, _ids, _useCols, _beginData, _numData);
138 }
GetVal(int64 id,int idx)139 double GetVal(int64 id, int idx) const {
140 if (IsNull(ids[idx]))
141 return double(id);
142 else {
143 int r, c;
144 if (useCols) {
145 r = beginData + int(id);
146 c = ids[idx];
147 } else {
148 r = ids[idx];
149 c = beginData + int(id);
150 }
151 const Value &val = data->Get(r, c);
152 if (val.Is<double>())
153 return double(val);
154 else
155 return ScanDouble(val.ToString());
156 }
157 }
y(int64 id)158 virtual inline double y(int64 id) {return GetVal(id, 0);}
x(int64 id)159 virtual inline double x(int64 id) {return GetVal(id, 1);}
xn(int n,int64 id)160 virtual inline double xn(int n, int64 id) {return useCols ? data->Get(beginData + int(id), ids[n]) : data->Get(ids[n], beginData + int(id));}
GetCount()161 virtual inline int64 GetCount() const {return numData;};
162 };
163
164 class ScatterCtrl : public Ctrl, public ScatterDraw {
165 public:
166 ScatterCtrl();
~ScatterCtrl()167 virtual ~ScatterCtrl() noexcept {RemoveInstance(this);};
168
169 enum ScatterAction {NO_ACTION = 0, SCROLL, ZOOM_H_ENL, ZOOM_H_RED, ZOOM_V_ENL, ZOOM_V_RED,
170 SHOW_COORDINATES, CONTEXT_MENU, ZOOM_WINDOW,
171 SCROLL_LEFT, SCROLL_RIGHT, SCROLL_UP, SCROLL_DOWN, ZOOM_FIT};
172 #define SHOW_INFO SHOW_COORDINATES
173
174 struct MouseBehavior {
MouseBehaviorMouseBehavior175 MouseBehavior(bool _ctrl, bool _alt, bool _shift, bool _left, bool _middle, int _middleWheel, bool _right, ScatterAction _action) :
176 ctrl(_ctrl), alt(_alt), shift(_shift), left(_left), middle(_middle), middleWheel(_middleWheel), right(_right), action(_action) {}
177 bool ctrl;
178 bool alt;
179 bool shift;
180 bool left;
181 bool middle;
182 int middleWheel;
183 bool right;
184 ScatterAction action;
185 };
186 void AddMouseBehavior(bool ctrl, bool alt, bool shift, bool left, bool middle, int middlewheel, bool right, ScatterAction action);
187 void RemoveMouseBehavior(ScatterAction action);
188 void ClearMouseBehavior();
189
190 enum MouseAction {NONE, LEFT_DOWN, LEFT_UP, LEFT_DOUBLE, LEFT_MOVE, MIDDLE_DOWN, MIDDLE_UP, MIDDLE_MOVE,
191 RIGHT_DOWN, RIGHT_UP, RIGHT_MOVE};
192 Function<void(Point, dword, MouseAction)> WhenMouseClick;
193
194 struct KeyBehavior {
KeyBehaviorKeyBehavior195 KeyBehavior(bool _ctrl, bool _alt, bool _shift, int _key, bool _isVirtualKey, ScatterAction _action) :
196 ctrl(_ctrl), alt(_alt), shift(_shift), key(_key), isVirtualKey(_isVirtualKey), action(_action) {}
197 bool ctrl;
198 bool alt;
199 bool shift;
200 int key;
201 bool isVirtualKey;
202 ScatterAction action;
203 };
204 void AddKeyBehavior(bool ctrl, bool alt, bool shift, int key, bool isVirtualKey, ScatterAction action);
205 void RemoveKeyBehavior(ScatterAction action);
206 void ClearKeyBehavior();
207
208 ScatterCtrl& ShowContextMenu(bool show = true) {showContextMenu = show; return *this;}
209 ScatterCtrl& ShowPropertiesDlg(bool show = true){
210 showPropDlg = show;
211 CheckButtonVisible();
212 return *this;
213 }
214 ScatterCtrl& ShowProcessDlg(bool show = true) {
215 showProcessDlg = show;
216 CheckButtonVisible();
217 return *this;
218 }
219 ScatterCtrl& ShowButtons(bool show = true) {
220 showButtons = show;
221 CheckButtonVisible();
222 return *this;
223 }
224 void CheckButtonVisible();
225
ShowLoadData(bool _showLoadData)226 ScatterCtrl& ShowLoadData(bool _showLoadData) {
227 this->showLoadData = _showLoadData;
228 return *this;
229 }
ShowSaveData(bool _showSaveData)230 ScatterCtrl& ShowSaveData(bool _showSaveData) {
231 this->showSaveData = _showSaveData;
232 return *this;
233 }
234
235 ScatterCtrl& SetPopText(const String x, const String y1, const String y2, const String z = "z")
236 {popTextX = x; popTextY = y1; popTextY2 = y2; popTextZ = z; return *this;}
237
238 ScatterCtrl& ShowInfo(bool show = true) {showInfo = show; return *this;}
ShowAllMenus()239 ScatterCtrl& ShowAllMenus() {return ShowInfo().ShowContextMenu().ShowPropertiesDlg().ShowProcessDlg().ShowButtons();}
240
241 #ifdef PLATFORM_WIN32
242 void SaveAsMetafile(const char* file);
243 #endif
244 void SaveToClipboard(bool saveAsMetafile = false);
245 void SaveToFile(String fileName = Null);
246
247 void LoadControl();
248 void SaveControl();
249 void OnChangeSaveCtrl();
250
Refresh()251 virtual void Refresh() {Ctrl::Refresh();};
GetSize()252 virtual Size GetSize() const {return Ctrl::GetSize();};
253
SetColor(const Upp::Color & _color)254 ScatterCtrl& SetColor(const Upp::Color& _color) {ScatterDraw::SetColor(_color); return *this;};
SetGridColor(const Upp::Color & grid_color)255 ScatterCtrl& SetGridColor(const Upp::Color& grid_color) {ScatterDraw::SetGridColor(grid_color); return *this;};
SetGridWidth(double grid_width)256 ScatterCtrl& SetGridWidth(double grid_width) {ScatterDraw::SetGridWidth(grid_width); return *this;};
SetPlotAreaColor(const Upp::Color & p_a_color)257 ScatterCtrl& SetPlotAreaColor(const Upp::Color& p_a_color) {ScatterDraw::SetPlotAreaColor(p_a_color); return *this;};
SetAxisColor(const Upp::Color & axis_color)258 ScatterCtrl& SetAxisColor(const Upp::Color& axis_color) {ScatterDraw::SetAxisColor(axis_color); return *this;};
SetAxisWidth(int axis_width)259 ScatterCtrl& SetAxisWidth(int axis_width) {ScatterDraw::SetAxisWidth(axis_width); return *this;};
SetTitle(const String & _title)260 ScatterCtrl& SetTitle(const String& _title) {ScatterDraw::SetTitle(_title); return *this;};
SetTitleFont(const Upp::Font & fontTitle)261 ScatterCtrl& SetTitleFont(const Upp::Font& fontTitle) {ScatterDraw::SetTitleFont(fontTitle); return *this;};
SetTitleColor(const Upp::Color & colorTitle)262 ScatterCtrl& SetTitleColor(const Upp::Color& colorTitle) {ScatterDraw::SetTitleColor(colorTitle); return *this;};
SetLabelsFont(const Upp::Font & fontLabels)263 ScatterCtrl& SetLabelsFont(const Upp::Font& fontLabels) {ScatterDraw::SetLabelsFont(fontLabels); return *this;};
SetLabelsColor(const Upp::Color & colorLabels)264 ScatterCtrl& SetLabelsColor(const Upp::Color& colorLabels) {ScatterDraw::SetLabelsColor(colorLabels); return *this;};
SetLabelX(const String & _xLabel)265 ScatterCtrl& SetLabelX(const String& _xLabel) {ScatterDraw::SetLabelX(_xLabel); return *this;};
SetLabelY(const String & _yLabel)266 ScatterCtrl& SetLabelY(const String& _yLabel) {ScatterDraw::SetLabelY(_yLabel); return *this;};
SetLabelY2(const String & _yLabel)267 ScatterCtrl& SetLabelY2(const String& _yLabel) {ScatterDraw::SetLabelY2(_yLabel); return *this;};
SetPlotAreaMargin(int hLeft,int hRight,int vTop,int vBottom)268 ScatterCtrl& SetPlotAreaMargin(int hLeft, int hRight, int vTop, int vBottom)
269 {ScatterDraw::SetPlotAreaMargin(hLeft, hRight, vTop, vBottom); return *this;};
SetPlotAreaLeftMargin(int margin)270 ScatterCtrl& SetPlotAreaLeftMargin(int margin) {ScatterDraw::SetPlotAreaLeftMargin(margin);return *this;};
GetPlotAreaLeftMargin()271 int GetPlotAreaLeftMargin() {return ScatterDraw::GetPlotAreaLeftMargin();};
SetPlotAreaTopMargin(int margin)272 ScatterCtrl& SetPlotAreaTopMargin(int margin) {ScatterDraw::SetPlotAreaTopMargin(margin); return *this;};
GetPlotAreaTopMargin()273 int GetPlotAreaTopMargin() {return ScatterDraw::GetPlotAreaTopMargin();};
SetPlotAreaRightMargin(int margin)274 ScatterCtrl& SetPlotAreaRightMargin(int margin) {ScatterDraw::SetPlotAreaRightMargin(margin);return *this;};
GetPlotAreaRightMargin()275 int GetPlotAreaRightMargin() {return ScatterDraw::GetPlotAreaRightMargin();};
SetPlotAreaBottomMargin(int margin)276 ScatterCtrl& SetPlotAreaBottomMargin(int margin) {ScatterDraw::SetPlotAreaBottomMargin(margin);return *this;};
GetPlotAreaBottomMargin()277 int GetPlotAreaBottomMargin() {return ScatterDraw::GetPlotAreaBottomMargin();};
278
279 ScatterCtrl& ShowLegend(bool show = true) {ScatterDraw::ShowLegend(show); return *this;}
GetShowLegend()280 bool GetShowLegend() {return ScatterDraw::GetShowLegend();}
SetLegendPos(const Point & _pos)281 ScatterCtrl& SetLegendPos(const Point &_pos) {ScatterDraw::SetLegendPos(_pos); return *this;}
SetLegendPosX(int x)282 ScatterCtrl& SetLegendPosX(int x) {ScatterDraw::SetLegendPosX(x); return *this;}
SetLegendPosY(int y)283 ScatterCtrl& SetLegendPosY(int y) {ScatterDraw::SetLegendPosY(y); return *this;}
GetLegendPos()284 Point& GetLegendPos() {return ScatterDraw::GetLegendPos();}
SetLegendNumCols(int num)285 ScatterCtrl& SetLegendNumCols(int num) {ScatterDraw::SetLegendNumCols(num); return *this;}
GetLegendNumCols()286 int GetLegendNumCols() {return ScatterDraw::GetLegendNumCols();}
SetLegendRowSpacing(int num)287 ScatterCtrl& SetLegendRowSpacing(int num) {ScatterDraw::SetLegendRowSpacing(num); return *this;}
GetLegendRowSpacing()288 int GetLegendRowSpacing() {return ScatterDraw::GetLegendRowSpacing();}
SetLegendAnchor(int anchor)289 ScatterCtrl& SetLegendAnchor(int anchor) {ScatterDraw::SetLegendAnchor(static_cast<LEGEND_POS>(anchor)); return *this;}
GetLegendAnchor()290 int GetLegendAnchor() {return ScatterDraw::GetLegendAnchor();}
SetLegendFillColor(const Upp::Color & fill)291 ScatterCtrl& SetLegendFillColor(const Upp::Color &fill) {ScatterDraw::SetLegendFillColor(fill); return *this;}
SetLegendBorderColor(const Upp::Color & border)292 ScatterCtrl& SetLegendBorderColor(const Upp::Color &border) {ScatterDraw::SetLegendBorderColor(border); return *this;}
GetLegendFillColor()293 Upp::Color& GetLegendFillColor() {return ScatterDraw::GetLegendFillColor();}
GetLegendBorderColor()294 Upp::Color& GetLegendBorderColor() {return ScatterDraw::GetLegendBorderColor();}
295
296 using ScatterDraw::AddSeries;
297 ScatterCtrl &AddSeries(ArrayCtrl &data, bool useCols = true, int idX = 0, int idY = 1, int idZ = 2, int beginData = 0, int numData = Null);
298 ScatterCtrl &AddSeries(GridCtrl &data, bool useCols = true, int idX = 0, int idY = 1, int idZ = 2, int beginData = 0, int numData = Null);
299 using ScatterDraw::InsertSeries;
300 void InsertSeries(int id, ArrayCtrl &data, bool useCols = true, int idX = 0, int idY = 1, int idZ = 2, int beginData = 0, int numData = Null);
301 void InsertSeries(int id, GridCtrl &data, bool useCols = true, int idX = 0, int idY = 1, int idZ = 2, int beginData = 0, int numData = Null);
302
RemoveAllSeries()303 void RemoveAllSeries() {
304 GuiLock __;
305 ScatterDraw::RemoveAllSeries();
306 }
307
SetMaxRefreshTime(int _maxRefresh_ms)308 ScatterCtrl& SetMaxRefreshTime(int _maxRefresh_ms) {maxRefresh_ms = _maxRefresh_ms; return *this;}
GetMaxRefreshTime()309 int GetMaxRefreshTime() {return maxRefresh_ms;}
310
SetDefaultCSVSeparator(String sep)311 ScatterCtrl& SetDefaultCSVSeparator(String sep) {defaultCSVseparator = sep; return *this;}
GetDefaultCSVSeparator()312 String GetDefaultCSVSeparator() {return defaultCSVseparator;}
313
314 ScatterCtrl &SetMouseHandling(bool valx = true, bool valy = false) {ScatterDraw::SetMouseHandling(valx, valy); return *this;}
315 ScatterCtrl &SetMouseHandlingLinked(bool valx = true, bool valy = false) {ScatterDraw::SetMouseHandlingLinked(valx, valy); return *this;}
316
SetSaveSize(Size & _size)317 ScatterCtrl &SetSaveSize(Size &_size) {saveSize = _size; return *this;}
GetSaveSize()318 Size &GetSaveSize() {return saveSize;}
SetSaveSizeX(int cx)319 ScatterCtrl &SetSaveSizeX(int cx) {saveSize.cx = cx; return *this;}
SetSaveSizeY(int cy)320 ScatterCtrl &SetSaveSizeY(int cy) {saveSize.cy = cy; return *this;}
SetJPGQuality(int quality)321 ScatterCtrl &SetJPGQuality(int quality) {jpgQuality = quality; return *this;}
GetJPGQuality()322 int GetJPGQuality() {return jpgQuality;}
323
324 enum Angle {Angle_0, Angle_90, Angle_180, Angle_270};
Rotate(Angle angle)325 ScatterCtrl &Rotate(Angle angle) {rotate = angle; Refresh(); return *this;}
GetRotate()326 Angle GetRotate() {return static_cast<Angle>(rotate);}
327
328 private:
329 template <class T>
Ize(T & io)330 void Ize(T& io) {
331 ScatterDraw::Ize(io);
332 io
333 ("defaultFileNamePlot", defaultFileNamePlot)
334 ("defaultDataFile", defaultDataFile)
335 ("saveSize", saveSize)
336 ("jpgQuality", jpgQuality)
337 ("rotate", rotate)
338 ;
339 }
340
341 public:
Xmlize(XmlIO & xml)342 void Xmlize(XmlIO& xml) {Ize(xml);}
Jsonize(JsonIO & json)343 void Jsonize(JsonIO& json) {Ize(json);}
344
Serialize(Stream & s)345 void Serialize(Stream& s) {
346 s % defaultFileNamePlot
347 % defaultDataFile
348 % saveSize
349 % jpgQuality
350 % rotate
351 ;
352 }
353 virtual void Paint(Draw& w);
354 virtual void LeftDown(Point, dword);
355 virtual void LeftDouble(Point p, dword);
356 virtual void LeftUp(Point, dword);
357 virtual void MiddleDown(Point, dword);
358 virtual void MouseMove(Point, dword);
359 virtual void MiddleUp(Point, dword);
360 virtual void RightDown(Point, dword);
361 virtual void RightUp(Point, dword);
362 virtual void MouseLeave();
363 virtual void MouseWheel(Point, int zdelta, dword);
364 virtual bool Key(dword key, int count);
365 virtual void GotFocus();
366 virtual void LostFocus();
367
GetInstancesCount()368 static int GetInstancesCount() {return instances.GetCount();}
GetInstance(int i)369 static ScatterCtrl &GetInstance(int i) {return *(instances[i]);}
370
SetPopUp(bool _pop)371 void SetPopUp(bool _pop) {pop = _pop;}
372
373 private:
374 bool showInfo = false;
375 PopUpInfo popInfoBegin, popInfoVert, popInfoHoriz, popInfoEnd;
376 PopUpText popTextBegin, popTextVert, popTextHoriz, popTextEnd;
377 String popTextX = t_("x"),
378 popTextY = t_("y"),
379 popTextY2 = t_("y right"),
380 popTextZ = t_("z");
381 Point popLT = Null, popRB = Null;
382 bool pop;
383 bool isZoomWindow = false;
384 const Point popOffset = Point(10, 12);
385 MouseAction mouseAction = NONE;
386
387 int butDownX, butDownY;
388 bool isScrolling = false,
389 isLabelPopUp = false;
390
391 bool showContextMenu = false,
392 showPropDlg = false,
393 showProcessDlg = false,
394 showButtons = false,
395 showLoadData = false, showSaveData = false;
396
397 int lastRefresh_ms = Null;
398 dword lastRefresh0_ms;
399 int maxRefresh_ms = 500;
400
401 bool highlighting = false;
402
403 Upp::Array<MouseBehavior> mouseBehavior;
404 Upp::Array<KeyBehavior> keyBehavior;
405
406 void Paint0(Draw& w, const Size &sz);
407
408 void ProcessPopUp(Point &pt);
409
410 void DoMouseAction(bool down, Point pt, ScatterAction action, int wheel);
411 void DoKeyAction(ScatterAction action);
412 void ProcessMouse(bool down, Point &pt, bool ctrl, bool alt, bool shift, bool left, bool middle, int middleWheel, bool right);
413 bool ProcessKey(int key);
414 void LabelPopUp(bool down, Point &pt);
415 void Scrolling(bool down, Point &pt, bool isOut = false);
416 void MouseZoom(int zdelta, bool hor, bool ver);
417 void ZoomWindow(bool down, Point &pt);
418
419 void ContextMenu(Bar& bar);
420 void DoShowEditDlg(int itab);
421 void DoShowData();
422 void DoProcessing();
423
424 void Closest(double &x, double &y, double &y2);
425
426 virtual Image CursorImage(Point p, dword keyflags);
427
428 template <class T>
429 void SetDrawing(T& w, const Size &sz, bool ctrl = true);
430 void TimerCallback();
431
432 String defaultCSVseparator = ";";
433
434 String defaultFileNamePlot;
435 void OnTypeImage(FileSel *_fs);
436
437 String defaultDataFile;
438 void OnTypeDataFile(FileSel *_fs);
439
440 Button processButton, dataButton, propertiesButton;
441
442 Size saveSize = Size(1000, 600);
443 int jpgQuality = 90;
444
445 int rotate = Angle_0;
446 Point &MousePointRot(Point &pt);
447 Point &MousePointUnrot(Point &pt);
448
449 static Vector<ScatterCtrl *> instances;
AddInstance(ScatterCtrl * instance)450 static void AddInstance(ScatterCtrl *instance) {instances << instance;}
RemoveInstance(ScatterCtrl * instance)451 static void RemoveInstance(ScatterCtrl *instance) {
452 instances.RemoveIf([&](int i) {return instance == instances[i];});
453 }
454 };
455
456 template <class T>
SetDrawing(T & w,const Size & sz,bool ctrl)457 void ScatterCtrl::SetDrawing(T& w, const Size &sz, bool ctrl) {
458 ScatterDraw::SetSize(sz);
459 ScatterDraw::SetDrawing(w, ctrl);
460 if (!IsNull(popLT)) {
461 if (popLT != popRB) {
462 if (isZoomWindow) {
463 DrawLine(w, popLT.x, popLT.y, popLT.x, popRB.y, 1, SColorHighlight());
464 DrawLine(w, popRB.x, popLT.y, popRB.x, popRB.y, 1, SColorHighlight());
465 DrawLine(w, popLT.x, popLT.y, popRB.x, popLT.y, 1, SColorHighlight());
466 DrawLine(w, popLT.x, popRB.y, popRB.x, popRB.y, 1, SColorHighlight());
467 #ifdef PLATFORM_WIN32
468 Ctrl::Refresh();
469 #endif
470 } else {
471 DrawVArrow(w, popLT.x, popLT.y, popLT.x, popRB.y, 1, 4, 15, SColorHighlight());
472 DrawHArrow(w, popLT.x, popRB.y, popRB.x, popRB.y, 1, 4, 15, SColorHighlight());
473 if (!pop) {
474 popTextBegin.DoPaint(w);
475 popTextVert.DoPaint(w);
476 popTextHoriz.DoPaint(w);
477 popTextEnd.DoPaint(w);
478 }
479 #ifdef PLATFORM_WIN32
480 Ctrl::Refresh(min(popLT.x-4, popRB.x-4), min(popLT.y-4, popRB.y-4),
481 abs(popRB.x-popLT.x) + 9, abs(popRB.y-popLT.y) + 9);
482 #endif
483 }
484 } else {
485 if (!pop)
486 popTextBegin.DoPaint(w);
487 #ifdef PLATFORM_WIN32
488 Ctrl::Refresh();
489 #endif
490 }
491 }
492 }
493
494 class ScatterWindow : public TopWindow {
495 public:
ScatterWindow()496 ScatterWindow() {
497 Sizeable().Zoomable();
498 Add(scatter.SizePos());
499 scatter.ShowAllMenus().SetPlotAreaLeftMargin(70);
500 }
operator()501 ScatterCtrl &operator()() {return scatter;}
502
503 ScatterWindow &OpenMain(bool dataInternal = true, bool zoomToFit = true) {
504 if(scatter.ThereAreSecondaryY())
505 scatter.SetPlotAreaRightMargin(70);
506 if (dataInternal)
507 scatter.SetDataSourceInternal();
508 if (zoomToFit)
509 scatter.ZoomToFit(true, true);
510 TopWindow::SetRect(0, 0, 800, 500);
511 TopWindow::OpenMain();
512 Ctrl::ProcessEvents();
513 return *this;
514 }
515
Refresh()516 void Refresh() {
517 scatter.Refresh();
518 Ctrl::ProcessEvents();
519 }
520
521 private:
522 ScatterCtrl scatter;
523 };
524
525 class ScatterWindowPool {
526 public:
Get()527 static ScatterWindow &Get() {return pool.Add();}
528
529 private:
530 static Array<ScatterWindow> pool;
531 };
532
533 }
534
535 #include "Properties.h"
536
537
538 #endif
539