Package com.badlogic.gdx.scenes.scene2d.ui

Source Code of com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle

/*******************************************************************************
* 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.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
import com.badlogic.gdx.graphics.g2d.BitmapFontCache;
import com.badlogic.gdx.scenes.scene2d.utils.Align;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.utils.StringBuilder;

/** A text label, with optional word wrapping.
* <p>
* The preferred size of the label is determined by the actual text bounds, unless {@link #setWrap(boolean) word wrap} is enabled.
* @author Nathan Sweet */
public class Label extends Widget {
  static private final Color tempColor = new Color();

  private LabelStyle style;
  private final TextBounds bounds = new TextBounds();
  private final StringBuilder text = new StringBuilder();
  private StringBuilder tempText;
  private BitmapFontCache cache;
  private int labelAlign = Align.left;
  private HAlignment lineAlign = HAlignment.LEFT;
  private boolean wrap;
  private float lastPrefHeight;
  private boolean sizeInvalid = true;
  private float fontScaleX = 1, fontScaleY = 1;
  private boolean ellipse;

  public Label (CharSequence text, Skin skin) {
    this(text, skin.get(LabelStyle.class));
  }

  public Label (CharSequence text, Skin skin, String styleName) {
    this(text, skin.get(styleName, LabelStyle.class));
  }

  /** Creates a label, using a {@link LabelStyle} that has a BitmapFont with the specified name from the skin and the specified
   * color. */
  public Label (CharSequence text, Skin skin, String fontName, Color color) {
    this(text, new LabelStyle(skin.getFont(fontName), color));
  }

  /** Creates a label, using a {@link LabelStyle} that has a BitmapFont with the specified name and the specified color from the
   * skin. */
  public Label (CharSequence text, Skin skin, String fontName, String colorName) {
    this(text, new LabelStyle(skin.getFont(fontName), skin.getColor(colorName)));
  }

  public Label (CharSequence text, LabelStyle style) {
    if (text != null) this.text.append(text);
    setStyle(style);
    setSize(getPrefWidth(), getPrefHeight());
  }

  public void setStyle (LabelStyle style) {
    if (style == null) throw new IllegalArgumentException("style cannot be null.");
    if (style.font == null) throw new IllegalArgumentException("Missing LabelStyle font.");
    this.style = style;
    cache = new BitmapFontCache(style.font, style.font.usesIntegerPositions());
    invalidateHierarchy();
  }

  /** Returns the label's style. Modifying the returned style may not have an effect until {@link #setStyle(LabelStyle)} is
   * called. */
  public LabelStyle getStyle () {
    return style;
  }

  /** @param newText May be null. */
  public void setText (CharSequence newText) {
    if (newText instanceof StringBuilder) {
      if (text.equals(newText)) return;
      text.setLength(0);
      text.append((StringBuilder)newText);
    } else {
      if (newText == null) newText = "";
      if (textEquals(newText)) return;
      text.setLength(0);
      text.append(newText);
    }
    invalidateHierarchy();
  }

  public boolean textEquals (CharSequence other) {
    int length = text.length;
    char[] chars = text.chars;
    if (length != other.length()) return false;
    for (int i = 0; i < length; i++)
      if (chars[i] != other.charAt(i)) return false;
    return true;
  }

  public StringBuilder getText () {
    return text;
  }

  public void invalidate () {
    super.invalidate();
    sizeInvalid = true;
  }

  private void scaleAndComputeSize () {
    BitmapFont font = cache.getFont();
    float oldScaleX = font.getScaleX();
    float oldScaleY = font.getScaleY();
    if (fontScaleX != 1 || fontScaleY != 1) font.setScale(fontScaleX, fontScaleY);

    computeSize();

    if (fontScaleX != 1 || fontScaleY != 1) font.setScale(oldScaleX, oldScaleY);
  }

  private void computeSize () {
    sizeInvalid = false;
    if (wrap) {
      float width = getWidth();
      if (style.background != null) width -= style.background.getLeftWidth() + style.background.getRightWidth();
      bounds.set(cache.getFont().getWrappedBounds(text, width));
    } else
      bounds.set(cache.getFont().getMultiLineBounds(text));
  }

  public void layout () {
    BitmapFont font = cache.getFont();
    float oldScaleX = font.getScaleX();
    float oldScaleY = font.getScaleY();
    if (fontScaleX != 1 || fontScaleY != 1) font.setScale(fontScaleX, fontScaleY);

    if (sizeInvalid) computeSize();

    if (wrap) {
      float prefHeight = getPrefHeight();
      if (prefHeight != lastPrefHeight) {
        lastPrefHeight = prefHeight;
        invalidateHierarchy();
      }
    }

    float width = getWidth(), height = getHeight();
    StringBuilder text;
    if (ellipse && width < bounds.width) {
      float ellipseWidth = font.getBounds("...").width;
      text = tempText != null ? tempText : (tempText = new StringBuilder());
      text.setLength(0);
      if (width > ellipseWidth) {
        text.append(this.text, 0, font.computeVisibleGlyphs(this.text, 0, this.text.length, width - ellipseWidth));
        text.append("...");
      }
    } else
      text = this.text;

    Drawable background = style.background;
    float x = 0, y = 0;
    if (background != null) {
      x = background.getLeftWidth();
      y = background.getBottomHeight();
      width -= background.getLeftWidth() + background.getRightWidth();
      height -= background.getBottomHeight() + background.getTopHeight();
    }
    if ((labelAlign & Align.top) != 0) {
      y += cache.getFont().isFlipped() ? 0 : height - bounds.height;
      y += style.font.getDescent();
    } else if ((labelAlign & Align.bottom) != 0) {
      y += cache.getFont().isFlipped() ? height - bounds.height : 0;
      y -= style.font.getDescent();
    } else
      y += (int)((height - bounds.height) / 2);
    if (!cache.getFont().isFlipped()) y += bounds.height;

    if ((labelAlign & Align.left) == 0) {
      if ((labelAlign & Align.right) != 0)
        x += width - bounds.width;
      else
        x += (int)((width - bounds.width) / 2);
    }

    if (wrap)
      cache.setWrappedText(text, x, y, bounds.width, lineAlign);
    else
      cache.setMultiLineText(text, x, y, bounds.width, lineAlign);

    if (fontScaleX != 1 || fontScaleY != 1) font.setScale(oldScaleX, oldScaleY);
  }

