1/******************************************************************************* 2 * Copyright (c) 2011, Nathan Sweet <nathan.sweet@gmail.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * * Neither the name of the <organization> nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 ******************************************************************************/ 27 28package com.badlogic.gdx.scenes.scene2d.ui; 29 30import com.badlogic.gdx.scenes.scene2d.Actor; 31import com.badlogic.gdx.scenes.scene2d.Touchable; 32import com.badlogic.gdx.scenes.scene2d.utils.Layout; 33import com.badlogic.gdx.utils.Array; 34import com.badlogic.gdx.utils.SnapshotArray; 35 36/** A stack is a container that sizes its children to its size and positions them at 0,0 on top of each other. 37 * <p> 38 * The preferred and min size of the stack is the largest preferred and min size of any children. The max size of the stack is the 39 * smallest max size of any children. 40 * @author Nathan Sweet */ 41public class Stack extends WidgetGroup { 42 private float prefWidth, prefHeight, minWidth, minHeight, maxWidth, maxHeight; 43 private boolean sizeInvalid = true; 44 45 public Stack () { 46 setTransform(false); 47 setWidth(150); 48 setHeight(150); 49 setTouchable(Touchable.childrenOnly); 50 } 51 52 public Stack (Actor... actors) { 53 this(); 54 for (Actor actor : actors) 55 addActor(actor); 56 } 57 58 public void invalidate () { 59 super.invalidate(); 60 sizeInvalid = true; 61 } 62 63 private void computeSize () { 64 sizeInvalid = false; 65 prefWidth = 0; 66 prefHeight = 0; 67 minWidth = 0; 68 minHeight = 0; 69 maxWidth = 0; 70 maxHeight = 0; 71 SnapshotArray<Actor> children = getChildren(); 72 for (int i = 0, n = children.size; i < n; i++) { 73 Actor child = children.get(i); 74 float childMaxWidth, childMaxHeight; 75 if (child instanceof Layout) { 76 Layout layout = (Layout)child; 77 prefWidth = Math.max(prefWidth, layout.getPrefWidth()); 78 prefHeight = Math.max(prefHeight, layout.getPrefHeight()); 79 minWidth = Math.max(minWidth, layout.getMinWidth()); 80 minHeight = Math.max(minHeight, layout.getMinHeight()); 81 childMaxWidth = layout.getMaxWidth(); 82 childMaxHeight = layout.getMaxHeight(); 83 } else { 84 prefWidth = Math.max(prefWidth, child.getWidth()); 85 prefHeight = Math.max(prefHeight, child.getHeight()); 86 minWidth = Math.max(minWidth, child.getWidth()); 87 minHeight = Math.max(minHeight, child.getHeight()); 88 childMaxWidth = 0; 89 childMaxHeight = 0; 90 } 91 if (childMaxWidth > 0) maxWidth = maxWidth == 0 ? childMaxWidth : Math.min(maxWidth, childMaxWidth); 92 if (childMaxHeight > 0) maxHeight = maxHeight == 0 ? childMaxHeight : Math.min(maxHeight, childMaxHeight); 93 } 94 } 95 96 public void add (Actor actor) { 97 addActor(actor); 98 } 99 100 public void layout () { 101 if (sizeInvalid) computeSize(); 102 float width = getWidth(), height = getHeight(); 103 Array<Actor> children = getChildren(); 104 for (int i = 0, n = children.size; i < n; i++) { 105 Actor child = children.get(i); 106 child.setBounds(0, 0, width, height); 107 if (child instanceof Layout) ((Layout)child).validate(); 108 } 109 } 110 111 public float getPrefWidth () { 112 if (sizeInvalid) computeSize(); 113 return prefWidth; 114 } 115 116 public float getPrefHeight () { 117 if (sizeInvalid) computeSize(); 118 return prefHeight; 119 } 120 121 public float getMinWidth () { 122 if (sizeInvalid) computeSize(); 123 return minWidth; 124 } 125 126 public float getMinHeight () { 127 if (sizeInvalid) computeSize(); 128 return minHeight; 129 } 130 131 public float getMaxWidth () { 132 if (sizeInvalid) computeSize(); 133 return maxWidth; 134 } 135 136 public float getMaxHeight () { 137 if (sizeInvalid) computeSize(); 138 return maxHeight; 139 } 140} 141