]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/utils/vtkToolTip.java
e5625746997581b87ab77ba8603be596846ccb2c
[simantics/3d.git] / org.simantics.g3d.vtk / src / org / simantics / g3d / vtk / utils / vtkToolTip.java
1 package org.simantics.g3d.vtk.utils;
2
3 import javax.vecmath.Point2d;
4 import javax.vecmath.Point3d;
5
6 import org.simantics.g3d.scenegraph.RenderListener;
7 import org.simantics.g3d.vtk.common.VtkView;
8
9 import vtk.vtkTextActor;
10 import vtk.vtkTextProperty;
11
12 public class vtkToolTip<T> implements RenderListener{
13         
14         VtkView view;
15         long tooltipDelay = 1000;
16         
17         double backgroundColor[] = new double[] {0.8,0.8,0.8};
18         double backgroundOpacity = 0.8;
19         double color[] = new double[] {0.0,0.0,0.0};
20         double frameColor[] = new double[] {0.0,0.0,0.0};
21         
22         T obj = null;
23         Point3d pos3d;
24         Point2d pos2d;
25         String tooltip = null;
26         boolean showing = false;
27         boolean changed = false;
28         long setTime = 0;
29         
30         
31         
32         public vtkToolTip(VtkView view) {
33                 this.view = view;
34                 view.addListener(this);
35         }
36         
37         public long getTooltipDelay() {
38                 return tooltipDelay;
39         }
40         
41         /**
42          * Sets tooltip delay. Default is 1000 = 1s.
43          * @param tooltipDelay
44          */
45         public void setTooltipDelay(long tooltipDelay) {
46                 this.tooltipDelay = tooltipDelay;
47         }
48         
49         /**
50          * Sets background color. Default is light grey {0.8,0.8,0.8} 
51          * @param backgroundColor
52          */
53         public void setBackgroundColor(double[] backgroundColor) {
54                 this.backgroundColor = backgroundColor;
55         }
56         
57         /**
58          * Sets background opacity. Default is 0.8. 0.0 is fully transparent.
59          * @param backgroundOpacity
60          */
61         public void setBackgroundOpacity(double backgroundOpacity) {
62                 this.backgroundOpacity = backgroundOpacity;
63         }
64         
65         /**
66          * Sets text color. Default is black {0.0,0.0,0.0}
67          * @param color
68          */
69         public void setColor(double[] color) {
70                 this.color = color;
71         }
72         
73         /**
74          * Sets frame/border color. Default is black {0.0,0.0,0.0}
75          * Use null for no frame.
76          * 
77          * @param color
78          */
79         public void setFrameColor(double[] frameColor) {
80                 this.frameColor = frameColor;
81         }
82         
83         /**
84          * Removes/hides current tooltip.
85          */
86         public void remove() {
87                 this.obj = null;
88                 this.pos3d = null;
89                 this.pos2d = null;
90                 this.tooltip = null;
91                 if (showing) {
92                         view.refresh();
93                 }
94                 //System.out.println("remove");
95         }
96         
97         /**
98          * Sets current tooltip.
99          * 
100          * Position of the tooltip is based on projected 3d coordinate.
101          * 
102          * @param obj
103          * @param pos
104          * @param tooltip
105          */
106         public void setHoverObject(T obj, Point3d pos, String tooltip) {
107                 if (this.obj != null && this.obj == obj) {
108                         this.pos3d = pos;
109                         return;
110                 }
111                 this.obj = obj;
112                 this.pos3d = pos;
113                 this.pos2d = null;
114                 this.tooltip = tooltip;
115                 this.setTime = System.currentTimeMillis();
116                 view.refresh();
117                 //System.out.println("setHoverObj " + obj + " "  + pos + " " + tooltip);
118                 
119         }
120         
121         /**
122          * Sets current tooltip.
123          * 
124          * Position of the tooltip is based given screen coordinate.
125          * 
126          * @param obj
127          * @param pos
128          * @param tooltip
129          */
130         public void setHoverObject(T obj, Point2d pos, String tooltip) {
131                 if (this.obj != null && this.obj == obj) {
132                         this.pos2d = pos;
133                         return;
134                 }
135                 this.obj = obj;
136                 this.pos3d = null;
137                 this.pos2d = pos;
138                 this.tooltip = tooltip;
139                 this.setTime = System.currentTimeMillis();
140                 this.changed = true;
141                 view.refresh();
142                 //System.out.println("setHoverObj " + obj + " "  + pos + " " + tooltip);
143         }
144         
145         
146         @Override
147         public void preRender() {
148                 if (tooltip == null) {
149                         if (showing) {
150                                 removeTooltip();
151                         }
152                 } else {
153                         if (changed) {
154                                 removeTooltip();
155                         }
156                         if (!showing) {
157                                 addTooltip();
158                         } else {
159                                 updateTooltip();
160                         }
161                 }
162                 
163         }
164         
165         @Override
166         public void postRender() {
167                 if (!showing && tooltip != null)
168                         view.refresh();
169         }
170         
171         vtkTextActor textActor = null;
172         
173         protected void addTooltip() {
174                 //System.out.println("addTooltip");
175                 if (showing)
176                         return;
177                 long currentTime = System.currentTimeMillis();
178                 if (currentTime-setTime < tooltipDelay)
179                         return;
180                 
181                 if (textActor == null) {
182                         textActor = new vtkTextActor();
183                         vtkTextProperty prop = textActor.GetTextProperty();
184                         prop.SetBackgroundColor(backgroundColor);
185                         prop.SetBackgroundOpacity(backgroundOpacity);
186                         prop.SetColor(color);
187                         if (frameColor != null) {
188                                 prop.SetFrameColor(frameColor);
189                                 prop.SetFrame(1);
190                         } else {
191                                 prop.SetFrame(0);
192                         }
193                         
194                         prop.Delete();
195                         view.addDeletable(textActor);
196                 }
197                 textActor.SetInput(tooltip);
198                 showing = true;
199                 view.getRenderer().AddActor2D(textActor);
200                 updateTooltip();
201                 changed = false;
202         }
203         
204         protected void removeTooltip() {
205                 //System.out.println("removeTooltip");
206                 if (!showing)
207                         return;
208                 if (textActor == null)
209                         return;
210                 view.getRenderer().RemoveActor2D(textActor);
211                 showing = false;
212                 changed = false;
213         }
214         
215
216         protected void updateTooltip() {
217                 if (!showing)
218                         return;
219         
220                 Point2d p;
221                 if (pos3d != null) {
222                         p =  vtkUtil.getScreenCoordinates(view.getRenderer(), pos3d);
223                         
224                 } else {
225                         p = new Point2d(pos2d);
226                 }
227                 screenPoint(p);
228                 textActor.SetDisplayPosition((int)p.x, (int)p.y);
229         }
230         
231         /**
232          * Adjusts screen coordinates so that the tooltip fits into the window.
233          * @param pos
234          */
235         private void screenPoint(Point2d pos) {
236                 double bounds[] = new double[4];
237                 textActor.GetBoundingBox(view.getRenderer(), bounds);
238                 int size[] = view.getRenderer().GetRenderWindow().GetSize();
239                 double sw = size[0];
240                 double sh = size[1];
241                 
242                 Point2d min = new Point2d(pos.x-bounds[0], pos.y-bounds[2]);
243                 Point2d max = new Point2d(pos.x+bounds[1]+1.0, pos.y+bounds[3]+1.0);
244                 if (min.x < 0) {
245                         pos.x -= min.x;
246                 } else if (max.x > sw) {
247                         pos.x -= (max.x - sw);
248                 }
249                 if (min.y < 0) {
250                         pos.y -= min.y;
251                 } else if (max.y > sh) {
252                         pos.y -= (max.y - sh);
253                 }
254                         
255         }
256
257 }