JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
Tooltip.java
Go to the documentation of this file.
1/**
2 * Copyright 2023-2024 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.graph.ui;
29
30import com.jogamp.common.os.Clock;
31import com.jogamp.graph.curve.Region;
32import com.jogamp.graph.curve.opengl.GLRegion;
33import com.jogamp.graph.curve.opengl.RegionRenderer;
34import com.jogamp.math.Vec2f;
35import com.jogamp.math.Vec3f;
36import com.jogamp.math.Vec4f;
37import com.jogamp.math.geom.AABBox;
38import com.jogamp.math.util.PMVMatrix4f;
39import com.jogamp.opengl.GL2ES2;
40import com.jogamp.opengl.GLProfile;
41import com.jogamp.opengl.util.texture.TextureSequence;
42
43/** A HUD tooltip for {@link Shape}, see {@link Shape#setToolTip(Tooltip)}. */
44public abstract class Tooltip {
45
46 /** Default tooltip delay is {@value}ms */
47 public static final long DEFAULT_DELAY = 1000;
48
49 /** Delay in ms, zero implies no time based alarm */
50 private final long delayMS;
51 /** Alarm t1, time to show tooltip, i.e. t0 + delayMS, if delayMS > 0 */
52 private volatile long alarmT1;
53 /** Toggle for forced tooltip display */
54 private volatile boolean forced;
55 /** Shape 'tool' owning this tooltip. */
56 private Shape tool;
57 /** Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}. */
58 protected final int renderModes;
59 protected final Vec4f backColor = new Vec4f(1, 1, 1, 0.9f);
60 protected final Vec4f frontColor = new Vec4f(0.2f, 0.2f, 0.2f, 1);
61
62 @Override
63 public String toString() {
64 return "Tooltip[d "+delayMS+", next "+alarmT1+", forced "+forced+"]";
65 }
66 /**
67 *
68 * @param backColor optional HUD tip background color, if null a slightly transparent white background is used
69 * @param frontColor optional HUD tip front color, if null an opaque almost-black is used
70 * @param delayMS delay until HUD tip is visible after timer start (mouse moved), zero implies no time based alarm
71 * @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
72 */
73 protected Tooltip(final Vec4f backColor, final Vec4f frontColor, final long delayMS, final int renderModes) {
74 this.delayMS = delayMS;
75 this.alarmT1 = 0;
76 this.forced = false;
77 this.tool = null;
78 this.renderModes = renderModes;
79 if( null != backColor ) {
80 this.backColor.set(backColor);
81 }
82 if( null != frontColor ) {
83 this.frontColor.set(frontColor);
84 }
85 }
86 /* pp */ final void setTool(final Shape tool) { this.tool = tool; }
87
88 /** Returns {@link Shape} 'tool' owning this tooltip, set after {@link Shape#setToolTip(Tooltip)}. */
89 public final Shape getTool() {
90 return tool;
91 }
92
93 /**
94 * Stops the timer if not enforced via {@link #now()} or {@code clearForced} is true.
95 * @param clearForced if true, also clears enforced flag set by {@link #now()}
96 * @return true if timer has been stopped, otherwise false
97 */
98 public final boolean stop(final boolean clearForced) {
99 if( clearForced ) {
100 this.alarmT1 = 0;
101 this.forced = false;
102 return true;
103 } else if( !this.forced ) {
104 this.alarmT1 = 0;
105 return true;
106 } else {
107 return false;
108 }
109 }
110
111 /** Starts the timer. */
112 public final void start() {
113 if( !this.forced && delayMS > 0 ) {
114 this.alarmT1 = Clock.currentMillis() + delayMS;
115 }
116 }
117
118 /** Enforce tooltip display with next {@link #tick()}. */
119 public final void now() {
120 this.forced = true;
121 this.alarmT1 = Clock.currentMillis() - 1;
122 }
123
124 /** Returns true if display is enforced via {@link #now()}. */
125 public final boolean forced() {
126 return forced;
127 }
128
129 /**
130 * Send tick to this tooltip
131 * @return true if {@link #start() started} timer has been reached or is enforced via {@link #now()} to {@link #createTip(PMVMatrix4f)}, otherwise false
132 */
133 public final boolean tick() {
134 if( 0 == alarmT1 ) {
135 return false;
136 }
137 if( Clock.currentMillis() < alarmT1 ) {
138 return false;
139 }
140 this.alarmT1 = 0;
141 this.forced = false;
142 return true;
143 }
144
145 /**
146 * Little helper for {@link #createTip(Scene, AABBox)} returning the Mv {@link AABBox} of the tool within {@link Scene} Mv space.
147 * <p>
148 * Method uses {@link #getTool()}
149 * <pre>
150 * return getTool().getBounds().transform(pmv.getMv(), new AABBox());
151 * </pre>
152 * </p>
153 */
155 return getTool().getBounds().transform(pmv.getMv(), new AABBox());
156 }
157 /** Little helper for {@link #createTip(Scene, AABBox)} returning the Mv position of the tip within {@link Scene} Mv space. */
158 public Vec2f getTipMvPosition(final Scene scene, final PMVMatrix4f pmv, final float tipWidth, final float tipHeight) {
159 return getTipMvPosition(scene, getToolMvBounds(pmv), tipWidth, tipHeight);
160 }
161 /** Little helper for {@link #createTip(Scene, AABBox)} returning the Mv position of the tip @ center within {@link Scene} Mv space. */
162 public Vec2f getTipMvPosition(final Scene scene, final AABBox toolMvBounds, final float tipWidth, final float tipHeight) {
163 final AABBox sceneAABox = scene.getBounds();
164 final Vec2f pos = new Vec2f();
165 if( toolMvBounds.getCenter().x() - tipWidth/2 < sceneAABox.getLow().x() ) {
166 pos.setX( sceneAABox.getLow().x() );
167 } else if( toolMvBounds.getCenter().x() + tipWidth/2 > sceneAABox.getHigh().x() ) {
168 pos.setX( sceneAABox.getHigh().x() - tipWidth);
169 } else {
170 pos.setX( toolMvBounds.getCenter().x()-tipWidth/2 );
171 }
172 if( toolMvBounds.getCenter().y() + tipHeight <= sceneAABox.getHigh().y() ) {
173 pos.setY( toolMvBounds.getCenter().y() );
174 } else if( toolMvBounds.getHigh().y() >= tipHeight ) {
175 pos.setY( toolMvBounds.getHigh().y() - tipHeight );
176 } else {
177 pos.setY( sceneAABox.getHigh().y() - tipHeight );
178 }
179 return pos;
180 }
181 /** Little helper for {@link #createTip(Scene, AABBox)} returning the Mv position of the tip @ center within {@link Scene} Mv space. */
182 public Vec2f getTipMvPosition(final Scene scene, final Vec3f toolMvPos, final float tipWidth, final float tipHeight) {
183 final AABBox sceneAABox = scene.getBounds();
184 final Vec2f pos = new Vec2f();
185 if( toolMvPos.x() - tipWidth/2 < sceneAABox.getLow().x() ) {
186 pos.setX( sceneAABox.getLow().x() );
187 } else if( toolMvPos.x() + tipWidth/2 > sceneAABox.getHigh().x() ) {
188 pos.setX( sceneAABox.getHigh().x() - tipWidth);
189 } else {
190 pos.setX( toolMvPos.x()-tipWidth/2 );
191 }
192 if( toolMvPos.y() + tipHeight <= sceneAABox.getHigh().y() ) {
193 pos.setY( toolMvPos.y() );
194 } else {
195 pos.setY( sceneAABox.getHigh().y() - tipHeight );
196 }
197 return pos;
198 }
199
200 /**
201 * Create a new HUD tip shape, usually called by {@link Scene}
202 * @param scene the {@link Scene} caller for which this HUD tip shape is created
203 * @param toolMvBounds {@link AABBox} of the {@link #getTool()} in model-view (Mv) space of the given {@link Scene}
204 * @return newly created HUD tip shape
205 * @see #destroyTip(GL2ES2, RegionRenderer, Shape)
206 */
207 public abstract Shape createTip(final Scene scene, AABBox toolMvBounds);
208
209 /**
210 * Destroy a {@link #createTip(Scene, AABBox) created} HUD tip.
211 * <p>
212 * Called after {@link Scene#removeShape(Shape)}, allowing implementation to perform certain
213 * resource cleanup tasks. Even keeping the {@link Shape} tip alive is possible.
214 * </p>
215 * <p>
216 * This default implementation simply calls {@link Shape#destroy(GL2ES2, RegionRenderer)}.
217 * </p>
218 * @param gl current {@link GL2ES2}
219 * @param renderModes Graph's {@link Region} render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence) create(..)}.
220 * @param tip created tip {@link Shape} via {@link #createTip(Scene, AABBox)}
221 * @see #createTip(Scene, AABBox)
222 */
223 public void destroyTip(final GL2ES2 gl, final RegionRenderer renderer, final Shape tip) {
224 tip.destroy(gl, renderer);
225 }
226
227}
GraphUI Scene.
Definition: Scene.java:102
AABBox getBounds(final PMVMatrix4f pmv, final Shape shape)
Returns AABBox dimension of given Shape from this container's perspective, i.e.
Definition: Scene.java:676
Generic Shape, potentially using a Graph via GraphShape or other means of representing content.
Definition: Shape.java:87
final AABBox getBounds()
Returns the unscaled bounding AABBox for this shape, borrowing internal instance.
Definition: Shape.java:732
final void destroy(final GL2ES2 gl, final RegionRenderer renderer)
Destroys all data.
Definition: Shape.java:457
A HUD tooltip for Shape, see Shape#setToolTip(Tooltip).
Definition: Tooltip.java:44
static final long DEFAULT_DELAY
Default tooltip delay is {@value}ms.
Definition: Tooltip.java:47
void destroyTip(final GL2ES2 gl, final RegionRenderer renderer, final Shape tip)
Destroy a created HUD tip.
Definition: Tooltip.java:223
Vec2f getTipMvPosition(final Scene scene, final PMVMatrix4f pmv, final float tipWidth, final float tipHeight)
Little helper for createTip(Scene, AABBox) returning the Mv position of the tip within Scene Mv space...
Definition: Tooltip.java:158
final void now()
Enforce tooltip display with next tick().
Definition: Tooltip.java:119
abstract Shape createTip(final Scene scene, AABBox toolMvBounds)
Create a new HUD tip shape, usually called by Scene.
final int renderModes
Graph's Region render modes, see create(..).
Definition: Tooltip.java:58
AABBox getToolMvBounds(final PMVMatrix4f pmv)
Little helper for createTip(Scene, AABBox) returning the Mv AABBox of the tool within Scene Mv space.
Definition: Tooltip.java:154
Tooltip(final Vec4f backColor, final Vec4f frontColor, final long delayMS, final int renderModes)
Definition: Tooltip.java:73
final void start()
Starts the timer.
Definition: Tooltip.java:112
Vec2f getTipMvPosition(final Scene scene, final AABBox toolMvBounds, final float tipWidth, final float tipHeight)
Little helper for createTip(Scene, AABBox) returning the Mv position of the tip @ center within Scene...
Definition: Tooltip.java:162
final boolean stop(final boolean clearForced)
Stops the timer if not enforced via now() or clearForced is true.
Definition: Tooltip.java:98
final Shape getTool()
Returns Shape 'tool' owning this tooltip, set after Shape#setToolTip(Tooltip).
Definition: Tooltip.java:89
Vec2f getTipMvPosition(final Scene scene, final Vec3f toolMvPos, final float tipWidth, final float tipHeight)
Little helper for createTip(Scene, AABBox) returning the Mv position of the tip @ center within Scene...
Definition: Tooltip.java:182
final boolean forced()
Returns true if display is enforced via now().
Definition: Tooltip.java:125
final boolean tick()
Send tick to this tooltip.
Definition: Tooltip.java:133
2D Vector based upon two float components.
Definition: Vec2f.java:37
void setY(final float y)
Definition: Vec2f.java:139
void setX(final float x)
Definition: Vec2f.java:138
3D Vector based upon three float components.
Definition: Vec3f.java:37
4D Vector based upon four float components.
Definition: Vec4f.java:37
Vec4f set(final Vec4f o)
this = o, returns this.
Definition: Vec4f.java:67
Axis Aligned Bounding Box.
Definition: AABBox.java:54
final Vec3f getHigh()
Returns the maximum right-top-near (xyz) coordinate.
Definition: AABBox.java:131
final Vec3f getLow()
Returns the minimum left-bottom-far (xyz) coordinate.
Definition: AABBox.java:140
AABBox transform(final Matrix4f mat, final AABBox out)
Transform this box using the given Matrix4f into out @endiliteral.
Definition: AABBox.java:933
final Vec3f getCenter()
Returns computed center of this AABBox of getLow() and getHigh().
Definition: AABBox.java:737
PMVMatrix4f implements the basic computer graphics Matrix4f pack using projection (P),...
final Matrix4f getMv()
Returns the modelview matrix (Mv).