Graphics: remove useless test to improve speed with big number of objects
[scilab.git] / scilab / modules / graphic_objects / src / java / org / scilab / modules / graphic_objects / graphicObject / GraphicObject.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010-2011 - DIGITEO - Manuel JULIACHS
4  * Copyright (C) 2011 - DIGITEO - Vincent COUVERT
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-en.txt
11  *
12  */
13
14 package org.scilab.modules.graphic_objects.graphicObject;
15
16 import org.scilab.modules.graphic_objects.ObjectRemovedException;
17 import org.scilab.modules.graphic_objects.axes.Axes;
18 import org.scilab.modules.graphic_objects.figure.Figure;
19 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
20 import org.scilab.modules.graphic_objects.legend.Legend;
21
22 import java.util.Arrays;
23 import java.util.LinkedList;
24 import java.util.List;
25
26 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.*;
27
28 /**
29  * GraphicObject class
30  * @author Manuel JULIACHS
31  * @author Vincent COUVERT
32  */
33 public abstract class GraphicObject implements Cloneable {
34
35     public enum UpdateStatus {
36         Success,        // Property updated with new values
37         NoChange,       // Property leave unchanged
38         Fail            // Update Fail
39     };
40
41     /** User data array default size */
42     public static final int USER_DATA_DEFAULT_SIZE = 0;
43
44     /** Graphic objects types */
45     public enum Type { ARC, AXES, AXESMODEL, AXIS, CHAMP, COMPOUND, FAC3D, FEC, FIGURE, FIGUREMODEL, GRAYPLOT,
46                        LABEL, LEGEND, MATPLOT, PLOT3D, POLYLINE, RECTANGLE, SEGS, TEXT, CHECKBOX, EDIT, FRAME,
47                        IMAGE, LISTBOX, POPUPMENU, PUSHBUTTON, RADIOBUTTON, CONSOLE, JAVACONSOLE, SLIDER, TABLE, UITEXT, UIMENU, UIMENUMODEL,
48                        PROGRESSIONBAR, WAITBAR, UICONTEXTMENU, UNKNOWNOBJECT
49                      };
50
51     /** GraphicObject properties */
52     public enum GraphicObjectPropertyType { PARENT, CHILDREN, CHILDREN_COUNT, HIDDEN, VISIBLE, USERDATA, USERDATASIZE, TYPE, REFERENCED, VALID, DATA,
53                                             PARENT_FIGURE, PARENT_AXES, HASLEGENDCHILD, LEGENDCHILD, SELECTEDCHILD, TAG, CALLBACK, CALLBACKTYPE, UNKNOWNPROPERTY
54                                           };
55
56     /** Identifier */
57     private String identifier;
58
59     /** Parent object is known by its UID */
60     private String parent;
61
62     /** Child objects list. Known by their UID */
63     private List <String> children;
64
65     /** Specifies whether the object is visible or not */
66     private boolean visible;
67
68     /** Specifies if the "handle" is referenced in scilab */
69     private boolean referenced;
70
71     /** Specifies if the "handle" is valid, i.e included in a rendered object */
72     private boolean valid;
73
74     /** Specifies if the "handle" is hidden, i.e not listed as children in Scilab view */
75     private boolean hidden;
76
77     /** User data */
78     private Integer[] userData;
79
80     /** Tag */
81     private String tag;
82
83     /** Callback */
84     private CallBack callback;
85
86     /**
87      * Identifier of the selected child
88      * This was previously implemented as a list, but is used in practice
89      * to store only the identifier of the currently selected child.
90      * To do: use a list if required
91      */
92     private String selectedChild;
93
94     /** Constructor */
95     public GraphicObject() {
96         identifier = null;
97         parent = "";
98         children = new LinkedList<String>();
99         visible = true;
100         userData = null;
101         valid = true;
102         referenced = false;
103         selectedChild = "";
104         tag = "";
105         callback = new CallBack("");
106     }
107
108     /**
109      * Clone
110      * @return clone
111      * @see java.lang.Object#clone()
112      */
113     public GraphicObject clone() {
114         GraphicObject copy = null;
115
116         try {
117             copy = (GraphicObject) super.clone();
118         } catch (CloneNotSupportedException e) {
119             // TODO Auto-generated catch block
120             e.printStackTrace();
121         }
122
123         /*
124          * Creating an empty list is done to avoid
125          * still referencing the original object's own list,
126          * which occurs when the Figure model is cloned.
127          */
128         copy.setChildren(new LinkedList<String>());
129
130         /*
131          * Avoids keeping the Figure model as a parent
132          * when the Axes model is cloned.
133          */
134         copy.setParent("");
135
136         /*
137          * Sets no object as the selected child.
138          */
139         copy.setSelectedChild("");
140
141         return copy;
142     }
143
144     abstract public void accept(Visitor visitor) throws ObjectRemovedException;
145
146     /**
147      * Returns the enum associated to a type name
148      * @param typeName the property name
149      * @return the type enum
150      */
151     public static Type getTypeFromName(int typeName) {
152         switch (typeName) {
153         case __GO_ARC__ :
154             return Type.ARC;
155         case __GO_AXES__ :
156             return Type.AXES;
157         case __GO_AXESMODEL__ :
158             return Type.AXESMODEL;
159         case __GO_AXIS__ :
160             return Type.AXIS;
161         case __GO_CHAMP__ :
162             return Type.CHAMP;
163         case __GO_COMPOUND__ :
164             return Type.COMPOUND;
165         case __GO_FAC3D__ :
166             return Type.FAC3D;
167         case __GO_FEC__ :
168             return Type.FEC;
169         case __GO_FIGURE__ :
170             return Type.FIGURE;
171         case __GO_FIGUREMODEL__ :
172             return Type.FIGUREMODEL;
173         case __GO_GRAYPLOT__ :
174             return Type.GRAYPLOT;
175         case __GO_LABEL__ :
176             return Type.LABEL;
177         case __GO_LEGEND__ :
178             return Type.LEGEND;
179         case __GO_MATPLOT__ :
180             return Type.MATPLOT;
181         case __GO_PLOT3D__ :
182             return Type.PLOT3D;
183         case __GO_POLYLINE__ :
184             return Type.POLYLINE;
185         case __GO_RECTANGLE__ :
186             return Type.RECTANGLE;
187         case __GO_SEGS__ :
188             return Type.SEGS;
189         case __GO_TEXT__ :
190             return Type.TEXT;
191         case __GO_UI_CHECKBOX__ :
192             return Type.CHECKBOX;
193         case __GO_UI_EDIT__ :
194             return Type.EDIT;
195         case __GO_UI_FRAME__ :
196             return Type.FRAME;
197         case __GO_UI_IMAGE__ :
198             return Type.IMAGE;
199         case __GO_UI_LISTBOX__ :
200             return Type.LISTBOX;
201         case __GO_UI_POPUPMENU__ :
202             return Type.POPUPMENU;
203         case __GO_UI_PUSHBUTTON__ :
204             return Type.PUSHBUTTON;
205         case __GO_UI_RADIOBUTTON__ :
206             return Type.RADIOBUTTON;
207         case __GO_UI_SLIDER__ :
208             return Type.SLIDER;
209         case __GO_UI_TABLE__ :
210             return Type.TABLE;
211         case __GO_UI_TEXT__ :
212             return Type.UITEXT;
213         case __GO_UIMENU__ :
214             return Type.UIMENU;
215         case __GO_UICONTEXTMENU__ :
216             return Type.UICONTEXTMENU;
217         case __GO_PROGRESSIONBAR__ :
218             return Type.PROGRESSIONBAR;
219         case __GO_WAITBAR__ :
220             return Type.WAITBAR;
221         default :
222             return Type.UNKNOWNOBJECT;
223         }
224     }
225
226     /**
227      * Returns the enum associated to a property name
228      * @param propertyName the property name
229      * @return the property enum
230      */
231     public Object getPropertyFromName(int propertyName) {
232         switch (propertyName) {
233         case __GO_PARENT__ :
234             return  GraphicObjectPropertyType.PARENT;
235         case __GO_CHILDREN__ :
236             return GraphicObjectPropertyType.CHILDREN;
237         case __GO_CHILDREN_COUNT__ :
238             return GraphicObjectPropertyType.CHILDREN_COUNT;
239         case __GO_HIDDEN__ :
240             return GraphicObjectPropertyType.HIDDEN;
241         case __GO_VISIBLE__ :
242             return GraphicObjectPropertyType.VISIBLE;
243         case __GO_USER_DATA__ :
244             return GraphicObjectPropertyType.USERDATA;
245         case __GO_USER_DATA_SIZE__ :
246             return GraphicObjectPropertyType.USERDATASIZE;
247         case __GO_REFERENCED__ :
248             return GraphicObjectPropertyType.REFERENCED;
249         case __GO_VALID__ :
250             return GraphicObjectPropertyType.VALID;
251         case __GO_PARENT_FIGURE__ :
252             return GraphicObjectPropertyType.PARENT_FIGURE;
253         case __GO_PARENT_AXES__ :
254             return GraphicObjectPropertyType.PARENT_AXES;
255         case __GO_HAS_LEGEND_CHILD__ :
256             return GraphicObjectPropertyType.HASLEGENDCHILD;
257         case __GO_LEGEND_CHILD__ :
258             return GraphicObjectPropertyType.LEGENDCHILD;
259         case __GO_SELECTED_CHILD__ :
260             return GraphicObjectPropertyType.SELECTEDCHILD;
261         case __GO_TYPE__ :
262             return GraphicObjectPropertyType.TYPE;
263         case __GO_DATA_MODEL__ :
264             return GraphicObjectPropertyType.DATA;
265         case __GO_TAG__ :
266             return GraphicObjectPropertyType.TAG;
267         case __GO_CALLBACK__ :
268             return GraphicObjectPropertyType.CALLBACK;
269         case __GO_CALLBACKTYPE__ :
270             return GraphicObjectPropertyType.CALLBACKTYPE;
271         default:
272             //System.err.println("[ERROR] Unknown Property : "+propertyName+" !!!!!!!!!!");
273             return GraphicObjectPropertyType.UNKNOWNPROPERTY;
274         }
275     }
276
277     /**
278      * Fast property get method
279      * @param property the property to get
280      * @return the property value
281      */
282     public Object getProperty(Object property) {
283         if (!(property instanceof GraphicObjectPropertyType)) {
284             return null;
285         }
286
287         GraphicObjectPropertyType p = (GraphicObjectPropertyType) property;
288         switch (p) {
289         case PARENT:
290             return getParent();
291         case CHILDREN:
292             return getChildren();
293         case CHILDREN_COUNT:
294             return children.size();
295         case VALID:
296             return isValid();
297         case HIDDEN:
298             return isHidden();
299         case VISIBLE:
300             return getVisible();
301         case USERDATA:
302             return getUserData();
303         case USERDATASIZE:
304             return getUserDataSize();
305         case PARENT_FIGURE:
306             return getParentFigure();
307         case PARENT_AXES:
308             return getParentAxes();
309         case HASLEGENDCHILD:
310             return getHasLegendChild();
311         case LEGENDCHILD:
312             return getLegendChild();
313         case SELECTEDCHILD:
314             return getSelectedChild();
315         case TYPE:
316             return getType();
317         case DATA:
318             return getIdentifier();
319         case TAG:
320             return getTag();
321         case CALLBACK:
322             return getCallbackString();
323         case CALLBACKTYPE:
324             return getCallbackType();
325         case UNKNOWNPROPERTY:
326             return null;
327         default:
328             return null;
329         }
330     }
331
332     /**
333      * Fast property set method
334      * @param property the property to set
335      * @param value the property value
336      * @return true if the property has been set, false otherwise
337      */
338     public UpdateStatus setProperty(Object property, Object value) {
339         if (!(property instanceof GraphicObjectPropertyType)) {
340             return UpdateStatus.Success;
341         }
342
343         GraphicObjectPropertyType p = (GraphicObjectPropertyType) property;
344         switch (p) {
345         case PARENT:
346             setParent((String) value);
347             break;
348         case CHILDREN:
349             setChildren((String[]) value);
350             break;
351         case VALID:
352             setValid((Boolean) value);
353             break;
354         case HIDDEN:
355             setHidden((Boolean) value);
356             break;
357         case VISIBLE:
358             setVisible((Boolean) value);
359             break;
360         case USERDATA:
361             setUserData((Integer[]) value);
362             break;
363         case USERDATASIZE:
364             return UpdateStatus.Fail;
365         case SELECTEDCHILD:
366             setSelectedChild((String) value);
367             break;
368         case DATA:
369             return UpdateStatus.Success;
370         case TAG:
371             setTag((String) value);
372             break;
373         case CALLBACK:
374             setCallbackString((String) value);
375             break;
376         case CALLBACKTYPE:
377             setCallbackType((Integer) value);
378             break;
379         case UNKNOWNPROPERTY:
380             return UpdateStatus.Fail;
381         default:
382             return UpdateStatus.Success;
383         }
384
385         return UpdateStatus.Success;
386     }
387
388     /**
389      * Returns a null property
390      * @param property property name
391      * @return null property
392      */
393     public Object getNullProperty(String property) {
394         return null;
395     }
396
397     /**
398      * Void property get method
399      * @param property the property name
400      */
401     public Object getPropertyVoid(String property) {
402         // TODO
403         return null;
404     }
405
406     /* TODO */
407     /**
408      * Void property set method
409      * @param property the property name
410      * @param value the property value
411      */
412     public void setPropertyVoid(String property, Object value) {
413         // TODO
414     }
415
416     /**
417      * @return the children
418      */
419     public String[] getChildren() {
420         return children.toArray(new String[children.size()]);
421     }
422
423     /**
424      * Adds a child.
425      * @param child the identifier of the added child.
426      */
427     public void addChild(String child) {
428         children.add(0, child);
429     }
430
431     /**
432      * Removes a child.
433      * @param child the identifier of the removed child.
434      */
435     public void removeChild(String child) {
436         children.remove(child);
437     }
438
439     /**
440      * @param children the children to set
441      */
442     private void setChildren(List<String> children) {
443         this.children = children;
444     }
445
446     /**
447      * @param children the children to set
448      */
449     public void setChildren(String[] children) {
450         this.children = new LinkedList<String>(Arrays.asList(children));
451     }
452
453     /**
454      * @return the identifier
455      */
456     public String getIdentifier() {
457         return identifier;
458     }
459
460     /**
461      * @param identifier the identifier to set
462      */
463     public void setIdentifier(String identifier) {
464         this.identifier = identifier;
465     }
466
467     /**
468      * @return the parent
469      */
470     public String getParent() {
471         return parent;
472     }
473
474     /**
475      * @param parent the parent to set
476      */
477     public void setParent(String parent) {
478         this.parent = parent;
479     }
480
481     /**
482      * @return the userData
483      */
484     public Object getUserData() {
485         return userData;
486     }
487
488     /**
489      * @param userData the userData to set
490      */
491     public void setUserData(Integer[] userData) {
492         this.userData = userData;
493     }
494
495     /**
496      * @return the userDataSize
497      */
498     public Integer getUserDataSize() {
499         if (userData != null) {
500             return userData.length;
501         }
502         return 0;
503     }
504
505     /**
506      * @return the tag
507      */
508     public String getTag() {
509         return tag;
510     }
511
512     /**
513      * @param tag the tag to set
514      */
515     public void setTag(String tag) {
516         this.tag = tag;
517     }
518
519     /**
520      * @return the callback
521      */
522     public String getCallbackString() {
523         return callback.getCommand();
524     }
525
526     /**
527      * @param callback the callback to set
528      */
529     public void setCallbackString(String callback) {
530         this.callback.setCommand(callback);
531     }
532
533     /**
534      * @return the callbackType
535      */
536     public Integer getCallbackType() {
537         return callback.getCommandType();
538     }
539
540     /**
541      * @param callbackType the callbackType to set
542      */
543     public void setCallbackType(Integer callbackType) {
544         this.callback.setCommandType(callbackType);
545     }
546
547     /**
548      * Get parent Figure method
549      * Returns the identifier of the object's parent Figure
550      * If the object is a Figure, then returns its own identifier.
551      * To be done: use a member variable storing the up-to-date current parent Figure,
552      * returned instead of recursively ascending the hierarchy at each call.
553      * @return the parent Figure identifier
554      */
555     public String getParentFigure() {
556         if (this instanceof Figure) {
557             return getIdentifier();
558         } else {
559             if (getParent() != null && GraphicController.getController().getObjectFromId(getParent()) != null) {
560                 return GraphicController.getController().getObjectFromId(getParent()).getParentFigure();
561             } else {
562                 /* No parent Figure found */
563                 return "";
564             }
565         }
566     }
567
568     /**
569      * Get parent Axes method
570      * Returns the identifier of the object's parent Axes
571      * If the object is an Axes, then returns its own identifier.
572      * To be done: use a member variable storing the up-to-date current parent Axes,
573      * returned instead of recursively ascending the hierarchy at each call.
574      * @return the parent Axes identifier
575      */
576     public String getParentAxes() {
577         if (this instanceof Axes) {
578             return getIdentifier();
579         } else {
580             if (getParent() != null && GraphicController.getController().getObjectFromId(getParent()) != null) {
581                 return GraphicController.getController().getObjectFromId(getParent()).getParentAxes();
582             } else {
583                 /* No parent Axes found */
584                 return "";
585             }
586         }
587     }
588
589     /**
590      * Get has legend child method
591      * Returns a boolean indicating whether one of the object's direct children
592      * is a Legend object. Only one Legend is supposed to be present in the list.
593      * To be done: storing the property and updating it only when a Legend object
594      * is inserted or deleted instead of searching the children list when the
595      * property is queried.
596      * @return a Boolean indicating whether the object has a child Legend object or not
597      */
598     public Boolean getHasLegendChild() {
599         for (int i = 0; i < children.size(); i++) {
600             GraphicObject currentObject = GraphicController.getController().getObjectFromId(children.get(i));
601
602             if (currentObject instanceof Legend) {
603                 return true;
604             }
605         }
606
607         return false;
608     }
609
610     /**
611      * Returns the identifier of the object's direct child that is a Legend object.
612      * It returns an empty string if the object has no Legend in its children list
613      * (one Legend is supposed to be present at most).
614      * @return the object's child Legend object identifier, or an empty string if no child Legend found.
615      */
616     public String getLegendChild() {
617         for (int i = 0; i < children.size(); i++) {
618             GraphicObject currentObject = GraphicController.getController().getObjectFromId(children.get(i));
619
620             if (currentObject instanceof Legend) {
621                 return currentObject.getIdentifier();
622             }
623         }
624
625         /* No child legend found */
626         return "";
627     }
628
629     /**
630      * Get selected child method
631      * @return the selected child
632      */
633     public String getSelectedChild() {
634         return selectedChild;
635     }
636
637     /**
638      * Set selected child method
639      * @param selectedChild the selected child to set
640      */
641     public void setSelectedChild(String selectedChild) {
642         this.selectedChild = selectedChild;
643     }
644
645     /**
646      * Get visible method
647      * @return the visible
648      */
649     public Boolean getVisible() {
650         return visible;
651     }
652
653     /**
654      * Set visible method
655      * @param visible the visible to set
656      */
657     public void setVisible(Boolean visible) {
658         this.visible = visible;
659     }
660
661     /**
662      * Each type should name itself
663      * @return Type as String
664      */
665     public abstract Integer getType();
666
667     /**
668      * isValid method
669      * @return valid
670      */
671     public Boolean isValid() {
672         return valid;
673     }
674
675     /**
676      * Set hidden method
677      * @param hidden the value to set
678      */
679     public void setHidden(Boolean hidden) {
680         this.hidden = hidden;
681     }
682
683     /**
684      * isHidden method
685      * @return hidden
686      */
687     public Boolean isHidden() {
688         return hidden;
689     }
690
691     /**
692      * Set valid method
693      * @param valid the validity to set
694      */
695     public void setValid(Boolean valid) {
696         this.valid = valid;
697     }
698
699     /**
700      * isReferenced method
701      * @return referenced
702      */
703     public Boolean isReferenced() {
704         return referenced;
705     }
706
707     /**
708      * Set referenced method
709      * @param referenced the reference status to set
710      */
711     public void setReferenced(Boolean referenced) {
712         this.referenced = referenced;
713     }
714 }