diff options
author | Sven Göthel <[email protected]> | 2024-01-15 11:02:09 +0100 |
---|---|---|
committer | Sven Göthel <[email protected]> | 2024-01-15 11:02:09 +0100 |
commit | 2bd66b50f21fd21e2102ac75cf4ce6cf875aca4d (patch) | |
tree | 4e8a332f2eed9fe2e1554180dea3f52e1eb080a7 /src/graphui/classes/com/jogamp/graph/ui | |
parent | 31ef5df9c5868b2b8e4ce843a4bf0a6c3f5a9879 (diff) |
GraphUI Shape: Add receiveKeyEvents() and receiveMouseEvents() allowing a Shape to receive forwarded events from another Shape; Added receive*Events() specialisation for RangeSlider
Forwarding events from shape to shape is useful, allowing inner shapes to send them to its group,
which itself may send it out towards an outer widget like RangeSlider.
RangeSlider's receive*Events() specialisation receives desired events from the source to its barAndKnob and knob
shapes, which are listening. It also suppresses the mouseClicked() event as it is only useful coming from itself.
Diffstat (limited to 'src/graphui/classes/com/jogamp/graph/ui')
3 files changed, 135 insertions, 8 deletions
diff --git a/src/graphui/classes/com/jogamp/graph/ui/Shape.java b/src/graphui/classes/com/jogamp/graph/ui/Shape.java index 225750b09..eaca76236 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/Shape.java +++ b/src/graphui/classes/com/jogamp/graph/ui/Shape.java @@ -34,9 +34,7 @@ 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; @@ -137,6 +135,79 @@ public abstract class Shape { boolean run(final Shape shape); } + /** + * Forward {@link KeyListener}, to be attached to a key event source forwarded to the receiver set at constructor. + * <p> + * This given receiver {@link Shape} must be {@link #setInteractive(boolean)} to have the events forwarded. + * </p> + * @see Shape#receiveKeyEvents(Shape) + */ + public static class ForwardKeyListener implements KeyListener { + public final Shape receiver; + /** + * {@link ForwardKeyListener} Constructor + * @param receiver the {@link KeyListener} receiver + */ + public ForwardKeyListener(final Shape receiver) { + this.receiver = receiver; + } + + private void dispatch(final KeyEvent e) { + if( receiver.isInteractive() ) { + receiver.dispatchKeyEvent(e); + } + } + @Override + public void keyPressed(final KeyEvent e) { dispatch(e); } + @Override + public void keyReleased(final KeyEvent e) { dispatch(e); } + } + + /** + * Forward {@link MouseGestureListener}, to be attached to a mouse event source forwarded to the receiver set at constructor. + * <p> + * This given receiver {@link Shape} must be {@link #setInteractive(boolean)} to have the events forwarded. + * </p> + * @see Shape#receiveMouseEvents(Shape) + */ + public static class ForwardMouseListener implements MouseGestureListener { + public final Shape receiver; + /** + * {@link ForwardMouseListener} Constructor + * @param receiver the {@link MouseGestureListener} receiver + */ + public ForwardMouseListener(final Shape receiver) { + this.receiver = receiver; + } + private void dispatch(final MouseEvent e) { + if( receiver.isInteractive() ) { + receiver.dispatchMouseEvent(e); + } + } + @Override + public void mouseClicked(final MouseEvent e) { dispatch(e); } + @Override + public void mouseEntered(final MouseEvent e) { dispatch(e); } + @Override + public void mouseExited(final MouseEvent e) { dispatch(e); } + @Override + public void mousePressed(final MouseEvent e) { dispatch(e); } + @Override + public void mouseReleased(final MouseEvent e) { dispatch(e); } + @Override + public void mouseMoved(final MouseEvent e) { dispatch(e); } + @Override + public void mouseDragged(final MouseEvent e) { dispatch(e); } + @Override + public void mouseWheelMoved(final MouseEvent e) { dispatch(e); } + @Override + public void gestureDetected(final GestureEvent e) { + if( receiver.isInteractive() ) { + receiver.dispatchGestureEvent(e); + } + } + }; + protected static final boolean DEBUG_DRAW = false; private static final boolean DEBUG = false; @@ -1492,7 +1563,6 @@ public abstract class Shape { mouseListeners = clonedListeners; return this; } - public final Shape removeMouseListener(final MouseGestureListener l) { if (l == null) { return this; @@ -1503,6 +1573,19 @@ public abstract class Shape { mouseListeners = clonedListeners; return this; } + /** + * Forward {@link MouseGestureListener} events to this {@link Shape} from {@code source} using a {@link ForwardMouseListener}. + * <p> + * This source {@link Shape} must be {@link #setInteractive(boolean)} to receive and forward the events. + * </p> + * <p> + * This receiver {@link Shape} must be {@link #setInteractive(boolean)} to have the events forwarded. + * </p> + * @see #receiveKeyEvents(Shape) + */ + public void receiveMouseEvents(final Shape source) { + source.addMouseListener(new Shape.ForwardMouseListener(this)); + } public final Shape addKeyListener(final KeyListener l) { if(l == null) { @@ -1514,7 +1597,6 @@ public abstract class Shape { keyListeners = clonedListeners; return this; } - public final Shape removeKeyListener(final KeyListener l) { if (l == null) { return this; @@ -1525,6 +1607,19 @@ public abstract class Shape { keyListeners = clonedListeners; return this; } + /** + * Forward {@link KeyListener} events to this {@link Shape} from {@code source} using a {@link ForwardKeyListener}. + * <p> + * This source {@link Shape} must be {@link #setInteractive(boolean)} to receive and forward the events. + * </p> + * <p> + * This receiver {@link Shape} must be {@link #setInteractive(boolean)} to have the events forwarded. + * </p> + * @see #receiveMouseEvents(Shape) + */ + public void receiveKeyEvents(final Shape source) { + source.addKeyListener(new Shape.ForwardKeyListener(this)); + } /** * Combining {@link MouseListener} and {@link GestureListener} @@ -1727,6 +1822,16 @@ public abstract class Shape { } // resizableOrDraggable && EVENT_MOUSE_DRAGGED e.setAttachment(shapeEvent); + return dispatchMouseEvent(e); + } + + /** + * Dispatch given NEWT mouse event to this shape + * @param e original Newt {@link MouseEvent} + * @return true to signal operation complete and to stop traversal, otherwise false + */ + /* pp */ final boolean dispatchMouseEvent(final MouseEvent e) { + final short eventType = e.getEventType(); for(int i = 0; !e.isConsumed() && i < mouseListeners.size(); i++ ) { final MouseGestureListener l = mouseListeners.get(i); switch( eventType ) { @@ -1799,9 +1904,19 @@ public abstract class Shape { final Shape.EventInfo shapeEvent = new EventInfo(glWinX, glWinY, this, objPos); e.setAttachment(shapeEvent); + dispatchGestureEvent(e); + } + + /** + * Dispatch given NEWT mouse event to this shape + * @param e original Newt {@link MouseEvent} + * @return true to signal operation complete and to stop traversal, otherwise false + */ + /* pp */ final boolean dispatchGestureEvent(final GestureEvent e) { for(int i = 0; !e.isConsumed() && i < mouseListeners.size(); i++ ) { mouseListeners.get(i).gestureDetected(e); } + return e.isConsumed(); // end signal traversal if consumed } /** 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 fadb3e1b2..4c5a6d1f0 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java +++ b/src/graphui/classes/com/jogamp/graph/ui/widgets/MediaPlayer.java @@ -255,7 +255,7 @@ public class MediaPlayer extends Widget { } } } ); - ctrlSlider.addListener(new SliderAdapter() { + ctrlSlider.addSliderListener(new SliderAdapter() { private void seekPlayer(final int ptsMS) { final int durationMS = mPlayer.getDuration(); timeLabel.setText(getMultilineTime(ptsMS, durationMS)); diff --git a/src/graphui/classes/com/jogamp/graph/ui/widgets/RangeSlider.java b/src/graphui/classes/com/jogamp/graph/ui/widgets/RangeSlider.java index ab57cc5d7..a11700287 100644 --- a/src/graphui/classes/com/jogamp/graph/ui/widgets/RangeSlider.java +++ b/src/graphui/classes/com/jogamp/graph/ui/widgets/RangeSlider.java @@ -146,7 +146,6 @@ public final class RangeSlider extends Widget { } private RangeSlider(final int renderModes_, final Vec2f size, final float knobScale, final Vec2f minMax, final float unitSize, final float pageSz, final float value) { - // final int renderModes = ( renderModes_ & ~Region.AA_RENDERING_MASK ) | Region.COLORCHANNEL_RENDERING_BIT; final int renderModes = renderModes_ & ~(Region.AA_RENDERING_MASK | Region.COLORCHANNEL_RENDERING_BIT); this.unitSize = unitSize; this.pageSize = pageSz; @@ -179,14 +178,14 @@ public final class RangeSlider extends Widget { barLineWidth = ( size.y() - height ) * pageBarLineScale; knobLength = width; knobHeight = height; - setPaddding(new Padding(size.y(), 0, size.y(), 0)); + setPaddding(new Padding(size.y()/2f, 0, size.y()/2f, 0)); } else { width = size.x() * pageKnobScale; height = pageSizePct * this.size.y(); barLineWidth = ( size.x() - width ) * pageBarLineScale; knobLength = height; knobHeight = width; - setPaddding(new Padding(0, size.x(), 0, size.x())); + setPaddding(new Padding(0, size.x()/2f, 0, size.x()/2f)); // System.err.println("ZZZ minMax "+minMax+", pageSize "+pageSize+" "+(pageSizePct*100f)+"% -> "+knobHeight+"/"+this.size.y()); } bar = new Rectangle(renderModes, this.size.x(), this.size.y(), barLineWidth); @@ -362,6 +361,19 @@ public final class RangeSlider extends Widget { } @Override + public void receiveKeyEvents(final Shape source) { + source.addKeyListener(new Shape.ForwardKeyListener(barAndKnob)); + source.addKeyListener(new Shape.ForwardKeyListener(knob)); + } + @Override + public void receiveMouseEvents(final Shape source) { + source.addMouseListener(new Shape.ForwardMouseListener(barAndKnob) { + @Override + public void mouseClicked(final MouseEvent e) { /* nop */ } + }); + } + + @Override protected void clearImpl0(final GL2ES2 gl, final RegionRenderer renderer) { super.clearImpl0(gl, renderer); sliderListeners.clear(); |