From a9c76153fd9a472679c1fc85189f6d4ecda7979e Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 29 Apr 2023 03:13:01 +0200 Subject: GraphUI Working GridLayout w/ and w/o cell-size and alignment; Added BoxLayout. --- .../jogamp/opengl/demos/graph/ui/FontView01.java | 28 +- .../opengl/demos/graph/ui/UILayoutBox01.java | 301 ++++++++++++ .../opengl/demos/graph/ui/UILayoutGrid01.java | 503 +++++++++++++++++++++ .../opengl/demos/graph/ui/UISceneDemo03.java | 2 +- .../opengl/demos/graph/ui/UISceneDemo03b.java | 48 +- .../opengl/demos/graph/ui/UISceneDemo11.java | 5 +- .../opengl/demos/graph/ui/UISceneDemo12.java | 224 --------- .../opengl/demos/graph/ui/UISceneDemo20.java | 48 +- 8 files changed, 880 insertions(+), 279 deletions(-) create mode 100644 src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutBox01.java create mode 100644 src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutGrid01.java delete mode 100644 src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo12.java (limited to 'src/demos') diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java index 8803fbf14..a8d82fcc4 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/FontView01.java @@ -40,8 +40,9 @@ import com.jogamp.graph.font.FontScale; import com.jogamp.graph.ui.Group; import com.jogamp.graph.ui.Scene; import com.jogamp.graph.ui.Shape; +import com.jogamp.graph.ui.layout.Alignment; +import com.jogamp.graph.ui.layout.Gap; import com.jogamp.graph.ui.layout.GridLayout; -import com.jogamp.graph.ui.layout.Padding; import com.jogamp.graph.ui.shapes.GlyphShape; import com.jogamp.graph.ui.shapes.Label; import com.jogamp.graph.ui.shapes.Rectangle; @@ -62,11 +63,11 @@ import com.jogamp.opengl.util.Animator; * This may become a little font viewer application, having FontForge as its role model. */ public class FontView01 { - private static float gridWidth = 2/3f; + private static float GlyphGridWidth = 2/3f; static GraphUIDemoArgs options = new GraphUIDemoArgs(1280, 720, Region.VBAA_RENDERING_BIT); public static void main(final String[] args) throws IOException { - float mmPerCell = 10f; + float mmPerCell = 8f; String fontfilename = null; int gridCols = -1; int gridRows = -1; @@ -153,15 +154,16 @@ public class FontView01 { System.err.println("mmPerCell "+mmPerCell); } if( 0 >= gridCols ) { - gridCols = (int)( ( window.getSurfaceWidth() * gridWidth / ppmm[0] ) / mmPerCell ); + gridCols = (int)( ( window.getSurfaceWidth() * GlyphGridWidth / ppmm[0] ) / mmPerCell ); } if( 0 >= gridRows ) { gridRows = (int)( ( window.getSurfaceHeight() / ppmm[1] ) / mmPerCell ); } final int cellCount = gridCols * gridRows; + final float gridSize = gridCols > gridRows ? 1f/gridCols : 1f/gridRows; System.err.println("Grid "+gridCols+" x "+gridRows+", "+cellCount+" cells, gridSize "+gridSize); - final Group mainGrid = new Group(new GridLayout(gridCols, gridSize, gridSize, new Padding(gridSize*0.05f, gridSize*0.05f))); + final Group mainGrid = new Group(new GridLayout(gridCols, gridSize, gridSize, Alignment.Fill, new Gap(gridSize*0.10f))); final Group glyphCont = new Group(); { @@ -175,7 +177,7 @@ public class FontView01 { glyphInfo.setColor(0.1f, 0.1f, 0.1f, 1.0f); infoCont.addShape(glyphInfo); } - final Group infoGrid = new Group(new GridLayout(1/2f, 1/2f, new Padding(1/2f*0.005f, 1/2f*0.005f), 2)); + final Group infoGrid = new Group(new GridLayout(1/2f, 1/2f, Alignment.Fill, new Gap(1/2f*0.01f), 2)); infoGrid.addShape(glyphCont); infoGrid.addShape(infoCont); @@ -243,19 +245,19 @@ public class FontView01 { final AABBox sceneBox = scene.getBounds(); System.err.println("SceneBox "+sceneBox); final AABBox mainGridBox = mainGrid.getBounds(); - final float sgxy; - if( mainGridBox.getWidth() > mainGridBox.getHeight() ) { - sgxy = sceneBox.getWidth() * gridWidth / mainGridBox.getWidth(); - } else { - sgxy = sceneBox.getHeight() / mainGridBox.getHeight(); + final float sxy; + { + final float sx = sceneBox.getWidth() * GlyphGridWidth / mainGridBox.getWidth(); + final float sy = sceneBox.getHeight() / mainGridBox.getHeight(); + sxy = sx < sy ? sx : sy; } - mainGrid.scale(sgxy, sgxy, 1f); + mainGrid.scale(sxy, sxy, 1f); mainGrid.moveTo(sceneBox.getMinX(), sceneBox.getMinY(), 0f); scene.addShape(mainGrid); // late add at correct position and size System.err.println("Grid "+mainGrid); System.err.println("Grid "+mainGrid.getLayout()); System.err.println("Grid[0] "+mainGrid.getShapes().get(0)); - final float rightWidth = sceneBox.getWidth() * ( 1f - gridWidth ); + final float rightWidth = sceneBox.getWidth() * ( 1f - GlyphGridWidth ); { final float icScale = sceneBox.getHeight(); infoGrid.validate(reqGLP); diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutBox01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutBox01.java new file mode 100644 index 000000000..754614ed4 --- /dev/null +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutBox01.java @@ -0,0 +1,301 @@ +/** + * Copyright 2010-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.opengl.demos.graph.ui; + +import java.io.IOException; + +import com.jogamp.graph.curve.Region; +import com.jogamp.graph.font.Font; +import com.jogamp.graph.font.FontFactory; +import com.jogamp.graph.font.FontSet; +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.BoxLayout; +import com.jogamp.graph.ui.layout.Margin; +import com.jogamp.graph.ui.layout.Padding; +import com.jogamp.graph.ui.shapes.Button; +import com.jogamp.graph.ui.shapes.Label; +import com.jogamp.graph.ui.shapes.Rectangle; +import com.jogamp.graph.ui.shapes.BaseButton; +import com.jogamp.newt.event.MouseEvent; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.GL; +import com.jogamp.opengl.GLCapabilities; +import com.jogamp.opengl.GLProfile; +import com.jogamp.opengl.demos.graph.ui.util.GraphUIDemoArgs; +import com.jogamp.opengl.fixedfunc.GLMatrixFunc; +import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.opengl.math.Recti; +import com.jogamp.opengl.math.Vec3f; +import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.PMVMatrix; + +/** + * Res independent {@link Shape}s in a {@link Group} using a {@link BoxLayout}, contained within a Scene attached to GLWindow. + *

+ * Pass '-keep' to main-function to keep running after animation, + * then user can test Shape drag-move and drag-resize w/ 1-pointer. + *

+ */ +public class UILayoutBox01 { + static GraphUIDemoArgs options = new GraphUIDemoArgs(1280, 720, Region.VBAA_RENDERING_BIT); + + /** + * Our PMVMatrixSetup: + * - gluPerspective like Scene's default + * - no normal scale to 1, keep a longer distance to near plane for rotation effects. We scale Shapes + */ + public static class MyPMVMatrixSetup implements PMVMatrixSetup { + static float Z_DIST = -1f; + @Override + public void set(final PMVMatrix pmv, final Recti viewport) { + final float ratio = (float)viewport.width()/(float)viewport.height(); + pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmv.glLoadIdentity(); + pmv.gluPerspective(Scene.DEFAULT_ANGLE, ratio, Scene.DEFAULT_ZNEAR, Scene.DEFAULT_ZFAR); + pmv.glTranslatef(0f, 0f, Z_DIST); // Scene.DEFAULT_SCENE_DIST); + + pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmv.glLoadIdentity(); + } + + @Override + public void setPlaneBox(final AABBox planeBox, final PMVMatrix pmv, final Recti viewport) { + final float orthoDist = -Z_DIST; // Scene.DEFAULT_SCENE_DIST; + final Vec3f obj00Coord = new Vec3f(); + final Vec3f obj11Coord = new Vec3f(); + + Scene.winToPlaneCoord(pmv, viewport, Scene.DEFAULT_ZNEAR, Scene.DEFAULT_ZFAR, viewport.x(), viewport.y(), orthoDist, obj00Coord); + Scene.winToPlaneCoord(pmv, viewport, Scene.DEFAULT_ZNEAR, Scene.DEFAULT_ZFAR, viewport.width(), viewport.height(), orthoDist, obj11Coord); + + planeBox.setSize( obj00Coord, obj11Coord ); + } + }; + + static final boolean reLayout = false; + + public static void main(final String[] args) throws IOException { + if( 0 != args.length ) { + final int[] idx = { 0 }; + for (idx[0] = 0; idx[0] < args.length; ++idx[0]) { + if( options.parse(args, idx) ) { + continue; + } + } + } + System.err.println(options); + + final GLProfile reqGLP = GLProfile.get(options.glProfileName); + System.err.println("GLProfile: "+reqGLP); + + final Animator animator = new Animator(); + + final GLCapabilities caps = new GLCapabilities(reqGLP); + caps.setAlphaBits(4); + if( options.sceneMSAASamples > 0 ) { + caps.setSampleBuffers(true); + caps.setNumSamples(options.sceneMSAASamples); + } + System.out.println("Requested: " + caps); + + final GLWindow window = GLWindow.create(caps); + window.setSize(options.surface_width, options.surface_height); + window.setTitle(UILayoutBox01.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight()); + window.addWindowListener(new WindowAdapter() { + @Override + public void windowResized(final WindowEvent e) { + window.setTitle(UILayoutBox01.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight()); + } + @Override + public void windowDestroyNotify(final WindowEvent e) { + animator.stop(); + } + }); + + + final Scene scene = new Scene(); + scene.setPMVMatrixSetup(new MyPMVMatrixSetup()); + scene.setClearParams(new float[] { 1f, 1f, 1f, 1f}, GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + scene.setFrustumCullingEnabled(true); + scene.attachInputListenerTo(window); + window.addGLEventListener(scene); + window.setVisible(true); + scene.waitUntilDisplayed(); + + animator.setUpdateFPSFrames(1*60, null); // System.err); + animator.add(window); + animator.start(); + + /** + * We can share this instance w/ all UI elements, + * since only mouse action / gesture is complete for a single one (press, drag, released and click). + */ + final Shape.MouseGestureAdapter dragZoomRotateListener = new Shape.MouseGestureAdapter() { + @Override + public void mouseWheelMoved(final MouseEvent e) { + final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment(); + final Shape shape = shapeEvent.shape; + final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f ); + // swap axis for onscreen rotation matching natural feel + final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp ); + shape.getRotation().rotateByEuler( rot.scale( 2f ) ); + } + }; + + // + // Resolution independent, no screen size + // + final Font font = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_SERIF); + System.err.println("Font: "+font.getFullFamilyName()); + + final AABBox sceneBox = scene.getBounds(); + System.err.println("SceneBox "+sceneBox); + + final float sxy = 1/8f * sceneBox.getWidth(); + float nextPos = 0; + + final Group groupA0 = new Group(new BoxLayout( new Padding(0.15f, 0.15f) ) ); + { + groupA0.addShape( new BaseButton(options.renderModes, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) ); + groupA0.addShape( new Button(options.renderModes, font, "stack-0", 0.50f, 0.50f/2f).setCorner(0f).setDragAndResizeable(false) ); + groupA0.addShape( new Label(options.renderModes, font, 0.70f/4f, "A0 pajq").setDragAndResizeable(false).setColor(0, 0, 1, 1) ); + } + groupA0.setInteractive(true); + groupA0.addMouseListener(dragZoomRotateListener); + groupA0.scale(sxy, sxy, 1); + groupA0.moveTo(sceneBox.getLow()).move(nextPos, 0, 0); + 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; }); + scene.addShape(groupA0); + scene.addShape( new Rectangle(options.renderModes, 1f, 1f, 0.01f).scale(sxy, sxy, 1).moveTo(sceneBox.getLow()).move(nextPos, 0, 0).setInteractive(false).setColor(0, 0, 0, 1) ); + nextPos = groupA0.getScaledWidth() * 1.5f; + + final Group groupA1 = new Group(new BoxLayout( 1f, 1f, new Margin(0.05f, 0.05f), new Padding(0.10f, 0.10f) ) ); + { + // groupA1.addShape( new BaseButton(options.renderModes, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) ); + groupA1.addShape( new BaseButton(options.renderModes | Region.COLORCHANNEL_RENDERING_BIT, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) + .setBorder(0.01f).setPaddding(new Padding(0.0f)) ); + groupA1.addShape( new Button(options.renderModes, font, "stack-1", 0.50f, 0.50f/2f).setCorner(0f).addMouseListener(dragZoomRotateListener) ); + groupA1.addShape( new Label(options.renderModes, font, 0.70f/4f, "A1 pajq").setDragAndResizeable(false).setColor(0, 0, 1, 1) ); + } + // groupA1.setInteractive(true); + groupA1.scale(sxy, sxy, 1); + groupA1.moveTo(sceneBox.getLow()).move(nextPos, 0, 0); + groupA1.validate(reqGLP); + System.err.println("Group-A1 "+groupA1); + System.err.println("Group-A1 Layout "+groupA1.getLayout()); + groupA1.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupA1); + // scene.addShape( new Rectangle(options.renderModes, 1f, 1f, 0.01f).scale(sxy, sxy, 1).moveTo(sceneBox.getLow()).move(nextPos, 0, 0).setInteractive(false).setColor(0, 0, 0, 1) ); + scene.addShape( new Button(options.renderModes, font, "stack-1b", 0.50f, 0.50f/2f).setCorner(0f) + .scale(sxy, sxy, 1f).moveTo(sceneBox.getLow()).move(nextPos, groupA1.getScaledHeight(), 0) + .addMouseListener(dragZoomRotateListener) ); + + nextPos += groupA1.getScaledWidth() * 1.5f; + + final Group groupA2 = new Group(new BoxLayout( 1f, 1f, new Margin(0.10f, Margin.CENTER), new Padding(0.05f, 0) ) ); + { + // groupA2.addShape( new BaseButton(options.renderModes, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) ); + groupA2.addShape( new BaseButton(options.renderModes | Region.COLORCHANNEL_RENDERING_BIT, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) + .setBorder(0.01f).setPaddding(new Padding(0.0f)).setBorderColor(1, 0, 0, 1) ); + groupA2.addShape( new Button(options.renderModes, font, "stack-2", 0.50f, 0.50f/2f).setCorner(0f).setDragAndResizeable(false) ); + groupA2.addShape( new Label(options.renderModes, font, 0.70f/4f, "A2 pajq").setDragAndResizeable(false).setColor(0, 0, 1, 1) ); + } + groupA2.setInteractive(true); + groupA2.scale(sxy, sxy, 1); + groupA2.moveTo(sceneBox.getLow()).move(nextPos, 0, 0); + groupA2.validate(reqGLP); + System.err.println("Group-A2 "+groupA2); + System.err.println("Group-A2 Layout "+groupA2.getLayout()); + groupA2.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupA2); + // scene.addShape( new Rectangle(options.renderModes, 1f, 1f, 0.01f).scale(sxy, sxy, 1).moveTo(sceneBox.getLow()).move(nextPos, 0, 0).setInteractive(false).setColor(0, 0, 0, 1) ); + nextPos += groupA2.getScaledWidth() * 1.5f; + + final Group groupA3 = new Group(new BoxLayout( 1f, 1f, new Margin(0.10f, Margin.CENTER), new Padding(0.05f, 0f) ) ); + { + // groupA3.addShape( new BaseButton(options.renderModes, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) ); + groupA3.addShape( new BaseButton(options.renderModes | Region.COLORCHANNEL_RENDERING_BIT, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) + .setBorder(0.01f).setPaddding(new Padding(0.0f)).setBorderColor(0, 0, 1, 1) ); + groupA3.addShape( new Button(options.renderModes, font, "stack-3", 0.50f, 0.50f/2f).setCorner(0f).setDragAndResizeable(false) ); + groupA3.addShape( new Label(options.renderModes, font, 0.70f/4f, "A3 pajq").setDragAndResizeable(false).setColor(0, 0, 1, 1) ); + } + groupA3.scale(sxy, sxy, 1); + groupA3.moveTo(sceneBox.getLow()).move(nextPos, 0, 0); + groupA3.validate(reqGLP); + System.err.println("Group-A3 "+groupA3); + System.err.println("Group-A3 Layout "+groupA3.getLayout()); + groupA3.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupA3); + // scene.addShape( new Rectangle(options.renderModes, 1f, 1f, 0.01f).scale(sxy, sxy, 1).moveTo(sceneBox.getLow()).move(nextPos, 0, 0).setInteractive(false).setColor(0, 0, 0, 1) ); + nextPos += groupA3.getScaledWidth() * 1.5f; + + final Group groupA4 = new Group(new BoxLayout( 1f, 1f, new Margin(Margin.CENTER), new Padding(0.0f, 0f) ) ); + { + // groupA4.addShape( new BaseButton(options.renderModes, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) ); + groupA4.addShape( new BaseButton(options.renderModes | Region.COLORCHANNEL_RENDERING_BIT, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) + .setBorder(0.01f).setPaddding(new Padding(0.0f)).setBorderColor(0f, 0f, 0f, 1) ); + groupA4.addShape( new Button(options.renderModes, font, "stack-4", 0.50f, 0.50f/2f).setCorner(0f).setDragAndResizeable(false) ); + groupA4.addShape( new Label(options.renderModes, font, 0.70f/4f, "A4 pajq").setDragAndResizeable(false).setColor(0, 0, 1, 1) ); + } + groupA4.scale(sxy, sxy, 1); + groupA4.moveTo(sceneBox.getLow()).move(nextPos, 0, 0); + groupA4.validate(reqGLP); + System.err.println("Group-A4 "+groupA4); + System.err.println("Group-A4 Layout "+groupA4.getLayout()); + groupA4.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupA4); + // scene.addShape( new Rectangle(options.renderModes, 1f, 1f, 0.01f).scale(sxy, sxy, 1).moveTo(sceneBox.getLow()).move(nextPos, 0, 0).setInteractive(false).setColor(0, 0, 0, 1) ); + nextPos += groupA4.getScaledWidth() * 1.5f; + + if( reLayout ) { + try { Thread.sleep(1000); } catch (final InterruptedException e1) { } + groupA4.markShapeDirty(); + groupA4.validate(reqGLP); + System.err.println("Group-A4.2 "+groupA4); + System.err.println("Group-A4 Layout.2 "+groupA4.getLayout()); + } + + // + // + // + nextPos = 0; + + try { Thread.sleep(1000); } catch (final InterruptedException e1) { } + if( !options.stayOpen ) { + window.destroy(); + } + } +} diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutGrid01.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutGrid01.java new file mode 100644 index 000000000..a62a5a65a --- /dev/null +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UILayoutGrid01.java @@ -0,0 +1,503 @@ +/** + * Copyright 2010-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.opengl.demos.graph.ui; + +import java.io.IOException; + +import com.jogamp.graph.curve.Region; +import com.jogamp.graph.font.Font; +import com.jogamp.graph.font.FontFactory; +import com.jogamp.graph.font.FontSet; +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.Alignment; +import com.jogamp.graph.ui.layout.Gap; +import com.jogamp.graph.ui.layout.GridLayout; +import com.jogamp.graph.ui.layout.Padding; +import com.jogamp.graph.ui.shapes.Button; +import com.jogamp.newt.event.MouseEvent; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.GL; +import com.jogamp.opengl.GLCapabilities; +import com.jogamp.opengl.GLProfile; +import com.jogamp.opengl.demos.graph.ui.util.GraphUIDemoArgs; +import com.jogamp.opengl.fixedfunc.GLMatrixFunc; +import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.opengl.math.Recti; +import com.jogamp.opengl.math.Vec3f; +import com.jogamp.opengl.math.Vec4f; +import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.opengl.util.Animator; +import com.jogamp.opengl.util.PMVMatrix; + +/** + * Res independent {@link Shape}s in a {@link Group} using a {@link GridLayout}, contained within a Scene attached to GLWindow. + *

+ * Pass '-keep' to main-function to keep running after animation, + * then user can test Shape drag-move and drag-resize w/ 1-pointer. + *

+ */ +public class UILayoutGrid01 { + static GraphUIDemoArgs options = new GraphUIDemoArgs(1280, 720, Region.VBAA_RENDERING_BIT); + + /** + * Our PMVMatrixSetup: + * - gluPerspective like Scene's default + * - no normal scale to 1, keep a longer distance to near plane for rotation effects. We scale Shapes + */ + public static class MyPMVMatrixSetup implements PMVMatrixSetup { + static float Z_DIST = -1f; + @Override + public void set(final PMVMatrix pmv, final Recti viewport) { + final float ratio = (float)viewport.width()/(float)viewport.height(); + pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION); + pmv.glLoadIdentity(); + pmv.gluPerspective(Scene.DEFAULT_ANGLE, ratio, Scene.DEFAULT_ZNEAR, Scene.DEFAULT_ZFAR); + pmv.glTranslatef(0f, 0f, Z_DIST); // Scene.DEFAULT_SCENE_DIST); + + pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); + pmv.glLoadIdentity(); + } + + @Override + public void setPlaneBox(final AABBox planeBox, final PMVMatrix pmv, final Recti viewport) { + final float orthoDist = -Z_DIST; // Scene.DEFAULT_SCENE_DIST; + final Vec3f obj00Coord = new Vec3f(); + final Vec3f obj11Coord = new Vec3f(); + + Scene.winToPlaneCoord(pmv, viewport, Scene.DEFAULT_ZNEAR, Scene.DEFAULT_ZFAR, viewport.x(), viewport.y(), orthoDist, obj00Coord); + Scene.winToPlaneCoord(pmv, viewport, Scene.DEFAULT_ZNEAR, Scene.DEFAULT_ZFAR, viewport.width(), viewport.height(), orthoDist, obj11Coord); + + planeBox.setSize( obj00Coord, obj11Coord ); + } + }; + + static final boolean reLayout = false; + static final int reLayoutSleep = 500; + + public static void main(final String[] args) throws IOException { + if( 0 != args.length ) { + final int[] idx = { 0 }; + for (idx[0] = 0; idx[0] < args.length; ++idx[0]) { + if( options.parse(args, idx) ) { + continue; + } + } + } + options.renderModes |= Region.COLORCHANNEL_RENDERING_BIT; + System.err.println(options); + + final GLProfile reqGLP = GLProfile.get(options.glProfileName); + System.err.println("GLProfile: "+reqGLP); + + final Animator animator = new Animator(); + + final GLCapabilities caps = new GLCapabilities(reqGLP); + caps.setAlphaBits(4); + if( options.sceneMSAASamples > 0 ) { + caps.setSampleBuffers(true); + caps.setNumSamples(options.sceneMSAASamples); + } + System.out.println("Requested: " + caps); + + final GLWindow window = GLWindow.create(caps); + window.setSize(options.surface_width, options.surface_height); + window.setTitle(UILayoutGrid01.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight()); + window.addWindowListener(new WindowAdapter() { + @Override + public void windowResized(final WindowEvent e) { + window.setTitle(UILayoutGrid01.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight()); + } + @Override + public void windowDestroyNotify(final WindowEvent e) { + animator.stop(); + } + }); + + + final Scene scene = new Scene(); + scene.setPMVMatrixSetup(new MyPMVMatrixSetup()); + scene.setClearParams(new float[] { 1f, 1f, 1f, 1f}, GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + scene.setFrustumCullingEnabled(true); + scene.attachInputListenerTo(window); + window.addGLEventListener(scene); + window.setVisible(true); + scene.waitUntilDisplayed(); + + animator.setUpdateFPSFrames(1*60, null); // System.err); + animator.add(window); + animator.start(); + + /** + * We can share this instance w/ all UI elements, + * since only mouse action / gesture is complete for a single one (press, drag, released and click). + */ + final Shape.MouseGestureAdapter dragZoomRotateListener = new Shape.MouseGestureAdapter() { + @Override + public void mouseWheelMoved(final MouseEvent e) { + final Shape.EventInfo shapeEvent = (Shape.EventInfo) e.getAttachment(); + final Shape shape = shapeEvent.shape; + final Vec3f rot = new Vec3f(e.getRotation()).scale( FloatUtil.PI / 180.0f ); + // swap axis for onscreen rotation matching natural feel + final float tmp = rot.x(); rot.setX( rot.y() ); rot.setY( tmp ); + shape.getRotation().rotateByEuler( rot.scale( 2f ) ); + } + }; + + // + // Resolution independent, no screen size + // + final Font font = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_SERIF); + System.err.println("Font: "+font.getFullFamilyName()); + + final AABBox sceneBox = scene.getBounds(); + System.err.println("SceneBox "+sceneBox); + + final Vec4f borderColor = new Vec4f(0, 0, 1f, 0.6f); + final float borderThickness = 0.01f; + final float sxy = 1/10f * sceneBox.getWidth(); + float nextXPos = 0, nextYTop = sceneBox.getHeight(); + + final Group groupA0 = new Group(new GridLayout(1, 1f, 1/2f, Alignment.Fill, new Gap(0.10f))); + groupA0.addShape( new Button(options.renderModes, font, "ro co", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + groupA0.setBorder(borderThickness).setBorderColor(borderColor); + groupA0.scale(sxy, sxy, 1); + groupA0.setInteractive(true); + groupA0.validate(reqGLP); + groupA0.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupA0.getScaledHeight(), 0); + System.err.println("Group-A0 "+groupA0); + System.err.println("Group-A0 Layout "+groupA0.getLayout()); + groupA0.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupA0); + nextXPos += groupA0.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupA0.markShapeDirty(); + groupA0.validate(reqGLP); + System.err.println("Group-A0.2 "+groupA0); + System.err.println("Group-A0 Layout.2 "+groupA0.getLayout()); + groupA0.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + final Group groupA1 = new Group(new GridLayout(1, 1, 1/2f, Alignment.Fill, new Gap(0.10f))); + groupA1.addShape( new Button(options.renderModes, font, "ro co", 1f, 1/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupA1.addShape( new Button(options.renderModes, font, "r1 r1", 1f, 1/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupA1.setBorder(sxy*borderThickness).setBorderColor(borderColor); + groupA1.scale(sxy, sxy, 1); + groupA1.setInteractive(true); + groupA1.validate(reqGLP); + groupA1.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupA1.getScaledHeight(), 0); + System.err.println("Group-A1 "+groupA1); + System.err.println("Group-A1 Layout "+groupA1.getLayout()); + groupA1.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupA1); + nextXPos += groupA1.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupA1.markShapeDirty(); + groupA1.validate(reqGLP); + System.err.println("Group-A1.2 "+groupA1); + System.err.println("Group-A1 Layout.2 "+groupA1.getLayout()); + groupA1.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + final Group groupA2 = new Group(new GridLayout(1, 1/2f, Alignment.Fill, new Gap(0.10f), 1)); + groupA2.addShape( new Button(options.renderModes, font, "ro co", 1f, 1/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupA2.addShape( new Button(options.renderModes, font, "r1 c1", 1f, 1/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupA2.setBorder(sxy*borderThickness).setBorderColor(borderColor); + groupA2.scale(sxy, sxy, 1); + groupA2.setInteractive(true); + groupA2.validate(reqGLP); + groupA2.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupA2.getScaledHeight(), 0); + System.err.println("Group-A2 "+groupA2); + System.err.println("Group-A2 Layout "+groupA2.getLayout()); + groupA2.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupA2); + nextXPos += groupA2.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupA2.markShapeDirty(); + groupA2.validate(reqGLP); + System.err.println("Group-A2.2 "+groupA2); + System.err.println("Group-A2 Layout.2 "+groupA2.getLayout()); + groupA2.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + final Group groupA3 = new Group(new GridLayout(2, 1f, 1/2f, Alignment.Fill, new Gap(0.10f))); + { + groupA3.addShape( new Button(options.renderModes, font, "ro co", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + groupA3.addShape( new Button(options.renderModes, font, "r1 c2", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupA3.addShape( new Button(options.renderModes, font, "r2 c1", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupA3.addShape( new Button(options.renderModes, font, "r2 c2", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + } + groupA3.setBorder(borderThickness).setBorderColor(borderColor); + groupA3.scale(sxy, sxy, 1); + groupA3.setInteractive(true); + groupA3.validate(reqGLP); + groupA3.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupA3.getScaledHeight(), 0); + System.err.println("Group-A3 "+groupA3); + System.err.println("Group-A3 Layout "+groupA3.getLayout()); + groupA3.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupA3); + nextXPos += groupA3.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupA3.markShapeDirty(); + groupA3.validate(reqGLP); + System.err.println("Group-A3.2 "+groupA3); + System.err.println("Group-A3 Layout.2 "+groupA3.getLayout()); + groupA3.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + final Group groupA4 = new Group(new GridLayout(2, 1f, 1/2f, Alignment.Fill, new Gap(0.10f))); + { + groupA4.addShape( new Button(options.renderModes, font, "ro co", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + groupA4.addShape( new Button(options.renderModes, font, "r1 c2", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupA4.addShape( new Button(options.renderModes, font, "r2 c1", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupA4.addShape( new Button(options.renderModes, font, "r2 c2", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + groupA4.addShape( new Button(options.renderModes, font, "r3 c1", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + } + groupA4.setBorder(borderThickness).setBorderColor(borderColor); + groupA4.scale(sxy, sxy, 1); + groupA4.setInteractive(true); + groupA4.validate(reqGLP); + groupA4.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupA4.getScaledHeight(), 0); + System.err.println("Group-A4 "+groupA4); + System.err.println("Group-A4 Layout "+groupA4.getLayout()); + groupA4.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupA4); + nextXPos += groupA4.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupA4.markShapeDirty(); + groupA4.validate(reqGLP); + System.err.println("Group-A4.2 "+groupA4); + System.err.println("Group-A4 Layout.2 "+groupA4.getLayout()); + groupA4.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + // next line + nextXPos = 0; + nextYTop = 2f*sceneBox.getHeight()/3f; + + final Group groupB0 = new Group(new GridLayout(2, sxy, sxy/2f, Alignment.Fill, new Gap(sxy*0.10f))); + { + groupB0.addShape( new Button(options.renderModes, font, "ro co", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + groupB0.addShape( new Button(options.renderModes, font, "r1 c2", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupB0.addShape( new Button(options.renderModes, font, "r2 c1", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupB0.addShape( new Button(options.renderModes, font, "r2 c2", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + groupB0.addShape( new Button(options.renderModes, font, "r3 c1", 1f, 1f/2f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + } + groupB0.setBorder(sxy*borderThickness).setBorderColor(borderColor); + // groupB0.scale(2*sxy, 2*sxy, 1); + groupB0.setInteractive(true); + groupB0.validate(reqGLP); + groupB0.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupB0.getScaledHeight(), 0); + System.err.println("Group-B0 "+groupB0); + System.err.println("Group-B0 Layout "+groupB0.getLayout()); + groupB0.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupB0); + nextXPos += groupB0.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupB0.markShapeDirty(); + groupB0.validate(reqGLP); + System.err.println("Group-B0.2 "+groupB0); + System.err.println("Group-B0 Layout.2 "+groupB0.getLayout()); + groupB0.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + final Group groupB1 = new Group(new GridLayout(2, sxy, sxy/2f, Alignment.FillCenter, new Gap(sxy*0.10f))); + { + final Padding p = new Padding(0.05f); + groupB1.addShape( new Button(options.renderModes, font, "ro co", 1, 1/2f).setCorner(0f).setPaddding(p).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + groupB1.addShape( new Button(options.renderModes, font, "r1 c2", 1, 1/2f).setCorner(0f).setPaddding(p).setBorder(borderThickness).setDragAndResizeable(false) ); + groupB1.addShape( new Button(options.renderModes, font, "r2 c1", 1, 1/2f).setCorner(0f).setPaddding(p).setBorder(borderThickness).setDragAndResizeable(false) ); + groupB1.addShape( new Button(options.renderModes, font, "r2 c2", 1, 1/2f).setCorner(0f).setPaddding(p).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + groupB1.addShape( new Button(options.renderModes, font, "r3 c1", 1, 1/2f).setCorner(0f).setPaddding(p).setBorder(borderThickness).addMouseListener(dragZoomRotateListener) ); + } + groupB1.setBorder(sxy*borderThickness).setBorderColor(borderColor); + // groupB1.scale(2*sxy, 2*sxy, 1); + groupB1.setInteractive(true); + groupB1.validate(reqGLP); + groupB1.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupB1.getScaledHeight(), 0); + System.err.println("Group-B1 "+groupB1); + System.err.println("Group-B1 Layout "+groupB1.getLayout()); + groupB1.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupB1); + nextXPos += groupB1.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupB1.markShapeDirty(); + groupB1.validate(reqGLP); + System.err.println("Group-B1.2 "+groupB1); + System.err.println("Group-B1 Layout.2 "+groupB1.getLayout()); + groupB1.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + final Group groupB2 = new Group(new GridLayout(2, sxy, sxy/2f, Alignment.FillCenter, new Gap(sxy*0.10f))); + { + final Padding p = new Padding(sxy/2f*0.05f); + groupB2.addShape( new Button(options.renderModes, font, "ro co", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).addMouseListener(dragZoomRotateListener) ); + groupB2.addShape( new Button(options.renderModes, font, "r1 c2", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).setDragAndResizeable(false) ); + groupB2.addShape( new Button(options.renderModes, font, "r2 c1", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).setDragAndResizeable(false) ); + groupB2.addShape( new Button(options.renderModes, font, "r2 c2", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).addMouseListener(dragZoomRotateListener) ); + groupB2.addShape( new Button(options.renderModes, font, "r3 c1", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).addMouseListener(dragZoomRotateListener) ); + } + groupB2.setBorder(sxy*borderThickness).setBorderColor(borderColor); + // groupB2.scale(2*sxy, 2*sxy, 1); + groupB2.setInteractive(true); + groupB2.validate(reqGLP); + groupB2.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupB2.getScaledHeight(), 0); + System.err.println("Group-B2 "+groupB2); + System.err.println("Group-B2 Layout "+groupB2.getLayout()); + groupB2.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupB2); + nextXPos += groupB2.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupB2.markShapeDirty(); + groupB2.validate(reqGLP); + System.err.println("Group-B2.2 "+groupB2); + System.err.println("Group-B2 Layout.2 "+groupB2.getLayout()); + groupB2.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + final Group groupB3 = new Group(new GridLayout(2, sxy, sxy/2f, Alignment.Fill, new Gap(sxy*0.10f))); + { + final Padding p = new Padding(sxy/2f*0.05f); + groupB3.addShape( new Button(options.renderModes, font, "ro co", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).addMouseListener(dragZoomRotateListener) ); + groupB3.addShape( new Button(options.renderModes, font, "r1 c2", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).setDragAndResizeable(false) ); + groupB3.addShape( new Button(options.renderModes, font, "r2 c1", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).setDragAndResizeable(false) ); + groupB3.addShape( new Button(options.renderModes, font, "r2 c2", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).addMouseListener(dragZoomRotateListener) ); + groupB3.addShape( new Button(options.renderModes, font, "r3 c1", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy/2f*borderThickness).addMouseListener(dragZoomRotateListener) ); + } + groupB3.setBorder(sxy*borderThickness).setBorderColor(borderColor); + // groupB3.scale(2*sxy, 2*sxy, 1); + groupB3.setInteractive(true); + groupB3.validate(reqGLP); + groupB3.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupB3.getScaledHeight(), 0); + System.err.println("Group-B3 "+groupB3); + System.err.println("Group-B3 Layout "+groupB3.getLayout()); + groupB3.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupB3); + nextXPos += groupB3.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupB3.markShapeDirty(); + groupB3.validate(reqGLP); + System.err.println("Group-B3.2 "+groupB3); + System.err.println("Group-B3 Layout.2 "+groupB3.getLayout()); + groupB3.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + // next line + nextXPos = 0; + nextYTop = sceneBox.getHeight()/3f; + + final Group groupC0 = new Group(new GridLayout(2, 0, 0, Alignment.Fill, new Gap(0.03f))); + { + final Group glyphGrid = new Group(new GridLayout(2, 0.3f, 0.3f, Alignment.Fill, new Gap(0.3f * 0.10f))); + glyphGrid.addShape( new Button(options.renderModes, font, "0.0", 1f, 1f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + glyphGrid.addShape( new Button(options.renderModes, font, "0.1", 1f, 1f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + glyphGrid.addShape( new Button(options.renderModes, font, "1.0", 1f, 1f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + glyphGrid.addShape( new Button(options.renderModes, font, "1.1", 1f, 1f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupC0.addShape(glyphGrid.setBorder(borderThickness)); + + final Group infoGrid = new Group(new GridLayout(1, 1/4f, 1/2f, Alignment.Fill, new Gap(0.02f))); + // final Group glyphView = new Group(); + // glyphView.addShape(new Rectangle(options.renderModes, 1f, 1f, 0.005f).setInteractive(false)); + // glyphView.addShape(new Button(options.renderModes, font, "S", 1f, 1f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + // infoGrid.addShape(glyphView.setBorder(borderThickness)); + infoGrid.addShape(new Button(options.renderModes, font, " S ", 1/2f, 1f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + + // final Group infoView = new Group(); + // infoView.addShape(new Button(options.renderModes, font, "Info", 1f, 1f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + // infoGrid.addShape(infoView.setBorder(borderThickness)); + infoGrid.addShape(new Button(options.renderModes, font, " Info ", 1/2f, 1f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + groupC0.addShape(infoGrid.setBorder(borderThickness)); + // groupC0.addShape(new Button(options.renderModes, font, "S", 1/4f, 0.5f).setCorner(0f).setBorder(borderThickness).setDragAndResizeable(false) ); + } + groupC0.setBorder(sxy*borderThickness).setBorderColor(borderColor); + groupC0.scale(2*sxy, 2*sxy, 1); + groupC0.setInteractive(true); + groupC0.validate(reqGLP); + groupC0.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupC0.getScaledHeight(), 0); + System.err.println("Group-C0 "+groupC0); + System.err.println("Group-C0 Layout "+groupC0.getLayout()); + groupC0.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupC0); + nextXPos += groupC0.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupC0.markShapeDirty(); + groupC0.validate(reqGLP); + System.err.println("Group-C0.2 "+groupC0); + System.err.println("Group-C0 Layout.2 "+groupC0.getLayout()); + groupC0.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + final Group groupC3 = new Group(new GridLayout(2, sxy, sxy/2f, Alignment.Center, new Gap(sxy*0.10f))); + { + final Padding p = new Padding(sxy*0.05f); + groupC3.addShape( new Button(options.renderModes, font, "ro co", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy*borderThickness).addMouseListener(dragZoomRotateListener) ); + groupC3.addShape( new Button(options.renderModes, font, "r1 c2", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy*borderThickness).setDragAndResizeable(false) ); + groupC3.addShape( new Button(options.renderModes, font, "r2 c1", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy*borderThickness).setDragAndResizeable(false) ); + groupC3.addShape( new Button(options.renderModes, font, "r2 c2", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy*borderThickness).addMouseListener(dragZoomRotateListener) ); + groupC3.addShape( new Button(options.renderModes, font, "r3 c1", sxy/2f, sxy/4f).setCorner(0f).setPaddding(p).setBorder(sxy*borderThickness).addMouseListener(dragZoomRotateListener) ); + } + groupC3.setBorder(sxy*borderThickness).setBorderColor(borderColor); + // groupC3.scale(2*sxy, 2*sxy, 1); + groupC3.setInteractive(true); + groupC3.validate(reqGLP); + groupC3.moveTo(sceneBox.getLow()).move(nextXPos, nextYTop-groupC3.getScaledHeight(), 0); + System.err.println("Group-C3 "+groupC3); + System.err.println("Group-C3 Layout "+groupC3.getLayout()); + groupC3.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + scene.addShape(groupC3); + nextXPos += groupC3.getScaledWidth() * 1.1f; + if( reLayout ) { + try { Thread.sleep(reLayoutSleep); } catch (final InterruptedException e1) { } + groupC3.markShapeDirty(); + groupC3.validate(reqGLP); + System.err.println("Group-C3.2 "+groupC3); + System.err.println("Group-C3 Layout.2 "+groupC3.getLayout()); + groupC3.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); + } + + try { Thread.sleep(1000); } catch (final InterruptedException e1) { } + scene.screenshot(true, scene.nextScreenshotFile(null, UILayoutGrid01.class.getSimpleName(), options.renderModes, caps, null)); + if( !options.stayOpen ) { + window.destroy(); + } + } +} diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03.java index c5aa32d55..0c00508d8 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03.java @@ -128,7 +128,7 @@ public class UISceneDemo03 { final Scene scene = new Scene(); scene.setClearParams(new float[] { 1f, 1f, 1f, 1f }, GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); scene.setPMVMatrixSetup(new MyPMVMatrixSetup()); - scene.setDebugBox(options.debugBoxThickness); + scene.setDebugBorderBox(options.debugBoxThickness); final Group glyphGroup = new Group(); scene.addShape(glyphGroup); diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03b.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03b.java index 1668ec883..805d9dafc 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03b.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo03b.java @@ -100,7 +100,9 @@ public class UISceneDemo03b { } public static void main(final String[] args) throws IOException { - int autoSpeed = 0; + int autoSpeed = -1; + setVelocity(80/1000f); + options.keepRunning = true; if (0 != args.length) { final int[] idx = { 0 }; @@ -110,6 +112,7 @@ public class UISceneDemo03b { } else if (args[idx[0]].equals("-v")) { ++idx[0]; setVelocity(MiscUtils.atoi(args[idx[0]], (int) velocity * 1000) / 1000f); + autoSpeed = 0; } else if(args[idx[0]].equals("-aspeed")) { autoSpeed = -1; setVelocity(80/1000f); @@ -134,12 +137,12 @@ public class UISceneDemo03b { final Scene scene = new Scene(); scene.setClearParams(new float[] { 1f, 1f, 1f, 1f }, GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); scene.setPMVMatrixSetup(new MyPMVMatrixSetup()); - scene.setDebugBox(options.debugBoxThickness); + scene.setDebugBorderBox(options.debugBoxThickness); final Group glyphGroup = new Group(); scene.addShape(glyphGroup); - // scene.setFrustumCullingEnabled(true); + scene.setFrustumCullingEnabled(true); glyphGroup.setFrustumCullingEnabled(true); final Animator animator = new Animator(); @@ -212,6 +215,13 @@ public class UISceneDemo03b { final GLProfile hasGLP = window.getChosenGLCapabilities().getGLProfile(); final AABBox sceneBox = scene.getBounds(); + glyphGroup.addShape( new Rectangle(options.renderModes, sceneBox, sceneBox.getWidth()*0.01f) ); + // glyphGroup.addShape( new Rectangle(options.renderModes, sceneBox.getMinX(), sceneBox.getMinY(), sceneBox.getWidth(), sceneBox.getHeight(), sceneBox.getWidth()*0.01f) ); + // glyphGroup.addShape( new Rectangle(options.renderModes, sceneBox.getMinX()*0.5f, sceneBox.getMinY()*0.5f, sceneBox.getWidth()*0.5f, sceneBox.getHeight()*0.5f, sceneBox.getWidth()*0.5f*0.01f, sceneBox.getMinZ()) ); + glyphGroup.scale(0.8f, 0.8f, 1f); + // glyphGroup.scale(0.5f, 0.5f, 1f); + glyphGroup.setRotationPivot(0, 0, 0); + glyphGroup.validate(hasGLP); System.err.println("SceneBox " + sceneBox); System.err.println("Frustum " + scene.getMatrix().getFrustum()); System.err.println("GlyphGroup.0: "+glyphGroup); @@ -259,7 +269,8 @@ public class UISceneDemo03b { // Setup the moving glyphs // - final List glyphShapes = new ArrayList(); + final List glyphShapesAnim = new ArrayList(); + final List glyphShapesAll = new ArrayList(); final float pixPerMM, dpiV; { @@ -271,12 +282,14 @@ public class UISceneDemo03b { boolean z_only = true; int txt_idx = 0; - final AABBox glyphBox = glyphGroup.getBounds().resize(sceneBox); + final AABBox glyphBox = glyphGroup.getBounds(); final float g_w = glyphBox.getWidth(); final float g_h = glyphBox.getHeight(); - glyphGroup.scale(0.8f, 0.8f, 1f); - glyphGroup.validate(hasGLP); + + // glyphGroup.scale(0.8f, 0.8f, 1f); + // glyphGroup.validate(hasGLP); System.err.println("GlyphBox " + glyphBox); + System.err.println("GlyphGroup " + glyphGroup); glyphGroup.addMouseListener( new Shape.MouseGestureAdapter() { @Override @@ -361,11 +374,11 @@ public class UISceneDemo03b { } z_only = !z_only; window.invoke(true, (drawable) -> { - glyphGroup.removeAllShapes(drawable.getGL().getGL2ES2(), scene.getRenderer()); + glyphGroup.removeShapes(drawable.getGL().getGL2ES2(), scene.getRenderer(), glyphShapesAll); return true; }); - glyphGroup.addShape( new Rectangle(options.renderModes, g_w, g_h, g_w*0.01f) ); - glyphGroup.getShapes().get(0).setInteractive(false); + glyphShapesAll.clear(); + glyphShapesAnim.clear(); final float[] movingGlyphPixPerShapeUnit; { @@ -378,9 +391,9 @@ public class UISceneDemo03b { final int[] movingGlyphSizePx = testGlyph.getSurfaceSize(scene, pmv, new int[2]); // [px] movingGlyphPixPerShapeUnit = testGlyph.getPixelPerShapeUnit(movingGlyphSizePx, new float[2]); // [px]/[shapeUnit] - final AABBox box = GlyphShape.processString(glyphShapes, options.renderModes, font, originalTexts[txt_idx]); + final AABBox box = GlyphShape.processString(glyphShapesAll, options.renderModes, font, originalTexts[txt_idx]); System.err.println("Shapes: "+box); - for(final GlyphShape gs : glyphShapes) { + for(final GlyphShape gs : glyphShapesAll) { gs.setScale(fontScale, fontScale, 1f); gs.setColor(0.1f, 0.1f, 0.1f, 1); final Vec3f target = gs.getOrigPos(fontScale).add(glyphBox.getMinX(), 0f, 0f); @@ -396,14 +409,15 @@ public class UISceneDemo03b { testGlyph.setEnabled(false); glyphGroup.addShape(testGlyph); } - glyphGroup.addShapes(glyphShapes); + glyphGroup.addShapes(glyphShapesAll); + glyphShapesAnim.addAll(glyphShapesAll); final float pos_eps = FloatUtil.EPSILON * 5000; // ~= 0.0005960 final float rot_eps = FloatUtil.adegToRad(0.5f); // 1 adeg ~= 0.01745 rad final long t0_us = Clock.currentNanos() / 1000; // [us] final long[] t2_us = { t0_us }; - while (!glyphShapes.isEmpty()) { + while (!glyphShapesAnim.isEmpty()) { window.invoke(true, (drawable) -> { final long t3_us = Clock.currentNanos() / 1000; final float dt_s = (t3_us - t2_us[0]) / 1e6f; @@ -413,8 +427,8 @@ public class UISceneDemo03b { final float velocity_obj = velocity_px / movingGlyphPixPerShapeUnit[0]; // [shapeUnit]/[s] final float dxy = velocity_obj * dt_s; // [shapeUnit] - for (int idx = glyphShapes.size() - 1; 0 <= idx; --idx) { - final GlyphShape glyph = glyphShapes.get(idx); + for (int idx = glyphShapesAnim.size() - 1; 0 <= idx; --idx) { + final GlyphShape glyph = glyphShapesAnim.get(idx); final Vec3f pos = new Vec3f(glyph.getPosition()); final Vec3f target = glyph.getOrigPos(fontScale).add(glyphBox.getMinX(), 0f, 0f); final Vec3f p_t = target.minus(pos); @@ -435,7 +449,7 @@ public class UISceneDemo03b { } glyph.moveTo(target.x(), target.y(), target.z()); q.setIdentity(); - glyphShapes.remove(idx); + glyphShapesAnim.remove(idx); continue; } if( !pos_ok ) { 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 001f585fd..6c20247c2 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo11.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo11.java @@ -37,8 +37,9 @@ import com.jogamp.graph.font.FontSet; import com.jogamp.graph.ui.Group; import com.jogamp.graph.ui.Scene; import com.jogamp.graph.ui.Shape; +import com.jogamp.graph.ui.layout.Alignment; +import com.jogamp.graph.ui.layout.Gap; import com.jogamp.graph.ui.layout.GridLayout; -import com.jogamp.graph.ui.layout.Padding; import com.jogamp.graph.ui.shapes.Button; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; @@ -81,7 +82,7 @@ public class UISceneDemo11 { final Font font = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_SERIF); System.err.println("Font: "+font.getFullFamilyName()); - final Group groupA0 = new Group(new GridLayout(2, 1f, 1/2f, new Padding(0.05f, 0.05f))); + final Group groupA0 = new Group(new GridLayout(2, 1f, 1/2f, Alignment.Fill, new Gap(0.10f))); { 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) ); diff --git a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo12.java b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo12.java deleted file mode 100644 index 4a0fa9a90..000000000 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo12.java +++ /dev/null @@ -1,224 +0,0 @@ -/** - * Copyright 2010-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.opengl.demos.graph.ui; - -import java.io.IOException; - -import com.jogamp.graph.curve.Region; -import com.jogamp.graph.font.Font; -import com.jogamp.graph.font.FontFactory; -import com.jogamp.graph.font.FontSet; -import com.jogamp.graph.ui.Group; -import com.jogamp.graph.ui.Scene; -import com.jogamp.graph.ui.Shape; -import com.jogamp.graph.ui.layout.BoxLayout; -import com.jogamp.graph.ui.layout.GridLayout; -import com.jogamp.graph.ui.layout.Margin; -import com.jogamp.graph.ui.layout.Padding; -import com.jogamp.graph.ui.shapes.Button; -import com.jogamp.graph.ui.shapes.Label; -import com.jogamp.graph.ui.shapes.Rectangle; -import com.jogamp.graph.ui.shapes.BaseButton; -import com.jogamp.newt.event.WindowAdapter; -import com.jogamp.newt.event.WindowEvent; -import com.jogamp.newt.opengl.GLWindow; -import com.jogamp.opengl.GL; -import com.jogamp.opengl.GLCapabilities; -import com.jogamp.opengl.GLProfile; -import com.jogamp.opengl.demos.graph.ui.util.GraphUIDemoArgs; -import com.jogamp.opengl.math.geom.AABBox; -import com.jogamp.opengl.util.Animator; - -/** - * Res independent {@link Shape}s in a {@link Group} using a {@link GridLayout}, contained within a Scene attached to GLWindow. - *

- * Pass '-keep' to main-function to keep running after animation, - * then user can test Shape drag-move and drag-resize w/ 1-pointer. - *

- */ -public class UISceneDemo12 { - static GraphUIDemoArgs options = new GraphUIDemoArgs(1280, 720, Region.VBAA_RENDERING_BIT); - - public static void main(final String[] args) throws IOException { - if( 0 != args.length ) { - final int[] idx = { 0 }; - for (idx[0] = 0; idx[0] < args.length; ++idx[0]) { - if( options.parse(args, idx) ) { - continue; - } - } - } - System.err.println(options); - - final GLProfile reqGLP = GLProfile.get(options.glProfileName); - System.err.println("GLProfile: "+reqGLP); - - final Animator animator = new Animator(); - - final GLCapabilities caps = new GLCapabilities(reqGLP); - caps.setAlphaBits(4); - if( options.sceneMSAASamples > 0 ) { - caps.setSampleBuffers(true); - caps.setNumSamples(options.sceneMSAASamples); - } - System.out.println("Requested: " + caps); - - final GLWindow window = GLWindow.create(caps); - window.setSize(options.surface_width, options.surface_height); - window.setTitle(UISceneDemo12.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight()); - window.addWindowListener(new WindowAdapter() { - @Override - public void windowResized(final WindowEvent e) { - window.setTitle(UISceneDemo12.class.getSimpleName()+": "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight()); - } - @Override - public void windowDestroyNotify(final WindowEvent e) { - animator.stop(); - } - }); - - - final Scene scene = new Scene(); - scene.setClearParams(new float[] { 1f, 1f, 1f, 1f}, GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - scene.setFrustumCullingEnabled(true); - scene.attachInputListenerTo(window); - window.addGLEventListener(scene); - window.setVisible(true); - scene.waitUntilDisplayed(); - - animator.setUpdateFPSFrames(1*60, null); // System.err); - animator.add(window); - animator.start(); - // - // Resolution independent, no screen size - // - final Font font = FontFactory.get(FontFactory.UBUNTU).get(FontSet.FAMILY_LIGHT, FontSet.STYLE_SERIF); - System.err.println("Font: "+font.getFullFamilyName()); - - final AABBox sceneBox = scene.getBounds(); - System.err.println("SceneBox "+sceneBox); - - final float sxy = 1/8f; - float nextPos = 0; - - final Group groupA0 = new Group(new BoxLayout( new Padding(0.15f, 0.15f) ) ); - { - groupA0.addShape( new BaseButton(options.renderModes, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) ); - groupA0.addShape( new Button(options.renderModes, font, "stack1", 0.50f, 0.50f/2f).setCorner(0f).setDragAndResizeable(false) ); - groupA0.addShape( new Label(options.renderModes, font, 0.70f/4f, "pajq").setDragAndResizeable(false).setColor(0, 0, 1, 1) ); - } - groupA0.setInteractive(true); - groupA0.scale(sxy, sxy, 1); - groupA0.moveTo(sceneBox.getLow()).move(nextPos, 0, 0); - 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; }); - scene.addShape(groupA0); - scene.addShape( new Rectangle(options.renderModes, 1f, 1f, 0.01f).scale(sxy, sxy, 1).moveTo(sceneBox.getLow()).move(nextPos, 0, 0).setInteractive(false).setColor(0, 0, 0, 1) ); - nextPos = groupA0.getScaledWidth() * 1.5f; - - final Group groupA1 = new Group(new BoxLayout( 1f, 1f, new Margin(0.05f, 0.05f), new Padding(0.10f, 0.10f) ) ); - { - groupA1.addShape( new BaseButton(options.renderModes, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) ); - groupA1.addShape( new Button(options.renderModes, font, "stack2", 0.50f, 0.50f/2f).setCorner(0f).setDragAndResizeable(false) ); - groupA1.addShape( new Label(options.renderModes, font, 0.70f/4f, "pajq").setDragAndResizeable(false).setColor(0, 0, 1, 1) ); - } - groupA1.setInteractive(true); - groupA1.scale(sxy, sxy, 1); - groupA1.moveTo(sceneBox.getLow()).move(nextPos, 0, 0); - groupA1.validate(reqGLP); - System.err.println("Group-A1 "+groupA1); - System.err.println("Group-A1 Layout "+groupA1.getLayout()); - groupA1.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); - scene.addShape(groupA1); - scene.addShape( new Rectangle(options.renderModes, 1f, 1f, 0.01f).scale(sxy, sxy, 1).moveTo(sceneBox.getLow()).move(nextPos, 0, 0).setInteractive(false).setColor(0, 0, 0, 1) ); - nextPos += groupA1.getScaledWidth() * 1.5f; - - final Group groupA2 = new Group(new BoxLayout( 1f, 1f, new Margin(0.10f, Margin.CENTER), new Padding(0.05f, 0) ) ); - { - groupA2.addShape( new BaseButton(options.renderModes, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) ); - groupA2.addShape( new Button(options.renderModes, font, "stack3", 0.50f, 0.50f/2f).setCorner(0f).setDragAndResizeable(false) ); - groupA2.addShape( new Label(options.renderModes, font, 0.70f/4f, "pajq").setDragAndResizeable(false).setColor(0, 0, 1, 1) ); - } - groupA2.setInteractive(true); - groupA2.scale(sxy, sxy, 1); - groupA2.moveTo(sceneBox.getLow()).move(nextPos, 0, 0); - groupA2.validate(reqGLP); - System.err.println("Group-A2 "+groupA2); - System.err.println("Group-A2 Layout "+groupA2.getLayout()); - groupA2.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); - scene.addShape(groupA2); - scene.addShape( new Rectangle(options.renderModes, 1f, 1f, 0.01f).scale(sxy, sxy, 1).moveTo(sceneBox.getLow()).move(nextPos, 0, 0).setInteractive(false).setColor(0, 0, 0, 1) ); - nextPos += groupA2.getScaledWidth() * 1.5f; - - final Group groupA3 = new Group(new BoxLayout( 1f, 1f, new Margin(Margin.CENTER) ) ); - { - groupA3.addShape( new BaseButton(options.renderModes, 0.70f, 0.70f).setCorner(0f).setInteractive(false).setColor(0, 1, 0, 1) ); - groupA3.addShape( new Button(options.renderModes, font, "stack4", 0.50f, 0.50f/2f).setCorner(0f).setDragAndResizeable(false) ); - groupA3.addShape( new Label(options.renderModes, font, 0.70f/4f, "pajq").setDragAndResizeable(false).setColor(0, 0, 1, 1) ); - } - groupA3.setInteractive(true); - groupA3.scale(sxy, sxy, 1); - groupA3.moveTo(sceneBox.getLow()).move(nextPos, 0, 0); - groupA3.validate(reqGLP); - System.err.println("Group-A1 "+groupA3); - System.err.println("Group-A1 Layout "+groupA3.getLayout()); - groupA3.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); - scene.addShape(groupA3); - scene.addShape( new Rectangle(options.renderModes, 1f, 1f, 0.01f).scale(sxy, sxy, 1).moveTo(sceneBox.getLow()).move(nextPos, 0, 0).setInteractive(false).setColor(0, 0, 0, 1) ); - nextPos += groupA3.getScaledWidth() * 1.5f; - - // - // - // - nextPos = 0; - - final Group groupB0 = new Group(new GridLayout(2, 1f, 1/2f, new Padding(0.05f, 0.05f))); - { - groupB0.addShape( new Button(options.renderModes, font, "r1 c1", 1f, 1f/2f).setCorner(0f).setDragAndResizeable(false) ); - groupB0.addShape( new Button(options.renderModes, font, "r1 c2", 1f, 1f/2f).setCorner(0f).setDragAndResizeable(false) ); - groupB0.addShape( new Button(options.renderModes, font, "r2 c1", 1f, 1f/2f).setCorner(0f).setDragAndResizeable(false) ); - groupB0.addShape( new Button(options.renderModes, font, "r2 c2", 1f, 1f/2f).setCorner(0f).setDragAndResizeable(false) ); - } - groupB0.setInteractive(true); - groupB0.scale(sxy, sxy, 1); - groupB0.moveTo(sceneBox.getLow()).move(nextPos, sceneBox.getHeight()/2f, 0); - groupB0.validate(reqGLP); - System.err.println("Group-B0 "+groupB0); - System.err.println("Group-B0 Layout "+groupB0.getLayout()); - groupB0.forAll( (shape) -> { System.err.println("Shape... "+shape); return false; }); - scene.addShape(groupB0); - nextPos = groupB0.getScaledWidth() * 1.5f; - - try { Thread.sleep(1000); } catch (final InterruptedException e1) { } - if( !options.stayOpen ) { - window.destroy(); - } - } -} 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 d732795ca..eeb52082f 100644 --- a/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java +++ b/src/demos/com/jogamp/opengl/demos/graph/ui/UISceneDemo20.java @@ -49,8 +49,9 @@ 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.Alignment; +import com.jogamp.graph.ui.layout.Gap; 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; @@ -307,7 +308,7 @@ public class UISceneDemo20 implements GLEventListener { scene.setPMVMatrixSetup(new MyPMVMatrixSetup()); 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.setDebugBorderBox(options.debugBoxThickness); scene.addShape(buttonsLeft); scene.addShape(buttonsRight); } @@ -384,12 +385,12 @@ public class UISceneDemo20 implements GLEventListener { final float buttonLWidth = buttonXSizeNorm; final float buttonLHeight = buttonLWidth / 2.5f; - buttonsLeft.setLayout(new GridLayout(buttonLWidth, buttonLHeight, new Padding(buttonLHeight*0.25f, buttonLWidth*0.05f), 7)); + buttonsLeft.setLayout(new GridLayout(buttonLWidth, buttonLHeight, Alignment.Fill, new Gap(buttonLHeight*0.50f, buttonLWidth*0.10f), 7)); final float buttonRWidth = 2f*buttonLWidth; final float buttonRHeight = 2f*buttonLHeight; - buttonsRight.setLayout(new GridLayout(1, buttonRWidth, buttonRHeight, new Padding(buttonLHeight*0.25f, buttonLWidth*0.05f))); + buttonsRight.setLayout(new GridLayout(1, buttonRWidth, buttonRHeight, Alignment.Fill, new Gap(buttonLHeight*0.50f, buttonLWidth*0.10f))); System.err.println("Button Size: "+buttonLWidth+" x "+buttonLHeight); @@ -861,20 +862,22 @@ public class UISceneDemo20 implements GLEventListener { buttonsRight.setScale(button_sxy, button_sxy, 1f); final float dz = 0f; - final float dyTop = sceneHeight * relTop; + final float dxLeft = sceneBox.getMinX(); + final float dyBottom = sceneBox.getMinY(); + final float dyTop = dyBottom + 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); + buttonsLeft.moveTo(dxLeft, dyTop - buttonsLeft.getScaledHeight(), dz); + buttonsRight.moveTo(dxLeft + sceneWidth - buttonsRight.getScaledWidth(), dyTop - buttonsRight.getScaledHeight(), dz); jogampLabel.setScale(sceneHeight, sceneHeight, 1f); - final float dxMiddleAbs = sceneWidth * relMiddle; - final float dyTopLabelAbs = sceneHeight - jogampLabel.getScaledLineHeight(); + final float dxMiddleAbs = dxLeft + sceneWidth * relMiddle; + final float dyTopLabelAbs = dyBottom + sceneHeight - jogampLabel.getScaledLineHeight(); jogampLabel.moveTo(dxMiddleAbs, dyTopLabelAbs - jogampLabel.getScaledLineHeight(), dz); { final float pixelSize10Pt = FontScale.toPixels(fontSizePt, dpiV); @@ -920,8 +923,8 @@ public class UISceneDemo20 implements GLEventListener { if(null == labels[currentText]) { final AABBox sbox = scene.getBounds(); final float sceneHeight = sbox.getHeight(); - final float dyTop = sbox.getHeight() - jogampLabel.getScaledLineHeight(); - final float dxMiddle = sbox.getWidth() * relMiddle; + final float dyTop = sbox.getMinY() + sbox.getHeight() - jogampLabel.getScaledLineHeight(); + final float dxMiddle = sbox.getMinX() + sbox.getWidth() * relMiddle; labels[currentText] = new Label(renderModes, font, fontSizeFixedNorm, strings[currentText]); labels[currentText].setScale(sceneHeight, sceneHeight, 1f); labels[currentText].setColor(0.1f, 0.1f, 0.1f, 1.0f); @@ -984,32 +987,33 @@ public class UISceneDemo20 implements GLEventListener { /** * Our PMVMatrixSetup: * - gluPerspective like Scene's default - * - no normal scale to 1, keep distance to near plane for rotation effects. We scale Shapes - * - translate origin to bottom-left + * - no normal scale to 1, keep a longer distance to near plane for rotation effects. We scale Shapes */ public static class MyPMVMatrixSetup implements PMVMatrixSetup { + static float Z_DIST = -1f; @Override public void set(final PMVMatrix pmv, final Recti viewport) { final float ratio = (float)viewport.width()/(float)viewport.height(); pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION); pmv.glLoadIdentity(); pmv.gluPerspective(Scene.DEFAULT_ANGLE, ratio, Scene.DEFAULT_ZNEAR, Scene.DEFAULT_ZFAR); - pmv.glTranslatef(0f, 0f, Scene.DEFAULT_SCENE_DIST); + pmv.glTranslatef(0f, 0f, Z_DIST); pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); pmv.glLoadIdentity(); - - // Translate origin to bottom-left - final AABBox planeBox0 = new AABBox(); - setPlaneBox(planeBox0, pmv, viewport); - pmv.glMatrixMode(GLMatrixFunc.GL_PROJECTION); - pmv.glTranslatef(planeBox0.getMinX(), planeBox0.getMinY(), 0f); - pmv.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); } @Override public void setPlaneBox(final AABBox planeBox, final PMVMatrix pmv, final Recti viewport) { - Scene.getDefaultPMVMatrixSetup().setPlaneBox(planeBox, pmv, viewport); + // Scene.getDefaultPMVMatrixSetup().setPlaneBox(planeBox, pmv, viewport); + final float orthoDist = -Z_DIST; // Scene.DEFAULT_SCENE_DIST; + final Vec3f obj00Coord = new Vec3f(); + final Vec3f obj11Coord = new Vec3f(); + + Scene.winToPlaneCoord(pmv, viewport, Scene.DEFAULT_ZNEAR, Scene.DEFAULT_ZFAR, viewport.x(), viewport.y(), orthoDist, obj00Coord); + Scene.winToPlaneCoord(pmv, viewport, Scene.DEFAULT_ZNEAR, Scene.DEFAULT_ZFAR, viewport.width(), viewport.height(), orthoDist, obj11Coord); + + planeBox.setSize( obj00Coord, obj11Coord ); } }; -- cgit v1.2.3