Add full options management to figure
[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.1-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, DATATIP, LIGHT, TABGROUP, TAB, LAYER, BORDER, 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 Integer identifier;
58
59     /** Parent object is known by its UID */
60     private Integer parent;
61
62     /** Child objects list. Known by their UID */
63     private List <Integer> 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 Integer selectedChild;
93
94     /** Constructor */
95     public GraphicObject() {
96         identifier = 0;
97         parent = 0;
98         children = new LinkedList<Integer>();
99         visible = true;
100         userData = null;
101         valid = true;
102         referenced = false;
103         selectedChild = 0;
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<Integer>());
129
130         /*
131          * Avoids keeping the Figure model as a parent
132          * when the Axes model is cloned.
133          */
134         copy.setParent(0);
135
136         /*
137          * Sets no object as the selected child.
138          */
139         copy.setSelectedChild(0);
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             case __GO_DATATIP__:
222                 return Type.DATATIP;
223             case __GO_LIGHT__ :
224                 return Type.LIGHT;
225             case __GO_UI_TAB__ :
226                 return Type.TAB;
227             case __GO_UI_LAYER__ :
228                 return Type.LAYER;
229             case __GO_UI_FRAME_BORDER__ :
230                 return Type.BORDER;
231             default :
232                 return Type.UNKNOWNOBJECT;
233         }
234     }
235
236     /**
237      * Returns the enum associated to a property name
238      * @param propertyName the property name
239      * @return the property enum
240      */
241     public Object getPropertyFromName(int propertyName) {
242         switch (propertyName) {
243             case __GO_PARENT__ :
244                 return  GraphicObjectPropertyType.PARENT;
245             case __GO_CHILDREN__ :
246                 return GraphicObjectPropertyType.CHILDREN;
247             case __GO_CHILDREN_COUNT__ :
248                 return GraphicObjectPropertyType.CHILDREN_COUNT;
249             case __GO_HIDDEN__ :
250                 return GraphicObjectPropertyType.HIDDEN;
251             case __GO_VISIBLE__ :
252                 return GraphicObjectPropertyType.VISIBLE;
253             case __GO_USER_DATA__ :
254                 return GraphicObjectPropertyType.USERDATA;
255             case __GO_USER_DATA_SIZE__ :
256                 return GraphicObjectPropertyType.USERDATASIZE;
257             case __GO_REFERENCED__ :
258                 return GraphicObjectPropertyType.REFERENCED;
259             case __GO_VALID__ :
260                 return GraphicObjectPropertyType.VALID;
261             case __GO_PARENT_FIGURE__ :
262                 return GraphicObjectPropertyType.PARENT_FIGURE;
263             case __GO_PARENT_AXES__ :
264                 return GraphicObjectPropertyType.PARENT_AXES;
265             case __GO_HAS_LEGEND_CHILD__ :
266                 return GraphicObjectPropertyType.HASLEGENDCHILD;
267             case __GO_LEGEND_CHILD__ :
268                 return GraphicObjectPropertyType.LEGENDCHILD;
269             case __GO_SELECTED_CHILD__ :
270                 return GraphicObjectPropertyType.SELECTEDCHILD;
271             case __GO_TYPE__ :
272                 return GraphicObjectPropertyType.TYPE;
273             case __GO_DATA_MODEL__ :
274                 return GraphicObjectPropertyType.DATA;
275             case __GO_TAG__ :
276                 return GraphicObjectPropertyType.TAG;
277             case __GO_CALLBACK__ :
278                 return GraphicObjectPropertyType.CALLBACK;
279             case __GO_CALLBACKTYPE__ :
280                 return GraphicObjectPropertyType.CALLBACKTYPE;
281             default:
282                 //System.err.println("[ERROR] Unknown Property : "+propertyName+" !!!!!!!!!!");
283                 return GraphicObjectPropertyType.UNKNOWNPROPERTY;
284         }
285     }
286
287     /**
288      * Fast property get method
289      * @param property the property to get
290      * @return the property value
291      */
292     public Object getProperty(Object property) {
293         if (!(property instanceof GraphicObjectPropertyType)) {
294             return null;
295         }
296
297         GraphicObjectPropertyType p = (GraphicObjectPropertyType) property;
298         switch (p) {
299             case PARENT:
300                 return getParent();
301             case CHILDREN:
302                 return getChildren();
303             case CHILDREN_COUNT:
304                 return children.size();
305             case VALID:
306                 return isValid();
307             case HIDDEN:
308                 return isHidden();
309             case VISIBLE:
310                 return getVisible();
311             case USERDATA:
312                 return getUserData();
313             case USERDATASIZE:
314                 return getUserDataSize();
315             case PARENT_FIGURE:
316                 return getParentFigure();
317             case PARENT_AXES:
318                 return getParentAxes();
319             case HASLEGENDCHILD:
320                 return getHasLegendChild();
321             case LEGENDCHILD:
322                 return getLegendChild();
323             case SELECTEDCHILD:
324                 return getSelectedChild();
325             case TYPE:
326                 return getType();
327             case DATA:
328                 return getIdentifier();
329             case TAG:
330                 return getTag();
331             case CALLBACK:
332                 return getCallbackString();
333             case CALLBACKTYPE:
334                 return getCallbackType();
335             case UNKNOWNPROPERTY:
336                 return null;
337             default:
338                 return null;
339         }
340     }
341
342     /**
343      * Fast property set method
344      * @param property the property to set
345      * @param value the property value
346      * @return true if the property has been set, false otherwise
347      */
348     public UpdateStatus setProperty(Object property, Object value) {
349         if (!(property instanceof GraphicObjectPropertyType)) {
350             return UpdateStatus.Success;
351         }
352
353         GraphicObjectPropertyType p = (GraphicObjectPropertyType) property;
354         switch (p) {
355             case PARENT:
356                 setParent((Integer) value);
357                 break;
358             case CHILDREN:
359                 setChildren((Integer[]) value);
360                 break;
361             case VALID:
362                 setValid((Boolean) value);
363                 break;
364             case HIDDEN:
365                 setHidden((Boolean) value);
366                 break;
367             case VISIBLE:
368                 setVisible((Boolean) value);
369                 break;
370             case USERDATA:
371                 setUserData((Integer[]) value);
372                 break;
373             case USERDATASIZE:
374                 return UpdateStatus.Fail;
375             case SELECTEDCHILD:
376                 setSelectedChild((Integer) value);
377                 break;
378             case DATA:
379                 return UpdateStatus.Success;
380             case TAG:
381                 setTag((String) value);
382                 break;
383             case CALLBACK:
384                 setCallbackString((String) value);
385                 break;
386             case CALLBACKTYPE:
387                 setCallbackType((Integer) value);
388                 break;
389             case UNKNOWNPROPERTY:
390                 return UpdateStatus.Fail;
391             default:
392                 return UpdateStatus.Success;
393         }
394
395         return UpdateStatus.Success;
396     }
397
398     /**
399      * Returns a null property
400      * @param property property name
401      * @return null property
402      */
403     public Object getNullProperty(String property) {
404         return null;
405     }
406
407     /**
408      * Void property get method
409      * @param property the property name
410      */
411     public Object getPropertyVoid(String property) {
412         // TODO
413         return null;
414     }
415
416     /* TODO */
417     /**
418      * Void property set method
419      * @param property the property name
420      * @param value the property value
421      */
422     public void setPropertyVoid(String property, Object value) {
423         // TODO
424     }
425
426     /**
427      * @return the children
428      */
429     public Integer[] getChildren() {
430         return children.toArray(new Integer[children.size()]);
431     }
432
433     /**
434      * Adds a child.
435      * @param child the identifier of the added child.
436      */
437     public void addChild(Integer child) {
438         children.add(0, child);
439     }
440
441     /**
442      * Removes a child.
443      * @param child the identifier of the removed child.
444      */
445     public void removeChild(Integer child) {
446         children.remove(child);
447     }
448
449     /**
450      * @param children the children to set
451      */
452     private UpdateStatus setChildren(List<Integer> children) {
453         this.children = children;
454         return UpdateStatus.Success;
455     }
456
457     /**
458      * @param children the children to set
459      */
460     public UpdateStatus setChildren(Integer[] children) {
461         this.children = new LinkedList<Integer>(Arrays.asList(children));
462         return UpdateStatus.Success;
463     }
464
465     /**
466      * @return the identifier
467      */
468     public Integer getIdentifier() {
469         return identifier;
470     }
471
472     /**
473      * @param identifier the identifier to set
474      */
475     public UpdateStatus setIdentifier(Integer identifier) {
476         this.identifier = identifier;
477         return UpdateStatus.Success;
478     }
479
480     /**
481      * @return the parent
482      */
483     public Integer getParent() {
484         return parent;
485     }
486
487     /**
488      * @param parent the parent to set
489      * @return TODO
490      */
491     public UpdateStatus setParent(Integer parent) {
492         this.parent = parent;
493         return UpdateStatus.Success;
494     }
495
496     /**
497      * @return the userData
498      */
499     public Object getUserData() {
500         return userData;
501     }
502
503     /**
504      * @param userData the userData to set
505      * @return TODO
506      */
507     public UpdateStatus setUserData(Integer[] userData) {
508         this.userData = userData;
509         return UpdateStatus.Success;
510     }
511
512     /**
513      * @return the userDataSize
514      */
515     public Integer getUserDataSize() {
516         if (userData != null) {
517             return userData.length;
518         }
519         return 0;
520     }
521
522     /**
523      * @return the tag
524      */
525     public String getTag() {
526         return tag;
527     }
528
529     /**
530      * @param tag the tag to set
531      * @return TODO
532      */
533     public UpdateStatus setTag(String tag) {
534         this.tag = tag;
535         return UpdateStatus.Success;
536     }
537
538     /**
539      * @return the callback
540      */
541     public String getCallbackString() {
542         return callback.getCommand();
543     }
544
545     /**
546      * @param callback the callback to set
547      * @return TODO
548      */
549     public UpdateStatus setCallbackString(String callback) {
550         return this.callback.setCommand(callback);
551     }
552
553     /**
554      * @return the callbackType
555      */
556     public Integer getCallbackType() {
557         return callback.getCommandType();
558     }
559
560     /**
561      * @param callbackType the callbackType to set
562      * @return TODO
563      */
564     public UpdateStatus setCallbackType(Integer callbackType) {
565         this.callback.setCommandType(callbackType);
566         return UpdateStatus.Success;
567     }
568
569     /**
570      * Get parent Figure method
571      * Returns the identifier of the object's parent Figure
572      * If the object is a Figure, then returns its own identifier.
573      * To be done: use a member variable storing the up-to-date current parent Figure,
574      * returned instead of recursively ascending the hierarchy at each call.
575      * @return the parent Figure identifier
576      */
577     public Integer getParentFigure() {
578         if (this instanceof Figure) {
579             return getIdentifier();
580         } else {
581             if (getParent() != 0 && GraphicController.getController().getObjectFromId(getParent()) != null) {
582                 return GraphicController.getController().getObjectFromId(getParent()).getParentFigure();
583             } else {
584                 /* No parent Figure found */
585                 return 0;
586             }
587         }
588     }
589
590     /**
591      * Get parent Axes method
592      * Returns the identifier of the object's parent Axes
593      * If the object is an Axes, then returns its own identifier.
594      * To be done: use a member variable storing the up-to-date current parent Axes,
595      * returned instead of recursively ascending the hierarchy at each call.
596      * @return the parent Axes identifier
597      */
598     public Integer getParentAxes() {
599         if (this instanceof Axes) {
600             return getIdentifier();
601         } else {
602             if (getParent() != 0 && GraphicController.getController().getObjectFromId(getParent()) != null) {
603                 return GraphicController.getController().getObjectFromId(getParent()).getParentAxes();
604             } else {
605                 /* No parent Axes found */
606                 return 0;
607             }
608         }
609     }
610
611     /**
612      * Get has legend child method
613      * Returns a boolean indicating whether one of the object's direct children
614      * is a Legend object. Only one Legend is supposed to be present in the list.
615      * To be done: storing the property and updating it only when a Legend object
616      * is inserted or deleted instead of searching the children list when the
617      * property is queried.
618      * @return a Boolean indicating whether the object has a child Legend object or not
619      */
620     public Boolean getHasLegendChild() {
621         for (int i = 0; i < children.size(); i++) {
622             GraphicObject currentObject = GraphicController.getController().getObjectFromId(children.get(i));
623
624             if (currentObject instanceof Legend) {
625                 return true;
626             }
627         }
628
629         return false;
630     }
631
632     /**
633      * Returns the identifier of the object's direct child that is a Legend object.
634      * It returns an empty string if the object has no Legend in its children list
635      * (one Legend is supposed to be present at most).
636      * @return the object's child Legend object identifier, or an empty string if no child Legend found.
637      */
638     public Integer getLegendChild() {
639         for (int i = 0; i < children.size(); i++) {
640             GraphicObject currentObject = GraphicController.getController().getObjectFromId(children.get(i));
641
642             if (currentObject instanceof Legend) {
643                 return currentObject.getIdentifier();
644             }
645         }
646
647         /* No child legend found */
648         return 0;
649     }
650
651     /**
652      * Get selected child method
653      * @return the selected child
654      */
655     public Integer getSelectedChild() {
656         return selectedChild;
657     }
658
659     /**
660      * Set selected child method
661      * @param selectedChild the selected child to set
662      */
663     public UpdateStatus setSelectedChild(Integer selectedChild) {
664         this.selectedChild = selectedChild;
665         return UpdateStatus.Success;
666     }
667
668     /**
669      * Get visible method
670      * @return the visible
671      */
672     public Boolean getVisible() {
673         return visible;
674     }
675
676     /**
677      * Set visible method
678      * @param visible the visible to set
679      * @return TODO
680      */
681     public UpdateStatus setVisible(Boolean visible) {
682         this.visible = visible;
683         return UpdateStatus.Success;
684     }
685
686     /**
687      * Each type should name itself
688      * @return Type as String
689      */
690     public abstract Integer getType();
691
692     /**
693      * isValid method
694      * @return valid
695      */
696     public Boolean isValid() {
697         return valid;
698     }
699
700     /**
701      * Set hidden method
702      * @param hidden the value to set
703      * @return TODO
704      */
705     public UpdateStatus setHidden(Boolean hidden) {
706         this.hidden = hidden;
707         return UpdateStatus.Success;
708     }
709
710     /**
711      * isHidden method
712      * @return hidden
713      */
714     public Boolean isHidden() {
715         return hidden;
716     }
717
718     /**
719      * Set valid method
720      * @param valid the validity to set
721      * @return TODO
722      */
723     public UpdateStatus setValid(Boolean valid) {
724         this.valid = valid;
725         return UpdateStatus.Success;
726     }
727
728     /**
729      * isReferenced method
730      * @return referenced
731      */
732     public Boolean isReferenced() {
733         return referenced;
734     }
735
736     /**
737      * Set referenced method
738      * @param referenced the reference status to set
739      * @return TODO
740      */
741     public UpdateStatus setReferenced(Boolean referenced) {
742         this.referenced = referenced;
743         return UpdateStatus.Success;
744     }
745 }