summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo11.java18
-rw-r--r--src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java281
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/Group.java47
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java144
-rw-r--r--src/graphui/classes/com/jogamp/graph/ui/layout/Padding.java49
5 files changed, 348 insertions, 191 deletions
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo11.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo11.java
index 3e9c3f4bf..0479349b7 100644
--- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo11.java
+++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo11.java
@@ -38,6 +38,7 @@ import com.jogamp.graph.ui.Group;
import com.jogamp.graph.ui.Scene;
import com.jogamp.graph.ui.Shape;
import com.jogamp.graph.ui.layout.GridLayout;
+import com.jogamp.graph.ui.layout.Padding;
import com.jogamp.graph.ui.shapes.Button;
import com.jogamp.graph.ui.shapes.GLButton;
import com.jogamp.newt.event.MouseEvent;
@@ -82,17 +83,18 @@ public class UISceneDemo11 {
final Font font = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_SERIF);
System.err.println("Font: "+font.getFullFamilyName());
- final float shapeWidth = 1/8f;
- final float shapeHeight = shapeWidth/2.5f;
- final Group groupA0 = new Group(new GridLayout(2, shapeWidth*1.1f, shapeHeight*1.1f));
+ final Group groupA0 = new Group(new GridLayout(2, 1f, 1/2f, new Padding(0.1f, 0.1f)));
{
- groupA0.addShape( new Button(renderModes, font, "1", shapeWidth, shapeHeight) );
- groupA0.addShape( new Button(renderModes, font, "2", shapeWidth, shapeHeight) );
- groupA0.addShape( new Button(renderModes, font, "3", shapeWidth, shapeHeight) );
- groupA0.addShape( new Button(renderModes, font, "4", shapeWidth, shapeHeight) );
+ groupA0.addShape( new Button(options.renderModes, font, "r1 c1", 1f, 1f/2f).setCorner(0f).setDragAndResizeable(false) );
+ groupA0.addShape( new Button(options.renderModes, font, "r1 c2", 1f, 1f/2f).setCorner(0f).setDragAndResizeable(false) );
+ groupA0.addShape( new Button(options.renderModes, font, "r2 c1", 1f, 1f/2f).setCorner(0f).setDragAndResizeable(false) );
+ groupA0.addShape( new Button(options.renderModes, font, "r2 c2", 1f, 1f/2f).setCorner(0f).setDragAndResizeable(false) );
}
- groupA0.validate(glp);
+ groupA0.setInteractive(true);
+ groupA0.scale(1/8f, 1/8f, 1);
+ groupA0.validate(reqGLP);
System.err.println("Group-A0 "+groupA0);
+ System.err.println("Group-A0 Layout "+groupA0.getLayout());
groupA0.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; });
final Scene scene = new Scene();
diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java
index f181e51b9..4d132814c 100644
--- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java
+++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java
@@ -45,9 +45,12 @@ import com.jogamp.graph.font.Font;
import com.jogamp.graph.font.FontFactory;
import com.jogamp.graph.font.FontScale;
import com.jogamp.graph.ui.GraphShape;
+import com.jogamp.graph.ui.Group;
import com.jogamp.graph.ui.Scene;
import com.jogamp.graph.ui.Shape;
import com.jogamp.graph.ui.Scene.PMVMatrixSetup;
+import com.jogamp.graph.ui.layout.GridLayout;
+import com.jogamp.graph.ui.layout.Padding;
import com.jogamp.graph.ui.shapes.Button;
import com.jogamp.graph.ui.shapes.GLButton;
import com.jogamp.graph.ui.shapes.ImageButton;
@@ -194,12 +197,11 @@ public class UISceneDemo20 implements GLEventListener {
private final Font fontFPS;
private final Uri filmURL;
- private final float relTop = 80f/100f;
+ private final float relTop = 90f/100f;
private final float relMiddle = 22f/100f;
- private final float relLeft = 11f/100f;
/** Relative Button Size to Window Height, normalized to 1. */
- private static final float buttonXSizeNorm = 0.084f;
+ private static final float buttonXSizeNorm = 0.09f; // 0.084f;
private static final float fontSizePt = 10f;
/** Relative Font Size to Window Height for Main Text, normalized to 1. */
private static final float fontSizeFixedNorm = 0.04f;
@@ -217,8 +219,8 @@ public class UISceneDemo20 implements GLEventListener {
private String actionText = null;
private Label[] labels = null;
private String[] strings = null;
- private final List<RoundButton> buttons = new ArrayList<RoundButton>();
- private int buttonsLeftCount = 0;
+ final Group buttonsLeft = new Group();
+ final Group buttonsRight = new Group();
private Label truePtSizeLabel = null;
private Label jogampLabel = null;
private Label fpsLabel = null;
@@ -305,20 +307,27 @@ public class UISceneDemo20 implements GLEventListener {
scene.getRenderState().setHintMask(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED);
// scene.setSampleCount(3); // easy on embedded devices w/ just 3 samples (default is 4)?
scene.setDebugBox(options.debugBoxThickness);
+ scene.addShape(buttonsLeft);
+ scene.addShape(buttonsRight);
}
private void rotateButtons(final Vec3f angdeg) {
angdeg.scale(FloatUtil.PI / 180.0f); // -> radians
- for(int i=0; i<buttons.size(); i++) {
- buttons.get(i).getRotation().rotateByEuler( angdeg );
+ final List<Shape> sl = new ArrayList<Shape>();
+ sl.addAll(buttonsLeft.getShapes());
+ sl.addAll(buttonsRight.getShapes());
+ for(final Shape s : sl) {
+ s.getRotation().rotateByEuler( angdeg );
}
}
private void setButtonsSpacing(final float dx, final float dy) {
- for(int i=0; i<buttons.size(); i++) {
- final RoundButton b = buttons.get(i);
- if( b instanceof Button ) {
- final Button lb = (Button) b;
+ final List<Shape> sl = new ArrayList<Shape>();
+ sl.addAll(buttonsLeft.getShapes());
+ sl.addAll(buttonsRight.getShapes());
+ for(final Shape s : sl) {
+ if( s instanceof Button ) {
+ final Button lb = (Button) s;
final float sx = lb.getSpacingX()+dx, sy = lb.getSpacingY()+dy;
System.err.println("Spacing: X "+sx+", Y "+sy);
lb.setSpacing(sx, sy);
@@ -327,20 +336,31 @@ public class UISceneDemo20 implements GLEventListener {
}
private void setButtonsCorner(final float dc) {
- for(int i=0; i<buttons.size(); i++) {
- final float c = buttons.get(i).getCorner()+dc;
- System.err.println("Corner: "+c);
- buttons.get(i).setCorner(c);
+ final List<Shape> sl = new ArrayList<Shape>();
+ sl.addAll(buttonsLeft.getShapes());
+ sl.addAll(buttonsRight.getShapes());
+ for(final Shape s : sl) {
+ if( s instanceof RoundButton ) {
+ final RoundButton rb = (RoundButton)s;
+ final float c = rb.getCorner()+dc;
+ System.err.println("Corner: "+c);
+ rb.setCorner(c);
+ }
}
}
private void resetButtons() {
- for(int i=0; i<buttons.size(); i++) {
- final RoundButton b = buttons.get(i);
- b.getRotation().setIdentity();
- b.setCorner(RoundButton.DEFAULT_CORNER);
- if( b instanceof Button ) {
- ((Button)b).setSpacing(Button.DEFAULT_SPACING_X, Button.DEFAULT_SPACING_Y);
+ final List<Shape> sl = new ArrayList<Shape>();
+ sl.addAll(buttonsLeft.getShapes());
+ sl.addAll(buttonsRight.getShapes());
+ for(final Shape s : sl) {
+ if( s instanceof RoundButton ) {
+ final RoundButton b = (RoundButton)s;
+ b.getRotation().setIdentity();
+ b.setCorner(RoundButton.DEFAULT_CORNER);
+ if( b instanceof Button ) {
+ ((Button)b).setSpacing(Button.DEFAULT_SPACING_X, Button.DEFAULT_SPACING_Y);
+ }
}
}
}
@@ -356,24 +376,25 @@ public class UISceneDemo20 implements GLEventListener {
return scene.getShapeByName(name);
}
- private void initButtons(final GL2ES2 gl, final float scale) {
+ private void initButtons(final GL2ES2 gl) {
final boolean pass2Mode = Region.isTwoPass( renderModes ) ;
- buttons.clear();
-
- final float buttonXSize = buttonXSizeNorm * scale;
- final float buttonYSize = buttonXSize / 2.5f;
- final float button2XSize = 2f*buttonXSize;
- final float button2YSize = 2f*buttonYSize;
- System.err.println("Button Size: "+buttonXSize+" x "+buttonYSize+", scale "+scale);
- final float xStartLeft = 0f; // aligned to left edge w/ space via reshape
- final float xStartRight = -button2XSize - button2XSize/8f; // aligned to right edge via reshape
- final float yStartTop = 0f; // aligned to top edge w/ space via reshape
- final float diffX = 1.2f * buttonXSize;
- final float diffY = 1.5f * buttonYSize;
-
- Button button = new Button(renderModes, fontButtons, " Next Text ", buttonXSize, buttonYSize);
+ buttonsLeft.removeAllShapes(gl, scene.getRenderer());
+ buttonsRight.removeAllShapes(gl, scene.getRenderer());
+
+ final float buttonLWidth = buttonXSizeNorm;
+ final float buttonLHeight = buttonLWidth / 2.5f;
+ buttonsLeft.setLayout(new GridLayout(buttonLWidth, buttonLHeight, new Padding(buttonLWidth*0.1f, buttonLHeight*0.5f), 7));
+
+ final float buttonRWidth = 2f*buttonLWidth;
+ final float buttonRHeight = 2f*buttonLHeight;
+
+ buttonsRight.setLayout(new GridLayout(1, buttonRWidth, buttonRHeight, new Padding(buttonLWidth*0.1f, buttonLHeight*0.5f)));
+
+ System.err.println("Button Size: "+buttonLWidth+" x "+buttonLHeight);
+
+ RoundButton button;
+ button = new Button(renderModes, fontButtons, " Next Text ", buttonLWidth, buttonLHeight);
button.setName(BUTTON_NEXTTEXT);
- button.move(xStartLeft, yStartTop-diffY*buttons.size(), 0f);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
@@ -386,11 +407,10 @@ public class UISceneDemo20 implements GLEventListener {
}
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
+ buttonsLeft.addShape(button);
- button = new Button(renderModes, fontButtons, "Show fps", buttonXSize, buttonYSize);
+ button = new Button(renderModes, fontButtons, "Show fps", buttonLWidth, buttonLHeight);
button.setName(BUTTON_FPS);
- button.move(xStartLeft,yStartTop - diffY*buttons.size(), 0f);
button.setToggleable(true);
button.setToggle(fpsLabel.isEnabled());
button.addMouseListener(new Shape.MouseGestureAdapter() {
@@ -403,11 +423,10 @@ public class UISceneDemo20 implements GLEventListener {
fpsLabel.setEnabled(!fpsLabel.isEnabled());
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
+ buttonsLeft.addShape(button);
- button = new Button(renderModes, fontButtons, " V-Sync ", buttonXSize, buttonYSize);
+ button = new Button(renderModes, fontButtons, " V-Sync ", buttonLWidth, buttonLHeight);
button.setName(BUTTON_VSYNC);
- button.move(xStartLeft,yStartTop - diffY*buttons.size(), 0f);
button.setToggleable(true);
button.setToggle(gl.getSwapInterval()>0);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@@ -427,10 +446,9 @@ public class UISceneDemo20 implements GLEventListener {
});
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
+ buttonsLeft.addShape(button);
- button = new Button(renderModes, fontButtons, "< Tilt >", buttonXSize, buttonYSize);
- button.move(xStartLeft,yStartTop - diffY*buttons.size(), 0f);
+ button = new Button(renderModes, fontButtons, "< Tilt >", buttonLWidth, buttonLHeight);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
@@ -445,11 +463,10 @@ public class UISceneDemo20 implements GLEventListener {
public void mouseWheelMoved(final MouseEvent e) {
rotateButtons(new Vec3f( 0f, e.getRotation()[1], 0f ) );
} } );
- buttons.add(button);
+ buttonsLeft.addShape(button);
- if( pass2Mode ) { // second column to the left
- button = new Button(renderModes, fontButtons, "< Samples >", buttonXSize, buttonYSize);
- button.move(xStartLeft,yStartTop - diffY*buttons.size(), 0f);
+ if( pass2Mode ) {
+ button = new Button(renderModes, fontButtons, "< Samples >", buttonLWidth, buttonLHeight);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
@@ -465,10 +482,9 @@ public class UISceneDemo20 implements GLEventListener {
sampleCount = scene.setSampleCount(sampleCount); // validated / clipped
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
+ buttonsLeft.addShape(button);
- button = new Button(renderModes, fontButtons, "< Quality >", buttonXSize, buttonYSize);
- button.move(xStartLeft,yStartTop - diffY*buttons.size(), 0f);
+ button = new Button(renderModes, fontButtons, "< Quality >", buttonLWidth, buttonLHeight);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
@@ -491,14 +507,13 @@ public class UISceneDemo20 implements GLEventListener {
}
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
+ buttonsLeft.addShape(button);
}
- button = new Button(renderModes, fontButtons, "Quit", buttonXSize, buttonYSize);
+ button = new Button(renderModes, fontButtons, "Quit", buttonLWidth, buttonLHeight);
button.setName(BUTTON_QUIT);
- button.move(xStartLeft,yStartTop - diffY*buttons.size(), 0f);
button.setColor(0.7f, 0.0f, 0.0f, 1.0f);
- button.setLabelColor(1.2f, 1.2f, 1.2f);
+ ((Button)button).setLabelColor(1.2f, 1.2f, 1.2f);
button.setPressedColorMod(1.1f, 0.0f, 0.0f, 1.0f);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
@@ -516,36 +531,29 @@ public class UISceneDemo20 implements GLEventListener {
} }.start();
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
+ buttonsLeft.addShape(button);
// second column to the left
{
- final int j = 1; // column
- int k = 0; // row
- button = new Button(renderModes, fontButtons, "Y Flip", buttonXSize, buttonYSize);
- button.move(xStartLeft - diffX*j,yStartTop - diffY*k, 0f);
+ button = new Button(renderModes, fontButtons, "Y Flip", buttonLWidth, buttonLHeight);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
rotateButtons(new Vec3f ( 0f, 180f, 0f ));
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
+ buttonsLeft.addShape(button);
- k++;
- button = new Button(renderModes, fontButtons, "X Flip", buttonXSize, buttonYSize);
- button.move(xStartLeft - diffX*j,yStartTop - diffY*k, 0f);
+ button = new Button(renderModes, fontButtons, "X Flip", buttonLWidth, buttonLHeight);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
rotateButtons(new Vec3f ( 180f, 0f, 0f ));
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
- k++;
+ buttonsLeft.addShape(button);
- button = new Button(renderModes, fontButtons, "< Space >", buttonXSize, buttonYSize);
- button.move(xStartLeft - diffX*j,yStartTop - diffY*k, 0f);
+ button = new Button(renderModes, fontButtons, "< Space >", buttonLWidth, buttonLHeight);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
@@ -562,11 +570,9 @@ public class UISceneDemo20 implements GLEventListener {
public void mouseWheelMoved(final MouseEvent e) {
setButtonsSpacing(e.getRotation()[0]/100f, e.getRotation()[1]/200f);
} } );
- buttons.add(button);
- k++;
+ buttonsLeft.addShape(button);
- button = new Button(renderModes, fontButtons, "< Corner >", buttonXSize, buttonYSize);
- button.move(xStartLeft - diffX*j,yStartTop - diffY*k, 0f);
+ button = new Button(renderModes, fontButtons, "< Corner >", buttonLWidth, buttonLHeight);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
@@ -583,22 +589,18 @@ public class UISceneDemo20 implements GLEventListener {
public void mouseWheelMoved(final MouseEvent e) {
setButtonsCorner(e.getRotation()[1]/20f);
} } );
- buttons.add(button);
- k++;
+ buttonsLeft.addShape(button);
- button = new Button(renderModes, fontButtons, " Reset ", buttonXSize, buttonYSize);
- button.move(xStartLeft - diffX*j,yStartTop - diffY*k, 0f);
+ button = new Button(renderModes, fontButtons, " Reset ", buttonLWidth, buttonLHeight);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
resetButtons();
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
- k++;
+ buttonsLeft.addShape(button);
- button = new Button(renderModes, fontButtons, " Snapshot ", buttonXSize, buttonYSize);
- button.move(xStartLeft - diffX*j,yStartTop - diffY*k, 0f);
+ button = new Button(renderModes, fontButtons, " Snapshot ", buttonLWidth, buttonLHeight);
button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
@@ -608,12 +610,12 @@ public class UISceneDemo20 implements GLEventListener {
});
} } );
button.addMouseListener(dragZoomRotateListener);
- buttons.add(button);
- k++;
+ buttonsLeft.addShape(button);
}
- buttonsLeftCount = buttons.size();
-
+ //
+ // buttonRight
+ //
final int texUnitMediaPlayer, texUnitImageButton, texUnitGLELButton;
{
// works - but not required ..
@@ -625,27 +627,27 @@ public class UISceneDemo20 implements GLEventListener {
if( true ) {
final GLMediaPlayer mPlayer = GLMediaPlayerFactory.createDefault();
mPlayer.setTextureUnit(texUnitMediaPlayer);
- final MediaButton mPlayerButton = new MediaButton(renderModes, button2XSize,
- button2YSize, mPlayer);
- mPlayerButton.setName(BUTTON_MOVIE);
- mPlayerButton.setVerbose(false);
- mPlayerButton.addDefaultEventListener();
- mPlayerButton.move(xStartRight, yStartTop - diffY*1, 0f);
- mPlayerButton.setToggleable(true);
- mPlayerButton.setToggle(true); // toggle == false -> mute audio
- mPlayerButton.setToggleOffColorMod(0f, 1f, 0f, 1.0f);
- mPlayerButton.addMouseListener(dragZoomRotateListener);
- mPlayerButton.addMouseListener(new Shape.MouseGestureAdapter() {
+ button = new MediaButton(renderModes, buttonRWidth, buttonRHeight, mPlayer);
+ button.setName(BUTTON_MOVIE);
+ ((MediaButton)button).setVerbose(false);
+ ((MediaButton)button).addDefaultEventListener();
+ button.setToggleable(true);
+ button.setToggle(true); // toggle == false -> mute audio
+ button.setToggleOffColorMod(0f, 1f, 0f, 1.0f);
+ button.addMouseListener(dragZoomRotateListener);
+ button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
- mPlayer.setAudioVolume( mPlayerButton.isToggleOn() ? 1f : 0f );
+ final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
+ final MediaButton s = (MediaButton)info.shape;
+ mPlayer.setAudioVolume( s.isToggleOn() ? 1f : 0f );
} } );
- buttons.add(mPlayerButton);
+ buttonsRight.addShape(button);
mPlayer.playStream(filmURL, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.STREAM_ID_AUTO, GLMediaPlayer.TEXTURE_COUNT_DEFAULT);
}
if( true ) {
final ImageSequence imgSeq = new ImageSequence(texUnitImageButton, true);
- final ImageButton imgButton = new ImageButton(renderModes, button2XSize, button2YSize, imgSeq);
+ button = new ImageButton(renderModes, buttonRWidth, buttonRHeight, imgSeq);
try {
imgSeq.addFrame(gl, UISceneDemo20.class, "button-released-145x53.png", TextureIO.PNG);
imgSeq.addFrame(gl, UISceneDemo20.class, "button-pressed-145x53.png", TextureIO.PNG);
@@ -653,19 +655,22 @@ public class UISceneDemo20 implements GLEventListener {
e2.printStackTrace();
}
imgSeq.setManualStepping(true);
- imgButton.move(xStartRight, yStartTop - diffY*2.5f, 0f);
- imgButton.addMouseListener(dragZoomRotateListener);
- imgButton.addMouseListener(new Shape.MouseGestureAdapter() {
+ button.addMouseListener(dragZoomRotateListener);
+ button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mousePressed(final MouseEvent e) {
- imgButton.setCurrentIdx(1);
- System.err.println("XXX: "+imgButton);
+ final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
+ final ImageButton s = (ImageButton)info.shape;
+ s.setCurrentIdx(1);
+ System.err.println("XXX: "+s);
}
@Override
public void mouseReleased(final MouseEvent e) {
- imgButton.setCurrentIdx(0);
+ final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
+ final ImageButton s = (ImageButton)info.shape;
+ s.setCurrentIdx(0);
} } );
- buttons.add(imgButton);
+ buttonsRight.addShape(button);
}
if( true ) {
// Issues w/ OSX and NewtCanvasAWT when rendering / animating
@@ -694,21 +699,22 @@ public class UISceneDemo20 implements GLEventListener {
System.err.println("Gears Anim: End");
}
}).start();
- final GLButton b = new GLButton(renderModes, button2XSize, button2YSize,
- texUnitGLELButton, gears, false /* useAlpha */);
- b.setName(BUTTON_GLEL);
- b.setToggleable(true);
- b.setToggle(false); // toggle == true -> animation
- b.setAnimate(false);
- b.move(xStartRight, yStartTop - diffY*4f, 0f);
- b.addMouseListener(dragZoomRotateListener);
- b.addMouseListener(new Shape.MouseGestureAdapter() {
+ button = new GLButton(renderModes, buttonRWidth, buttonRHeight,
+ texUnitGLELButton, gears, false /* useAlpha */);
+ button.setName(BUTTON_GLEL);
+ button.setToggleable(true);
+ button.setToggle(false); // toggle == true -> animation
+ ((GLButton)button).setAnimate(false);
+ button.addMouseListener(dragZoomRotateListener);
+ button.addMouseListener(new Shape.MouseGestureAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
- b.setAnimate( b.isToggleOn() );
- animate[0] = b.getAnimate();
+ final Shape.EventInfo info = (Shape.EventInfo)e.getAttachment();
+ final GLButton s = (GLButton)info.shape;
+ s.setAnimate( s.isToggleOn() );
+ animate[0] = s.getAnimate();
} } );
- buttons.add(b);
+ buttonsRight.addShape(button);
}
}
@@ -820,6 +826,7 @@ public class UISceneDemo20 implements GLEventListener {
initTexts();
initLabels(gl);
+ initButtons(gl);
scene.init(drawable);
@@ -848,31 +855,23 @@ public class UISceneDemo20 implements GLEventListener {
final float sceneWidth = sceneBox.getWidth();
final float sceneHeight = sceneBox.getHeight();
final float button_sxy = sceneWidth > sceneHeight ? sceneWidth : sceneHeight;
- if( buttons.isEmpty() ) {
- initButtons(drawable.getGL().getGL2ES2(), button_sxy);
- scene.addShapes(buttons);
- }
- final float dw = sceneWidth - lastSceneWidth;
- final float dh = sceneHeight - lastSceneHeight;
+ buttonsLeft.validate(drawable.getGL().getGL2ES2());
+ buttonsRight.validate(drawable.getGL().getGL2ES2());
- final float dz = 0f;
- final float dyTop = dh * relTop;
- final float dxLeft = dw * relLeft;
- final float dxRight = dw;
-
- System.err.println("XXX: dw "+dw+", dh "+dh+", dxLeft "+dxLeft+", dxRight "+dxRight+", dyTop "+dyTop);
+ buttonsLeft.setScale(button_sxy, button_sxy, 1f);
+ buttonsRight.setScale(button_sxy, button_sxy, 1f);
- for(int i=0; i<buttons.size() && i<buttonsLeftCount; i++) {
- // System.err.println("Button["+i+"].L0: "+buttons.get(i));
- buttons.get(i).move(dxLeft, dyTop, dz);
- // System.err.println("Button["+i+"].LM: "+buttons.get(i));
- }
- for(int i=buttonsLeftCount; i<buttons.size(); i++) {
- // System.err.println("Button["+i+"].R0: "+buttons.get(i));
- buttons.get(i).move(dxRight, dyTop, dz);
- // System.err.println("Button["+i+"].RM: "+buttons.get(i));
- }
+ final float dz = 0f;
+ final float dyTop = sceneHeight * relTop;
+
+ System.err.println("XXX: dw "+sceneWidth+", dh "+sceneHeight+", dyTop "+dyTop);
+ System.err.println("BL "+buttonsLeft);
+ System.err.println("BL "+buttonsLeft.getLayout());
+ System.err.println("BR "+buttonsRight);
+ System.err.println("BR "+buttonsRight.getLayout());
+ buttonsLeft.moveTo(0f, dyTop - buttonsLeft.getScaledHeight(), dz);
+ buttonsRight.moveTo(sceneWidth - buttonsRight.getScaledWidth(), dyTop - buttonsRight.getScaledHeight(), dz);
jogampLabel.setScale(sceneHeight, sceneHeight, 1f);
diff --git a/src/graphui/classes/com/jogamp/graph/ui/Group.java b/src/graphui/classes/com/jogamp/graph/ui/Group.java
index b3ae5b41d..e349b1302 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/Group.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/Group.java
@@ -48,10 +48,22 @@ import jogamp.graph.ui.TreeTool;
* @see Group.Layout
*/
public class Group extends Shape implements Container {
- /** Layout for the group, called @ {@link Group#validate(GL2ES2)} or {@link Group#validate(GLProfile)}. */
+ /** Layout for the GraphUI {@link Group}, called @ {@link Shape#validate(GL2ES2)} or {@link Shape#validate(GLProfile)}. */
public static interface Layout {
- /** Performing the layout, called @ {@link Group#validate(GL2ES2)} or {@link Group#validate(GLProfile)}. */
- void layout(Group g);
+ /**
+ * Performing the layout of {@link Group#getShapes()}, called @ {@link Shape#validate(GL2ES2)} or {@link Shape#validate(GLProfile)}.
+ * <p>
+ * According to the implemented layout, method
+ * - may scale the {@Link Shape}s
+ * - may move the {@Link Shape}s
+ * - may reuse the given {@link PMVMatrix} `pmv`
+ * - must update the given {@link AABBox} `box`
+ * </p>
+ * @param g the {@link Group} to layout
+ * @param box the bounding box of {@link Group} to be updated by this method.
+ * @param pmv a {@link PMVMatrix} which can be reused.
+ */
+ void layout(final Group g, final AABBox box, final PMVMatrix pmv);
}
private final List<Shape> shapes = new ArrayList<Shape>();
@@ -161,12 +173,6 @@ public class Group extends Shape implements Container {
}
}
- private void layout() {
- if( null != layouter ) {
- layouter.layout(this);
- }
- }
-
private boolean doFrustumCulling = false;
@Override
@@ -200,21 +206,25 @@ public class Group extends Shape implements Container {
@Override
protected void validateImpl(final GLProfile glp, final GL2ES2 gl) {
if( isShapeDirty() ) {
- layout();
final PMVMatrix pmv = new PMVMatrix();
final AABBox tmpBox = new AABBox();
for(final Shape s : shapes) {
- // s.validateImpl(glp, gl);
if( null != gl ) {
s.validate(gl);
} else {
s.validate(glp);
}
- pmv.glPushMatrix();
- s.setTransform(pmv);
- s.getBounds().transformMv(pmv, tmpBox);
- pmv.glPopMatrix();
- box.resize(tmpBox);
+ }
+ if( null != layouter ) {
+ layouter.layout(this, box, pmv);
+ } else {
+ for(final Shape s : shapes) {
+ pmv.glPushMatrix();
+ s.setTransform(pmv);
+ s.getBounds().transformMv(pmv, tmpBox);
+ pmv.glPopMatrix();
+ box.resize(tmpBox);
+ }
}
}
}
@@ -249,6 +259,11 @@ public class Group extends Shape implements Container {
}
@Override
+ public String getSubString() {
+ return super.getSubString()+", shapes "+shapes.size();
+ }
+
+ @Override
public boolean forOne(final PMVMatrix pmv, final Shape shape, final Runnable action) {
return TreeTool.forOne(shapes, pmv, shape, action);
}
diff --git a/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java b/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java
index bd2fd2d76..7d1739dd6 100644
--- a/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java
+++ b/src/graphui/classes/com/jogamp/graph/ui/layout/GridLayout.java
@@ -1,5 +1,5 @@
/**
- * Copyright 2010-2023 JogAmp Community. All rights reserved.
+ * Copyright 2023 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:
@@ -27,43 +27,135 @@
*/
package com.jogamp.graph.ui.layout;
+import java.util.List;
+
+import com.jogamp.graph.ui.GraphShape;
import com.jogamp.graph.ui.Group;
import com.jogamp.graph.ui.Shape;
-import com.jogamp.graph.ui.Group.Layout;
+import com.jogamp.opengl.math.geom.AABBox;
+import com.jogamp.opengl.util.PMVMatrix;
+/**
+ * GraphUI Grid {@link Group.Layout}.
+ */
public class GridLayout implements Group.Layout {
- private final int columns;
- private final float padX, padY;
+ /** Layout order for {@link Group#getShapes()}} after population. */
+ public static enum Order {
+ /** COLUMN layout order of {@link Group#getShapes()}} is left to right and top to bottom. */
+ COLUMN,
+ /** ROW layout order of {@link Group#getShapes()}} is top to bottom and left to right. */
+ ROW
+ }
+ private final Order order;
+ private final int col_limit;
+ private final int row_limit;
+ private final float cellWidth, cellHeight;
+ private final Padding padding;
+ private int row_count, col_count;
+
+
+ /**
+ * Default layout order of {@link Group#getShapes()}} is {@link Order#COLUMN}.
+ * @param column_limit [1..inf)
+ * @param cellWidth
+ * @param cellHeight
+ */
+ public GridLayout(final int column_limit, final float cellWidth, final float cellHeight) {
+ this(Math.max(1, column_limit), -1, cellWidth, cellHeight, new Padding());
+ }
+
+ /**
+ * Default layout order of {@link Group#getShapes()}} is {@link Order#COLUMN}.
+ * @param column_limit [1..inf)
+ * @param cellWidth
+ * @param cellHeight
+ * @param padding
+ */
+ public GridLayout(final int column_limit, final float cellWidth, final float cellHeight, final Padding padding) {
+ this(Math.max(1, column_limit), -1, cellWidth, cellHeight, padding);
+ }
/**
- *
- * @param columns [1..inf)
- * @param padX
- * @param padY
+ * Default layout order of {@link Group#getShapes()}} is {@link Order#ROW}.
+ * @param cellWidth
+ * @param cellHeight
+ * @param padding
+ * @param row_limit [1..inf)
*/
- public GridLayout(final int columns, final float padX, final float padY) {
- this.columns = Math.max(1, columns);
- this.padX = padX;
- this.padY = padY;
+ public GridLayout(final float cellWidth, final float cellHeight, final Padding padding, final int row_limit) {
+ this(-1, Math.max(1, row_limit), cellWidth, cellHeight, padding);
+ }
+
+ private GridLayout(final int column_limit, final int row_limit, final float cellWidth, final float cellHeight, final Padding padding) {
+ this.order = 0 < column_limit ? Order.COLUMN : Order.ROW;
+ this.col_limit = column_limit;
+ this.row_limit = row_limit;
+ this.cellWidth = cellWidth;
+ this.cellHeight = cellHeight;
+ this.padding = padding;;
+ row_count = 0;
+ col_count = 0;
}
+ public Order getOrder() { return order; }
+ public int getColumnCount() { return col_count; }
+ public int getRowCount() { return row_count; }
+
@Override
- public void layout(final Group g) {
- int col = 0;
- float x=0;
- float y=0;
- for(final Shape s : g.getShapes()) {
- s.moveTo(x, y, 0);
- if( col + 1 == columns ) {
- col = 0;
- // row++;
- x = 0;
- y -= padY;
- } else {
- col++;
- x += padX;
+ public void layout(final Group g, final AABBox box, final PMVMatrix pmv) {
+ final List<Shape> shapes = g.getShapes();
+ if( Order.COLUMN == order ) {
+ row_count = (int) Math.ceil( (double)shapes.size() / (double)col_limit );
+ col_count = col_limit;
+ } else { // Order.ROW_MAJOR == order
+ row_count = row_limit;
+ col_count = (int) Math.ceil( (double)shapes.size() / (double)row_limit );
+ }
+ int col_i = 0, row_i = 0;
+ final AABBox sbox = new AABBox();
+ for(final Shape s : shapes) {
+ // measure size
+ pmv.glPushMatrix();
+ s.setTransform(pmv);
+ s.getBounds().transformMv(pmv, sbox);
+ pmv.glPopMatrix();
+
+ // adjust size and position (centered)
+ final float x = ( ( col_i ) * ( cellWidth + padding.width() ) ) + padding.left;
+ final float y = ( ( row_count - row_i - 1 ) * ( cellHeight + padding.height() ) ) + padding.bottom;
+ final float sx = cellWidth / sbox.getWidth();
+ final float sy = cellHeight/ sbox.getHeight();
+ final float sxy = sx < sy ? sx : sy;
+ final float dxh = sbox.getWidth() * ( sx - sxy ) * 0.5f;
+ final float dyh = sbox.getHeight() * ( sy - sxy ) * 0.5f;
+ s.moveTo( x + dxh, y + dyh, 0f );
+ s.scale( sxy, sxy, 1f);
+ box.resize( x + cellWidth + padding.right, y + cellHeight + padding.top, 0);
+ box.resize( x - padding.left, y - padding.bottom, 0);
+ // System.err.println("["+row_i+"]["+col_i+"]: "+x+" / "+y);
+
+ // position for next cell
+ if( Order.COLUMN == order ) {
+ if( col_i + 1 == col_limit ) {
+ col_i = 0;
+ row_i++;
+ } else {
+ col_i++;
+ }
+ } else { // Order.ROW_MAJOR == order
+ if( row_i + 1 == row_limit ) {
+ row_i = 0;
+ col_i++;
+ } else {
+ row_i++;
+ }
}
}
}
+
+ @Override
+ public String toString() {
+ return "Grid["+row_count+"x"+col_count+", "+order+", cell["+cellWidth+" x "+cellHeight+"], "+padding+"]";
+ }
}
diff --git a/src/graphui/classes/com/jogamp/graph/ui/layout/Padding.java b/src/graphui/classes/com/jogamp/graph/ui/layout/Padding.java
new file mode 100644
index 000000000..f4b35e723
--- /dev/null
+++ b/src/graphui/classes/com/jogamp/graph/ui/layout/Padding.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2023 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.layout;
+
+/**
+ * GraphUI Padding of cells, e.g. {@link GridLayout}.
+ */
+public class Padding {
+ public final float left, right, bottom, top;
+
+ public Padding() {
+ left = 0f; right = 0f; bottom = 0f; top = 0f;
+ }
+ public Padding(final float width, final float height) {
+ left = width/2f; right = width/2f; bottom = height/2f; top = height/2f;
+ }
+ public Padding(final float left, final float right, final float bottom, final float top) {
+ this.left = left; this.right = right; this.bottom = bottom; this.top = top;
+ }
+ public float width() { return left + right; }
+ public float height() { return bottom + top; }
+ @Override
+ public String toString() { return "Padding[l "+left+", r "+right+", b "+bottom+", t "+top+"]"; }
+}