From 620077ed656885cb558e5644c75a262346d512aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Fri, 6 Jul 2018 14:05:41 +0200 Subject: add engine/ui - interfaces Drawable and Touchable - basic ui widgets --- core/src/ch/asynk/zproject/engine/Drawable.java | 19 +++ core/src/ch/asynk/zproject/engine/Touchable.java | 6 + .../src/ch/asynk/zproject/engine/ui/Alignment.java | 168 +++++++++++++++++++++ core/src/ch/asynk/zproject/engine/ui/Assembly.java | 53 +++++++ core/src/ch/asynk/zproject/engine/ui/Button.java | 65 ++++++++ core/src/ch/asynk/zproject/engine/ui/Element.java | 112 ++++++++++++++ core/src/ch/asynk/zproject/engine/ui/Label.java | 62 ++++++++ core/src/ch/asynk/zproject/engine/ui/Patch.java | 22 +++ core/src/ch/asynk/zproject/engine/ui/Root.java | 16 ++ 9 files changed, 523 insertions(+) create mode 100644 core/src/ch/asynk/zproject/engine/Drawable.java create mode 100644 core/src/ch/asynk/zproject/engine/Touchable.java create mode 100644 core/src/ch/asynk/zproject/engine/ui/Alignment.java create mode 100644 core/src/ch/asynk/zproject/engine/ui/Assembly.java create mode 100644 core/src/ch/asynk/zproject/engine/ui/Button.java create mode 100644 core/src/ch/asynk/zproject/engine/ui/Element.java create mode 100644 core/src/ch/asynk/zproject/engine/ui/Label.java create mode 100644 core/src/ch/asynk/zproject/engine/ui/Patch.java create mode 100644 core/src/ch/asynk/zproject/engine/ui/Root.java diff --git a/core/src/ch/asynk/zproject/engine/Drawable.java b/core/src/ch/asynk/zproject/engine/Drawable.java new file mode 100644 index 0000000..ca5fe91 --- /dev/null +++ b/core/src/ch/asynk/zproject/engine/Drawable.java @@ -0,0 +1,19 @@ +package ch.asynk.zproject.engine; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +public interface Drawable +{ + public float getX(); + public float getY(); + public float getWidth(); + public float getHeight(); + public float getInnerX(); + public float getInnerY(); + public float getInnerWidth(); + public float getInnerHeight(); + public void draw(Batch batch); + default public void drawDebug(ShapeRenderer debugShapes) { } + public void setPosition(float x, float y, float w, float h); +} diff --git a/core/src/ch/asynk/zproject/engine/Touchable.java b/core/src/ch/asynk/zproject/engine/Touchable.java new file mode 100644 index 0000000..b486aca --- /dev/null +++ b/core/src/ch/asynk/zproject/engine/Touchable.java @@ -0,0 +1,6 @@ +package ch.asynk.zproject.engine; + +public interface Touchable +{ + public boolean touch(float x, float y); +} diff --git a/core/src/ch/asynk/zproject/engine/ui/Alignment.java b/core/src/ch/asynk/zproject/engine/ui/Alignment.java new file mode 100644 index 0000000..385b419 --- /dev/null +++ b/core/src/ch/asynk/zproject/engine/ui/Alignment.java @@ -0,0 +1,168 @@ +package ch.asynk.zproject.engine.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/zproject/engine/ui/Assembly.java b/core/src/ch/asynk/zproject/engine/ui/Assembly.java new file mode 100644 index 0000000..a8f00ab --- /dev/null +++ b/core/src/ch/asynk/zproject/engine/ui/Assembly.java @@ -0,0 +1,53 @@ +package ch.asynk.zproject.engine.ui; + +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; + +import ch.asynk.zproject.engine.util.IterableSet; + +public abstract class Assembly extends Element +{ + private IterableSet children; + + public Assembly(int c) + { + this.children = new IterableSet(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); + } + } + + @Override public boolean touch(float x, float y) + { + for (Element e : children) + if (e.touch(x, y)) + return true; + return false; + } + + @Override public void update() + { + children.forEach( c -> c.update() ); + } + + @Override public void draw(Batch batch) + { + 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/zproject/engine/ui/Button.java b/core/src/ch/asynk/zproject/engine/ui/Button.java new file mode 100644 index 0000000..54f4314 --- /dev/null +++ b/core/src/ch/asynk/zproject/engine/ui/Button.java @@ -0,0 +1,65 @@ +package ch.asynk.zproject.engine.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; + + public Button(BitmapFont font, NinePatch patch) + { + this(font, patch, 0, 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) + { + write(text, getX(), getY()); + } + + public void write(String text, float x, float y) + { + label.write(text, x, y); + } + + public void setLabelAlignment(Alignment alignment) + { + label.setAlignment(alignment); + } + + @Override public void update() + { + label.preUpdate(); // compute width and height + rect.width = label.getWidth() + 2 * (padding + spacing); + rect.height = label.getHeight() + 2 * (padding + spacing); + super.update(); + label.doUpdate(); // compute x and y + label.postUpdate(); // compute fx and fy + } + + @Override public void draw(Batch batch) + { + if (!visible) return; + 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/zproject/engine/ui/Element.java b/core/src/ch/asynk/zproject/engine/ui/Element.java new file mode 100644 index 0000000..5fb4ed7 --- /dev/null +++ b/core/src/ch/asynk/zproject/engine/ui/Element.java @@ -0,0 +1,112 @@ +package ch.asynk.zproject.engine.ui; + +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.math.Rectangle; + +import ch.asynk.zproject.engine.Drawable; +import ch.asynk.zproject.engine.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; // drawing coordinates + protected float x, y; // given position + + protected Element() + { + this.blocked = false; + this.visible = true; + this.padding = 0; + this.rect = new Rectangle(0, 0, 0, 0); + this.parent = null; + this.alignment = alignment.RELATIVE; + this.x = this.y = 0; + } + + @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); + } + + @Override public void setPosition(float x, float y, float w, float h) + { + this.x = x; + this.y = y; + rect.width = w; + rect.height = h; + // rect.set(rec.x, y, w, h); + } + + public void setParent(Element parent) + { + this.parent = parent; + } + + public void setPadding(float padding) + { + this.padding = padding; + } + + public void setAlignment(Alignment alignment) + { + this.alignment = alignment; + } + + 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 preUpdate() { } + protected void postUpdate() { } + protected void doUpdate() + { + 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); + } + } + + public void update() + { + preUpdate(); + doUpdate(); + postUpdate(); + } +} diff --git a/core/src/ch/asynk/zproject/engine/ui/Label.java b/core/src/ch/asynk/zproject/engine/ui/Label.java new file mode 100644 index 0000000..6b6b65e --- /dev/null +++ b/core/src/ch/asynk/zproject/engine/ui/Label.java @@ -0,0 +1,62 @@ +package ch.asynk.zproject.engine.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; + setPosition(x, y); + } + + @Override protected void preUpdate() + { + this.layout.setText(font, (text == null) ? "" : text); + super.setPosition(x, y, (layout.width + (2 * padding)), (layout.height + (2 * padding))); + } + + @Override protected void postUpdate() + { + fx = getInnerX(); + fy = getInnerY() + layout.height; + } + + @Override public void draw(Batch batch) + { + if (!visible) return; + font.draw(batch, layout, fx, fy); + } +} diff --git a/core/src/ch/asynk/zproject/engine/ui/Patch.java b/core/src/ch/asynk/zproject/engine/ui/Patch.java new file mode 100644 index 0000000..cf9ed4f --- /dev/null +++ b/core/src/ch/asynk/zproject/engine/ui/Patch.java @@ -0,0 +1,22 @@ +package ch.asynk.zproject.engine.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; + patch.draw(batch, getX(), getY(), getWidth(), getHeight()); + } +} diff --git a/core/src/ch/asynk/zproject/engine/ui/Root.java b/core/src/ch/asynk/zproject/engine/ui/Root.java new file mode 100644 index 0000000..02eb251 --- /dev/null +++ b/core/src/ch/asynk/zproject/engine/ui/Root.java @@ -0,0 +1,16 @@ +package ch.asynk.zproject.engine.ui; + +public class Root extends Assembly +{ + public Root(int c) + { + super(c); + this.alignment = Alignment.ABSOLUTE; + } + + public void resize(float width, float height) + { + setPosition(0, 0, width, height); + update(); + } +} -- cgit v1.1-2-g2b99