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