/* * Copyright 2016 MovingBlocks * * 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 org.terasology.rendering.nui.layouts; import org.junit.Before; import org.junit.Test; import org.terasology.math.geom.Rect2i; import org.terasology.math.geom.Vector2f; import org.terasology.math.geom.Vector2i; import org.terasology.rendering.nui.Canvas; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.terasology.math.TeraMath.ceilToInt; public class ZoomableLayoutTest { private static final int CANVAS_WIDTH = 100; private static final int CANVAS_HEIGHT = 50; private static final float WORLD_WIDTH = 100; private static final float WORLD_HEIGHT = 100; private ZoomableLayout zoomableLayout; private Canvas canvas; private ZoomableLayout.PositionalWidget item1; private ZoomableLayout.PositionalWidget item2; private ZoomableLayout.PositionalWidget item3; private Vector2f pos1; private Vector2f pos2; private Vector2f pos3; private Vector2f size1; private Vector2f size2; private Vector2f size3; @Before public void setup() { zoomableLayout = new ZoomableLayout(); item1 = mock(ZoomableLayout.PositionalWidget.class); item2 = mock(ZoomableLayout.PositionalWidget.class); item3 = mock(ZoomableLayout.PositionalWidget.class); canvas = mock(Canvas.class); // // +------+ // | 1 | // +------+ // +-+ // |2| // +-+ // // +---+ // | 3 | // | | // +---+ //positions of the widgets in the world pos1 = new Vector2f(10, 10); pos2 = new Vector2f(40, 40); pos3 = new Vector2f(80, 70); when(item1.getPosition()).thenReturn(pos1); when(item2.getPosition()).thenReturn(pos2); when(item3.getPosition()).thenReturn(pos3); //size of widgets size1 = new Vector2f(20, 10); size2 = new Vector2f(5, 10); size3 = new Vector2f(10, 20); when(item1.getSize()).thenReturn(size1); when(item2.getSize()).thenReturn(size2); when(item3.getSize()).thenReturn(size3); when(item1.isVisible()).thenReturn(true); when(item2.isVisible()).thenReturn(true); when(item3.isVisible()).thenReturn(true); Vector2i availableSize = new Vector2i(CANVAS_WIDTH, CANVAS_HEIGHT); when(canvas.size()).thenReturn(availableSize); zoomableLayout.setWindowSize(new Vector2f(WORLD_WIDTH, WORLD_HEIGHT)); zoomableLayout.addWidget(item1); zoomableLayout.addWidget(item2); zoomableLayout.addWidget(item3); } @Test public void testScaling() throws Exception { zoomableLayout.onDraw(canvas); //world size scaled to fit ratio of screen size - world size now 200 x 100 assertEquals(zoomableLayout.getWindowSize(), new Vector2f(WORLD_WIDTH * 2, WORLD_HEIGHT)); assertEquals(zoomableLayout.getScreenSize(), new Vector2i(CANVAS_WIDTH, CANVAS_HEIGHT)); assertEquals(zoomableLayout.getPixelSize(), new Vector2f(CANVAS_WIDTH / (WORLD_WIDTH * 2), CANVAS_HEIGHT / WORLD_HEIGHT)); //coordinates on widgets scaled down by half verify(canvas).drawWidget(item1, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos1.x / 2), ceilToInt(pos1.y / 2)), new Vector2i(ceilToInt((pos1.x + size1.x) / 2), ceilToInt((pos1.y + size1.y) / 2)))); verify(canvas).drawWidget(item2, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos2.x / 2), ceilToInt(pos2.y / 2)), new Vector2i(ceilToInt((pos2.x + size2.x) / 2), ceilToInt((pos2.y + size2.y) / 2)))); verify(canvas).drawWidget(item3, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos3.x / 2), ceilToInt(pos3.y / 2)), new Vector2i(ceilToInt((pos3.x + size3.x) / 2), ceilToInt((pos3.y + size3.y) / 2)))); } @Test public void testZoomOut() throws Exception { zoomableLayout.onDraw(canvas); //zoom out 2x from top left corner zoomableLayout.zoom(2, 2, new Vector2i(0, 0)); zoomableLayout.onDraw(canvas); //world size doubled assertEquals(zoomableLayout.getWindowSize(), new Vector2f(WORLD_WIDTH * 2 * 2, WORLD_HEIGHT * 2)); assertEquals(zoomableLayout.getScreenSize(), new Vector2i(CANVAS_WIDTH, CANVAS_HEIGHT)); assertEquals(zoomableLayout.getPixelSize(), new Vector2f(CANVAS_WIDTH / (WORLD_WIDTH * 2 * 2), CANVAS_HEIGHT / (WORLD_HEIGHT * 2))); verify(canvas).drawWidget(item1, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos1.x / 4), ceilToInt(pos1.y / 4)), new Vector2i(ceilToInt((pos1.x + size1.x) / 4), ceilToInt((pos1.y + size1.y) / 4)))); verify(canvas).drawWidget(item2, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos2.x / 4), ceilToInt(pos2.y / 4)), new Vector2i(ceilToInt((pos2.x + size2.x) / 4), ceilToInt((pos2.y + size2.y) / 4)))); verify(canvas).drawWidget(item3, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos3.x / 4), ceilToInt(pos3.y / 4)), new Vector2i(ceilToInt((pos3.x + size3.x) / 4), ceilToInt((pos3.y + size3.y) / 4)))); } @Test public void testZoomInAndDrag() throws Exception { zoomableLayout.onDraw(canvas); //zoom in 2x towards left top corner zoomableLayout.zoom(0.5f, 0.5f, new Vector2i(0, 0)); zoomableLayout.onDraw(canvas); //world size halved assertEquals(zoomableLayout.getWindowSize(), new Vector2f(WORLD_WIDTH, WORLD_HEIGHT / 2)); assertEquals(zoomableLayout.getScreenSize(), new Vector2i(CANVAS_WIDTH, CANVAS_HEIGHT)); assertEquals(zoomableLayout.getPixelSize(), new Vector2f(CANVAS_WIDTH / WORLD_WIDTH, CANVAS_HEIGHT / (WORLD_HEIGHT / 2))); verify(canvas).drawWidget(item1, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos1.x), ceilToInt(pos1.y)), new Vector2i(ceilToInt(pos1.x + size1.x), ceilToInt(pos1.y + size1.y)))); verify(canvas).drawWidget(item2, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos2.x), ceilToInt(pos2.y)), new Vector2i(ceilToInt(pos2.x + size2.x), ceilToInt(pos2.y + size2.y)))); verify(canvas).drawWidget(item3, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos3.x), ceilToInt(pos3.y)), new Vector2i(ceilToInt(pos3.x + size3.x), ceilToInt(pos3.y + size3.y)))); //simulate drag to item2 zoomableLayout.setWindowPosition(pos2); zoomableLayout.onDraw(canvas); //item1 out of canvas verify(canvas).drawWidget(item1, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos1.x - pos2.x), ceilToInt(pos1.y - pos2.y)), new Vector2i(ceilToInt(pos1.x + size1.x - pos2.x), ceilToInt(pos1.y + size1.y - pos2.y)))); verify(canvas).drawWidget(item2, Rect2i.createFromMinAndMax(Vector2i.zero(), new Vector2i(ceilToInt(size2.x), ceilToInt(size2.y)))); verify(canvas).drawWidget(item3, Rect2i.createFromMinAndMax(new Vector2i(ceilToInt(pos3.x - pos2.x), ceilToInt(pos3.y - pos2.y)), new Vector2i(ceilToInt(pos3.x + size3.x - pos2.x), ceilToInt(pos3.y + size3.y - pos2.y)))); } }