--- /dev/null
+package org.simantics.g3d.vtk.utils;
+
+import javax.vecmath.Point2d;
+import javax.vecmath.Point3d;
+
+import org.simantics.g3d.scenegraph.RenderListener;
+import org.simantics.g3d.vtk.common.VtkView;
+
+import vtk.vtkTextActor;
+import vtk.vtkTextProperty;
+
+public class vtkToolTip<T> implements RenderListener{
+
+ VtkView view;
+ long tooltipDelay = 1000;
+
+ double backgroundColor[] = new double[] {0.8,0.8,0.8};
+ double backgroundOpacity = 0.8;
+ double color[] = new double[] {0.0,0.0,0.0};
+ double frameColor[] = new double[] {0.0,0.0,0.0};
+
+ T obj = null;
+ Point3d pos3d;
+ Point2d pos2d;
+ String tooltip = null;
+ boolean showing = false;
+ boolean changed = false;
+ long setTime = 0;
+
+
+
+ public vtkToolTip(VtkView view) {
+ this.view = view;
+ view.addListener(this);
+ }
+
+ public long getTooltipDelay() {
+ return tooltipDelay;
+ }
+
+ /**
+ * Sets tooltip delay. Default is 1000 = 1s.
+ * @param tooltipDelay
+ */
+ public void setTooltipDelay(long tooltipDelay) {
+ this.tooltipDelay = tooltipDelay;
+ }
+
+ /**
+ * Sets background color. Default is light grey {0.8,0.8,0.8}
+ * @param backgroundColor
+ */
+ public void setBackgroundColor(double[] backgroundColor) {
+ this.backgroundColor = backgroundColor;
+ }
+
+ /**
+ * Sets background opacity. Default is 0.8. 0.0 is fully transparent.
+ * @param backgroundOpacity
+ */
+ public void setBackgroundOpacity(double backgroundOpacity) {
+ this.backgroundOpacity = backgroundOpacity;
+ }
+
+ /**
+ * Sets text color. Default is black {0.0,0.0,0.0}
+ * @param color
+ */
+ public void setColor(double[] color) {
+ this.color = color;
+ }
+
+ /**
+ * Sets frame/border color. Default is black {0.0,0.0,0.0}
+ * Use null for no frame.
+ *
+ * @param color
+ */
+ public void setFrameColor(double[] frameColor) {
+ this.frameColor = frameColor;
+ }
+
+ /**
+ * Removes/hides current tooltip.
+ */
+ public void remove() {
+ this.obj = null;
+ this.pos3d = null;
+ this.pos2d = null;
+ this.tooltip = null;
+ if (showing) {
+ view.refresh();
+ }
+ //System.out.println("remove");
+ }
+
+ /**
+ * Sets current tooltip.
+ *
+ * Position of the tooltip is based on projected 3d coordinate.
+ *
+ * @param obj
+ * @param pos
+ * @param tooltip
+ */
+ public void setHoverObject(T obj, Point3d pos, String tooltip) {
+ if (this.obj != null && this.obj == obj) {
+ this.pos3d = pos;
+ return;
+ }
+ this.obj = obj;
+ this.pos3d = pos;
+ this.pos2d = null;
+ this.tooltip = tooltip;
+ this.setTime = System.currentTimeMillis();
+ view.refresh();
+ //System.out.println("setHoverObj " + obj + " " + pos + " " + tooltip);
+
+ }
+
+ /**
+ * Sets current tooltip.
+ *
+ * Position of the tooltip is based given screen coordinate.
+ *
+ * @param obj
+ * @param pos
+ * @param tooltip
+ */
+ public void setHoverObject(T obj, Point2d pos, String tooltip) {
+ if (this.obj != null && this.obj == obj) {
+ this.pos2d = pos;
+ return;
+ }
+ this.obj = obj;
+ this.pos3d = null;
+ this.pos2d = pos;
+ this.tooltip = tooltip;
+ this.setTime = System.currentTimeMillis();
+ this.changed = true;
+ view.refresh();
+ //System.out.println("setHoverObj " + obj + " " + pos + " " + tooltip);
+ }
+
+
+ @Override
+ public void preRender() {
+ if (tooltip == null) {
+ if (showing) {
+ removeTooltip();
+ }
+ } else {
+ if (changed) {
+ removeTooltip();
+ }
+ if (!showing) {
+ addTooltip();
+ } else {
+ updateTooltip();
+ }
+ }
+
+ }
+
+ @Override
+ public void postRender() {
+ if (!showing && tooltip != null)
+ view.refresh();
+ }
+
+ vtkTextActor textActor = null;
+
+ protected void addTooltip() {
+ //System.out.println("addTooltip");
+ if (showing)
+ return;
+ long currentTime = System.currentTimeMillis();
+ if (currentTime-setTime < tooltipDelay)
+ return;
+
+ if (textActor == null) {
+ textActor = new vtkTextActor();
+ vtkTextProperty prop = textActor.GetTextProperty();
+ prop.SetBackgroundColor(backgroundColor);
+ prop.SetBackgroundOpacity(backgroundOpacity);
+ prop.SetColor(color);
+ if (frameColor != null) {
+ prop.SetFrameColor(frameColor);
+ prop.SetFrame(1);
+ } else {
+ prop.SetFrame(0);
+ }
+
+ prop.Delete();
+ view.addDeletable(textActor);
+ }
+ textActor.SetInput(tooltip);
+ showing = true;
+ view.getRenderer().AddActor2D(textActor);
+ updateTooltip();
+ changed = false;
+ }
+
+ protected void removeTooltip() {
+ //System.out.println("removeTooltip");
+ if (!showing)
+ return;
+ if (textActor == null)
+ return;
+ view.getRenderer().RemoveActor2D(textActor);
+ showing = false;
+ changed = false;
+ }
+
+
+ protected void updateTooltip() {
+ if (!showing)
+ return;
+
+ Point2d p;
+ if (pos3d != null) {
+ p = vtkUtil.getScreenCoordinates(view.getRenderer(), pos3d);
+
+ } else {
+ p = new Point2d(pos2d);
+ }
+ screenPoint(p);
+ textActor.SetDisplayPosition((int)p.x, (int)p.y);
+ }
+
+ /**
+ * Adjusts screen coordinates so that the tooltip fits into the window.
+ * @param pos
+ */
+ private void screenPoint(Point2d pos) {
+ double bounds[] = new double[4];
+ textActor.GetBoundingBox(view.getRenderer(), bounds);
+ int size[] = view.getRenderer().GetRenderWindow().GetSize();
+ double sw = size[0];
+ double sh = size[1];
+
+ Point2d min = new Point2d(pos.x-bounds[0], pos.y-bounds[2]);
+ Point2d max = new Point2d(pos.x+bounds[1]+1.0, pos.y+bounds[3]+1.0);
+ if (min.x < 0) {
+ pos.x -= min.x;
+ } else if (max.x > sw) {
+ pos.x -= (max.x - sw);
+ }
+ if (min.y < 0) {
+ pos.y -= min.y;
+ } else if (max.y > sh) {
+ pos.y -= (max.y - sh);
+ }
+
+ }
+
+}