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