From: Marko Luukkainen Date: Thu, 15 Oct 2020 15:04:30 +0000 (+0300) Subject: Tooltip support X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=34cb7e694463fb4463a9bde610a1fd3bfd330644;p=simantics%2F3d.git Tooltip support gitlab #142 Change-Id: I477a47d767675703f6a36c0724f91e2da2987fd3 --- diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java index 26d6843b..0ce1acd2 100644 --- a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/vtkCameraAndSelectorAction.java @@ -17,6 +17,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import javax.vecmath.Point2d; +import javax.vecmath.Point2i; import javax.vecmath.Point3d; import org.eclipse.jface.viewers.ISelection; @@ -209,6 +211,8 @@ public class vtkCameraAndSelectorAction extends vtkAwtAction implements ISelecti return; if (e.getButton() != MouseEvent.BUTTON1) return; + lastX = e.getX(); + lastY = e.getY(); vtkProp spick[] = panel.pick(e.getX(), e.getY()); if (spick != null && spick.length > 0) { for (vtkProp selectActor : spick) { @@ -291,6 +295,22 @@ public class vtkCameraAndSelectorAction extends vtkAwtAction implements ISelecti } } + /** + * Returns mouse position in AWT screen coordinates. + * @return + */ + public Point2i getMousePositionAWT() { + return new Point2i(lastX, lastY); + } + + /** + * Returns mouse position in VTK screen coordinates. + * @return + */ + public Point2d getMousePosition() { + return new Point2d(lastX, rw.GetSize()[1]-lastY); + } + public List getSelectActor() { return selectActors; } diff --git a/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/utils/vtkToolTip.java b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/utils/vtkToolTip.java new file mode 100644 index 00000000..e5625746 --- /dev/null +++ b/org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/utils/vtkToolTip.java @@ -0,0 +1,257 @@ +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); + } + + } + +}