/**
* Copyright 2013 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.test.junit.jogl.awt;
import com.jogamp.opengl.*;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.awt.GLCanvas;
import javax.swing.BoundedRangeModel;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.ScrollPaneConstants;
import com.jogamp.common.util.awt.AWTEDTExecutor;
import com.jogamp.newt.event.awt.AWTWindowAdapter;
import com.jogamp.newt.event.TraceWindowAdapter;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.jogl.demos.es2.RedSquareES2;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.MiscUtils;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.lang.reflect.InvocationTargetException;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
/**
* Bug 816: OSX CALayer Positioning Bug.
* <p>
* Diff. OSX CALayer positioning w/ java6, [7uxx..7u40[, and >= 7u40
* </p>
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestBug816OSXCALayerPos01AWT extends UITestCase {
public enum FrameLayout { None, Flow, DoubleBorderCenterSurrounded, Box, Split };
static long duration = 1600; // ms
static final int width = 640, height = 480;
static boolean forceES2 = false;
static boolean forceGL3 = false;
static int swapInterval = 1;
static java.awt.Dimension rwsize = new Dimension(800, 600);
static void setComponentSize(final Frame frame, final Component comp1, final java.awt.Dimension new_sz1, final Component comp2, final java.awt.Dimension new_sz2) {
try {
AWTEDTExecutor.singleton.invoke(true /* wait */, new Runnable() {
public void run() {
comp1.setMinimumSize(new_sz1);
comp1.setPreferredSize(new_sz1);
comp1.setSize(new_sz1);
if( null != comp2 ) {
comp2.setMinimumSize(new_sz2);
comp2.setPreferredSize(new_sz2);
comp2.setSize(new_sz2);
}
if( null != frame ) {
frame.pack();
}
} } );
} catch( final Throwable throwable ) {
throwable.printStackTrace();
Assume.assumeNoException( throwable );
}
}
static void setFrameSize(final Frame frame, final boolean frameLayout, final java.awt.Dimension new_sz) {
try {
AWTEDTExecutor.singleton.invoke(true /* wait */, new Runnable() {
public void run() {
frame.setSize(new_sz);
if( frameLayout ) {
frame.validate();
}
} } );
} catch( final Throwable throwable ) {
throwable.printStackTrace();
Assume.assumeNoException( throwable );
}
}
protected void runTestGL(final GLCapabilities caps, final FrameLayout frameLayout, final boolean twoCanvas, final boolean resizeByComp) throws InterruptedException, InvocationTargetException {
final JFrame frame = new JFrame("Bug816: "+this.getTestMethodName());
Assert.assertNotNull(frame);
final Container framePane = frame.getContentPane();
final GLCanvas glCanvas1 = new GLCanvas(caps);
Assert.assertNotNull(glCanvas1);
final GLCanvas glCanvas2;
if( twoCanvas ) {
glCanvas2 = new GLCanvas(caps);
Assert.assertNotNull(glCanvas2);
} else {
glCanvas2 = null;
}
final Dimension glcDim = new Dimension(width/2, height);
final Dimension frameDim = new Dimension(twoCanvas ? width + 64: width/2 + 64, height + 64);
setComponentSize(null, glCanvas1, glcDim, glCanvas2, glcDim);
switch( frameLayout) {
case None: {
framePane.add(glCanvas1);
}
break;
case Flow: {
final Container c = new Container();
c.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
c.add(glCanvas1);
if( twoCanvas ) {
c.add(glCanvas2);
}
framePane.add(c);
}
break;
case DoubleBorderCenterSurrounded: {
final Container c = new Container();
c.setLayout(new BorderLayout());
c.add(new Button("north"), BorderLayout.NORTH);
c.add(new Button("south"), BorderLayout.SOUTH);
c.add(new Button("east"), BorderLayout.EAST);
c.add(new Button("west"), BorderLayout.WEST);
if( twoCanvas ) {
final Container c2 = new Container();
c2.setLayout(new GridLayout(1, 2));
c2.add(glCanvas1);
c2.add(glCanvas2);
c.add(c2, BorderLayout.CENTER);
} else {
c.add(glCanvas1, BorderLayout.CENTER);
}
framePane.setLayout(new BorderLayout());
framePane.add(new Button("NORTH"), BorderLayout.NORTH);
framePane.add(new Button("SOUTH"), BorderLayout.SOUTH);
framePane.add(new Button("EAST"), BorderLayout.EAST);
framePane.add(new Button("WEST"), BorderLayout.WEST);
framePane.add(c, BorderLayout.CENTER);
}
break;
case Box: {
final Container c = new Container();
c.setLayout(new BoxLayout(c, BoxLayout.X_AXIS));
c.add(glCanvas1);
if( twoCanvas ) {
c.add(glCanvas2);
}
framePane.add(c);
}
break;
case Split: {
final Dimension sbDim = new Dimension(16, 16);
final JScrollPane vsp = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
{
final JScrollBar vsb = vsp.getVerticalScrollBar();
vsb.setPreferredSize(sbDim);
final BoundedRangeModel model = vsb.getModel();
model.setMinimum(0);
model.setMaximum(100);
model.setValue(50);
model.setExtent(1);
vsb.setEnabled(true);
}
final JScrollPane hsp = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
{
final JScrollBar hsb = hsp.getHorizontalScrollBar();
hsb.setPreferredSize(sbDim);
final BoundedRangeModel model = hsb.getModel();
model.setMinimum(0);
model.setMaximum(100);
model.setValue(50);
model.setExtent(1);
hsb.setEnabled(true);
}
final JSplitPane horizontalSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true,
twoCanvas ? glCanvas2 : vsp, glCanvas1 );
horizontalSplitPane.setResizeWeight(0.5);
final JSplitPane verticalSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
true, horizontalSplitPane, hsp);
verticalSplitPane.setResizeWeight(0.5);
framePane.add(verticalSplitPane);
}
break;
}
final GearsES2 demo1 = new GearsES2(swapInterval);
glCanvas1.addGLEventListener(demo1);
if( twoCanvas ) {
final RedSquareES2 demo2 = new RedSquareES2(swapInterval);
glCanvas2.addGLEventListener(demo2);
}
final Animator animator = new Animator();
animator.add(glCanvas1);
if( twoCanvas ) {
animator.add(glCanvas2);
}
final QuitAdapter quitAdapter = new QuitAdapter();
new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter), glCanvas1).addTo(frame);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
if( resizeByComp ) {
frame.pack();
} else {
setFrameSize(frame, true, frameDim);
}
frame.setVisible(true);
}});
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true));
Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas1, true));
if( twoCanvas ) {
Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas2, true));
}
animator.start();
Assert.assertTrue(animator.isStarted());
Assert.assertTrue(animator.isAnimating());
System.err.println("canvas1 pos/siz: "+glCanvas1.getX()+"/"+glCanvas1.getY()+" "+glCanvas1.getSurfaceWidth()+"x"+glCanvas1.getSurfaceHeight());
if( twoCanvas ) {
System.err.println("canvas2 pos/siz: "+glCanvas2.getX()+"/"+glCanvas2.getY()+" "+glCanvas2.getSurfaceWidth()+"x"+glCanvas2.getSurfaceHeight());
}
Thread.sleep(Math.max(1000, duration/2));
if( null != rwsize ) {
final Dimension compRSizeHalf = new Dimension(rwsize.width/2, rwsize.height);
final Dimension frameRSizeHalf = new Dimension(twoCanvas ? rwsize.width + 64: rwsize.width/2 + 64, rwsize.height + 64);
if( resizeByComp ) {
setComponentSize(frame, glCanvas1, compRSizeHalf, glCanvas2, compRSizeHalf);
} else {
setFrameSize(frame, true, frameRSizeHalf);
}
System.err.println("resize canvas1 pos/siz: "+glCanvas1.getX()+"/"+glCanvas1.getY()+" "+glCanvas1.getSurfaceWidth()+"x"+glCanvas1.getSurfaceHeight());
if( twoCanvas ) {
System.err.println("resize canvas2 pos/siz: "+glCanvas2.getX()+"/"+glCanvas2.getY()+" "+glCanvas2.getSurfaceWidth()+"x"+glCanvas2.getSurfaceHeight());
}
}
final long t0 = System.currentTimeMillis();
long t1 = t0;
while(!quitAdapter.shouldQuit() && t1 - t0 < duration) {
Thread.sleep(100);
t1 = System.currentTimeMillis();
}
Assert.assertNotNull(frame);
Assert.assertNotNull(glCanvas1);
if( twoCanvas ) {
Assert.assertNotNull(glCanvas2);
} else {
Assert.assertNull(glCanvas2);
}
Assert.assertNotNull(animator);
animator.stop();
Assert.assertFalse(animator.isAnimating());
Assert.assertFalse(animator.isStarted());
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
frame.setVisible(false);
}});
Assert.assertEquals(false, frame.isVisible());
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
frame.remove(glCanvas1);
if( twoCanvas ) {
frame.remove(glCanvas2);
}
frame.dispose();
}});
}
static GLProfile getGLP() {
return GLProfile.getMaxProgrammableCore(true);
}
@Test
public void test00_Compo_None_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 0 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.None, false /* twoCanvas */, true /* resizeByComp */);
}
@Test
public void test01_Compo_Flow_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 1 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Flow, false /* twoCanvas */, true /* resizeByComp */);
}
@Test
public void test02_Compo_DblBrd_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 2 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.DoubleBorderCenterSurrounded, false /* twoCanvas */, true /* resizeByComp */);
}
@Test
public void test03_Compo_Box_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 3 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Box, false /* twoCanvas */, true /* resizeByComp */);
}
@Test
public void test04_Compo_Split_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 4 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Split, false /* twoCanvas */, true /* resizeByComp */);
}
@Test
public void test05_Compo_Flow_Two() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 5 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Flow, true/* twoCanvas */, true /* resizeByComp */);
}
@Test
public void test06_Compo_DblBrd_Two() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 6 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.DoubleBorderCenterSurrounded, true/* twoCanvas */, true /* resizeByComp */);
}
@Test
public void test07_Compo_Box_Two() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 7 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Box, true/* twoCanvas */, true /* resizeByComp */);
}
@Test
public void test08_Compo_Split_Two() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 8 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Split, true/* twoCanvas */, true /* resizeByComp */);
}
@Test
public void test10_Frame_None_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 10 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.None, false /* twoCanvas */, false /* resizeByComp */);
}
@Test
public void test11_Frame_Flow_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 11 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Flow, false /* twoCanvas */, false /* resizeByComp */);
}
@Test
public void test12_Frame_DblBrd_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 12 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.DoubleBorderCenterSurrounded, false /* twoCanvas */, false /* resizeByComp */);
}
@Test
public void test13_Frame_Box_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 13 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Box, false /* twoCanvas */, false /* resizeByComp */);
}
@Test
public void test14_Frame_Split_One() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 14) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Split, false /* twoCanvas */, false /* resizeByComp */);
}
@Test
public void test15_Frame_Flow_Two() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 15 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Flow, true/* twoCanvas */, false /* resizeByComp */);
}
@Test
public void test16_Frame_DblBrd_Two() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 16 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.DoubleBorderCenterSurrounded, true/* twoCanvas */, false /* resizeByComp */);
}
@Test
public void test17_Frame_Box_Two() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 17 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Box, true/* twoCanvas */, false /* resizeByComp */);
}
@Test
public void test18_Frame_Split_Two() throws InterruptedException, InvocationTargetException {
if( testNum != -1 && testNum != 18 ) { return ; }
final GLCapabilities caps = new GLCapabilities(getGLP());
runTestGL(caps, FrameLayout.Split, true/* twoCanvas */, false /* resizeByComp */);
}
static int testNum = -1;
public static void main(final String args[]) {
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
i++;
duration = MiscUtils.atol(args[i], duration);
} else if(args[i].equals("-test")) {
i++;
testNum = MiscUtils.atoi(args[i], 0);
} else if(args[i].equals("-noresize")) {
rwsize = null;
} else if(args[i].equals("-es2")) {
forceES2 = true;
} else if(args[i].equals("-gl3")) {
forceGL3 = true;
} else if(args[i].equals("-vsync")) {
i++;
swapInterval = MiscUtils.atoi(args[i], swapInterval);
}
}
System.err.println("resize "+rwsize);
System.err.println("forceES2 "+forceES2);
System.err.println("forceGL3 "+forceGL3);
System.err.println("swapInterval "+swapInterval);
org.junit.runner.JUnitCore.main(TestBug816OSXCALayerPos01AWT.class.getName());
}
}