aboutsummaryrefslogtreecommitdiffstats
path: root/src/graphui/classes/com
diff options
context:
space:
mode:
authorSven Göthel <[email protected]>2024-01-07 04:56:28 +0100
committerSven Göthel <[email protected]>2024-01-07 04:56:28 +0100
commitfa973b03fc1d6af5696cee27e1824c45da3150b4 (patch)
tree68a2f17d0063c0b867fde5283274414907eaa3b4 /src/graphui/classes/com
parentcf0c60eaabd7334c0ae2099a1f999032cddf14dd (diff)
GraphUI Shape: Enable Tooltip (currently text only) to be displayed after delay w/o mouse-move (1s)
For efficiency, all Tooltip instances is hooked to Scene via Shape as well as its singleton pop-up HUD tip after delay and no mouse move. TooltipText is a simple text Button implementation, but other more fancy HUD tips can be implemented. Shape adds - 'public Tooltip setToolTip(final CharSequence text, final Font font, final float scaleY, final Scene scene)' Demoed within MediaPlayer widget.
Diffstat (limited to 'src/graphui/classes/com')
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/Scene.java47
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/Shape.java50
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/Tooltip.java84
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/TooltipText.java99
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java15
5 files changed, 289 insertions, 6 deletions
diff --git a/src/graphui/classes/com/jogamp/graph/ui/Scene.java b/src/graphui/classes/com/jogamp/graph/ui/Scene.java
index 6d3f77971..c71060db4 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/Scene.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/Scene.java
@@ -36,6 +36,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicReference;
import com.jogamp.opengl.FPSCounter;
import com.jogamp.opengl.GL;
@@ -132,6 +133,8 @@ public final class Scene implements Container, GLEventListener {
private static final boolean DEBUG = false;
private final List<Shape> shapes = new CopyOnWriteArrayList<Shape>();
+ /* pp */ final List<Tooltip> toolTips = new CopyOnWriteArrayList<Tooltip>();
+ private final AtomicReference<GraphShape> toolTipHUD = new AtomicReference<GraphShape>();
private boolean doFrustumCulling = false;
@@ -500,6 +503,15 @@ public final class Scene implements Container, GLEventListener {
displayedOnce = true;
syncDisplayedOnce.notifyAll();
}
+ if( null == toolTipHUD.get() ) {
+ final GraphShape[] t = { null };
+ for(final Tooltip tt : toolTips ) {
+ if( tt.tick() && forOne(pmv, tt.tool, () -> { t[0] = tt.createTip(pmv); }) ) {
+ toolTipHUD.set( t[0] );
+ break; // done
+ }
+ }
+ }
}
private void displayGLSelect(final GLAutoDrawable drawable, final Object[] shapes) {
@@ -1042,6 +1054,7 @@ public final class Scene implements Container, GLEventListener {
private final class SBCGestureListener implements GestureHandler.GestureListener {
@Override
public void gestureDetected(final GestureEvent gh) {
+ clearToolTips();
if( null != activeShape ) {
// gesture .. delegate to active shape!
final InputEvent orig = gh.getTrigger();
@@ -1069,7 +1082,7 @@ public final class Scene implements Container, GLEventListener {
* @param glWinX in GL window coordinates, origin bottom-left
* @param glWinY in GL window coordinates, origin bottom-left
*/
- private final boolean dispatchMouseEventPickShape(final MouseEvent e, final int glWinX, final int glWinY) {
+ private final Shape dispatchMouseEventPickShape(final MouseEvent e, final int glWinX, final int glWinY) {
final PMVMatrix4f pmv = new PMVMatrix4f();
final Vec3f objPos = new Vec3f();
final Shape shape = pickShape(pmv, glWinX, glWinY, objPos, (final Shape s) -> {
@@ -1077,10 +1090,10 @@ public final class Scene implements Container, GLEventListener {
});
if( null != shape ) {
setActiveShape(shape);
- return true;
+ return shape;
} else {
releaseActiveShape();
- return false;
+ return null;
}
}
/**
@@ -1109,6 +1122,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mousePressed(final MouseEvent e) {
+ clearToolTips();
if( -1 == lId || e.getPointerId(0) == lId ) {
lx = e.getX();
ly = e.getY();
@@ -1122,6 +1136,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseReleased(final MouseEvent e) {
+ clearToolTips();
// flip to GL window coordinates, origin bottom-left
final int glWinX = e.getX();
final int glWinY = getHeight() - e.getY() - 1;
@@ -1137,6 +1152,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseClicked(final MouseEvent e) {
+ clearToolTips();
// flip to GL window coordinates
final int glWinX = e.getX();
final int glWinY = getHeight() - e.getY() - 1;
@@ -1153,6 +1169,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseDragged(final MouseEvent e) {
+ clearToolTips();
// drag activeShape, if no gesture-activity, only on 1st pointer
if( null != activeShape && activeShape.isInteractive() && !pinchToZoomGesture.isWithinGesture() && e.getPointerId(0) == lId ) {
lx = e.getX();
@@ -1168,6 +1185,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseWheelMoved(final MouseEvent e) {
+ clearToolTips();
// flip to GL window coordinates
final int glWinX = lx;
final int glWinY = getHeight() - ly - 1;
@@ -1176,6 +1194,7 @@ public final class Scene implements Container, GLEventListener {
@Override
public void mouseMoved(final MouseEvent e) {
+ clearToolTips();
if( -1 == lId || e.getPointerId(0) == lId ) {
lx = e.getX();
ly = e.getY();
@@ -1183,12 +1202,19 @@ public final class Scene implements Container, GLEventListener {
}
final int glWinX = lx;
final int glWinY = getHeight() - ly - 1;
- mouseOver = dispatchMouseEventPickShape(e, glWinX, glWinY);
+ final Shape s = dispatchMouseEventPickShape(e, glWinX, glWinY);
+ if( null != s ) {
+ mouseOver = true;
+ s.startToolTip();
+ } else {
+ mouseOver = false;
+ }
}
@Override
public void mouseEntered(final MouseEvent e) { }
@Override
public void mouseExited(final MouseEvent e) {
+ clearToolTips();
releaseActiveShape();
clear();
}
@@ -1209,6 +1235,19 @@ public final class Scene implements Container, GLEventListener {
}
}
+ private void clearToolTips() {
+ final Shape s = toolTipHUD.getAndSet(null);
+ if( null != s ) {
+ invoke(false, (final GLAutoDrawable drawable) -> {
+ removeShape(drawable.getGL().getGL2ES2(), s);
+ return true;
+ });
+ }
+ for(final Tooltip tt : toolTips) {
+ tt.stop();
+ }
+ }
+
/**
* Return a formatted status string containing avg fps and avg frame duration.
* @param glad GLAutoDrawable instance for FPSCounter, its chosen GLCapabilities and its GL's swap-interval
diff --git a/src/graphui/classes/com/jogamp/graph/ui/Shape.java b/src/graphui/classes/com/jogamp/graph/ui/Shape.java
index 65a989ebd..3e22cba78 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/Shape.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/Shape.java
@@ -34,7 +34,9 @@ import com.jogamp.nativewindow.NativeWindowException;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
+import com.jogamp.graph.curve.Region;
import com.jogamp.graph.curve.opengl.RegionRenderer;
+import com.jogamp.graph.font.Font;
import com.jogamp.graph.ui.layout.Padding;
import com.jogamp.math.FloatUtil;
import com.jogamp.math.Matrix4f;
@@ -203,6 +205,9 @@ 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;
+
/**
* Create a generic UI {@link Shape}
*/
@@ -304,6 +309,7 @@ public abstract class Shape {
*/
public final void clear(final GL2ES2 gl, final RegionRenderer renderer) {
synchronized ( dirtySync ) {
+ stopToolTip();
clearImpl0(gl, renderer);
resetState();
}
@@ -330,6 +336,7 @@ public abstract class Shape {
* @param renderer {@link RegionRenderer} used to release GPU resources
*/
public final void destroy(final GL2ES2 gl, final RegionRenderer renderer) {
+ removeToolTip();
destroyImpl0(gl, renderer);
resetState();
}
@@ -1293,8 +1300,16 @@ public abstract class Shape {
if( isActivable() ) {
this.zOffset = zOffset;
setIO(IO_ACTIVE, v);
+ final Tooltip tt = tooltip;
if( !v ) {
releaseInteraction();
+ if( null != tt ) {
+ tt.stop();
+ }
+ } else {
+ if( null != tt ) {
+ tt.start();
+ }
}
if( DEBUG ) {
System.err.println("XXX "+(v?" Active":"DeActive")+" "+this);
@@ -1322,6 +1337,41 @@ 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);
+ if( null != oldTT ) {
+ oldTT.stop();
+ oldTT.scene.toolTips.remove(oldTT);
+ }
+ tooltip = newTT;
+ newTT.scene.toolTips.add(newTT);
+ return newTT;
+ }
+ public void removeToolTip() {
+ final Tooltip tt = tooltip;
+ tooltip = null;
+ if( null != tt ) {
+ tt.stop();
+ tt.scene.toolTips.remove(tt);
+ }
+ }
+ private void stopToolTip() {
+ final Tooltip tt = tooltip;
+ if( null != tt ) {
+ tt.stop();
+ }
+ }
+ /* pp */ void startToolTip() {
+ final Tooltip tt = tooltip;
+ if( null != tt ) {
+ tt.start();
+ }
+ }
+ public Tooltip getTooltip() { return tooltip; }
+
/**
* Set whether this shape is interactive,
* i.e. any user interaction like
diff --git a/src/graphui/classes/com/jogamp/graph/ui/Tooltip.java b/src/graphui/classes/com/jogamp/graph/ui/Tooltip.java
new file mode 100644
index 000000000..6c1603800
--- /dev/null
+++ b/src/graphui/classes/com/jogamp/graph/ui/Tooltip.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright 2023-2024 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+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)}. */
+public abstract class Tooltip {
+
+ /** Shape belonging to this tooltip's tool. */
+ protected final Shape tool;
+ protected final long delayMS;
+ protected final Scene scene;
+ /** Delay t1, time to show tooltip, i.e. t0 + delayMS */
+ protected volatile long delayT1;
+
+ protected Tooltip(final Shape tool, final long delayMS, final Scene scene) {
+ this.tool = tool;
+ this.delayMS = delayMS;
+ this.scene = scene;
+ this.delayT1 = 0;
+ }
+
+ /** Stops the timer. */
+ public void stop() {
+ this.delayT1 = 0;
+ }
+
+ /** Starts the timer. */
+ public void start() {
+ final long t0 = Clock.currentMillis();
+ this.delayT1 = t0 + delayMS;
+ }
+
+ /**
+ * Send tick to this tooltip
+ * @return true if timer has been reached to {@link #createTip(PMVMatrix4f)}, otherwise false
+ */
+ public boolean tick() {
+ if( 0 == delayT1 ) {
+ return false;
+ }
+ final long t1 = Clock.currentMillis();
+ if( t1 < delayT1 ) {
+ return false;
+ }
+ this.delayT1 = 0;
+ return true;
+ }
+
+ /**
+ * Create a new HUD tip shape
+ * @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);
+
+} \ 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
new file mode 100644
index 000000000..6c2912bf4
--- /dev/null
+++ b/src/graphui/classes/com/jogamp/graph/ui/TooltipText.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright 2023-2024 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.graph.ui;
+
+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.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)}. */
+public class TooltipText extends Tooltip {
+ /** Text of this tooltip */
+ final private CharSequence tipText;
+ /** Font of this tooltip */
+ final private Font tipFont;
+ final private float scaleY;
+ final private int renderModes;
+ /**
+ * Ctor of {@link TooltipText}.
+ * @param scene the {@link Scene} to be attached to while pressed
+ * @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);
+ this.tipText = tipText;
+ this.tipFont = tipFont;
+ this.scaleY = scaleY;
+ this.renderModes = renderModes;
+ }
+
+ @Override
+ public GraphShape createTip(final PMVMatrix4f pmv) {
+ this.delayT1 = 0;
+ final float zEps = scene.getZEpsilon(16);
+
+ // Precompute text-box size .. guessing pixelSize
+ final AffineTransform tempT1 = new AffineTransform();
+ final AffineTransform tempT2 = new AffineTransform();
+ 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 float h = toolAABox.getHeight() * scaleY;
+ final float w = tipBox_em.getWidth() / tipBox_em.getHeight() * h;
+
+ final AABBox sceneAABox = scene.getBounds();
+ final float xpos, ypos;
+ if( toolAABox.getCenter().x()-w/2 < sceneAABox.getLow().x() ) {
+ xpos = sceneAABox.getLow().x();
+ } else {
+ xpos = toolAABox.getCenter().x()-w/2;
+ }
+ if( toolAABox.getHigh().y() > sceneAABox.getHigh().y() - h ) {
+ ypos = sceneAABox.getHigh().y() - h;
+ } else {
+ ypos = toolAABox.getHigh().y();
+ }
+ final Button ntip = (Button) new Button(renderModes, tipFont, tipText, w, h, zEps)
+ .setPerp()
+ .moveTo(xpos, ypos, 100*zEps)
+ .setColor(1, 1, 0, 0.80f)
+ // .setBorder(0.05f).setBorderColor(0, 0, 0, 1)
+ .setInteractive(false);
+ ntip.setLabelColor(0, 0, 0);
+ 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 75b07b7c8..0ceb9aaa9 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010-2023 JogAmp Community. All rights reserved.
+ * Copyright 2010-2024 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@@ -41,6 +41,7 @@ import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.ui.Group;
import com.jogamp.graph.ui.Scene;
import com.jogamp.graph.ui.Shape;
+import com.jogamp.graph.ui.TooltipText;
import com.jogamp.graph.ui.layout.Alignment;
import com.jogamp.graph.ui.layout.BoxLayout;
import com.jogamp.graph.ui.layout.Gap;
@@ -160,7 +161,8 @@ public class MediaPlayer extends Widget {
System.err.println(mp.toString());
for(final GLMediaPlayer.Chapter c : mp.getChapters()) {
System.err.println(c);
- ctrlSlider.addMark(c.start, new Vec4f(0.9f, 0.9f, 0.9f, 0.5f));
+ 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);
}
} else if( eventMask.isSet(GLMediaPlayer.EventMask.Bit.Play) ) {
playButton.setToggle(true);
@@ -289,6 +291,7 @@ public class MediaPlayer extends Widget {
ctrlBlend.setColor(0, 0, 0, alphaBlend);
this.addShape( ctrlBlend.setVisible(false) );
+ final float toolTipScaleY = 0.6f;
ctrlGroup = new Group(new GridLayout(ctrlCellWidth, ctrlCellHeight, Alignment.FillCenter, Gap.None, 1));
ctrlGroup.setName("ctrlGroup").setInteractive(false);
ctrlGroup.setPaddding(new Padding(0, borderSzS, 0, borderSzS));
@@ -303,6 +306,7 @@ public class MediaPlayer extends Widget {
});
playButton.setToggle(true); // on == play
ctrlGroup.addShape(playButton);
+ playButton.setToolTip("Play", fontInfo, toolTipScaleY, scene);
}
{ // 2
final Button button = new Button(renderModes, fontSymbols,
@@ -313,6 +317,7 @@ public class MediaPlayer extends Widget {
mPlayer.seek(0);
});
ctrlGroup.addShape(button);
+ button.setToolTip("Back", fontInfo, toolTipScaleY, scene);
}
{ // 3
final Button button = new Button(renderModes, fontSymbols,
@@ -323,6 +328,7 @@ public class MediaPlayer extends Widget {
mPlayer.setPlaySpeed(mPlayer.getPlaySpeed() - 0.5f);
});
ctrlGroup.addShape(button);
+ button.setToolTip("Fast-Rewind", fontInfo, toolTipScaleY, scene);
}
{ // 4
final Button button = new Button(renderModes, fontSymbols,
@@ -333,6 +339,7 @@ public class MediaPlayer extends Widget {
mPlayer.setPlaySpeed(mPlayer.getPlaySpeed() + 0.5f);
});
ctrlGroup.addShape(button);
+ button.setToolTip("Fast-Forward", fontInfo, toolTipScaleY, scene);
}
{ // 5
final Button button = new Button(renderModes, fontSymbols,
@@ -351,6 +358,7 @@ public class MediaPlayer extends Widget {
mPlayer.seek(pts1);
} } );
ctrlGroup.addShape(button);
+ button.setToolTip("Replay 5", fontInfo, toolTipScaleY, scene);
}
{ // 6
final Button button = new Button(renderModes, fontSymbols,
@@ -369,6 +377,7 @@ public class MediaPlayer extends Widget {
mPlayer.seek(pts1);
} } );
ctrlGroup.addShape(button);
+ button.setToolTip("Forward 5", fontInfo, toolTipScaleY, scene);
}
{ // 7
final Button button = new Button(renderModes, fontSymbols,
@@ -392,6 +401,7 @@ public class MediaPlayer extends Widget {
} } );
button.setToggle( !mPlayer.isAudioMuted() ); // on == volume
ctrlGroup.addShape(button);
+ button.setToolTip("Volume", fontInfo, toolTipScaleY, scene);
}
{ // 8
ctrlGroup.addShape(timeLabel);
@@ -457,6 +467,7 @@ public class MediaPlayer extends Widget {
});
button.setToggle( false ); // on == zoom
ctrlGroup.addShape(button);
+ button.setToolTip("Zoom", fontInfo, toolTipScaleY, scene);
}
for(final Shape cs : customCtrls ) {
ctrlGroup.addShape(cs);