com.aia.hichef.ui.n.MyWindow.java Source code

Java tutorial

Introduction

Here is the source code for com.aia.hichef.ui.n.MyWindow.java

Source

package com.aia.hichef.ui.n;

/*******************************************************************************
 * 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.
 ******************************************************************************/

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
import com.badlogic.gdx.graphics.g2d.BitmapFontCache;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.Window.WindowStyle;
import com.badlogic.gdx.scenes.scene2d.utils.Align;

/**
 * A table that can be dragged and act as a modal window. The top padding is
 * used as the window's title height.
 * <p>
 * The preferred size of a window is the preferred size of the title text and
 * the children as laid out by the table. After adding children to the window,
 * it can be convenient to call {@link #pack()} to size the window to the size
 * of the children.
 * 
 * @author Nathan Sweet
 */
public class MyWindow extends Table {
    static private final Vector2 tmpPosition = new Vector2();
    static private final Vector2 tmpSize = new Vector2();
    static private final int MOVE = 1 << 5;

    private WindowStyle style;
    private String title;
    private BitmapFontCache titleCache;
    boolean isMovable = true, isModal, isResizable;
    int resizeBorder = 8;
    boolean dragging;
    private int titleAlignment = Align.center;
    boolean keepWithinStage = true;
    Table buttonTable;

    public MyWindow(String title, Skin skin) {
        this(title, skin.get(WindowStyle.class));
        setSkin(skin);
    }

    public MyWindow(String title, Skin skin, String styleName) {
        this(title, skin.get(styleName, WindowStyle.class));
        setSkin(skin);
    }

    public MyWindow(String title, WindowStyle style) {
        if (title == null)
            throw new IllegalArgumentException("title cannot be null.");
        this.title = title;
        setTouchable(Touchable.enabled);
        setClip(true);
        setStyle(style);
        setWidth(150);
        setHeight(150);
        setTitle(title);

        setHeight(100);
        buttonTable = new Table();
        addActor(buttonTable);

        addCaptureListener(new InputListener() {
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                toFront();
                return false;
            }
        });
        addListener(new InputListener() {
            int edge;
            float startX, startY, lastX, lastY;

            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                if (button == 0) {
                    int border = resizeBorder;
                    float width = getWidth(), height = getHeight();
                    edge = 0;
                    if (isResizable) {
                        if (x < border)
                            edge |= Align.left;
                        if (x > width - border)
                            edge |= Align.right;
                        if (y < border)
                            edge |= Align.bottom;
                        if (y > height - border)
                            edge |= Align.top;
                        if (edge != 0)
                            border += 25;
                        if (x < border)
                            edge |= Align.left;
                        if (x > width - border)
                            edge |= Align.right;
                        if (y < border)
                            edge |= Align.bottom;
                        if (y > height - border)
                            edge |= Align.top;
                    }
                    if (isMovable && edge == 0 && y <= height && y >= height - getPadTop() && x >= 0 && x <= width)
                        edge = MOVE;
                    dragging = edge != 0;
                    startX = x;
                    startY = y;
                    lastX = x;
                    lastY = y;
                }
                return edge != 0 || isModal;
            }

            public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
                dragging = false;
            }

            public void touchDragged(InputEvent event, float x, float y, int pointer) {
                if (!dragging)
                    return;
                float width = getWidth(), height = getHeight();
                float windowX = getX(), windowY = getY();

                float minWidth = getMinWidth(), maxWidth = getMaxWidth();
                float minHeight = getMinHeight(), maxHeight = getMaxHeight();
                Stage stage = getStage();
                boolean clampPosition = keepWithinStage && getParent() == stage.getRoot();

                if ((edge & MOVE) != 0) {
                    float amountX = x - startX, amountY = y - startY;
                    windowX += amountX;
                    windowY += amountY;
                }
                if ((edge & Align.left) != 0) {
                    float amountX = x - startX;
                    if (width - amountX < minWidth)
                        amountX = -(minWidth - width);
                    if (clampPosition && windowX + amountX < 0)
                        amountX = -windowX;
                    width -= amountX;
                    windowX += amountX;
                }
                if ((edge & Align.bottom) != 0) {
                    float amountY = y - startY;
                    if (height - amountY < minHeight)
                        amountY = -(minHeight - height);
                    if (clampPosition && windowY + amountY < 0)
                        amountY = -windowY;
                    height -= amountY;
                    windowY += amountY;
                }
                if ((edge & Align.right) != 0) {
                    float amountX = x - lastX;
                    if (width + amountX < minWidth)
                        amountX = minWidth - width;
                    if (clampPosition && windowX + width + amountX > stage.getWidth())
                        amountX = stage.getWidth() - windowX - width;
                    width += amountX;
                }
                if ((edge & Align.top) != 0) {
                    float amountY = y - lastY;
                    if (height + amountY < minHeight)
                        amountY = minHeight - height;
                    if (clampPosition && windowY + height + amountY > stage.getHeight())
                        amountY = stage.getHeight() - windowY - height;
                    height += amountY;
                }
                lastX = x;
                lastY = y;
                setBounds(Math.round(windowX), Math.round(windowY), Math.round(width), Math.round(height));
            }

