diff options
| author | Jérémy Zurcher <jeremy@asynk.ch> | 2018-10-03 16:29:04 +0200 | 
|---|---|---|
| committer | Jérémy Zurcher <jeremy@asynk.ch> | 2018-10-03 16:29:04 +0200 | 
| commit | 2f1bec6890815033211fde71e645c5a57e502a20 (patch) | |
| tree | a83756b4df61e729fdbdf495c19423dc7799e269 /core/src/ch/asynk/gdx/boardgame/ui | |
| parent | 977ce8e5a8f967f2ad9acc634111231e3af9ef7a (diff) | |
| download | gdx-boardgame-2f1bec6890815033211fde71e645c5a57e502a20.zip gdx-boardgame-2f1bec6890815033211fde71e645c5a57e502a20.tar.gz | |
tabletop -> boardgame
Diffstat (limited to 'core/src/ch/asynk/gdx/boardgame/ui')
| -rw-r--r-- | core/src/ch/asynk/gdx/boardgame/ui/Alignment.java | 168 | ||||
| -rw-r--r-- | core/src/ch/asynk/gdx/boardgame/ui/Assembly.java | 63 | ||||
| -rw-r--r-- | core/src/ch/asynk/gdx/boardgame/ui/Button.java | 67 | ||||
| -rw-r--r-- | core/src/ch/asynk/gdx/boardgame/ui/Element.java | 116 | ||||
| -rw-r--r-- | core/src/ch/asynk/gdx/boardgame/ui/Label.java | 61 | ||||
| -rw-r--r-- | core/src/ch/asynk/gdx/boardgame/ui/Menu.java | 126 | ||||
| -rw-r--r-- | core/src/ch/asynk/gdx/boardgame/ui/Patch.java | 23 | ||||
| -rw-r--r-- | core/src/ch/asynk/gdx/boardgame/ui/Root.java | 28 | 
8 files changed, 652 insertions, 0 deletions
| diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Alignment.java b/core/src/ch/asynk/gdx/boardgame/ui/Alignment.java new file mode 100644 index 0000000..67da089 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Alignment.java @@ -0,0 +1,168 @@ +package ch.asynk.gdx.boardgame.ui; + +public enum Alignment +{ +    ABSOLUTE,           // Root +    RELATIVE,           // Default +    TOP_LEFT, +    TOP_RIGHT, +    TOP_CENTER, +    MIDDLE_LEFT, +    MIDDLE_RIGHT, +    MIDDLE_CENTER, +    BOTTOM_LEFT, +    BOTTOM_RIGHT, +    BOTTOM_CENTER; + +    public Alignment verticalMirror() +    { +        switch(this) { +            case TOP_LEFT: +                return TOP_RIGHT; +            case MIDDLE_LEFT: +                return MIDDLE_RIGHT; +            case BOTTOM_LEFT: +                return BOTTOM_RIGHT; +            case TOP_RIGHT: +                return TOP_LEFT; +            case MIDDLE_RIGHT: +                return MIDDLE_LEFT; +            case BOTTOM_RIGHT: +                return BOTTOM_LEFT; +        } +        return this; +    } + +    public Alignment horizontalMirror() +    { +        switch(this) { +            case TOP_LEFT: +                return BOTTOM_LEFT; +            case TOP_CENTER: +                return BOTTOM_CENTER; +            case TOP_RIGHT: +                return BOTTOM_RIGHT; +            case BOTTOM_LEFT: +                return TOP_LEFT; +            case BOTTOM_CENTER: +                return TOP_CENTER; +            case BOTTOM_RIGHT: +                return TOP_RIGHT; +        } +        return this; +    } + +    public boolean isTop() +    { +        switch(this) { +            case TOP_LEFT: +            case TOP_CENTER: +            case TOP_RIGHT: +                return true; +        } +        return false; +    } + +    public boolean isMiddle() +    { +        boolean r = false; +        switch(this) { +            case MIDDLE_LEFT: +            case MIDDLE_CENTER: +            case MIDDLE_RIGHT: +                return true; +        } +        return false; +    } + +    public boolean isBottom() +    { +        boolean r = false; +        switch(this) { +            case BOTTOM_LEFT: +            case BOTTOM_CENTER: +            case BOTTOM_RIGHT: +                return true; +        } +        return false; +    } + +    public boolean isLeft() +    { +        boolean r = false; +        switch(this) { +            case TOP_LEFT: +            case MIDDLE_LEFT: +            case BOTTOM_LEFT: +                return true; +        } +        return false; +    } + +    public boolean isRight() +    { +        boolean r = false; +        switch(this) { +            case TOP_RIGHT: +            case MIDDLE_RIGHT: +            case BOTTOM_RIGHT: +                return true; +        } +        return false; +    } + +    public boolean isCenter() +    { +        switch(this) { +            case TOP_CENTER: +            case MIDDLE_CENTER: +            case BOTTOM_CENTER: +                return true; +        } +        return false; +    } + +    public float getX(Element element, float width) +    { +        float x = element.getInnerX(); +        switch(this) { +            case TOP_LEFT: +            case MIDDLE_LEFT: +            case BOTTOM_LEFT: +                break; +            case TOP_CENTER: +            case MIDDLE_CENTER: +            case BOTTOM_CENTER: +                x += ((element.getInnerWidth() - width) / 2); +                break; +            case TOP_RIGHT: +            case MIDDLE_RIGHT: +            case BOTTOM_RIGHT: +                x += (element.getInnerWidth() - width); +                break; +        } +        return x; +    } + +    public float getY(Element element, float height) +    { +        float y = element.getInnerY(); +        switch(this) { +            case TOP_LEFT: +            case TOP_CENTER: +            case TOP_RIGHT: +                y += (element.getInnerHeight() - height); +                break; +            case MIDDLE_LEFT: +            case MIDDLE_CENTER: +            case MIDDLE_RIGHT: +                y += ((element.getInnerHeight() - height) / 2); +                break; +            case BOTTOM_LEFT: +            case BOTTOM_CENTER: +            case BOTTOM_RIGHT: +                break; +        } +        return y; +    } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Assembly.java b/core/src/ch/asynk/gdx/boardgame/ui/Assembly.java new file mode 100644 index 0000000..c603383 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Assembly.java @@ -0,0 +1,63 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +import ch.asynk.gdx.boardgame.util.IterableSet; + +public abstract class Assembly extends Element +{ +    private IterableSet<Element> children; +    private Element touched; + +    public Assembly(int c) +    { +        this.children = new IterableSet<Element>(c); +    } + +    public void add(Element e) +    { +        if (children.add(e)) { +            e.setParent(this); +        } +    } + +    public void remove(Element e) +    { +        if (children.remove(e)) { +            e.setParent(null); +        } +    } + +    public Element touched() +    { +        return touched; +    } + +    @Override public boolean touch(float x, float y) +    { +        for (Element e : children) +            if (e.touch(x, y)) { +                touched = e; +                return true; +            } +        touched = null; +        return false; +    } + +    @Override public void taint() +    { +        children.forEach( c -> c.taint() ); +    } + +    @Override public void draw(Batch batch) +    { +        if (tainted) computeGeometry(); +        children.forEach( c -> c.draw(batch) ); +    } + +    @Override public void drawDebug(ShapeRenderer debugShapes) +    { +        children.forEach( c -> c.drawDebug(debugShapes) ); +    } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Button.java b/core/src/ch/asynk/gdx/boardgame/ui/Button.java new file mode 100644 index 0000000..9bc1149 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Button.java @@ -0,0 +1,67 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +public class Button extends Patch +{ +    private Label label; +    private float spacing;      // for label alignment; + +    public Button(BitmapFont font, NinePatch patch) +    { +        this(font, patch, 0); +    } + +    public Button(BitmapFont font, NinePatch patch, float padding) +    { +        this(font, patch, padding, 0); +    } + +    public Button(BitmapFont font, NinePatch patch, float padding, float spacing) +    { +        super(patch); +        this.padding = padding; +        this.spacing = spacing; +        label = new Label(font); +        label.setParent(this); +        label.setAlignment(Alignment.MIDDLE_CENTER); +    } + +    public void write(String text) +    { +        label.write(text); +        this.tainted = true;    // might impact Button's geometry +    } + +    public void setLabelAlignment(Alignment alignment) +    { +        label.setAlignment(alignment); +    } + +    @Override public void computeGeometry() +    { +        float dd = 2 * (padding + spacing); +        label.computeGeometry();    // update dimensions +        rect.width = label.getWidth() + dd; +        rect.height = label.getHeight() + dd; +        super.computeGeometry(); +        label.computeGeometry();    // update position +    } + +    @Override public void draw(Batch batch) +    { +        if (!visible) return; +        if (tainted) computeGeometry(); +        super.draw(batch); +        label.draw(batch); +    } + +    @Override public void drawDebug(ShapeRenderer debugShapes) +    { +        super.drawDebug(debugShapes); +        label.drawDebug(debugShapes); +    } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Element.java b/core/src/ch/asynk/gdx/boardgame/ui/Element.java new file mode 100644 index 0000000..25f38eb --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Element.java @@ -0,0 +1,116 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.math.Rectangle; + +import ch.asynk.gdx.boardgame.Drawable; +import ch.asynk.gdx.boardgame.Touchable; + +public abstract class Element implements Drawable, Touchable +{ +    public boolean blocked; +    public boolean visible; +    protected float padding; +    protected Element parent; +    protected Alignment alignment; +    protected Rectangle rect;           // outer drawing coordinates +    protected float x, y;               // given position +    protected boolean tainted;          // geometry must be computed + +    protected Element() +    { +        this.blocked = false; +        this.visible = true; +        this.padding = 0; +        this.parent = null; +        this.alignment = alignment.RELATIVE; +        this.rect = new Rectangle(0, 0, 0, 0); +        this.x = this.y = 0; +        this.tainted = true; +    } + +    @Override public final float getX()        { return rect.x; } +    @Override public final float getY()        { return rect.y; } +    @Override public final float getWidth()    { return rect.width; } +    @Override public final float getHeight()   { return rect.height; } + +    @Override public final float getInnerX()              { return rect.x + padding; } +    @Override public final float getInnerY()              { return rect.y + padding; } +    @Override public final float getInnerWidth()          { return rect.width - 2 * padding; } +    @Override public final float getInnerHeight()         { return rect.height - 2 * padding; } + +    @Override public void drawDebug(ShapeRenderer debugShapes) +    { +        debugShapes.rect(getX(), getY(), getWidth(), getHeight()); +    } + +    @Override public boolean touch(float x, float y) +    { +        if (blocked || !visible) return false; +        return rect.contains(x, y); +    } + +    public void taint() +    { +        this.tainted = true; +    } + +    @Override public void setPosition(float x, float y, float w, float h) +    { +        this.x = x; +        this.y = y; +        this.rect.width = w; +        this.rect.height = h; +        this.tainted = true; +        // rect.(x,y) will be set in computeGeometry +    } + +    public void setParent(Element parent) +    { +        this.parent = parent; +        this.tainted = true; +    } + +    public void setPadding(float padding) +    { +        this.padding = padding; +        this.tainted = true; +    } + +    public void setAlignment(Alignment alignment) +    { +        this.alignment = alignment; +        this.tainted = true; +    } + +    public final void translate(float dx, float dy) +    { +        setPosition(x + dx, y + dy); +    } + +    public final void setPosition(Rectangle r) +    { +        setPosition(r.x, r.x, r.width, r.height); +    } + +    public final void setPosition(float x, float y) +    { +       setPosition(x, y, rect.width, rect.height); +    } + +    protected void computeGeometry() +    { +        if (alignment == Alignment.ABSOLUTE || parent == null) { +            rect.x = x; +            rect.y = y; +        } else if (alignment == Alignment.RELATIVE) { +            rect.x = x + parent.getInnerX(); +            rect.y = y + parent.getInnerX(); +        } else { +            rect.x = x + alignment.getX(parent, rect.width); +            rect.y = y + alignment.getY(parent, rect.height); +        } +        this.tainted = false; +        // System.err.println(String.format("%s : %s", this, rect)); +    } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Label.java b/core/src/ch/asynk/gdx/boardgame/ui/Label.java new file mode 100644 index 0000000..32ae814 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Label.java @@ -0,0 +1,61 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; + +public class Label extends Element +{ +    private BitmapFont font; +    private GlyphLayout layout; +    private float fx; +    private float fy; +    private String text; + +    public Label(BitmapFont font) +    { +        this(font, 0); +    } + +    public Label(BitmapFont font, float padding) +    { +        this(font, padding, Alignment.RELATIVE); +    } + +    public Label(BitmapFont font, float padding, Alignment alignment) +    { +        super(); +        this.font = font; +        this.padding = padding; +        this.alignment = alignment; +        this.layout = new GlyphLayout(); +    } + +    public void write(String text) +    { +        write(text, getX(), getY()); +    } + +    public void write(String text, float x, float y) +    { +        this.text = text; +        this.layout.setText(font, (text == null) ? "" : text); +        this.tainted = true; +    } + +    @Override protected void computeGeometry() +    { +        this.rect.width = (layout.width + (2 * padding)); +        this.rect.height = (layout.height + (2 * padding)); +        super.computeGeometry(); +        fx = getInnerX(); +        fy = getInnerY() + layout.height; +    } + +    @Override public void draw(Batch batch) +    { +        if (!visible) return; +        if (tainted) computeGeometry(); +        font.draw(batch, layout, fx, fy); +    } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Menu.java b/core/src/ch/asynk/gdx/boardgame/ui/Menu.java new file mode 100644 index 0000000..aa62483 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Menu.java @@ -0,0 +1,126 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; + +public class Menu extends Patch +{ +    private Label title; +    private Label[] entries; +    private Integer touchedItem; + +    private int entriesOffset;      // horizontal offset +    private int titleSpacing;       // between title and entries +    private int entriesSpacing;     // between entries + +    public Menu(BitmapFont font, NinePatch patch, String title, String[] entries) +    { +        super(patch); +        this.touchedItem = null; +        setTitle(font, title); +        setEntries(font, entries); +    } + +    public void setTitle(BitmapFont font, String title) +    { +        this.title = new Label(font); +        this.title.write(title); +        this.tainted = true; +    } + +    public void setEntries(BitmapFont font, String[] entries) +    { +        this.entries = new Label[entries.length]; +        for (int i = 0; i < entries.length; i++) { +            Label l = new Label(font); +            l.write(entries[i]); +            this.entries[i] = l; +        } +        this.tainted = true; +    } + +    public void setLabelsOffset(int entriesOffset) +    { +        this.entriesOffset = entriesOffset; +        this.tainted = true; +    } + +    public void setPaddings(int titlePadding, int labelPadding) +    { +        this.title.setPadding(titlePadding); +        for (Label label : entries) { +            label.setPadding(labelPadding); +        } +        this.tainted = true; +    } + +    public void setSpacings(int titleSpacing, int entriesSpacing) +    { +        this.titleSpacing = titleSpacing; +        this.entriesSpacing = entriesSpacing; +        this.tainted = true; +    } + +    @Override public void computeGeometry() +    { +        title.computeGeometry(); +        float h = title.getHeight(); +        float w = title.getWidth(); +        for (Label label : entries) { +            label.computeGeometry(); +            h += label.getHeight(); +            float t = label.getWidth() + entriesOffset; +            if (t > w) +                w = t; +        } +        h += (titleSpacing + (entriesSpacing * (entries.length - 1)) + (2 * padding)); +        w += (2 * padding); + +        rect.width = w; +        rect.height = h; +        super.computeGeometry(); + +        float x = getInnerX(); +        float y = getInnerY(); + +        // setPosition() will trigger computeGeometry() from within draw() +        for (int i = entries.length - 1; i >= 0; i--) { +            entries[i].setPosition(x + entriesOffset, y); +            y += entries[i].getHeight() + entriesSpacing; +        } +        y -= entriesSpacing; +        y += titleSpacing; +        title.setPosition(x, y); +    } + +    public Integer touched() +    { +        return touchedItem; +    } + +    @Override public boolean touch(float x, float y) +    { +        touchedItem = null; +        if (super.touch(x, y)) { +            for (int i = 0; i < entries.length; i++) { +                if (entries[i].touch(x, y)) { +                    touchedItem = i; +                    return true; +                } +            } +        } +        return false; +    } + +    @Override public void draw(Batch batch) +    { +        if (!visible) return; +        if (tainted) computeGeometry(); +        super.draw(batch); +        title.draw(batch); +        for (Label label : entries) { +            label.draw(batch); +        } +    } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Patch.java b/core/src/ch/asynk/gdx/boardgame/ui/Patch.java new file mode 100644 index 0000000..df2cc06 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Patch.java @@ -0,0 +1,23 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.NinePatch; + +public class Patch extends Element +{ +    private NinePatch patch; + +    public Patch(NinePatch patch) +    { +        super(); +        this.patch = patch; +        setPosition(0, 0, patch.getTotalWidth(), patch.getTotalHeight()); +    } + +    @Override public void draw(Batch batch) +    { +        if (!visible) return; +        if (tainted) computeGeometry(); +        patch.draw(batch, getX(), getY(), getWidth(), getHeight()); +    } +} diff --git a/core/src/ch/asynk/gdx/boardgame/ui/Root.java b/core/src/ch/asynk/gdx/boardgame/ui/Root.java new file mode 100644 index 0000000..2353c41 --- /dev/null +++ b/core/src/ch/asynk/gdx/boardgame/ui/Root.java @@ -0,0 +1,28 @@ +package ch.asynk.gdx.boardgame.ui; + +import com.badlogic.gdx.math.Rectangle; + +public class Root extends Assembly +{ +    public Root(int c) +    { +        super(c); +        this.alignment = Alignment.ABSOLUTE; +    } + +    public void resize(Rectangle r) +    { +        resize(r.x, r.y, r.width, r.height); +    } + +    public void resize(float width, float height) +    { +        resize(getX(), getY(), width, height); +    } + +    public void resize(float x, float y, float width, float height) +    { +        setPosition(x, y, width, height); +        taint(); +    } +} | 
