aboutsummaryrefslogtreecommitdiffstats
path: root/src/graphui/classes/com/jogamp/graph
diff options
context:
space:
mode:
authorSven Göthel <[email protected]>2024-01-07 21:27:18 +0100
committerSven Göthel <[email protected]>2024-01-07 21:27:18 +0100
commit6dbd73108ec0b2f829674c07771c232395034157 (patch)
treef6d8083e5384f4b80785a03f6d30d9e061a2af76 /src/graphui/classes/com/jogamp/graph
parentc2452b211dc3f347dbffaac4e6c35b3c3e8c6d65 (diff)
GraphUI Tooltip: Simplify integration w/ Scene + Shape; Use Shape.setToolTip(Tooltip) for generic usage; Add TooltipText colors.
Shape also takes care of setting Tooltip's tool-Shape (itself), simplifying Tooltip ctor and having it more independent from Scene/Shape. Tooltip also drop Scene reference, as it shall be passed from Scene caller at Tooltip.createTip(..)
Diffstat (limited to 'src/graphui/classes/com/jogamp/graph')
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/Scene.java47
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/Shape.java16
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/Tooltip.java36
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/TooltipText.java50
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java18
5 files changed, 101 insertions, 66 deletions
diff --git a/src/graphui/classes/com/jogamp/graph/ui/Scene.java b/src/graphui/classes/com/jogamp/graph/ui/Scene.java
index e2dc96b8d..15ced642b 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/Scene.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/Scene.java
@@ -133,8 +133,8 @@ public final class Scene implements Container, GLEventListener {
private static final boolean DEBUG = false;
private final List<Shape> shapes = new CopyOnWriteArrayList<Shape>();
- private final AtomicReference<Tooltip> startedToolTip = new AtomicReference<Tooltip>();
- private final AtomicReference<GraphShape> toolTipHUD = new AtomicReference<GraphShape>();
+ private final AtomicReference<Tooltip> toolTipStarted = new AtomicReference<Tooltip>();
+ private final AtomicReference<Shape> toolTipHUD = new AtomicReference<Shape>();
private boolean doFrustumCulling = false;
@@ -503,12 +503,11 @@ public final class Scene implements Container, GLEventListener {
displayedOnce = true;
syncDisplayedOnce.notifyAll();
}
- final Tooltip tt = startedToolTip.get();
+ final Tooltip tt = toolTipStarted.get();
if( null != tt && null == toolTipHUD.get() ) {
- final GraphShape[] t = { null };
- if( tt.tick() && forOne(pmv, tt.tool, () -> { t[0] = tt.createTip(pmv); }) ) {
- toolTipHUD.set( t[0] );
- startedToolTip.set(null);
+ final Shape[] hud = { null };
+ if( tt.tick() && forOne(pmv, tt.getTool(), () -> { hud[0] = tt.createTip(Scene.this, pmv); }) ) {
+ setToolTip( hud[0] );
}
}
}
@@ -1053,7 +1052,7 @@ public final class Scene implements Container, GLEventListener {
private final class SBCGestureListener implements GestureHandler.GestureListener {
@Override
public void gestureDetected(final GestureEvent gh) {
- clearToolTips();
+ clearToolTip();
if( null != activeShape ) {
// gesture .. delegate to active shape!
final InputEvent orig = gh.getTrigger();
@@ -1121,7 +1120,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mousePressed(final MouseEvent e) {
- clearToolTips();
+ clearToolTip();
if( -1 == lId || e.getPointerId(0) == lId ) {
lx = e.getX();
ly = e.getY();
@@ -1135,7 +1134,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseReleased(final MouseEvent e) {
- clearToolTips();
+ clearToolTip();
// flip to GL window coordinates, origin bottom-left
final int glWinX = e.getX();
final int glWinY = getHeight() - e.getY() - 1;
@@ -1151,7 +1150,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseClicked(final MouseEvent e) {
- clearToolTips();
+ clearToolTip();
// flip to GL window coordinates
final int glWinX = e.getX();
final int glWinY = getHeight() - e.getY() - 1;
@@ -1168,7 +1167,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseDragged(final MouseEvent e) {
- clearToolTips();
+ clearToolTip();
// drag activeShape, if no gesture-activity, only on 1st pointer
if( null != activeShape && activeShape.isInteractive() && !pinchToZoomGesture.isWithinGesture() && e.getPointerId(0) == lId ) {
lx = e.getX();
@@ -1184,7 +1183,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseWheelMoved(final MouseEvent e) {
- clearToolTips();
+ clearToolTip();
// flip to GL window coordinates
final int glWinX = lx;
final int glWinY = getHeight() - ly - 1;
@@ -1193,7 +1192,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseMoved(final MouseEvent e) {
- clearToolTips();
+ clearToolTip();
if( -1 == lId || e.getPointerId(0) == lId ) {
lx = e.getX();
ly = e.getY();
@@ -1204,7 +1203,7 @@ public final class Scene implements Container, GLEventListener {
final Shape s = dispatchMouseEventPickShape(e, glWinX, glWinY);
if( null != s ) {
mouseOver = true;
- startedToolTip.set( s.startToolTip() );
+ toolTipStarted.set( s.startToolTip() );
} else {
mouseOver = false;
}
@@ -1213,7 +1212,7 @@ public final class Scene implements Container, GLEventListener {
public void mouseEntered(final MouseEvent e) { }
@Override
public void mouseExited(final MouseEvent e) {
- clearToolTips();
+ clearToolTip();
releaseActiveShape();
clear();
}
@@ -1234,7 +1233,17 @@ public final class Scene implements Container, GLEventListener {
}
}
- private void clearToolTips() {
+ private void setToolTip(final Shape hud) {
+ toolTipStarted.set( null );
+ addShape( hud );
+ toolTipHUD.set( hud );
+ }
+
+ private void clearToolTip() {
+ final Tooltip tt = toolTipStarted.getAndSet(null);
+ if( null != tt ) {
+ tt.stop();
+ }
final Shape s = toolTipHUD.getAndSet(null);
if( null != s ) {
invoke(false, (final GLAutoDrawable drawable) -> {
@@ -1242,10 +1251,6 @@ public final class Scene implements Container, GLEventListener {
return true;
});
}
- final Tooltip tt = startedToolTip.getAndSet(null);
- if( null != tt ) {
- tt.stop();
- }
}
/**
diff --git a/src/graphui/classes/com/jogamp/graph/ui/Shape.java b/src/graphui/classes/com/jogamp/graph/ui/Shape.java
index cb5a5e896..6d1a80a06 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/Shape.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/Shape.java
@@ -205,7 +205,6 @@ public abstract class Shape {
private static final float resize_sxy_min = 1f/200f; // 1/2% - TODO: Maybe customizable?
private static final float resize_section = 1f/5f; // resize action in a corner
- private static final long toolTipdelayMS = 1000;
private volatile Tooltip tooltip = null;
/**
@@ -1333,22 +1332,23 @@ public abstract class Shape {
return position.z() * getScale().z() + zOffset;
}
- /** Set's a {@link TooltipText} for this shape using default 1s delay */
- public Tooltip setToolTip(final CharSequence text, final Font font, final float scaleY, final Scene scene) {
- final Tooltip oldTT = tooltip;
- tooltip = null;
- final Tooltip newTT = new TooltipText(text, font, scaleY, this, toolTipdelayMS, scene, Region.VBAA_RENDERING_BIT);
+ /** Set's a new {@link Tooltip} for this shape. */
+ public Tooltip setToolTip(final Tooltip newTooltip) {
+ final Tooltip oldTT = this.tooltip;
+ this.tooltip = null;
if( null != oldTT ) {
oldTT.stop();
}
- tooltip = newTT;
- return newTT;
+ newTooltip.setToolOwner(this);
+ this.tooltip = newTooltip;
+ return newTooltip;
}
public void removeToolTip() {
final Tooltip tt = tooltip;
tooltip = null;
if( null != tt ) {
tt.stop();
+ tt.setToolOwner(null);
}
}
private void stopToolTip() {
diff --git a/src/graphui/classes/com/jogamp/graph/ui/Tooltip.java b/src/graphui/classes/com/jogamp/graph/ui/Tooltip.java
index 88cfeac99..b8e2467fe 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/Tooltip.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/Tooltip.java
@@ -30,30 +30,37 @@ package com.jogamp.graph.ui;
import com.jogamp.common.os.Clock;
import com.jogamp.math.util.PMVMatrix4f;
-/** A HUD tooltip for {@link Shape}, see {@link Shape#setToolTip(CharSequence, com.jogamp.graph.font.Font, float, Scene)}. */
+/** A HUD tooltip for {@link Shape}, see {@link Shape#setToolTip(Tooltip)}. */
public abstract class Tooltip {
- /** Shape belonging to this tooltip's tool. */
- protected final Shape tool;
- protected final long delayMS;
- protected final Scene scene;
+ /** Default tooltip delay is {@value}ms */
+ public static final long DEFAULT_DELAY = 1000;
+
+ private final long delayMS;
/** Delay t1, time to show tooltip, i.e. t0 + delayMS */
- protected volatile long delayT1;
+ private volatile long delayT1;
+ /** Shape 'tool' owning this tooltip. */
+ private Shape tool;
- protected Tooltip(final Shape tool, final long delayMS, final Scene scene) {
- this.tool = tool;
+ protected Tooltip(final long delayMS) {
this.delayMS = delayMS;
- this.scene = scene;
this.delayT1 = 0;
+ this.tool = null;
+ }
+ /* pp */ final void setToolOwner(final Shape owner) { tool = owner; }
+
+ /** Returns {@link Shape} 'tool' owning this tooltip, set after {@link Shape#setToolTip(Tooltip)}. */
+ public final Shape getTool() {
+ return tool;
}
/** Stops the timer. */
- public void stop() {
+ public final void stop() {
this.delayT1 = 0;
}
/** Starts the timer. */
- public void start() {
+ public final void start() {
this.delayT1 = Clock.currentMillis() + delayMS;
}
@@ -61,7 +68,7 @@ public abstract class Tooltip {
* Send tick to this tooltip
* @return true if timer has been reached to {@link #createTip(PMVMatrix4f)}, otherwise false
*/
- public boolean tick() {
+ public final boolean tick() {
if( 0 == delayT1 ) {
return false;
}
@@ -73,10 +80,11 @@ public abstract class Tooltip {
}
/**
- * Create a new HUD tip shape
+ * Create a new HUD tip shape, usually called by {@link Scene}
+ * @param scene the {@link Scene} caller for which this HUD tip shape is created
* @param pmv {@link PMVMatrix4f}, which shall be properly initialized, e.g. via {@link Scene#setupMatrix(PMVMatrix4f)}
* @return newly created HUD tip shape
*/
- public abstract GraphShape createTip(final PMVMatrix4f pmv);
+ public abstract Shape createTip(final Scene scene, final PMVMatrix4f pmv);
} \ No newline at end of file
diff --git a/src/graphui/classes/com/jogamp/graph/ui/TooltipText.java b/src/graphui/classes/com/jogamp/graph/ui/TooltipText.java
index 6c2912bf4..b421604c9 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/TooltipText.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/TooltipText.java
@@ -31,35 +31,58 @@ import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.GLRegion;
import com.jogamp.graph.font.Font;
import com.jogamp.graph.ui.shapes.Button;
+import com.jogamp.math.Vec4f;
import com.jogamp.math.geom.AABBox;
import com.jogamp.math.geom.plane.AffineTransform;
import com.jogamp.math.util.PMVMatrix4f;
import com.jogamp.opengl.GLProfile;
-/** A HUD text {@link Tooltip} for {@link Shape}, see {@link Shape#setToolTip(CharSequence, com.jogamp.graph.font.Font, float, Scene)}. */
+/** A HUD text {@link Tooltip} for {@link Shape}, see {@link Shape#setToolTip(Tooltip)}. */
public class TooltipText extends Tooltip {
/** Text of this tooltip */
- final private CharSequence tipText;
+ private final CharSequence tipText;
/** Font of this tooltip */
- final private Font tipFont;
- final private float scaleY;
- final private int renderModes;
+ private final Font tipFont;
+ private final float scaleY;
+ private final int renderModes;
+ private final Vec4f backColor = new Vec4f();
+ private final Vec4f labelColor = new Vec4f();
+
/**
* Ctor of {@link TooltipText}.
- * @param scene the {@link Scene} to be attached to while pressed
+ * @param tipText HUD tip text
+ * @param tipFont HUD tip font
+ * @param backColor HUD tip background color
+ * @param labelColor HUD tip label color
+ * @param scaleY HUD tip vertical scale against tool height
+ * @param delayMS delay until HUD tip is visible after timer start (mouse moved)
* @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
*/
- /* pp */ TooltipText(final CharSequence tipText, final Font tipFont, final float scaleY, final Shape tool, final long delayMS, final Scene scene, final int renderModes) {
- super(tool, delayMS, scene);
+ public TooltipText(final CharSequence tipText, final Font tipFont, final Vec4f backColor, final Vec4f labelColor,
+ final float scaleY, final long delayMS, final int renderModes)
+ {
+ super(delayMS);
this.tipText = tipText;
this.tipFont = tipFont;
this.scaleY = scaleY;
this.renderModes = renderModes;
+ this.backColor.set(backColor);
+ this.labelColor.set(labelColor);
+ }
+ /**
+ * Ctor of {@link TooltipText} using {@link Tooltip#DEFAULT_DELAY}, {@link Region#VBAA_RENDERING_BIT}
+ * and a slightly transparent yellow background with an almost black opaque text color.
+ * @param tipText HUD tip text
+ * @param tipFont HUD tip font
+ * @param scaleY HUD tip vertical scale against tool height
+ * @param tool the tool shape for this tip
+ */
+ public TooltipText(final CharSequence tipText, final Font tipFont, final float scaleY) {
+ this(tipText, tipFont, new Vec4f(1, 1, 0, 0.80f), new Vec4f(0.1f, 0.1f, 0.1f, 1), scaleY, Tooltip.DEFAULT_DELAY, Region.VBAA_RENDERING_BIT);
}
@Override
- public GraphShape createTip(final PMVMatrix4f pmv) {
- this.delayT1 = 0;
+ public Shape createTip(final Scene scene, final PMVMatrix4f pmv) {
final float zEps = scene.getZEpsilon(16);
// Precompute text-box size .. guessing pixelSize
@@ -68,7 +91,7 @@ public class TooltipText extends Tooltip {
final AABBox tipBox_em = tipFont.getGlyphBounds(tipText, tempT1, tempT2);
// final AABBox toolAABox = scene.getBounds(new PMVMatrix4f(), tool);
- final AABBox toolAABox = tool.getBounds().transform(pmv.getMv(), new AABBox());
+ final AABBox toolAABox = getTool().getBounds().transform(pmv.getMv(), new AABBox());
final float h = toolAABox.getHeight() * scaleY;
final float w = tipBox_em.getWidth() / tipBox_em.getHeight() * h;
@@ -88,12 +111,11 @@ public class TooltipText extends Tooltip {
final Button ntip = (Button) new Button(renderModes, tipFont, tipText, w, h, zEps)
.setPerp()
.moveTo(xpos, ypos, 100*zEps)
- .setColor(1, 1, 0, 0.80f)
+ .setColor(backColor)
// .setBorder(0.05f).setBorderColor(0, 0, 0, 1)
.setInteractive(false);
- ntip.setLabelColor(0, 0, 0);
+ ntip.setLabelColor(labelColor);
ntip.setSpacing(0.10f, 0.10f);
- scene.addShape(ntip);
return ntip;
}
}
diff --git a/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java b/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java
index 2cde62668..57a9b3909 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java
@@ -162,7 +162,7 @@ public class MediaPlayer extends Widget {
for(final GLMediaPlayer.Chapter c : mp.getChapters()) {
System.err.println(c);
final Shape mark = ctrlSlider.addMark(c.start, new Vec4f(0.9f, 0.9f, 0.9f, 0.5f));
- mark.setToolTip(c.title+"\n"+PTS.millisToTimeStr(c.start, false), fontInfo, 5, scene);
+ mark.setToolTip(new TooltipText(c.title+"\n"+PTS.millisToTimeStr(c.start, false), fontInfo, 5));
}
} else if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.Play) ) {
playButton.setToggle(true);
@@ -306,7 +306,7 @@ public class MediaPlayer extends Widget {
});
playButton.setToggle(true); // on == play
ctrlGroup.addShape(playButton);
- playButton.setToolTip("Play", fontInfo, toolTipScaleY, scene);
+ playButton.setToolTip(new TooltipText("Play", fontInfo, toolTipScaleY));
}
{ // 2
final Button button = new Button(renderModes, fontSymbols,
@@ -317,7 +317,7 @@ public class MediaPlayer extends Widget {
mPlayer.seek(0);
});
ctrlGroup.addShape(button);
- button.setToolTip("Back", fontInfo, toolTipScaleY, scene);
+ button.setToolTip(new TooltipText("Back", fontInfo, toolTipScaleY));
}
{ // 3
final Button button = new Button(renderModes, fontSymbols,
@@ -328,7 +328,7 @@ public class MediaPlayer extends Widget {
mPlayer.setPlaySpeed(mPlayer.getPlaySpeed() - 0.5f);
});
ctrlGroup.addShape(button);
- button.setToolTip("Fast-Rewind", fontInfo, toolTipScaleY, scene);
+ button.setToolTip(new TooltipText("Fast-Rewind", fontInfo, toolTipScaleY));
}
{ // 4
final Button button = new Button(renderModes, fontSymbols,
@@ -339,7 +339,7 @@ public class MediaPlayer extends Widget {
mPlayer.setPlaySpeed(mPlayer.getPlaySpeed() + 0.5f);
});
ctrlGroup.addShape(button);
- button.setToolTip("Fast-Forward", fontInfo, toolTipScaleY, scene);
+ button.setToolTip(new TooltipText("Fast-Forward", fontInfo, toolTipScaleY));
}
{ // 5
final Button button = new Button(renderModes, fontSymbols,
@@ -358,7 +358,7 @@ public class MediaPlayer extends Widget {
mPlayer.seek(pts1);
} } );
ctrlGroup.addShape(button);
- button.setToolTip("Replay 5", fontInfo, toolTipScaleY, scene);
+ button.setToolTip(new TooltipText("Replay-5", fontInfo, toolTipScaleY));
}
{ // 6
final Button button = new Button(renderModes, fontSymbols,
@@ -377,7 +377,7 @@ public class MediaPlayer extends Widget {
mPlayer.seek(pts1);
} } );
ctrlGroup.addShape(button);
- button.setToolTip("Forward 5", fontInfo, toolTipScaleY, scene);
+ button.setToolTip(new TooltipText("Forward-5", fontInfo, toolTipScaleY));
}
{ // 7
final Button button = new Button(renderModes, fontSymbols,
@@ -401,7 +401,7 @@ public class MediaPlayer extends Widget {
} } );
button.setToggle( !mPlayer.isAudioMuted() ); // on == volume
ctrlGroup.addShape(button);
- button.setToolTip("Volume", fontInfo, toolTipScaleY, scene);
+ button.setToolTip(new TooltipText("Volume", fontInfo, toolTipScaleY));
}
{ // 8
ctrlGroup.addShape(timeLabel);
@@ -467,7 +467,7 @@ public class MediaPlayer extends Widget {
});
button.setToggle( false ); // on == zoom
ctrlGroup.addShape(button);
- button.setToolTip("Zoom", fontInfo, toolTipScaleY, scene);
+ button.setToolTip(new TooltipText("Zoom", fontInfo, toolTipScaleY));
}
for(final Shape cs : customCtrls ) {
ctrlGroup.addShape(cs);