1 #include "ScatterCtrl.h"
2
3 namespace Upp {
4
5 #define IMAGECLASS ScatterImgP
6 #define IMAGEFILE <ScatterCtrl/ScatterCtrl.iml>
7 #include <Draw/iml_source.h>
8
9
DoShowEditDlg(int itab)10 void ScatterCtrl::DoShowEditDlg(int itab)
11 {
12 PropertiesDlg dlg;
13 dlg.Init(*this);
14 dlg.Set(itab);
15 dlg.Perform();
16 }
17
Perform()18 void PropertiesDlg::Perform()
19 {
20 Run();
21 measures.Change();
22 measures.Change();
23 }
24
Init(ScatterCtrl & scatter)25 void MeasuresTab::Init(ScatterCtrl& scatter)
26 {
27 CtrlLayout(*this);
28 SizePos();
29
30 pscatter = &scatter;
31
32 xMin <<= scatter.GetXMin();
33 xMax <<= scatter.GetXRange() + scatter.GetXMin();
34 yMin <<= scatter.GetYMin();
35 yMax <<= scatter.GetYRange() + scatter.GetYMin();
36 yMin2 <<= scatter.GetYMin2();
37 yMax2 <<= scatter.GetY2Range() + scatter.GetYMin2();
38 xMinUnit <<= scatter.GetXMinUnit();
39 yMinUnit <<= scatter.GetYMinUnit();
40 xMajorUnit <<= scatter.GetMajorUnitsX();
41 yMajorUnit <<= scatter.GetMajorUnitsY();
42
43 opAttachX <<= !scatter.GetMouseHandlingX();
44 opAttachY <<= !scatter.GetMouseHandlingY();
45 opReticleX <<= scatter.GetDrawXReticle();
46 opReticleY <<= scatter.GetDrawYReticle();
47 opReticleY2 <<= scatter.GetDrawY2Reticle();
48 opReticleXNumbers <<= scatter.GetDrawXReticleNumbers();
49 opReticleYNumbers <<= scatter.GetDrawYReticleNumbers();
50 opReticleY2Numbers <<= scatter.GetDrawY2ReticleNumbers();
51 reticlethickness <<= scatter.GetAxisWidth();
52
53 linethickness <<= scatter.GetGridWidth();
54 linecolor <<= scatter.GetGridColor();
55 dashStyle.Clear();
56 for(int i = 0; i < DashStyle::GetCount(); i++)
57 dashStyle.Add(DashStyle::TypeName(i));
58
59 int id = DashStyle::StyleIndex(scatter.GetGridDash());
60 if (id < 0) {
61 id = DashStyle::Register(Format(t_("Dash \"%s\""), scatter.GetGridDash()), scatter.GetGridDash());
62 dashStyle.Add(DashStyle::TypeName(id));
63 }
64 dashStyle <<= DashStyle::TypeName(id);
65
66 xMin.WhenEnter = [=]{Change();};
67 xMax.WhenEnter = [=]{Change();};
68 yMin.WhenEnter = [=]{Change();};
69 yMax.WhenEnter = [=]{Change();};
70 yMin2.WhenEnter = [=]{Change();};
71 yMax2.WhenEnter = [=]{Change();};
72 xMinUnit.WhenEnter = [=]{Change();};
73 yMinUnit.WhenEnter = [=]{Change();};
74 xMajorUnit.WhenEnter = [=]{Change();};
75 yMajorUnit.WhenEnter = [=]{Change();};
76
77 opAttachX.WhenAction = [=]{Change();};
78 opAttachY.WhenAction = [=]{Change();};
79 opReticleX.WhenAction = [=]{Change();};
80 opReticleY.WhenAction = [=]{Change();};
81 opReticleY2.WhenAction = [=]{Change();};
82 opReticleXNumbers.WhenAction = [=]{Change();};
83 opReticleYNumbers.WhenAction = [=]{Change();};
84 opReticleY2Numbers.WhenAction = [=]{Change();};
85 reticlethickness.WhenAction = [=]{Change();};
86
87 linecolor.WhenAction = [=]{Change();};
88 linethickness.WhenAction = [=]{Change();};
89 dashStyle.WhenAction = [=]{Change();};
90
91 Change();
92 }
93
Change()94 void MeasuresTab::Change()
95 {
96 if (xMax <= xMin) {
97 Exclamation(t_("X min has to be lower than X max"));
98 return;
99 }
100 if (yMax <= yMin) {
101 Exclamation(t_("Y min has to be lower than Y max"));
102 return;
103 }
104 if (yMax2 <= yMin2) {
105 Exclamation(t_("Y min2 has to be lower than Y max2"));
106 return;
107 }
108
109 xMin.Enable(!opAttachX);
110 xMax.Enable(!opAttachX);
111 yMin.Enable(!opAttachY);
112 yMax.Enable(!opAttachY);
113
114 ScatterCtrl &scatter = *pscatter;
115
116 scatter.SetMouseHandlingLinked(!opAttachX, !opAttachY);
117 scatter.SetDrawXReticle(opReticleX).SetDrawYReticle(opReticleY).SetDrawY2Reticle(opReticleY2);
118 scatter.SetDrawXReticleNumbers(opReticleXNumbers).SetDrawYReticleNumbers(opReticleYNumbers).SetDrawY2ReticleNumbers(opReticleY2Numbers);
119 scatter.SetAxisWidth(~reticlethickness);
120
121 scatter.SetXYMinLinked(xMin, yMin, yMin2);
122 scatter.SetRangeLinked(xMax - xMin, yMax - yMin, yMax2 - yMin2);
123
124 scatter.SetMinUnits(xMinUnit, yMinUnit);
125 scatter.SetMajorUnits(xMajorUnit, yMajorUnit);
126
127 scatter.SetGridDash(DashStyle::Style(DashStyle::TypeIndex(~dashStyle)));
128 scatter.SetGridColor(~linecolor);
129 scatter.SetGridWidth(~linethickness);
130
131 scatter.SetModify();
132 scatter.Refresh();
133 }
134
Init(ScatterCtrl & scatter)135 void TextsTab::Init(ScatterCtrl& scatter)
136 {
137 CtrlLayout(*this);
138 SizePos();
139
140 pscatter = &scatter;
141
142 title <<= scatter.GetTitle();
143 title.WhenAction = [=]{Change();};
144 xLabel <<= scatter.GetLabelX();
145 xLabel.WhenAction = [=]{Change();};
146 yLabel <<= scatter.GetLabelY();
147 yLabel.WhenAction = [=]{Change();};
148 yLabel2 <<= scatter.GetLabelY2();
149 yLabel2.WhenAction = [=]{Change();};
150 backcolor <<= scatter.GetPlotAreaColor();
151 backcolor.WhenAction = [=]{Change();};
152 leftMargin <<= scatter.GetPlotAreaLeftMargin();
153 leftMargin.WhenAction = [=]{Change();};
154 rightMargin <<= scatter.GetPlotAreaRightMargin();
155 rightMargin.WhenAction = [=]{Change();};
156 topMargin <<= scatter.GetPlotAreaTopMargin();
157 topMargin.WhenAction = [=]{Change();};
158 bottomMargin <<= scatter.GetPlotAreaBottomMargin();
159 bottomMargin.WhenAction = [=]{Change();};
160 butFontTitle.SetImage(ScatterImgP::ColorA);
161 butFontTitle.WhenAction = [=]{Change();};
162 colorTitle <<= scatter.GetTitleColor();
163 colorTitle.WhenAction = [=]{Change();};
164 butFontLabel.SetImage(ScatterImgP::ColorA);
165 butFontLabel.WhenAction = [=]{OnFontLabel();};
166 colorLabel <<= scatter.GetLabelsColor();
167 colorLabel.WhenAction = [=]{Change();};
168
169 Change();
170 }
171
OnFontTitle()172 void TextsTab::OnFontTitle() {
173 FontSelect fontSelect;
174
175 fontSelect.Set(pscatter->GetTitleFont());
176 fontSelect.WhenAction = [=](Font f) {OnChangeFontTitle(f);};
177 fontSelect.Execute(butFontTitle);
178 }
179
OnChangeFontTitle(Font font)180 void TextsTab::OnChangeFontTitle(Font font) {
181 pscatter->SetTitleFont(font);
182 pscatter->Refresh();
183 }
184
OnFontLabel()185 void TextsTab::OnFontLabel() {
186 FontSelect fontSelect;
187
188 fontSelect.Set(pscatter->GetLabelsFont());
189 fontSelect.WhenAction = [=](Font f) {OnChangeFontLabel(f);};
190 fontSelect.Execute(butFontLabel);
191 }
192
OnChangeFontLabel(Font font)193 void TextsTab::OnChangeFontLabel(Font font) {
194 pscatter->SetLabelsFont(font);
195 pscatter->Refresh();
196 }
197
Change()198 void TextsTab::Change()
199 {
200 ScatterCtrl &scatter = *pscatter;
201
202 scatter.SetTitle(~title);
203 scatter.SetLabels(~xLabel, ~yLabel, ~yLabel2);
204 scatter.SetPlotAreaMargin(~leftMargin, ~rightMargin, ~topMargin, ~bottomMargin);
205 scatter.SetPlotAreaColor(~backcolor);
206 scatter.SetTitleColor(~colorTitle);
207
208 scatter.SetModify();
209 scatter.Refresh();
210 }
211
Init(ScatterCtrl & scatter)212 void LegendTab::Init(ScatterCtrl& scatter)
213 {
214 CtrlLayout(*this);
215 SizePos();
216
217 pscatter = &scatter;
218
219 showLegend <<= scatter.GetShowLegend();
220 showLegend.WhenAction = [=] {Change();};
221
222 legendPosition <<= (scatter.GetLegendAnchor() == ScatterDraw::TOP ? 0 : 1);
223 legendPosition.WhenAction = [=] {Change();};
224 switch(scatter.GetLegendAnchor()) {
225 case ScatterDraw::LEFT_TOP: legendAnchorLT = true; break;
226 case ScatterDraw::RIGHT_TOP: legendAnchorRT = true; break;
227 case ScatterDraw::LEFT_BOTTOM: legendAnchorLB = true; break;
228 case ScatterDraw::RIGHT_BOTTOM: legendAnchorRB = true; break;
229 }
230 legendAnchorLT.WhenAction = [&] {ChangeAnchor(&legendAnchorLT);};
231 legendAnchorRT.WhenAction = [&] {ChangeAnchor(&legendAnchorRT);};
232 legendAnchorLB.WhenAction = [&] {ChangeAnchor(&legendAnchorLB);};
233 legendAnchorRB.WhenAction = [&] {ChangeAnchor(&legendAnchorRB);};
234
235 fillColor <<= scatter.GetLegendFillColor();
236 fillColor.WhenAction = [=] {Change();};
237 borderColor <<= scatter.GetLegendBorderColor();
238 borderColor.WhenAction = [=] {Change();};
239 Point p = scatter.GetLegendPos();
240 tableHoriz <<= p.x;
241 tableHoriz.WhenAction = [=] {Change();};
242 tableVert <<= p.y;
243 tableVert.WhenAction = [=] {Change();};
244 numCols <<= scatter.GetLegendNumCols();
245 numCols.WhenAction = [=] {Change();};
246
247 rowSpacing <<= scatter.GetLegendRowSpacing();
248 rowSpacing.WhenAction = [=] {Change();};
249
250 Change();
251 }
252
ChangeAnchor(Option * op)253 void LegendTab::ChangeAnchor(Option *op)
254 {
255 legendAnchorLT <<= false;
256 legendAnchorRT <<= false;
257 legendAnchorLB <<= false;
258 legendAnchorRB <<= false;
259 *op <<= true;
260
261 Change();
262 }
263
Change()264 void LegendTab::Change()
265 {
266 ScatterCtrl &scatter = *pscatter;
267
268 scatter.ShowLegend(showLegend);
269 scatter.SetLegendRowSpacing(rowSpacing);
270 ScatterDraw::LEGEND_POS legendTableAnchor;
271 if (legendPosition == 0)
272 legendTableAnchor = ScatterDraw::TOP;
273 else if (legendAnchorLT)
274 legendTableAnchor = ScatterDraw::LEFT_TOP;
275 else if (legendAnchorRT)
276 legendTableAnchor = ScatterDraw::RIGHT_TOP;
277 else if (legendAnchorLB)
278 legendTableAnchor = ScatterDraw::LEFT_BOTTOM;
279 else if (legendAnchorRB)
280 legendTableAnchor = ScatterDraw::RIGHT_BOTTOM;
281 else {
282 legendAnchorLT = true;
283 legendTableAnchor = ScatterDraw::LEFT_TOP;
284 }
285 scatter.SetLegendAnchor(legendTableAnchor);
286 bool enable = (legendPosition != 0);
287 table.Enable(enable);
288 fillColor.Enable(enable); borderColor.Enable(enable);
289 tableHoriz.Enable(enable); tableVert.Enable(enable);
290 numCols.Enable(enable); rowSpacing.Enable(enable);
291 labelFill.Enable(enable); labelBorder.Enable(enable);
292 labelDistance.Enable(enable);
293 labelHoriz.Enable(enable); labelVert.Enable(enable);
294 labelNumCols.Enable(enable); labelRowSpacing.Enable(enable);
295 labelAnchorCorner.Enable(enable);
296 legendAnchorLT.Enable(enable); legendAnchorRT.Enable(enable);
297 legendAnchorLB.Enable(enable); legendAnchorRB.Enable(enable);
298
299 scatter.SetLegendFillColor(fillColor.GetData()).SetLegendBorderColor(borderColor.GetData());
300 scatter.SetLegendPosX(tableHoriz).SetLegendPosY(tableVert);
301 scatter.SetLegendNumCols(numCols);
302
303 scatter.SetModify();
304 scatter.Refresh();
305 }
306
Init(ScatterCtrl & scatter)307 void GeneralTab::Init(ScatterCtrl& scatter)
308 {
309 CtrlLayout(*this);
310 SizePos();
311
312 pscatter = &scatter;
313
314 dropResolution.Clear();
315 dropResolution.Add(ScatterDraw::MD_DRAW, t_("Draw"));
316 dropResolution.Add(ScatterDraw::MD_NOAA, t_("Painter No Antialiased"));
317 dropResolution.Add(ScatterDraw::MD_ANTIALIASED, t_("Painter Antialiased"));
318 dropResolution.Add(ScatterDraw::MD_SUBPIXEL, t_("Painter Subpixel"));
319 dropResolution = scatter.GetMode();
320 dropResolution.WhenAction = [=] {Change();};
321 dropRotate.Clear();
322 dropRotate.Add(ScatterCtrl::Angle_0, t_("0º"));
323 dropRotate.Add(ScatterCtrl::Angle_90, t_("90º"));
324 dropRotate.Add(ScatterCtrl::Angle_180, t_("180º"));
325 dropRotate.Add(ScatterCtrl::Angle_270, t_("270º"));
326 dropRotate = scatter.GetRotate();
327 dropRotate.WhenAction = [=] {Change();};
328 editWidth <<= scatter.GetSaveSize().cx;
329 editHeight <<= scatter.GetSaveSize().cy;
330 opResponsive <<= scatter.ScatterDraw::IsResponsive();
331 editSensitivity <<= scatter.ScatterDraw::GetResponsivenessFactor();
332 editJpgQ <<= scatter.GetJPGQuality();
333 editWidth.WhenAction = [=] {Change();};
334 editHeight.WhenAction = [=] {Change();};
335 opResponsive.WhenAction = [=] {Change();};
336 editSensitivity.WhenAction = [=] {Change();};
337 editJpgQ.WhenAction = [=] {Change();};
338
339 butApplyToAll.WhenAction = [=] {ChangeAll();};
340
341 Change();
342 }
343
Change()344 void GeneralTab::Change()
345 {
346 ScatterCtrl &scatter = *pscatter;
347
348 scatter.SetMode(~dropResolution);
349 scatter.Rotate((ScatterCtrl::Angle)(int)dropRotate.GetData());
350 Size size(~editWidth, ~editHeight);
351 scatter.SetSaveSize(size);
352 scatter.ScatterDraw::Responsive(~opResponsive, ~editSensitivity);
353 scatter.SetJPGQuality(~editJpgQ);
354
355 scatter.SetModify();
356 scatter.Refresh();
357 }
358
ChangeAll()359 void GeneralTab::ChangeAll()
360 {
361 for (int i = 0; i < ScatterCtrl::GetInstancesCount(); ++i) {
362 ScatterCtrl &scatter = ScatterCtrl::GetInstance(i);
363
364 scatter.SetMode(~dropResolution);
365 scatter.Rotate((ScatterCtrl::Angle)(int)dropRotate.GetData());
366 Size size(~editWidth, ~editHeight);
367 scatter.SetSaveSize(size);
368 scatter.ScatterDraw::Responsive(~opResponsive, ~editSensitivity);
369 scatter.SetJPGQuality(~editJpgQ);
370
371 scatter.SetModify();
372 scatter.Refresh();
373 }
374 }
375
Init(ScatterCtrl & scatter)376 void SeriesTab::Init(ScatterCtrl& scatter)
377 {
378 CtrlLayout(left);
379 CtrlLayout(right);
380 Horz(left.SizePos(), right.SizePos());
381 SetPos(3000, 0);
382 SizePos();
383
384 pscatter = &scatter;
385
386 Init0();
387 }
388
Init0()389 void SeriesTab::Init0()
390 {
391 ScatterCtrl &scatter = *pscatter;
392
393 right.Enable(!scatter.IsEmpty());
394
395 left.list.Reset();
396 left.list.SetLineCy(EditField::GetStdHeight());
397 left.list.AddColumn(t_("Name"));
398 for(int i = 0; i < scatter.GetCount(); i++)
399 left.list.Add(scatter.GetLegend(i));
400 left.list.SetCursor(0);
401 left.list.WhenSel = [=] {UpdateFields();};
402 left.butMoveUp.WhenAction = [=] {OnMoveUp();};
403 left.butMoveUp.SetImage(ScatterImgP::UpArrow);
404 left.butMoveDown.WhenAction = [=] {OnMoveDown();};
405 left.butMoveDown.SetImage(ScatterImgP::DownArrow);
406 left.butDelete.WhenAction = [=] {OnDelete();};
407
408 right.marktype.Clear();
409
410 right.markstyle.Add(t_("No mark"));
411 for(int i = 0; i < MarkPlot::GetCount(); i++)
412 right.markstyle.Add(MarkPlot::TypeName(i));
413 right.markstyle.SetIndex(0);
414
415 right.dashStyle.Clear();
416 for(int i = 0; i < DashStyle::GetCount(); i++)
417 right.dashStyle.Add(DashStyle::TypeName(i));
418
419 UpdateFields();
420
421 right.linecolor.WhenAction = [=] {Change();};
422 right.fillcolor.WhenAction = [=] {Change();};
423 right.visible.WhenAction = [=] {Change();};
424 right.dashStyle.WhenAction = [=] {Change();};
425 right.linethickness.WhenAction = [=] {Change();};
426
427 right.markstyle.WhenAction = [=] {Change();};
428 right.markcolor.WhenAction = [=] {Change();};
429 right.markwidth.WhenAction = [=] {Change();};
430 right.marktype.WhenAction = [=] {Change();};
431
432 right.showLegend.WhenAction = [=] {Change();};
433
434 right.unitsY.WhenAction = [=] {Change();};
435 right.unitsX.WhenAction = [=] {Change();};
436
437 right.name.WhenAction = [=] {Change();};
438 right.primary.WhenAction = [=] {Change();};
439
440 right.name.SetFocus();
441 }
442
ChangeMark()443 void SeriesTab::ChangeMark() {
444 int index = left.list.GetCursor();
445 if (index < 0)
446 return;
447
448 ScatterCtrl &scatter = *pscatter;
449
450 int id = MarkPlot::TypeIndex(~right.markstyle);
451
452 right.marktype.Clear();
453
454 if (id >= 0) {
455 for (int i = 0; i < MarkPlot::GetTypeCount(id); ++i)
456 right.marktype.Add(MarkPlot::TypeString(id, i));
457 }
458 if (right.marktype.GetCount() > 0)
459 right.marktype.SetIndex(0);
460 int idStyle = scatter.GetMarkStyleType(index);
461 if (idStyle >= 0 && idStyle < right.marktype.GetCount())
462 right.marktype.SetIndex(idStyle);
463 }
464
Change()465 void SeriesTab::Change()
466 {
467 int index = left.list.GetCursor();
468 if (index < 0)
469 return;
470
471 ScatterCtrl &scatter = *pscatter;
472
473 scatter.SetFillColor(index, ~right.fillcolor);
474 scatter.ScatterDraw::Show(index, ~right.visible);
475 scatter.Dash(index, DashStyle::Style(DashStyle::TypeIndex(~right.dashStyle)));
476 scatter.Stroke(index, ~right.linethickness, Upp::Color(~right.linecolor));
477 // if (IsNull(Upp::Color(~right.linecolor)))
478 // scatter.SetLineColor(index, Upp::Color(~right.linecolor));
479
480 scatter.MarkStyle(index, String(~right.markstyle));
481 scatter.SetMarkColor(index, Upp::Color(~right.markcolor));
482 scatter.SetMarkWidth(index, ~right.markwidth);
483 scatter.ShowSeriesLegend(index, ~right.showLegend);
484 ChangeMark();
485
486 scatter.Units(index, ~right.unitsY, ~right.unitsX);
487
488 scatter.SetDataPrimaryY(index, ~right.primary);
489
490 left.list.Set(index, ~right.name);
491 scatter.Legend(index, ~right.name);
492
493 scatter.SetModify();
494 scatter.Refresh();
495 }
496
UpdateFields()497 void SeriesTab::UpdateFields()
498 {
499 int index = left.list.GetCursor();
500 if (index < 0)
501 return;
502
503 ScatterCtrl &scatter = *pscatter;
504
505 right.name <<= left.list.Get(0);
506
507 right.fillcolor <<= scatter.GetFillColor(index);
508 right.visible <<= scatter.ScatterDraw::IsVisible(index);
509 int id = DashStyle::StyleIndex(scatter.GetDash(index));
510 if (id < 0) {
511 id = DashStyle::Register(Format(t_("Dash \"%s\""), scatter.GetDash(index)), scatter.GetDash(index));
512 right.dashStyle.Add(DashStyle::TypeName(id));
513 }
514 right.dashStyle <<= DashStyle::TypeName(id);
515
516 Upp::Color color;
517 double thickness;
518
519 scatter.GetStroke(index, thickness, color);
520 right.linethickness <<= thickness;
521 right.linecolor <<= color;
522 right.markstyle <<= scatter.GetMarkStyleName(index);
523 right.markcolor <<= scatter.GetMarkColor(index);
524 right.markwidth <<= scatter.GetMarkWidth(index);
525 ChangeMark();
526
527 right.showLegend <<= scatter.GetShowSeriesLegend(index);
528
529 right.unitsY <<= scatter.GetUnitsY(index);
530 right.unitsX <<= scatter.GetUnitsX(index);
531
532 right.primary <<= scatter.IsDataPrimaryY(index);
533 }
534
OnMoveUp()535 void SeriesTab::OnMoveUp()
536 {
537 int index = left.list.GetCursor();
538 if (index <= 0)
539 return;
540
541 ScatterCtrl &scatter = *pscatter;
542 scatter.SwapSeries(index, index-1);
543
544 Init0();
545
546 left.list.SetCursor(index-1);
547
548 scatter.SetModify();
549 scatter.Refresh();
550 }
551
OnMoveDown()552 void SeriesTab::OnMoveDown()
553 {
554 int index = left.list.GetCursor();
555 if (index < 0 || index == left.list.GetCount()-1)
556 return;
557
558 ScatterCtrl &scatter = *pscatter;
559 if (!scatter.SwapSeries(index, index+1))
560 return;
561
562 Init0();
563
564 left.list.SetCursor(index+1);
565
566 scatter.SetModify();
567 scatter.Refresh();
568 }
569
OnDelete()570 void SeriesTab::OnDelete()
571 {
572 int index = left.list.GetCursor();
573 if (index < 0)
574 return;
575
576 if (!PromptOKCancel(Format(t_("You are going to delete '%s' series.&Do you agree?"), DeQtf(String(left.list.Get(0))))))
577 return;
578
579 ScatterCtrl &scatter = *pscatter;
580 if(!scatter.ScatterDraw::RemoveSeries(index))
581 return;
582
583 Init0();
584
585 left.list.SetCursor(index);
586
587 scatter.SetModify();
588 scatter.Refresh();
589 }
590
591 }