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