/gdx/src/com/badlogic/gdx/scenes/scene2d/ui/List.java
Java | 231 lines | 170 code | 33 blank | 28 comment | 31 complexity | 28a83e5f020724387e518bc716d2cb8d MD5 | raw file
Possible License(s): CC-BY-SA-3.0, Apache-2.0, GPL-3.0, LGPL-2.1
- /*******************************************************************************
- * 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 com.badlogic.gdx.graphics.Color;
- import com.badlogic.gdx.graphics.g2d.BitmapFont;
- import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
- import com.badlogic.gdx.graphics.g2d.NinePatch;
- import com.badlogic.gdx.graphics.g2d.SpriteBatch;
- import com.badlogic.gdx.math.Rectangle;
- import com.badlogic.gdx.scenes.scene2d.InputEvent;
- import com.badlogic.gdx.scenes.scene2d.InputListener;
- import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.ChangeEvent;
- import com.badlogic.gdx.scenes.scene2d.utils.Cullable;
- import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
- import com.badlogic.gdx.utils.GdxRuntimeException;
- import com.badlogic.gdx.utils.Pools;
-
- /** A list (aka list box) displays textual items and highlights the currently selected item.
- * <p>
- * {@link ChangeEvent} is fired when the list selection changes.
- * <p>
- * The preferred size of the list is determined by the text bounds of the items and the size of the {@link ListStyle#selection}.
- * @author mzechner */
- public class List extends Widget implements Cullable {
- private ListStyle style;
- private String[] items;
- private int selectedIndex;
- private Rectangle cullingArea;
- private float prefWidth, prefHeight;
- private float itemHeight;
- private float textOffsetX, textOffsetY;
-
- public List (Object[] items, Skin skin) {
- this(items, skin.get(ListStyle.class));
- }
-
- public List (Object[] items, Skin skin, String styleName) {
- this(items, skin.get(styleName, ListStyle.class));
- }
-
- public List (Object[] items, ListStyle style) {
- setStyle(style);
- setItems(items);
- setWidth(getPrefWidth());
- setHeight(getPrefHeight());
-
- addListener(new InputListener() {
- public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
- if (pointer == 0 && button != 0) return false;
- List.this.touchDown(y);
- return true;
- }
- });
- }
-
- void touchDown (float y) {
- int oldIndex = selectedIndex;
- selectedIndex = (int)((getHeight() - y) / itemHeight);
- selectedIndex = Math.max(0, selectedIndex);
- selectedIndex = Math.min(items.length - 1, selectedIndex);
- ChangeEvent changeEvent = Pools.obtain(ChangeEvent.class);
- if (fire(changeEvent)) selectedIndex = oldIndex;
- Pools.free(changeEvent);
- }
-
- public void setStyle (ListStyle style) {
- if (style == null) throw new IllegalArgumentException("style cannot be null.");
- this.style = style;
- if (items != null)
- setItems(items);
- else
- invalidateHierarchy();
- }
-
- /** Returns the list's style. Modifying the returned style may not have an effect until {@link #setStyle(ListStyle)} is called. */
- public ListStyle getStyle () {
- return style;
- }
-
- @Override
- public void draw (SpriteBatch batch, float parentAlpha) {
- BitmapFont font = style.font;
- Drawable selectedDrawable = style.selection;
- Color fontColorSelected = style.fontColorSelected;
- Color fontColorUnselected = style.fontColorUnselected;
-
- Color color = getColor();
- batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
-
- float x = getX();
- float y = getY();
-
- font.setColor(fontColorUnselected.r, fontColorUnselected.g, fontColorUnselected.b, fontColorUnselected.a * parentAlpha);
- float itemY = getHeight();
- for (int i = 0; i < items.length; i++) {
- if (cullingArea == null || (itemY - itemHeight <= cullingArea.y + cullingArea.height && itemY >= cullingArea.y)) {
- if (selectedIndex == i) {
- selectedDrawable.draw(batch, x, y + itemY - itemHeight, Math.max(prefWidth, getWidth()), itemHeight);
- font.setColor(fontColorSelected.r, fontColorSelected.g, fontColorSelected.b, fontColorSelected.a * parentAlpha);
- }
- font.draw(batch, items[i], x + textOffsetX, y + itemY - textOffsetY);
- if (selectedIndex == i) {
- font.setColor(fontColorUnselected.r, fontColorUnselected.g, fontColorUnselected.b, fontColorUnselected.a
- * parentAlpha);
- }
- } else if (itemY < cullingArea.y) {
- break;
- }
- itemY -= itemHeight;
- }
- }
-
- /** @return The index of the currently selected item. The top item has an index of 0. */
- public int getSelectedIndex () {
- return selectedIndex;
- }
-
- public void setSelectedIndex (int index) {
- if (index < 0 || index >= items.length)
- throw new GdxRuntimeException("index must be >= 0 and < " + items.length + ": " + index);
- selectedIndex = index;
- }
-
- /** @return The text of the currently selected item or null if the list is empty. */
- public String getSelection () {
- if (items.length == 0) return null;
- return items[selectedIndex];
- }
-
- /** @return The index of the item that was selected, or -1. */
- public int setSelection (String item) {
- selectedIndex = -1;
- for (int i = 0, n = items.length; i < n; i++) {
- if (items[i].equals(item)) {
- selectedIndex = i;
- break;
- }
- }
- return selectedIndex;
- }
-
- public void setItems (Object[] objects) {
- if (objects == null) throw new IllegalArgumentException("items cannot be null.");
-
- if (!(objects instanceof String[])) {
- String[] strings = new String[objects.length];
- for (int i = 0, n = objects.length; i < n; i++)
- strings[i] = String.valueOf(objects[i]);
- items = strings;
- } else
- items = (String[])objects;
-
- selectedIndex = 0;
-
- final BitmapFont font = style.font;
- final Drawable selectedDrawable = style.selection;
-
- itemHeight = font.getCapHeight() - font.getDescent() * 2;
- itemHeight += selectedDrawable.getTopHeight() + selectedDrawable.getBottomHeight();
- prefWidth += selectedDrawable.getLeftWidth() + selectedDrawable.getRightWidth();
- textOffsetX = selectedDrawable.getLeftWidth();
- textOffsetY = selectedDrawable.getTopHeight() - font.getDescent();
-
- prefWidth = 0;
- for (int i = 0; i < items.length; i++) {
- TextBounds bounds = font.getBounds(items[i]);
- prefWidth = Math.max(bounds.width, prefWidth);
- }
- prefHeight = items.length * itemHeight;
-
- invalidateHierarchy();
- }
-
- public String[] getItems () {
- return items;
- }
-
- public float getPrefWidth () {
- return prefWidth;
- }
-
- public float getPrefHeight () {
- return prefHeight;
- }
-
- public void setCullingArea (Rectangle cullingArea) {
- this.cullingArea = cullingArea;
- }
-
- /** The style for a list, see {@link List}.
- * @author mzechner
- * @author Nathan Sweet */
- static public class ListStyle {
- public BitmapFont font;
- public Color fontColorSelected = new Color(1, 1, 1, 1);
- public Color fontColorUnselected = new Color(1, 1, 1, 1);
- public Drawable selection;
-
- public ListStyle () {
- }
-
- public ListStyle (BitmapFont font, Color fontColorSelected, Color fontColorUnselected, Drawable selection) {
- this.font = font;
- this.fontColorSelected.set(fontColorSelected);
- this.fontColorUnselected.set(fontColorUnselected);
- this.selection = selection;
- }
-
- public ListStyle (ListStyle style) {
- this.font = style.font;
- this.fontColorSelected.set(style.fontColorSelected);
- this.fontColorUnselected.set(style.fontColorUnselected);
- this.selection = style.selection;
- }
- }
- }