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 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); } } }