  public void draw (Batch batch, float parentAlpha) {
    validate();
    Color color = tempColor.set(getColor());
    color.a *= parentAlpha;
    if (style.background != null) {
      batch.setColor(color.r, color.g, color.b, color.a);
      style.background.draw(batch, getX(), getY(), getWidth(), getHeight());
    }
    if (style.fontColor != null) color.mul(style.fontColor);
    cache.setColors(color);
    cache.setPosition(getX(), getY());
    cache.draw(batch);
  }

  public float getPrefWidth () {
    if (wrap) return 0;
    if (sizeInvalid) scaleAndComputeSize();
    float width = bounds.width;
    Drawable background = style.background;
    if (background != null) width += background.getLeftWidth() + background.getRightWidth();
    return width;
  }

  public float getPrefHeight () {
    if (sizeInvalid) scaleAndComputeSize();
    float height = bounds.height - style.font.getDescent() * 2;
    Drawable background = style.background;
    if (background != null) height += background.getTopHeight() + background.getBottomHeight();
    return height;
  }

  public TextBounds getTextBounds () {
    if (sizeInvalid) scaleAndComputeSize();
    return bounds;
  }

  /** If false, the text will only wrap where it contains newlines (\n). The preferred size of the label will be the text bounds.
   * If true, the text will word wrap using the width of the label. The preferred width of the label will be 0, it is expected
   * that the something external will set the width of the label. Default is false.
   * <p>
   * When wrap is enabled, the label's preferred height depends on the width of the label. In some cases the parent of the label
   * will need to layout twice: once to set the width of the label and a second time to adjust to the label's new preferred
   * height. */
  public void setWrap (boolean wrap) {
    this.wrap = wrap;
    invalidateHierarchy();
  }

  /** @param alignment Aligns each line of text horizontally and all the text vertically.
   * @see Align */
  public void setAlignment (int alignment) {
    setAlignment(alignment, alignment);
  }

  /** @param labelAlign Aligns all the text with the label widget.
   * @param lineAlign Aligns each line of text (left, right, or center).
   * @see Align */
  public void setAlignment (int labelAlign, int lineAlign) {
    this.labelAlign = labelAlign;

    if ((lineAlign & Align.left) != 0)
      this.lineAlign = HAlignment.LEFT;
    else if ((lineAlign & Align.right) != 0)
      this.lineAlign = HAlignment.RIGHT;
    else
      this.lineAlign = HAlignment.CENTER;

    invalidate();
  }

  public void setFontScale (float fontScale) {
    this.fontScaleX = fontScale;
    this.fontScaleY = fontScale;
    invalidateHierarchy();
  }

  public void setFontScale (float fontScaleX, float fontScaleY) {
    this.fontScaleX = fontScaleX;
    this.fontScaleY = fontScaleY;
    invalidateHierarchy();
  }

  public float getFontScaleX () {
    return fontScaleX;
  }

  public void setFontScaleX (float fontScaleX) {
    this.fontScaleX = fontScaleX;
    invalidateHierarchy();
  }

  public float getFontScaleY () {
    return fontScaleY;
  }

  public void setFontScaleY (float fontScaleY) {
    this.fontScaleY = fontScaleY;
    invalidateHierarchy();
  }

  /** When true the text will be truncated with an ellipse if it does not fit within the width of the label. Default is false. */
  public void setEllipse (boolean ellipse) {
    this.ellipse = ellipse;
  }

  /** Allows subclasses to access the cache in {@link #draw(Batch, float)}. */
  protected BitmapFontCache getBitmapFontCache () {
    return cache;
  }

  /** The style for a label, see {@link Label}.
   * @author Nathan Sweet */
  static public class LabelStyle {
    public BitmapFont font;
    /** Optional. */
    public Color fontColor;
    /** Optional. */
    public Drawable background;

    public LabelStyle () {
    }

    public LabelStyle (BitmapFont font, Color fontColor) {
      this.font = font;
      this.fontColor = fontColor;
    }

    public LabelStyle (LabelStyle style) {
      this.font = style.font;
      if (style.fontColor != null) fontColor = new Color(style.fontColor);
      background = style.background;
    }
  }
}
TOP

Related Classes of com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.