Definitly fix bug 11067: add ticks_format and ticks_st properties to improve ticks...
[scilab.git] / scilab / modules / graphic_objects / src / java / org / scilab / modules / graphic_objects / axes / TicksProperty.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - DIGITEO - Manuel JULIACHS
4  * Copyright (C) 2013 - Scilab Enterprises - Calixte DENIZET
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
11  *
12  */
13
14 package org.scilab.modules.graphic_objects.axes;
15
16 import java.util.ArrayList;
17
18 import org.scilab.modules.graphic_objects.graphicObject.GraphicObject.UpdateStatus;
19 import org.scilab.modules.graphic_objects.textObject.Font;
20 import org.scilab.modules.graphic_objects.textObject.FormattedText;
21
22 /**
23  * TicksProperty class
24  * @author Manuel JULIACHS
25  */
26 public class TicksProperty {
27     /** TicksProperty properties names */
28     public enum TicksPropertyProperty { AUTO, LOCATIONS, LABELS,
29                                         FONT_SIZE, FONT_STYLE, FONT_COLOR, SUBTICKS
30                                       };
31
32     /** Default number of ticks */
33     private static final int DEFAULT_NUMBER_OF_TICKS = 11;
34
35     /** Specifies whether ticks are automatically computed or not */
36     private boolean auto;
37
38     /** Number of subticks between two main ticks */
39     private int subticks;
40
41     /** Default font */
42     private Font defaultFont;
43
44     private String format = "";
45     private Double[] st_factors = new Double[] {1., 0.};
46
47     /** TicksArrays class */
48     private class TicksArrays {
49         /** Ticks locations */
50         private double[] locations;
51
52         /** Ticks labels */
53         private ArrayList <FormattedText> labels;
54
55         /** Number of ticks */
56         private int number;
57
58         /**
59          * Constructor
60          */
61         public TicksArrays(int number) {
62             locations = new double[number];
63             labels = new ArrayList<FormattedText>(number);
64
65             for (int i = 0; i < number; i++) {
66                 labels.add(i, new FormattedText());
67             }
68
69             this.number = number;
70         }
71
72         @Override
73         public boolean equals(Object o) {
74             if (o instanceof TicksArrays) {
75                 TicksArrays ta = (TicksArrays) o;
76                 if (ta.number == number) {
77                     for (int i = 0; i < number; i++) {
78                         if (ta.locations[i] != locations[i] || !ta.labels.get(i).equals(labels.get(i))) {
79                             return false;
80                         }
81                     }
82
83                     return true;
84                 }
85             }
86
87             return false;
88         }
89
90         /**
91          * @return the number of ticks
92          */
93         public Integer getNumber() {
94             return number;
95         }
96
97         /**
98          * @return the labels
99          */
100         public ArrayList<FormattedText> getLabels() {
101             return labels;
102         }
103
104         /**
105          * @param labels the labels to set
106          */
107         public UpdateStatus setLabels(ArrayList<FormattedText> labels) {
108             UpdateStatus status = this.labels.equals(labels) ? UpdateStatus.NoChange : UpdateStatus.Success;
109             if (status == UpdateStatus.Success) {
110                 if (!this.labels.isEmpty()) {
111                     this.labels.clear();
112                 }
113
114                 for (int i = 0; i < labels.size(); i++) {
115                     this.labels.add(i, new FormattedText(labels.get(i)));
116                 }
117             }
118
119             return status;
120         }
121
122         /**
123          * @return the labels strings
124          */
125         public String[] getLabelsStrings() {
126             String[] labelsStrings;
127
128             labelsStrings = new String[number];
129
130             for (int i = 0; i < number; i++) {
131                 labelsStrings[i] = new String(labels.get(i).getText()).replaceAll("\u00A0", " ");
132             }
133
134             return labelsStrings;
135         }
136
137         /**
138          * Sets the ticks labels strings
139          * Requires the corresponding ticks locations to have previously been set.
140          * @param labels the labels to set
141          */
142         public UpdateStatus setLabelsStrings(String[] labels) {
143             if (labels.length != number) {
144                 return UpdateStatus.NoChange;
145             }
146
147             if (this.labels == null || this.labels.size() != labels.length) {
148                 this.labels = new ArrayList<FormattedText>(0);
149
150                 Font font = new Font(defaultFont);
151                 for (int i = 0; i < labels.length; i++) {
152                     FormattedText newText = new FormattedText(labels[i], font);
153                     this.labels.add(newText);
154                 }
155
156                 return UpdateStatus.Success;
157             }
158
159             UpdateStatus status = UpdateStatus.NoChange;
160             for (int i = 0; i < number; i++) {
161                 FormattedText ft = this.labels.get(i);
162                 if (!ft.getText().equals(labels[i])) {
163                     this.labels.get(i).setText(labels[i]);
164                     status = UpdateStatus.Success;
165                 }
166             }
167
168             return status;
169         }
170
171         /**
172          * @return the locations
173          */
174         public Double[] getLocations() {
175             Double[] retLocations;
176
177             retLocations = new Double[number];
178
179             for (int i = 0; i < number; i++) {
180                 retLocations[i] = locations[i];
181             }
182
183             return retLocations;
184         }
185
186         /**
187          * Sets the ticks locations
188          * Also sets the current number of ticks to the size of the locations array
189          * if the latter is resized.
190          * @param locations the locations to set
191          */
192         public UpdateStatus setLocations(Double[] locations) {
193             UpdateStatus status = UpdateStatus.Success;
194             if (this.locations == null || number != locations.length) {
195                 this.locations = new double[locations.length];
196                 number = locations.length;
197             } else {
198                 status = UpdateStatus.NoChange;
199             }
200
201             for (int i = 0; i < locations.length; i++) {
202                 if (status == UpdateStatus.NoChange) {
203                     if (this.locations[i] != locations[i]) {
204                         status = UpdateStatus.Success;
205                         this.locations[i] = locations[i];
206                     }
207                 } else {
208                     this.locations[i] = locations[i];
209                 }
210             }
211
212             return status;
213         }
214
215         /**
216          * Supposes all ticks labels have the same font style.
217          * To be corrected.
218          * @return the ticks labels font style
219          */
220         public Integer getFontStyle() {
221             if (!labels.isEmpty()) {
222                 return labels.get(0).getFont().getStyle();
223             }
224             return 0;
225         }
226
227         /**
228          * Supposes all ticks labels have the same font style.
229          * To be corrected.
230          * @param fontStyle the ticks labels font style to set
231          */
232         public UpdateStatus setFontStyle(Integer fontStyle) {
233             UpdateStatus status = UpdateStatus.NoChange;
234             for (int i = 0; i < labels.size(); i++) {
235                 Font f = labels.get(i).getFont();
236                 if (f.getStyle() != fontStyle) {
237                     f.setStyle(fontStyle);
238                     status = UpdateStatus.Success;
239                 }
240             }
241
242             return status;
243         }
244
245         /**
246          * Supposes all ticks labels have the same font size.
247          * To be corrected.
248          * @return the ticks labels font size
249          */
250         public Double getFontSize() {
251             if (!labels.isEmpty()) {
252                 return labels.get(0).getFont().getSize();
253             }
254             return 0.0;
255         }
256
257         /**
258          * Supposes all ticks labels have the same font size.
259          * To be corrected.
260          * @param fontSize the ticks labels font size to set
261          */
262         public UpdateStatus setFontSize(Double fontSize) {
263             UpdateStatus status = UpdateStatus.NoChange;
264             for (int i = 0; i < labels.size(); i++) {
265                 Font f = labels.get(i).getFont();
266                 if (f.getSize() != fontSize) {
267                     f.setSize(fontSize);
268                     status = UpdateStatus.Success;
269                 }
270             }
271
272             return status;
273         }
274
275         /**
276          * Supposes all ticks labels have the same font color.
277          * To be corrected.
278          * @return the ticks labels font color
279          */
280         public Integer getFontColor() {
281             if (!labels.isEmpty()) {
282                 return labels.get(0).getFont().getColor();
283             }
284             return 0;
285         }
286
287         /**
288          * Supposes all ticks labels have the same font color.
289          * To be corrected.
290          * @param fontColor the ticks labels font color to set
291          */
292         public UpdateStatus setFontColor(Integer fontColor) {
293             UpdateStatus status = UpdateStatus.NoChange;
294             for (int i = 0; i < labels.size(); i++) {
295                 Font f = labels.get(i).getFont();
296                 if (!f.getColor().equals(fontColor)) {
297                     f.setColor(fontColor);
298                     status = UpdateStatus.Success;
299                 }
300             }
301
302             return status;
303         }
304
305         /**
306          * Supposes all ticks labels have the same font fractional.
307          * To be corrected.
308          * @return the ticks labels font fractional
309          */
310         public Boolean getFontFractional() {
311             if (!labels.isEmpty()) {
312                 return labels.get(0).getFont().getFractional();
313             }
314             return false;
315         }
316
317         /**
318          * Supposes all ticks labels have the same font fractional.
319          * To be corrected.
320          * @param fontFractional the ticks labels font fractional to set
321          */
322         public UpdateStatus setFontFractional(Boolean fontFractional) {
323             UpdateStatus status = UpdateStatus.NoChange;
324             for (int i = 0; i < labels.size(); i++) {
325                 Font f = labels.get(i).getFont();
326                 if (f.getFractional() != fontFractional) {
327                     f.setFractional(fontFractional);
328                     status = UpdateStatus.Success;
329                 }
330             }
331
332             return status;
333         }
334     }
335
336     /** Automatic ticks */
337     TicksArrays automaticTicks;
338
339     /** User ticks */
340     TicksArrays userTicks;
341
342     /** Constructor */
343     public TicksProperty() {
344         auto = false;
345
346         subticks = 0;
347
348         defaultFont = new Font();
349
350         automaticTicks = new TicksArrays(DEFAULT_NUMBER_OF_TICKS);
351         userTicks = new TicksArrays(0);
352     }
353
354     /**
355      * Copy constructor
356      * @param ticksProperty the TicksProperty to copy
357      */
358     public TicksProperty(TicksProperty ticksProperty) {
359         auto = ticksProperty.auto;
360
361         subticks = ticksProperty.subticks;
362         format = ticksProperty.format;
363         st_factors = ticksProperty.st_factors;
364
365         defaultFont = new Font(ticksProperty.defaultFont);
366
367         automaticTicks = new TicksArrays(0);
368         userTicks = new TicksArrays(0);
369
370         automaticTicks.setLocations(ticksProperty.automaticTicks.getLocations());
371         userTicks.setLocations(ticksProperty.userTicks.getLocations());
372
373         automaticTicks.setLabels(ticksProperty.automaticTicks.getLabels());
374         userTicks.setLabels(ticksProperty.userTicks.getLabels());
375     }
376
377     @Override
378     public boolean equals(Object o) {
379         if (o instanceof TicksProperty) {
380             TicksProperty tp = (TicksProperty) o;
381             if (tp.auto == auto && tp.subticks == subticks && tp.defaultFont.equals(defaultFont)) {
382                 if (auto) {
383                     return automaticTicks.equals(tp.automaticTicks);
384                 } else {
385                     return userTicks.equals(tp.userTicks);
386                 }
387             }
388         }
389
390         return false;
391     }
392
393     /**
394      * @return the format
395      */
396     public String getFormat() {
397         return format;
398     }
399
400     /**
401      * @param format the format to set
402      */
403     public UpdateStatus setFormat(String format) {
404         if (!this.format.equals(format)) {
405             this.format = format;
406             return UpdateStatus.Success;
407         }
408
409         return UpdateStatus.NoChange;
410     }
411
412     /**
413      * @return the format
414      */
415     public Double[] getSTFactors() {
416         return st_factors;
417     }
418
419     /**
420      * @param format the format to set
421      */
422     public UpdateStatus setSTFactors(Double[] factors) {
423         if (!this.st_factors[0].equals(factors[0]) || !this.st_factors[1].equals(factors[1])) {
424             this.st_factors = factors;
425             return UpdateStatus.Success;
426         }
427
428         return UpdateStatus.NoChange;
429     }
430
431     /**
432      * @return the auto
433      */
434     public Boolean getAuto() {
435         return auto;
436     }
437
438     /**
439      * @param auto the auto to set
440      */
441     public UpdateStatus setAuto(Boolean auto) {
442         if (this.auto != auto) {
443             this.auto = auto;
444             return UpdateStatus.Success;
445         }
446
447         return UpdateStatus.NoChange;
448     }
449
450     /**
451      * @return the labels
452      */
453     public ArrayList<FormattedText> getLabels() {
454         if (auto) {
455             return automaticTicks.getLabels();
456         } else {
457             return userTicks.getLabels();
458         }
459     }
460
461     /**
462      * @param labels the labels to set
463      */
464     public UpdateStatus setLabels(ArrayList<FormattedText> labels) {
465         if (auto) {
466             return automaticTicks.setLabels(labels);
467         } else {
468             return userTicks.setLabels(labels);
469         }
470     }
471
472     /**
473      * @return the labels strings
474      */
475     public String[] getLabelsStrings() {
476         if (auto) {
477             return automaticTicks.getLabelsStrings();
478         } else  {
479             return userTicks.getLabelsStrings();
480         }
481     }
482
483     /**
484      * Sets the ticks labels strings
485      * Requires the corresponding ticks locations to have previously been set.
486      * @param labels the labels to set
487      */
488     public UpdateStatus setLabelsStrings(String[] labels) {
489         if (auto) {
490             return automaticTicks.setLabelsStrings(labels);
491         } else {
492             return userTicks.setLabelsStrings(labels);
493         }
494     }
495
496     /**
497      * @return the number of ticks
498      */
499     public Integer getNumber() {
500         if (auto) {
501             return automaticTicks.getNumber();
502         } else {
503             return userTicks.getNumber();
504         }
505     }
506
507     /**
508      * @return the locations
509      */
510     public Double[] getLocations() {
511         if (auto) {
512             return automaticTicks.getLocations();
513         } else {
514             return userTicks.getLocations();
515         }
516     }
517
518     /**
519      * Sets the ticks locations
520      * Also sets the current number of ticks to the size of the locations array
521      * if the latter is resized.
522      * @param locations the locations to set
523      */
524     public UpdateStatus setLocations(Double[] locations) {
525         if (auto) {
526             return automaticTicks.setLocations(locations);
527         } else {
528             return userTicks.setLocations(locations);
529         }
530     }
531
532     /**
533      * @return the subticks
534      */
535     public Integer getSubticks() {
536         return subticks;
537     }
538
539     /**
540      * @param subticks the subticks to set
541      */
542     public UpdateStatus setSubticks(Integer subticks) {
543         if (this.subticks != subticks) {
544             this.subticks = subticks;
545             return UpdateStatus.Success;
546         }
547
548         return UpdateStatus.NoChange;
549     }
550
551     /**
552      * Supposes that all automatic and user ticks labels have the same font style.
553      * To be corrected (commented out block) when the associated C get function is completed.
554      * @return the ticks labels font style
555      */
556     public Integer getFontStyle() {
557         return automaticTicks.getFontStyle();
558
559         /*
560           if (auto) {
561           return automaticTicks.getFontStyle();
562           } else {
563           return userTicks.getFontStyle();
564           }
565         */
566     }
567
568     /**
569      * Supposes that all automatic and user ticks labels have the same font style.
570      * To be corrected (commented out block) when the associated C set function is completed.
571      * @param fontStyle the ticks labels font style to set
572      */
573     public UpdateStatus setFontStyle(Integer fontStyle) {
574         UpdateStatus status = UpdateStatus.NoChange;
575         if (fontStyle != defaultFont.getStyle()) {
576             defaultFont.setStyle(fontStyle);
577             status = UpdateStatus.Success;
578         }
579
580         UpdateStatus s1 = automaticTicks.setFontStyle(fontStyle);
581         UpdateStatus s2 = userTicks.setFontStyle(fontStyle);
582
583         if (status == UpdateStatus.Success || s1 == UpdateStatus.Success || s2 == UpdateStatus.Success) {
584             return UpdateStatus.Success;
585         }
586
587         return UpdateStatus.NoChange;
588
589         /*
590           if (auto) {
591           automaticTicks.setFontStyle(fontStyle);
592           } else {
593           userTicks.setFontStyle(fontStyle);
594           }
595         */
596     }
597
598     /**
599      * Supposes that all automatic and user ticks labels have the same font size.
600      * To be corrected (commented out block) when the associated C get function is completed.
601      * @return the ticks labels font size
602      */
603     public Double getFontSize() {
604         return automaticTicks.getFontSize();
605
606         /*
607           if (auto) {
608           return automaticTicks.getFontSize();
609           } else {
610           return userTicks.getFontSize();
611           }
612         */
613     }
614
615     /**
616      * Supposes that all automatic and user ticks labels have the same font size.
617      * To be corrected (commented out block) when the associated C set function is completed.
618      * @param fontSize the ticks labels font size to set
619      */
620     public UpdateStatus setFontSize(Double fontSize) {
621         UpdateStatus status = UpdateStatus.NoChange;
622         if (fontSize != defaultFont.getSize()) {
623             defaultFont.setSize(fontSize);
624             status = UpdateStatus.Success;
625         }
626
627         UpdateStatus s1 = automaticTicks.setFontSize(fontSize);
628         UpdateStatus s2 = userTicks.setFontSize(fontSize);
629
630         if (status == UpdateStatus.Success || s1 == UpdateStatus.Success || s2 == UpdateStatus.Success) {
631             return UpdateStatus.Success;
632         }
633
634         return UpdateStatus.NoChange;
635
636         /*
637           if (auto) {
638           automaticTicks.setFontSize(fontSize);
639           } else {
640           userTicks.setFontSize(fontSize);
641           }
642         */
643     }
644
645     /**
646      * Supposes that all automatic and user ticks labels have the same font color.
647      * To be corrected (commented out block) when the associated C get function is completed.
648      * @return the ticks labels font color
649      */
650     public Integer getFontColor() {
651         return automaticTicks.getFontColor();
652
653         /*
654           if (auto) {
655           return automaticTicks.getFontColor();
656           } else {
657           return userTicks.getFontColor();
658           }
659         */
660     }
661
662     /**
663      * Supposes that all automatic and user ticks labels have the same font color.
664      * To be corrected (commented out block) when the associated C set function is completed.
665      * @param fontColor the ticks labels font color to set
666      */
667     public UpdateStatus setFontColor(Integer fontColor) {
668         UpdateStatus status = UpdateStatus.NoChange;
669         if (fontColor != defaultFont.getColor()) {
670             defaultFont.setColor(fontColor);
671             status = UpdateStatus.Success;
672         }
673
674         UpdateStatus s1 = automaticTicks.setFontColor(fontColor);
675         UpdateStatus s2 = userTicks.setFontColor(fontColor);
676
677         if (status == UpdateStatus.Success || s1 == UpdateStatus.Success || s2 == UpdateStatus.Success) {
678             return UpdateStatus.Success;
679         }
680
681         return UpdateStatus.NoChange;
682
683         /*
684           if (auto) {
685           automaticTicks.setFontColor(fontColor);
686           } else {
687           userTicks.setFontColor(fontColor);
688           }
689         */
690     }
691
692     /**
693      * Supposes all automatic and user ticks labels have the same font fractional.
694      * To be corrected (commented out block) when the associated C get function is completed.
695      * @return the ticks labels font fractional
696      */
697     public Boolean getFontFractional() {
698         return automaticTicks.getFontFractional();
699
700         /*
701           if (auto) {
702           return automaticTicks.getFontFractional();
703           } else {
704           return userTicks.getFontFractional();
705           }
706         */
707     }
708
709     /**
710      * Supposes all automatic and user ticks labels have the same font fractional.
711      * To be corrected (commented out block) when the associated C set function is completed.
712      * @param fontFractional the ticks labels font fractional to set
713      */
714     public UpdateStatus setFontFractional(Boolean fontFractional) {
715         UpdateStatus status = UpdateStatus.NoChange;
716         if (fontFractional != defaultFont.getFractional()) {
717             defaultFont.setFractional(fontFractional);
718             status = UpdateStatus.Success;
719         }
720
721         UpdateStatus s1 = automaticTicks.setFontFractional(fontFractional);
722         UpdateStatus s2 = userTicks.setFontFractional(fontFractional);
723
724         if (status == UpdateStatus.Success || s1 == UpdateStatus.Success || s2 == UpdateStatus.Success) {
725             return UpdateStatus.Success;
726         }
727
728         return UpdateStatus.NoChange;
729
730         /*
731           if (auto) {
732           automaticTicks.setFontFractional(fontFractional);
733           } else {
734           userTicks.setFontFractional(fontFractional);
735           }
736         */
737     }
738
739 }