            public boolean mouseMoved(InputEvent event, float x, float y) {
                return isModal;
            }

            public boolean scrolled(InputEvent event, float x, float y, int amount) {
                return isModal;
            }

            public boolean keyDown(InputEvent event, int keycode) {
                return isModal;
            }

            public boolean keyUp(InputEvent event, int keycode) {
                return isModal;
            }

            public boolean keyTyped(InputEvent event, char character) {
                return isModal;
            }
        });
    }

    public void setStyle(WindowStyle style) {
        if (style == null)
            throw new IllegalArgumentException("style cannot be null.");
        this.style = style;
        setBackground(style.background);
        titleCache = new BitmapFontCache(style.titleFont);
        titleCache.setColor(style.titleFontColor);
        if (title != null)
            setTitle(title);
        invalidateHierarchy();
    }

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

    void keepWithinStage() {
        if (!keepWithinStage)
            return;
        Stage stage = getStage();
        if (getParent() == stage.getRoot()) {
            float parentWidth = stage.getWidth();
            float parentHeight = stage.getHeight();
            if (getX() < 0)
                setX(0);
            if (getRight() > parentWidth)
                setX(parentWidth - getWidth());
            if (getY() < 0)
                setY(0);
            if (getTop() > parentHeight)
                setY(parentHeight - getHeight());
        }
    }

    public void draw(Batch batch, float parentAlpha) {
        keepWithinStage();

        if (style.stageBackground != null) {
            Color color = getColor();
            batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
            Stage stage = getStage();
            stageToLocalCoordinates(/* in/out */tmpPosition.set(0, 0));
            stageToLocalCoordinates(/* in/out */tmpSize.set(stage.getWidth(), stage.getHeight()));
            style.stageBackground.draw(batch, getX() + tmpPosition.x, getY() + tmpPosition.y, getX() + tmpSize.x,
                    getY() + tmpSize.y);
        }

        super.draw(batch, parentAlpha);
    }

    protected void drawBackground(Batch batch, float parentAlpha, float x, float y) {
        float width = getWidth(), height = getHeight();
        float padTop = getPadTop();

        super.drawBackground(batch, parentAlpha, x, y);

        // Draw button table.
        buttonTable.getColor().a = getColor().a;
        buttonTable.pack();
        buttonTable.setPosition(width - buttonTable.getWidth(),
                Math.min(height - padTop, height - buttonTable.getHeight()));
        buttonTable.draw(batch, parentAlpha);

        // Draw the title without the batch transformed or clipping applied.
        y += height;
        TextBounds bounds = titleCache.getBounds();
        if ((titleAlignment & Align.left) != 0)
            x += getPadLeft();
        else if ((titleAlignment & Align.right) != 0)
            x += width - bounds.width - getPadRight();
        else
            x += (width - bounds.width) / 2;
        if ((titleAlignment & Align.top) == 0) {
            if ((titleAlignment & Align.bottom) != 0)
                y -= padTop - bounds.height;
            else
                y -= (padTop - bounds.height) / 2;
        }
        titleCache.setColors(Color.tmp.set(getColor()).mul(style.titleFontColor));
        titleCache.setPosition((int) x, (int) y);
        titleCache.draw(batch, parentAlpha);
    }

    public Actor hit(float x, float y, boolean touchable) {
        Actor hit = super.hit(x, y, touchable);
        if (hit == null && isModal && (!touchable || getTouchable() == Touchable.enabled))
            return this;
        return hit;
    }

    public void setTitle(String title) {
        this.title = title;
        titleCache.setMultiLineText(title, 0, 0);
    }

    public String getTitle() {
        return title;
    }

    /**
     * @param titleAlignment
     *            {@link Align}
     */
    public void setTitleAlignment(int titleAlignment) {
        this.titleAlignment = titleAlignment;
    }

    public boolean isMovable() {
        return isMovable;
    }

    public void setMovable(boolean isMovable) {
        this.isMovable = isMovable;
    }

    public boolean isModal() {
        return isModal;
    }

    public void setModal(boolean isModal) {
        this.isModal = isModal;
    }

    public void setKeepWithinStage(boolean keepWithinStage) {
        this.keepWithinStage = keepWithinStage;
    }

    public boolean isResizable() {
        return isResizable;
    }

    public void setResizable(boolean isResizable) {
        this.isResizable = isResizable;
    }

    public void setResizeBorder(int resizeBorder) {
        this.resizeBorder = resizeBorder;
    }

    public boolean isDragging() {
        return dragging;
    }

    public float getTitleWidth() {
        return titleCache.getBounds().width;
    }

    public float getPrefWidth() {
        return Math.max(super.getPrefWidth(), getTitleWidth() + getPadLeft() + getPadRight());
    }

    public Table getButtonTable() {
        return buttonTable;
    }

}