expanding buttons and dynamic gui areas
parent
58618b97bc
commit
0f73574f13
|
|
@ -18,7 +18,9 @@ import xyz.valnet.hadean.util.Layers;
|
||||||
|
|
||||||
public abstract class ImmediateUI extends GameObject implements IMouseCaptureArea {
|
public abstract class ImmediateUI extends GameObject implements IMouseCaptureArea {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private boolean active;
|
private boolean active;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private boolean mouseDown;
|
private boolean mouseDown;
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
|
|
@ -27,6 +29,17 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre
|
||||||
end();
|
end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void renderAlpha() {
|
||||||
|
|
||||||
|
float f = 99;
|
||||||
|
Assets.flat.pushColor(new Vector4f(1, 0, 0, 0.3f));
|
||||||
|
for(Vector4f box : guiAreas) {
|
||||||
|
Drawing.setLayer(f += 0.001f);
|
||||||
|
Assets.fillColor.draw(box);
|
||||||
|
}
|
||||||
|
Assets.flat.popColor();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseEnter() {
|
public void mouseEnter() {
|
||||||
active = true;
|
active = true;
|
||||||
|
|
@ -47,8 +60,6 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre
|
||||||
if(button == 0) mouseDown = false;
|
if(button == 0) mouseDown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Vector4f getGuiBox();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getLayer() {
|
public float getLayer() {
|
||||||
return Layers.GENERAL_UI_INTERACTABLE;
|
return Layers.GENERAL_UI_INTERACTABLE;
|
||||||
|
|
@ -59,17 +70,18 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre
|
||||||
private record StackingContext(
|
private record StackingContext(
|
||||||
boolean fixedSize,
|
boolean fixedSize,
|
||||||
Vector4f box,
|
Vector4f box,
|
||||||
Vector4f occlusionBox
|
Vector4f occlusionBox,
|
||||||
|
boolean hasRegisteredGuiArea
|
||||||
// layout manager?
|
// layout manager?
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
private StackingContext context;
|
private transient StackingContext context;
|
||||||
private Stack<StackingContext> contextStack;
|
private transient Stack<StackingContext> contextStack = new Stack<StackingContext>();;
|
||||||
|
|
||||||
private transient Map<String, Button> buttons = new HashMap<String, Button>();
|
private transient Map<String, Button> buttons = new HashMap<String, Button>();
|
||||||
private Set<String> usedButtonId = new HashSet<String>();
|
private transient Set<String> usedButtonId = new HashSet<String>();
|
||||||
private transient Map<Button, Integer> clicks = new HashMap<Button, Integer>();
|
private transient Map<Button, Integer> clicks = new HashMap<Button, Integer>();
|
||||||
private int buttonCount;
|
private transient int buttonCount;
|
||||||
|
|
||||||
private String genButtonId() {
|
private String genButtonId() {
|
||||||
buttonCount ++;
|
buttonCount ++;
|
||||||
|
|
@ -113,33 +125,96 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final List<Vector4f> getGuiBoxes() {
|
||||||
|
return guiAreas;
|
||||||
|
}
|
||||||
|
|
||||||
|
private transient List<Vector4f> guiAreas = new ArrayList<Vector4f>();
|
||||||
|
|
||||||
// === ELEMENTS ===
|
// === ELEMENTS ===
|
||||||
|
//
|
||||||
|
|
||||||
protected void begin() {
|
protected void begin() {
|
||||||
buttonCount = 0;
|
buttonCount = 0;
|
||||||
usedButtonId.clear();
|
usedButtonId.clear();
|
||||||
Drawing.setLayer(Layers.GENERAL_UI_INTERACTABLE);
|
contextStack.clear();
|
||||||
context = new StackingContext(true, getGuiBox(), getGuiBox());
|
guiAreas.clear();
|
||||||
contextStack = new Stack<StackingContext>();
|
}
|
||||||
Assets.uiFrame.draw(context.occlusionBox);
|
|
||||||
pad();
|
protected void root(int x, int y, int w, int h) {
|
||||||
|
assert context == null : "root can only be a root element";
|
||||||
|
Vector4f box = new Vector4f(x, y, w, h);
|
||||||
|
context = new StackingContext(true, box, box, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void rootEnd() {
|
||||||
|
assert contextStack.size() == 0 : "cannot end fixedFrame with un-ended elements inside";
|
||||||
|
context = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fixedFrame(int w, int h) {
|
||||||
|
contextStack.push(context);
|
||||||
|
context = new StackingContext(
|
||||||
|
true,
|
||||||
|
new Vector4f(context.box.x, context.box.y, w, h),
|
||||||
|
context.occlusionBox.copy(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void dynamicFrame() {
|
||||||
|
contextStack.push(context);
|
||||||
|
context = new StackingContext(
|
||||||
|
false,
|
||||||
|
new Vector4f(context.box.x, context.box.y, context.box.z, 0),
|
||||||
|
context.occlusionBox.copy(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this will add _all_ frames, not just root frames to guiareas.
|
||||||
|
// not a problem, but not efficient. revisit.
|
||||||
|
protected void frameEnd() {
|
||||||
|
Drawing.setLayer(getLayer() + contextStack.size() - 1);
|
||||||
|
if(!context.fixedSize) {
|
||||||
|
Assets.uiFrame.draw(context.box);
|
||||||
|
guiAreas.add(context.box);
|
||||||
|
} else {
|
||||||
|
Assets.uiFrame.draw(context.occlusionBox);
|
||||||
|
guiAreas.add(context.occlusionBox);
|
||||||
|
}
|
||||||
|
context = contextStack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean button(String text) {
|
protected boolean button(String text) {
|
||||||
return button(genButtonId(), text);
|
return button(genButtonId(), text, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean button(String text, boolean expand) {
|
||||||
|
return button(genButtonId(), text, expand);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean button(String id, String text) {
|
protected boolean button(String id, String text) {
|
||||||
|
return button(id, text, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean button(String id, String text, boolean expand) {
|
||||||
float h = 32;
|
float h = 32;
|
||||||
|
if(expand && context.fixedSize) {
|
||||||
|
h = context.box.w;
|
||||||
|
}
|
||||||
Vector4f buttonBox = new Vector4f(context.box.x, context.box.y, context.box.z, h);
|
Vector4f buttonBox = new Vector4f(context.box.x, context.box.y, context.box.z, h);
|
||||||
Button btn = getButton(id);
|
Button btn = getButton(id);
|
||||||
|
|
||||||
|
if(!context.hasRegisteredGuiArea) {
|
||||||
|
guiAreas.add(buttonBox);
|
||||||
|
}
|
||||||
|
|
||||||
btn.setText(text);
|
btn.setText(text);
|
||||||
btn.setPosition((int) buttonBox.x, (int) buttonBox.y);
|
btn.setPosition((int) buttonBox.x, (int) buttonBox.y);
|
||||||
btn.setSize((int) buttonBox.z, (int) buttonBox.w);
|
btn.setSize((int) buttonBox.z, (int) buttonBox.w);
|
||||||
btn.setLayer(Layers.GENERAL_UI_INTERACTABLE + contextStack.size());
|
btn.setLayer(getLayer() + contextStack.size() + 1);
|
||||||
|
|
||||||
// System.out.println("" + buttonBox);
|
|
||||||
|
|
||||||
adjustBox(h);
|
adjustBox(h);
|
||||||
|
|
||||||
|
|
@ -160,7 +235,8 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre
|
||||||
new Vector4f(
|
new Vector4f(
|
||||||
context.box.x, context.box.y, context.box.z, 0
|
context.box.x, context.box.y, context.box.z, 0
|
||||||
),
|
),
|
||||||
context.occlusionBox.copy()
|
context.occlusionBox.copy(),
|
||||||
|
context.hasRegisteredGuiArea
|
||||||
);
|
);
|
||||||
pad();
|
pad();
|
||||||
}
|
}
|
||||||
|
|
@ -181,14 +257,16 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre
|
||||||
new Vector4f(
|
new Vector4f(
|
||||||
context.box.x + 8, context.box.y + 8, context.box.z - 16, context.box.w - 16
|
context.box.x + 8, context.box.y + 8, context.box.z - 16, context.box.w - 16
|
||||||
),
|
),
|
||||||
context.occlusionBox.copy()
|
context.occlusionBox.copy(),
|
||||||
|
context.hasRegisteredGuiArea
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
context = new StackingContext(false,
|
context = new StackingContext(false,
|
||||||
new Vector4f(
|
new Vector4f(
|
||||||
context.box.x + 8, context.box.y + 8, context.box.z - 16, 0
|
context.box.x + 8, context.box.y + 8, context.box.z - 16, 0
|
||||||
),
|
),
|
||||||
context.occlusionBox.copy()
|
context.occlusionBox.copy(),
|
||||||
|
context.hasRegisteredGuiArea
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -200,7 +278,6 @@ public abstract class ImmediateUI extends GameObject implements IMouseCaptureAre
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void end() {
|
protected void end() {
|
||||||
padEnd();
|
|
||||||
|
|
||||||
List<String> buttonIdsToRemove = new ArrayList<String>();
|
List<String> buttonIdsToRemove = new ArrayList<String>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package xyz.valnet.engine.scenegraph;
|
package xyz.valnet.engine.scenegraph;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
|
||||||
public interface IMouseCaptureArea {
|
public interface IMouseCaptureArea {
|
||||||
|
|
@ -8,6 +10,6 @@ public interface IMouseCaptureArea {
|
||||||
public void mouseDown(int button);
|
public void mouseDown(int button);
|
||||||
public void mouseUp(int button);
|
public void mouseUp(int button);
|
||||||
|
|
||||||
public Vector4f getGuiBox();
|
public List<Vector4f> getGuiBoxes();
|
||||||
public float getLayer();
|
public float getLayer();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import java.util.Map.Entry;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import xyz.valnet.engine.App;
|
import xyz.valnet.engine.App;
|
||||||
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
|
||||||
public abstract class SceneGraph implements IScene {
|
public abstract class SceneGraph implements IScene {
|
||||||
protected final List<GameObject> objects = new ArrayList<GameObject>();
|
protected final List<GameObject> objects = new ArrayList<GameObject>();
|
||||||
|
|
@ -72,6 +73,10 @@ public abstract class SceneGraph implements IScene {
|
||||||
obj.update(dTime);
|
obj.update(dTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mouseUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mouseUpdate() {
|
||||||
// DO MOUSE UPDATES!
|
// DO MOUSE UPDATES!
|
||||||
List<IMouseCaptureArea> mouseListeners = getAll(IMouseCaptureArea.class);
|
List<IMouseCaptureArea> mouseListeners = getAll(IMouseCaptureArea.class);
|
||||||
mouseListeners.sort(new Comparator<IMouseCaptureArea>() {
|
mouseListeners.sort(new Comparator<IMouseCaptureArea>() {
|
||||||
|
|
@ -82,22 +87,25 @@ public abstract class SceneGraph implements IScene {
|
||||||
return al < bl ? 1 : bl < al ? -1 : 0;
|
return al < bl ? 1 : bl < al ? -1 : 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for(IMouseCaptureArea listener : mouseListeners) {
|
for(IMouseCaptureArea listener : mouseListeners) {
|
||||||
boolean currentlyEntered = listener.getGuiBox().contains(App.mouseX, App.mouseY);
|
for(Vector4f guiBox : listener.getGuiBoxes()) {
|
||||||
if(currentlyEntered) {
|
boolean currentlyEntered = guiBox.contains(App.mouseX, App.mouseY);
|
||||||
if(listener != hoveredMouseListener) {
|
if(currentlyEntered) {
|
||||||
if(hoveredMouseListener != null) {
|
if(listener != hoveredMouseListener) {
|
||||||
hoveredMouseListener.mouseLeave();
|
if(hoveredMouseListener != null) {
|
||||||
|
hoveredMouseListener.mouseLeave();
|
||||||
|
}
|
||||||
|
hoveredMouseListener = listener;
|
||||||
|
listener.mouseEnter();
|
||||||
}
|
}
|
||||||
hoveredMouseListener = listener;
|
return;
|
||||||
listener.mouseEnter();
|
} else if(listener == hoveredMouseListener) {
|
||||||
|
// this is the one that is currently hovered, but it isnt!
|
||||||
|
// turn that shit OFF
|
||||||
|
hoveredMouseListener.mouseLeave();
|
||||||
|
hoveredMouseListener = null;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
} else if(listener == hoveredMouseListener) {
|
|
||||||
// this is the one that is currently hovered, but it isnt!
|
|
||||||
// turn that shit OFF
|
|
||||||
hoveredMouseListener.mouseLeave();
|
|
||||||
hoveredMouseListener = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,12 +71,6 @@ public class SelectionUI extends ImmediateUI implements ISelectionChangeListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector4f getGuiBox() {
|
|
||||||
if(selected.isEmpty()) return Vector4f.zero;
|
|
||||||
return new Vector4f(10, 576 - BottomBar.bottomBarHeight - height - padding, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getLayer() {
|
public float getLayer() {
|
||||||
return Layers.GENERAL_UI;
|
return Layers.GENERAL_UI;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package xyz.valnet.hadean.gameobjects.inputlayer;
|
package xyz.valnet.hadean.gameobjects.inputlayer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import xyz.valnet.engine.App;
|
import xyz.valnet.engine.App;
|
||||||
import xyz.valnet.engine.math.Vector2i;
|
import xyz.valnet.engine.math.Vector2i;
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
import xyz.valnet.engine.math.Vector4f;
|
||||||
|
|
@ -129,8 +131,8 @@ public class BuildLayer extends GameObject implements IMouseCaptureArea, ITransi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getGuiBox() {
|
public List<Vector4f> getGuiBoxes() {
|
||||||
return active ? new Vector4f(0, 0, 1024, 576) : Vector4f.zero;
|
return List.of(active ? new Vector4f(0, 0, 1024, 576) : Vector4f.zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -181,8 +181,8 @@ public class SelectionLayer extends GameObject implements IMouseCaptureArea, ITr
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getGuiBox() {
|
public List<Vector4f> getGuiBoxes() {
|
||||||
return new Vector4f(0, 0, 1000, 1000);
|
return List.of(new Vector4f(0, 0, 1000, 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,42 @@
|
||||||
package xyz.valnet.hadean.gameobjects.ui;
|
package xyz.valnet.hadean.gameobjects.ui;
|
||||||
|
|
||||||
import xyz.valnet.engine.graphics.ImmediateUI;
|
import xyz.valnet.engine.graphics.ImmediateUI;
|
||||||
import xyz.valnet.engine.math.Vector4f;
|
|
||||||
|
|
||||||
public class Popup extends ImmediateUI {
|
public class Popup extends ImmediateUI {
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector4f getGuiBox() {
|
|
||||||
return new Vector4f(256, 100, 512, 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void gui() {
|
protected void gui() {
|
||||||
header(" Popup Test");
|
root(100, 100, 200, 200); {
|
||||||
|
fixedFrame(200, 100); {
|
||||||
text("1\n1.5");
|
pad(); {
|
||||||
text("2");
|
header(" Popup Test");
|
||||||
|
|
||||||
group();
|
|
||||||
text("This should be in a frame!");
|
|
||||||
text("And this!");
|
|
||||||
groupEnd();
|
|
||||||
|
|
||||||
text("But not this...");
|
text("1\n1.5");
|
||||||
|
text("2");
|
||||||
|
|
||||||
|
group(); {
|
||||||
|
text("This should be in a frame!");
|
||||||
|
text("And this!");
|
||||||
|
} groupEnd();
|
||||||
|
|
||||||
|
text("But not this...");
|
||||||
|
|
||||||
|
if(button("Click Me!")) {
|
||||||
|
System.out.println("The Event!");
|
||||||
|
}
|
||||||
|
|
||||||
|
text("This after button...");
|
||||||
|
} padEnd();
|
||||||
|
} frameEnd();
|
||||||
|
} rootEnd();
|
||||||
|
|
||||||
if(button("Click Me!")) {
|
|
||||||
System.out.println("The Event!");
|
|
||||||
}
|
|
||||||
|
|
||||||
text("This after button...");
|
|
||||||
|
root(724, 100, 200, 200);
|
||||||
|
// text("Test Frame!");
|
||||||
|
button("Test Button Expand!", true);
|
||||||
|
button("Test Button Expand 2!", true);
|
||||||
|
rootEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,8 +289,8 @@ public class BuildTab extends Tab implements ISelectionChangeListener, IMouseCap
|
||||||
public void mouseUp(int button) {}
|
public void mouseUp(int button) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getGuiBox() {
|
public List<Vector4f> getGuiBoxes() {
|
||||||
return new Vector4f(padding, 576 - BottomBar.bottomBarHeight - padding - height, width, height);
|
return List.of(new Vector4f(padding, 576 - BottomBar.bottomBarHeight - padding - height, width, height));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package xyz.valnet.hadean.input;
|
package xyz.valnet.hadean.input;
|
||||||
|
|
||||||
import static xyz.valnet.engine.util.Math.lerp;
|
import static xyz.valnet.engine.util.Math.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import xyz.valnet.engine.graphics.Drawing;
|
import xyz.valnet.engine.graphics.Drawing;
|
||||||
import xyz.valnet.engine.graphics.Tile9;
|
import xyz.valnet.engine.graphics.Tile9;
|
||||||
|
|
@ -222,8 +224,8 @@ public class Button extends GameObject implements IMouseCaptureArea, ITransient
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector4f getGuiBox() {
|
public List<Vector4f> getGuiBoxes() {
|
||||||
return new Vector4f(x, y, width, height);
|
return List.of(new Vector4f(x, y, width, height));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ public class GameScene extends SceneGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
objects.add(new SelectionLayer());
|
objects.add(new SelectionLayer());
|
||||||
objects.add(new SelectionUI());
|
// objects.add(new SelectionUI());
|
||||||
|
|
||||||
objects.add(new BuildLayer());
|
objects.add(new BuildLayer());
|
||||||
|
|
||||||
|
|
@ -59,7 +59,7 @@ public class GameScene extends SceneGraph {
|
||||||
objects.add(new SaveTab());
|
objects.add(new SaveTab());
|
||||||
objects.add(new LoadTab());
|
objects.add(new LoadTab());
|
||||||
|
|
||||||
// objects.add(new Popup());
|
objects.add(new Popup());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue