All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.badlogic.gdx.scenes.scene2d.ui.Table Maven / Gradle / Ivy

/*******************************************************************************
 * 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.scenes.scene2d.ui;

import java.util.Arrays;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Value.Fixed;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.Layout;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Null;
import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.Pools;

/** A group that sizes and positions children using table constraints.
 * 

* Children added with {@link #add(Actor...)} (and similar methods returning a {@link Cell}) are laid out in rows and columns. * Other children may be added with {@link #addActor(Actor)} (and similar methods) but are not laid out automatically and don't * affect the preferred or minimum sizes. *

* By default, {@link #getTouchable()} is {@link Touchable#childrenOnly}. *

* The preferred and minimum sizes are that of the children laid out in columns and rows. * @author Nathan Sweet */ public class Table extends WidgetGroup { static public Color debugTableColor = new Color(0, 0, 1, 1); static public Color debugCellColor = new Color(1, 0, 0, 1); static public Color debugActorColor = new Color(0, 1, 0, 1); static final Pool cellPool = new Pool() { protected Cell newObject () { return new Cell(); } }; static private float[] columnWeightedWidth, rowWeightedHeight; private int columns, rows; private boolean implicitEndRow; private final Array cells = new Array(4); private final Cell cellDefaults; private final Array columnDefaults = new Array(2); private Cell rowDefaults; private boolean sizeInvalid = true; private float[] columnMinWidth, rowMinHeight; private float[] columnPrefWidth, rowPrefHeight; private float tableMinWidth, tableMinHeight; private float tablePrefWidth, tablePrefHeight; private float[] columnWidth, rowHeight; private float[] expandWidth, expandHeight; Value padTop = backgroundTop, padLeft = backgroundLeft, padBottom = backgroundBottom, padRight = backgroundRight; int align = Align.center; Debug debug = Debug.none; Array debugRects; @Null Drawable background; private boolean clip; private @Null Skin skin; boolean round = true; public Table () { this(null); } /** Creates a table with a skin, which is required to use {@link #add(CharSequence)} or {@link #add(CharSequence, String)}. */ public Table (@Null Skin skin) { this.skin = skin; cellDefaults = obtainCell(); setTransform(false); setTouchable(Touchable.childrenOnly); } private Cell obtainCell () { Cell cell = cellPool.obtain(); cell.setTable(this); return cell; } public void draw (Batch batch, float parentAlpha) { validate(); if (isTransform()) { applyTransform(batch, computeTransform()); drawBackground(batch, parentAlpha, 0, 0); if (clip) { batch.flush(); float padLeft = this.padLeft.get(this), padBottom = this.padBottom.get(this); if (clipBegin(padLeft, padBottom, getWidth() - padLeft - padRight.get(this), getHeight() - padBottom - padTop.get(this))) { drawChildren(batch, parentAlpha); batch.flush(); clipEnd(); } } else drawChildren(batch, parentAlpha); resetTransform(batch); } else { drawBackground(batch, parentAlpha, getX(), getY()); super.draw(batch, parentAlpha); } } /** Called to draw the background, before clipping is applied (if enabled). Default implementation draws the background * drawable. */ protected void drawBackground (Batch batch, float parentAlpha, float x, float y) { if (background == null) return; Color color = getColor(); batch.setColor(color.r, color.g, color.b, color.a * parentAlpha); background.draw(batch, x, y, getWidth(), getHeight()); } /** Sets the background drawable from the skin and adjusts the table's padding to match the background. This may only be called * if a skin has been set with {@link Table#Table(Skin)} or {@link #setSkin(Skin)}. * @see #setBackground(Drawable) */ public void setBackground (String drawableName) { if (skin == null) throw new IllegalStateException("Table must have a skin set to use this method."); setBackground(skin.getDrawable(drawableName)); } /** @param background May be null to clear the background. */ public void setBackground (@Null Drawable background) { if (this.background == background) return; float padTopOld = getPadTop(), padLeftOld = getPadLeft(), padBottomOld = getPadBottom(), padRightOld = getPadRight(); this.background = background; // The default pad values use the background's padding. float padTopNew = getPadTop(), padLeftNew = getPadLeft(), padBottomNew = getPadBottom(), padRightNew = getPadRight(); if (padTopOld + padBottomOld != padTopNew + padBottomNew || padLeftOld + padRightOld != padLeftNew + padRightNew) invalidateHierarchy(); else if (padTopOld != padTopNew || padLeftOld != padLeftNew || padBottomOld != padBottomNew || padRightOld != padRightNew) invalidate(); } /** @see #setBackground(Drawable) */ public Table background (@Null Drawable background) { setBackground(background); return this; } /** @see #setBackground(String) */ public Table background (String drawableName) { setBackground(drawableName); return this; } public @Null Drawable getBackground () { return background; } public @Null Actor hit (float x, float y, boolean touchable) { if (clip) { if (touchable && getTouchable() == Touchable.disabled) return null; if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) return null; } return super.hit(x, y, touchable); } /** Sets {@link #setClip(boolean)} to true. */ public Table clip () { setClip(true); return this; } public Table clip (boolean enabled) { setClip(enabled); return this; } /** Causes the contents to be clipped if they exceed the table's bounds. Enabling clipping sets {@link #setTransform(boolean)} * to true. */ public void setClip (boolean enabled) { clip = enabled; setTransform(enabled); invalidate(); } public boolean getClip () { return clip; } public void invalidate () { sizeInvalid = true; super.invalidate(); } /** Adds a new cell to the table with the specified actor. */ public Cell add (@Null T actor) { Cell cell = obtainCell(); cell.actor = actor; // The row was ended for layout, not by the user, so revert it. if (implicitEndRow) { implicitEndRow = false; rows--; cells.peek().endRow = false; } int cellCount = cells.size; if (cellCount > 0) { // Set cell column and row. Cell lastCell = cells.peek(); if (!lastCell.endRow) { cell.column = lastCell.column + lastCell.colspan; cell.row = lastCell.row; } else { cell.column = 0; cell.row = lastCell.row + 1; } // Set the index of the cell above. if (cell.row > 0) { Object[] cells = this.cells.items; outer: for (int i = cellCount - 1; i >= 0; i--) { Cell other = (Cell)cells[i]; for (int column = other.column, nn = column + other.colspan; column < nn; column++) { if (column == cell.column) { cell.cellAboveIndex = i; break outer; } } } } } else { cell.column = 0; cell.row = 0; } cells.add(cell); cell.set(cellDefaults); if (cell.column < columnDefaults.size) cell.merge(columnDefaults.get(cell.column)); cell.merge(rowDefaults); if (actor != null) addActor(actor); return cell; } public Table add (Actor... actors) { for (int i = 0, n = actors.length; i < n; i++) add(actors[i]); return this; } /** Adds a new cell with a label. This may only be called if a skin has been set with {@link Table#Table(Skin)} or * {@link #setSkin(Skin)}. */ public Cell





© 2015 - 2024 Weber Informatics LLC | Privacy Policy