/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.tests;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Container;
import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import com.badlogic.gdx.tests.utils.GdxTest;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
/** This tests both {@link Actor#parentToLocalCoordinates(Vector2)} and {@link Actor#localToParentCoordinates(Vector2)}. */
public class GroupTest extends GdxTest {
Stage stage;
SpriteBatch batch;
BitmapFont font;
ShapeRenderer renderer;
TextureRegion region;
TestGroup group1;
TestGroup group2;
HorizontalGroup horiz, horizWrap;
VerticalGroup vert, vertWrap;
public void create () {
batch = new SpriteBatch();
font = new BitmapFont();
renderer = new ShapeRenderer();
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
region = new TextureRegion(new Texture(Gdx.files.internal("data/group-debug.png")));
group2 = new TestGroup("group2");
group2.setTransform(true);
stage.addActor(group2);
group1 = new TestGroup("group1");
group1.setTransform(true);
group2.addActor(group1);
LabelStyle style = new LabelStyle();
style.font = new BitmapFont();
Texture texture = new Texture(Gdx.files.internal("data/badlogic.jpg"));
horiz = new HorizontalGroup().pad(10, 20, 30, 40).top().space(5).reverse();
for (int i = 1; i <= 15; i++) {
horiz.addActor(new Label(i + ",", style));
if (i == 7) horiz.addActor(new Container(new Image(texture)).size(10));
}
horiz.addActor(new Container(new Image(texture)).fill().prefSize(30));
horiz.debug();
horiz.setPosition(10, 10);
horiz.pack();
stage.addActor(horiz);
horizWrap = new HorizontalGroup().wrap().pad(10, 20, 30, 40).right().rowBottom().space(5).wrapSpace(15).reverse();
for (int i = 1; i <= 15; i++) {
horizWrap.addActor(new Label(i + ",", style));
if (i == 7) horizWrap.addActor(new Container(new Image(texture)).prefSize(10).fill());
}
horizWrap.addActor(new Container(new Image(texture)).prefSize(30));
horizWrap.debug();
horizWrap.setBounds(10, 85, 150, 40);
stage.addActor(horizWrap);
vert = new VerticalGroup().pad(10, 20, 30, 40).top().space(5).reverse();
for (int i = 1; i <= 8; i++) {
vert.addActor(new Label(i + ",", style));
if (i == 4) vert.addActor(new Container(new Image(texture)).size(10));
}
vert.addActor(new Container(new Image(texture)).size(30));
vert.debug();
vert.setPosition(515, 10);
vert.pack();
stage.addActor(vert);
vertWrap = new VerticalGroup().wrap().pad(10, 20, 30, 40).bottom().columnRight().space(5).wrapSpace(15).reverse();
for (int i = 1; i <= 8; i++) {
vertWrap.addActor(new Label(i + ",", style));
if (i == 4) vertWrap.addActor(new Container(new Image(texture)).prefSize(10).fill());
}
vertWrap.addActor(new Container(new Image(texture)).prefSize(30));
vertWrap.debug();
vertWrap.setBounds(610, 10, 150, 40);
stage.addActor(vertWrap);
}
public void render () {
horiz.setVisible(true);
horiz.setWidth(Gdx.input.getX() - horiz.getX());
// horiz.setWidth(200);
horiz.setHeight(100);
horiz.fill();
horiz.expand();
horiz.invalidate();
horizWrap.setVisible(true);
horizWrap.fill();
horizWrap.expand();
horizWrap.setWidth(Gdx.input.getX() - horizWrap.getX());
// horizWrap.setHeight(horizWrap.getPrefHeight());
horizWrap.setHeight(200);
vert.setHeight(Gdx.graphics.getHeight() - Gdx.input.getY() - vert.getY());
// vert.setWidth(200);
vertWrap.setHeight(Gdx.graphics.getHeight() - Gdx.input.getY() - vertWrap.getY());
// vertWrap.setWidth(vertWrap.getPrefWidth());
vertWrap.setWidth(200);
// Vary the transforms to exercise the different code paths.
group2.setBounds(150, 150, 150, 150);
group2.setRotation(45);
group2.setOrigin(150, 150);
group2.setScale(1.25f);
group1.setBounds(150, 150, 50, 50);
group1.setRotation(45);
group1.setOrigin(25, 25);
group1.setScale(1.3f);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
renderer.setProjectionMatrix(batch.getProjectionMatrix());
renderer.begin(ShapeType.Filled);
if (MathUtils.randomBoolean()) { // So we see when they are drawn on top of each other (which should be always).
renderer.setColor(Color.GREEN);
renderer.circle(group1.toScreenCoordinates.x, Gdx.graphics.getHeight() - group1.toScreenCoordinates.y, 5);
renderer.setColor(Color.RED);
renderer.circle(group1.localToParentCoordinates.x, Gdx.graphics.getHeight() - group1.localToParentCoordinates.y, 5);
} else {
renderer.setColor(Color.RED);
renderer.circle(group1.localToParentCoordinates.x, Gdx.graphics.getHeight() - group1.localToParentCoordinates.y, 5);
renderer.setColor(Color.GREEN);
renderer.circle(group1.toScreenCoordinates.x, Gdx.graphics.getHeight() - group1.toScreenCoordinates.y, 5);
}
renderer.end();
}
public void resize (int width, int height) {
stage.getViewport().update(width, height, true);
}
public boolean needsGL20 () {
return false;
}
class TestGroup extends Group {
private String name;
Vector2 toScreenCoordinates = new Vector2();
Vector2 localToParentCoordinates = new Vector2();
float testX = 25;
float testY = 25;
public TestGroup (String name) {
this.name = name;
addListener(new InputListener() {
public boolean mouseMoved (InputEvent event, float x, float y) {
// These come from Actor#parentToLocalCoordinates.
testX = x;
testY = y;
return true;
}
});
}
public void draw (Batch batch, float parentAlpha) {
// Use Stage#toScreenCoordinates, which we know is correct.
toScreenCoordinates.set(testX, testY).sub(getOriginX(), getOriginY()).scl(getScaleX(), getScaleY()).rotate(getRotation())
.add(getOriginX(), getOriginY()).add(getX(), getY());
getStage().toScreenCoordinates(toScreenCoordinates, batch.getTransformMatrix());
// Do the same as toScreenCoordinates via Actor#localToParentCoordinates.
localToAscendantCoordinates(null, localToParentCoordinates.set(testX, testY));
getStage().stageToScreenCoordinates(localToParentCoordinates);
// System.out.println(name + " " + toScreenCoordinates + " " + localToParentCoordinates);
batch.setColor(getColor());
batch.draw(region, getX(), getY(), getOriginX(), getOriginY(), getWidth(), getHeight(), getScaleX(), getScaleY(),
getRotation());
super.draw(batch, parentAlpha);
}
}
}