Panels test
This commit is contained in:
parent
1b73eea70a
commit
923d19bcc2
@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.screen;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@ -15,6 +16,9 @@ import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
|
||||
import ru.dbotthepony.mc.otm.menu.slot.MachineOutputSlot;
|
||||
import ru.dbotthepony.mc.otm.menu.slot.MatterContainerInputSlot;
|
||||
import ru.dbotthepony.mc.otm.menu.widget.AbstractWidget;
|
||||
import ru.dbotthepony.mc.otm.screen.panels.EditablePanel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MatteryScreen<T extends MatteryMenu> extends AbstractContainerScreen<T> {
|
||||
protected static final ResourceLocation CONTAINER_BASE = new ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/generic_machine.png");
|
||||
@ -24,6 +28,8 @@ public class MatteryScreen<T extends MatteryMenu> extends AbstractContainerScree
|
||||
return CONTAINER_BASE;
|
||||
}
|
||||
|
||||
protected ArrayList<EditablePanel> panels = new ArrayList<>();
|
||||
|
||||
public MatteryScreen(T p_97741_, Inventory p_97742_, Component p_97743_) {
|
||||
super(p_97741_, p_97742_, p_97743_);
|
||||
|
||||
@ -34,6 +40,61 @@ public class MatteryScreen<T extends MatteryMenu> extends AbstractContainerScree
|
||||
inventoryLabelY = imageHeight - 92;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double p_97748_, double p_97749_, int p_97750_) {
|
||||
for (var panel : panels) {
|
||||
if (panel.mouseClickedChecked(p_97748_, p_97749_, p_97750_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseClicked(p_97748_, p_97749_, p_97750_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged(double p_97752_, double p_97753_, int p_97754_, double p_97755_, double p_97756_) {
|
||||
for (var panel : panels) {
|
||||
if (panel.mouseDraggedChecked(p_97752_, p_97753_, p_97754_, p_97755_, p_97756_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseDragged(p_97752_, p_97753_, p_97754_, p_97755_, p_97756_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double p_97812_, double p_97813_, int p_97814_) {
|
||||
for (var panel : panels) {
|
||||
if (panel.mouseReleasedChecked(p_97812_, p_97813_, p_97814_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseReleased(p_97812_, p_97813_, p_97814_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double p_94686_, double p_94687_, double p_94688_) {
|
||||
for (var panel : panels) {
|
||||
if (panel.mouseScrolledChecked(p_94686_, p_94687_, p_94688_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseScrolled(p_94686_, p_94687_, p_94688_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int p_97765_, int p_97766_, int p_97767_) {
|
||||
for (var panel : panels) {
|
||||
if (panel.keyPressed(p_97765_, p_97766_, p_97767_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.keyPressed(p_97765_, p_97766_, p_97767_);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderTooltip(PoseStack pose, int mouseX, int mouseY) {
|
||||
super.renderTooltip(pose, mouseX, mouseY);
|
||||
@ -76,6 +137,10 @@ public class MatteryScreen<T extends MatteryMenu> extends AbstractContainerScree
|
||||
|
||||
}
|
||||
|
||||
public Font getFont() {
|
||||
return font;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBg(PoseStack pose, float p_97788_, int mouseX, int mouseY) {
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
|
@ -19,6 +19,16 @@ public class RenderHelper {
|
||||
identity.setIdentity();
|
||||
}
|
||||
|
||||
public static float depth_z = 0;
|
||||
|
||||
public static void setUpcomingDepth(float depth) {
|
||||
depth_z = depth;
|
||||
}
|
||||
|
||||
public static void clearUpcomingDepth() {
|
||||
depth_z = 0;
|
||||
}
|
||||
|
||||
// Regular functions
|
||||
|
||||
/**
|
||||
@ -50,10 +60,10 @@ public class RenderHelper {
|
||||
|
||||
var builder = Tesselator.getInstance().getBuilder();
|
||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);
|
||||
builder.vertex(matrix, x, y + height, 0).uv(u0, v1).endVertex();
|
||||
builder.vertex(matrix, x + width, y + height, 0).uv(u1, v1).endVertex();
|
||||
builder.vertex(matrix, x + width, y, 0).uv(u1, v0).endVertex();
|
||||
builder.vertex(matrix, x, y, 0).uv(u0, v0).endVertex();
|
||||
builder.vertex(matrix, x, y + height, depth_z).uv(u0, v1).endVertex();
|
||||
builder.vertex(matrix, x + width, y + height, depth_z).uv(u1, v1).endVertex();
|
||||
builder.vertex(matrix, x + width, y, depth_z).uv(u1, v0).endVertex();
|
||||
builder.vertex(matrix, x, y, depth_z).uv(u0, v0).endVertex();
|
||||
builder.end();
|
||||
BufferUploader.end(builder);
|
||||
}
|
||||
@ -111,6 +121,31 @@ public class RenderHelper {
|
||||
drawTexturedRectUV(stack.last().pose(), x, y, width, height, u0, v0, u1, v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stack stack to take transformation matrix from
|
||||
* @param x position x on screen
|
||||
* @param y position y on screen
|
||||
* @param width drawn rectangle width
|
||||
* @param height drawn rectangle height
|
||||
* @param image_x absolute asset x, to compute U0 coordinate from
|
||||
* @param image_y absolute asset y, to compute V0 coordinate from
|
||||
* @param mapped_width absolute asset width, to compute U1 coordinate from
|
||||
* @param mapped_height absolute asset height, to compute V1 coordinate from
|
||||
*/
|
||||
public static void drawTexturedRectAuto(
|
||||
PoseStack stack,
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height,
|
||||
float image_x,
|
||||
float image_y,
|
||||
float mapped_width,
|
||||
float mapped_height
|
||||
) {
|
||||
drawTexturedRectUV(stack.last().pose(), x, y, width, height, image_x / mapped_width, image_y / mapped_height, (image_x + width) / mapped_width, (image_y + height) / mapped_height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a textured rectangle on screen
|
||||
* with matrix from pose
|
||||
@ -255,6 +290,22 @@ public class RenderHelper {
|
||||
256
|
||||
);
|
||||
|
||||
public static void drawRegularSlot(
|
||||
PoseStack stack,
|
||||
float x,
|
||||
float y
|
||||
) {
|
||||
drawTexturedRectAuto(stack, x, y, 18, 18, 0, 96, 256, 256);
|
||||
}
|
||||
|
||||
public static void drawBigSlot(
|
||||
PoseStack stack,
|
||||
float x,
|
||||
float y
|
||||
) {
|
||||
drawTexturedRectAuto(stack, x, y, 26, 26, 18, 96, 256, 256);
|
||||
}
|
||||
|
||||
public static void drawWindowBackground(
|
||||
PoseStack stack,
|
||||
float x,
|
||||
|
10
src/main/java/ru/dbotthepony/mc/otm/screen/panels/Dock.java
Normal file
10
src/main/java/ru/dbotthepony/mc/otm/screen/panels/Dock.java
Normal file
@ -0,0 +1,10 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
public enum Dock {
|
||||
NONE,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
TOP,
|
||||
BOTTOM,
|
||||
FILL
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class EditBoxPanel extends MinecraftWidgetPanel<EditBox> {
|
||||
public EditBoxPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height, Component component) {
|
||||
super(screen, parent, x, y, width, height, (panel) -> {
|
||||
return new EditBox(screen.getFont(), (int) panel.getRenderX(), (int) panel.getRenderY(), (int) panel.getWidth(), (int) panel.getHeight(), component);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void copyValues(EditBox new_widget, EditBox old_widget) {
|
||||
new_widget.setValue(old_widget.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFocusChanged(boolean new_focused, boolean old_focused) {
|
||||
widget.setFocus(new_focused);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
requestFocus();
|
||||
return widget.mouseClicked(mouse_x, mouse_y, flag);
|
||||
}
|
||||
}
|
@ -0,0 +1,759 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Superclass of all panels
|
||||
* This panel represent part of GMod's Panels API
|
||||
* which allows much simpler GUI composition
|
||||
*/
|
||||
public class EditablePanel implements GuiEventListener {
|
||||
public record ScreenPos(float x, float y) {
|
||||
|
||||
}
|
||||
|
||||
private EditablePanel parent;
|
||||
public final MatteryScreen<?> screen;
|
||||
|
||||
protected boolean visible_internal = true;
|
||||
private boolean visible = true;
|
||||
|
||||
protected boolean focused = false;
|
||||
private boolean focused_internal = false;
|
||||
|
||||
// relative to parent
|
||||
// updated inside performLayout of parent if docked
|
||||
private float x;
|
||||
private float y;
|
||||
|
||||
// updated inside performLayout depending on dock
|
||||
private float width;
|
||||
private float height;
|
||||
|
||||
// updated on each rendered frame
|
||||
protected float parent_x;
|
||||
protected float parent_y;
|
||||
|
||||
private boolean needs_invalidation = false;
|
||||
|
||||
private final ArrayList<EditablePanel> children = new ArrayList<>();
|
||||
|
||||
private Dock docking = Dock.NONE;
|
||||
|
||||
public EditablePanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height) {
|
||||
this.parent = parent;
|
||||
this.screen = screen;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
if (parent != null)
|
||||
parent.onParent(this);
|
||||
|
||||
invalidateLayout();
|
||||
}
|
||||
|
||||
public float getRenderX() {
|
||||
return parent_x;
|
||||
}
|
||||
|
||||
public float getRenderY() {
|
||||
return parent_y;
|
||||
}
|
||||
|
||||
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
|
||||
}
|
||||
|
||||
public void render(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
if (!getVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (needs_invalidation) {
|
||||
needs_invalidation = false;
|
||||
performLayout();
|
||||
}
|
||||
|
||||
if (parent == null) {
|
||||
parent_x = x;
|
||||
parent_y = y;
|
||||
}
|
||||
|
||||
innerRender(stack, mouse_x, mouse_y, flag);
|
||||
|
||||
for (var child : children) {
|
||||
if (child.getVisible()) {
|
||||
child.parent_x = parent_x + child.x;
|
||||
child.parent_y = parent_y + child.y;
|
||||
|
||||
child.render(stack, mouse_x, mouse_y, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setDocking(Dock docking) {
|
||||
if (docking != this.docking) {
|
||||
this.docking = docking;
|
||||
|
||||
if (parent != null)
|
||||
parent.invalidateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public static record DockProperty(float left, float top, float right, float bottom) {
|
||||
public boolean equals(Object dock_margin) {
|
||||
if (dock_margin instanceof DockProperty prop) {
|
||||
return this == prop || left == prop.left && top == prop.top && right == prop.right && bottom == prop.bottom;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public DockProperty getDock_margin() {
|
||||
return dock_margin;
|
||||
}
|
||||
|
||||
public DockProperty getDock_padding() {
|
||||
return dock_padding;
|
||||
}
|
||||
|
||||
private DockProperty dock_margin = new DockProperty(0, 0, 0, 0);
|
||||
private DockProperty dock_padding = new DockProperty(0, 0, 0, 0);
|
||||
|
||||
public boolean setDockMargin(float left, float top, float right, float bottom) {
|
||||
var dock = new DockProperty(left, top, right, bottom);
|
||||
|
||||
if (!dock.equals(dock_margin)) {
|
||||
dock_margin = dock;
|
||||
|
||||
if (docking != Dock.NONE && parent != null)
|
||||
parent.invalidateLayout();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setDockPadding(float left, float top, float right, float bottom) {
|
||||
var dock = new DockProperty(left, top, right, bottom);
|
||||
|
||||
if (!dock.equals(dock_padding)) {
|
||||
dock_padding = dock;
|
||||
invalidateLayout();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ScreenPos localToScreen(float x, float y) {
|
||||
var get_parent = getParent();
|
||||
|
||||
while (get_parent != null) {
|
||||
x += get_parent.getX();
|
||||
y += get_parent.getY();
|
||||
get_parent = get_parent.getParent();
|
||||
}
|
||||
|
||||
return new ScreenPos(this.x + x, this.y + y);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public EditablePanel getRootParent() {
|
||||
if (getParent() == null)
|
||||
return null;
|
||||
|
||||
var get_parent = getParent();
|
||||
|
||||
while (true) {
|
||||
var get_parent2 = get_parent.getParent();
|
||||
|
||||
if (get_parent2 != null) {
|
||||
get_parent = get_parent2;
|
||||
} else {
|
||||
return get_parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public EditablePanel getRootPanel() {
|
||||
var get_parent = getRootParent();
|
||||
return get_parent != null ? get_parent : this;
|
||||
}
|
||||
|
||||
public ScreenPos localToScreen() {
|
||||
return localToScreen(0, 0);
|
||||
}
|
||||
|
||||
public ScreenPos screenToLocal(float x, float y) {
|
||||
var pos = localToScreen();
|
||||
return new ScreenPos(x - pos.x, y - pos.y);
|
||||
}
|
||||
|
||||
public ScreenPos screenToLocal(double x, double y) {
|
||||
var pos = localToScreen();
|
||||
return new ScreenPos((float) (x - pos.x), (float) (y - pos.y));
|
||||
}
|
||||
|
||||
public void invalidateLayout() {
|
||||
needs_invalidation = true;
|
||||
}
|
||||
|
||||
public EditablePanel getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public boolean getVisible() {
|
||||
return visible_internal && visible;
|
||||
}
|
||||
|
||||
public boolean getVisibleThis() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
protected void visibilityChanges(boolean new_visible, boolean old_visible) {
|
||||
|
||||
}
|
||||
|
||||
private void updateVisible() {
|
||||
for (var child : children) {
|
||||
var old_visible = child.getVisible();
|
||||
child.visible_internal = getVisible();
|
||||
var new_visible = child.getVisible();
|
||||
|
||||
if (old_visible != new_visible) {
|
||||
child.visibilityChanges(new_visible, old_visible);
|
||||
}
|
||||
|
||||
child.updateVisible();
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
if (this.visible != visible) {
|
||||
var old_visible = getVisible();
|
||||
this.visible = visible;
|
||||
var new_visible = getVisible();
|
||||
|
||||
if (old_visible != new_visible) {
|
||||
visibilityChanges(new_visible, old_visible);
|
||||
}
|
||||
|
||||
updateVisible();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasHierarchicalFocus() {
|
||||
return getHierarchicalFocus() != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private EditablePanel getHierarchicalFocus() {
|
||||
if (focused)
|
||||
return this;
|
||||
|
||||
for (var child : children) {
|
||||
if (child.focused) {
|
||||
return child.getHierarchicalFocus();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void onFocusChanged(boolean new_focused, boolean old_focused) {
|
||||
|
||||
}
|
||||
|
||||
private void updateFocused() {
|
||||
var old_value = focused_internal;
|
||||
focused_internal = hasHierarchicalFocus();
|
||||
|
||||
if (focused_internal != old_value) {
|
||||
onFocusChanged(focused_internal, old_value);
|
||||
}
|
||||
|
||||
for (var child : children) {
|
||||
child.updateFocused();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getFocused() {
|
||||
return focused || focused_internal;
|
||||
}
|
||||
|
||||
public boolean getFocusedThis() {
|
||||
return focused;
|
||||
}
|
||||
|
||||
public void setFocused(boolean focused) {
|
||||
if (this.focused != focused) {
|
||||
this.focused = focused;
|
||||
getRootPanel().updateFocused();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses this panel
|
||||
*/
|
||||
public void requestFocus() {
|
||||
if (focused)
|
||||
return;
|
||||
|
||||
if (focused_internal) {
|
||||
var child = getHierarchicalFocus();
|
||||
|
||||
while (child != null) {
|
||||
child.setFocused(false);
|
||||
child = getHierarchicalFocus();
|
||||
}
|
||||
|
||||
setFocused(true);
|
||||
} else {
|
||||
setFocused(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void killFocus() {
|
||||
if (this.focused_internal) {
|
||||
var child = getHierarchicalFocus();
|
||||
|
||||
while (child != null) {
|
||||
child.setFocused(false);
|
||||
child = getHierarchicalFocus();
|
||||
}
|
||||
|
||||
getRootPanel().updateFocused();
|
||||
}
|
||||
}
|
||||
|
||||
private void onParent(EditablePanel children) {
|
||||
this.children.add(children);
|
||||
updateVisible();
|
||||
invalidateLayout();
|
||||
}
|
||||
|
||||
private void onUnparent(EditablePanel children) {
|
||||
this.children.remove(children);
|
||||
invalidateLayout();
|
||||
}
|
||||
|
||||
public void setParent(@Nullable EditablePanel parent) {
|
||||
if (this.parent != parent) {
|
||||
invalidateLayout();
|
||||
|
||||
if (this.parent != null)
|
||||
this.parent.onParent(this);
|
||||
|
||||
this.parent = parent;
|
||||
|
||||
if (parent != null)
|
||||
parent.onParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected void xPosUpdated(float new_value, float old_value) {}
|
||||
protected void yPosUpdated(float new_value, float old_value) {}
|
||||
|
||||
protected void widthUpdated(float new_value, float old_value) {}
|
||||
protected void heightUpdated(float new_value, float old_value) {}
|
||||
|
||||
public void setPos(float x, float y) {
|
||||
setX(x);
|
||||
setY(y);
|
||||
}
|
||||
|
||||
public void setPos(double x, double y) {
|
||||
setX((float) x);
|
||||
setY((float) y);
|
||||
}
|
||||
|
||||
public void setSize(float w, float h) {
|
||||
setWidth(w);
|
||||
setHeight(h);
|
||||
}
|
||||
|
||||
public void setSize(double w, double h) {
|
||||
setWidth((float) w);
|
||||
setHeight((float) h);
|
||||
}
|
||||
|
||||
public void setDimensions(float x, float y, float w, float h) {
|
||||
setPos(x, y);
|
||||
setSize(w, h);
|
||||
}
|
||||
|
||||
public void setDimensions(double x, double y, double w, double h) {
|
||||
setPos(x, y);
|
||||
setSize(w, h);
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(float x) {
|
||||
if (x != this.x) {
|
||||
invalidateLayout();
|
||||
var old = this.x;
|
||||
this.x = x;
|
||||
xPosUpdated(x, old);
|
||||
}
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(float y) {
|
||||
if (y != this.y) {
|
||||
invalidateLayout();
|
||||
var old = this.y;
|
||||
this.y = y;
|
||||
yPosUpdated(y, old);
|
||||
}
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(float width) {
|
||||
if (width != this.width) {
|
||||
invalidateLayout();
|
||||
var old = this.width;
|
||||
this.width = width;
|
||||
widthUpdated(width, old);
|
||||
}
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(float height) {
|
||||
if (height != this.height) {
|
||||
invalidateLayout();
|
||||
var old = this.height;
|
||||
this.height = height;
|
||||
heightUpdated(height, old);
|
||||
}
|
||||
}
|
||||
|
||||
protected void performLayout() {
|
||||
var dock_left = dock_padding.left;
|
||||
var dock_right = dock_padding.right;
|
||||
var dock_top = dock_padding.top;
|
||||
var dock_bottom = dock_padding.bottom;
|
||||
|
||||
// determine sizes
|
||||
for (var child : children) {
|
||||
switch (child.docking) {
|
||||
case TOP -> dock_top += child.height + child.dock_margin.top;
|
||||
case BOTTOM -> dock_bottom += child.height + child.dock_margin.bottom;
|
||||
case LEFT -> dock_left += child.width + child.dock_margin.left;
|
||||
case RIGHT -> dock_right += child.width + child.dock_margin.right;
|
||||
}
|
||||
}
|
||||
|
||||
var dock_left2 = dock_padding.left;
|
||||
var dock_right2 = dock_padding.right;
|
||||
var dock_top2 = dock_padding.top;
|
||||
var dock_bottom2 = dock_padding.bottom;
|
||||
|
||||
// apply values
|
||||
for (var child : children) {
|
||||
switch (child.docking) {
|
||||
case TOP -> {
|
||||
child.setPos(dock_left + child.dock_margin.left, dock_top2 + child.dock_margin.top);
|
||||
dock_top2 += child.height + child.dock_margin.top + child.dock_margin.bottom;
|
||||
child.setWidth(Math.max(1, width - dock_left - dock_right - child.dock_margin.left - child.dock_margin.right));
|
||||
}
|
||||
|
||||
case BOTTOM -> {
|
||||
child.setPos(dock_left + child.dock_margin.left, height - dock_bottom2 - child.height - child.dock_margin.bottom);
|
||||
dock_bottom2 += child.height + child.dock_margin.top + child.dock_margin.bottom;
|
||||
child.setWidth(Math.max(1, width - dock_left - dock_right - child.dock_margin.left - child.dock_margin.right));
|
||||
}
|
||||
|
||||
case LEFT -> {
|
||||
child.setPos(dock_left2 + child.dock_margin.left, dock_top + child.dock_margin.top);
|
||||
dock_left2 += child.width + child.dock_margin.left + child.dock_margin.right;
|
||||
child.setHeight(Math.max(1, height - dock_top - dock_bottom - child.dock_margin.top - child.dock_margin.bottom));
|
||||
}
|
||||
|
||||
case RIGHT -> {
|
||||
child.setPos(width - dock_right2 - child.width - child.dock_margin.right, dock_top + child.dock_margin.top);
|
||||
dock_right2 += child.width + child.dock_margin.left + child.dock_margin.right;
|
||||
child.setHeight(Math.max(1, height - dock_top - dock_bottom - child.dock_margin.top - child.dock_margin.bottom));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean accept_mouse_input = true;
|
||||
private boolean accept_keyboard_input = true;
|
||||
private boolean ignore_mouse_event_boundaries = false;
|
||||
|
||||
public boolean getMouseInputEnabled() {
|
||||
return accept_mouse_input;
|
||||
}
|
||||
|
||||
public void setMouseInputEnabled(boolean value) {
|
||||
accept_mouse_input = value;
|
||||
}
|
||||
|
||||
public boolean getKeyboardInputEnabled() {
|
||||
return accept_keyboard_input;
|
||||
}
|
||||
|
||||
public void setKeyboardInputEnabled(boolean value) {
|
||||
accept_keyboard_input = value;
|
||||
}
|
||||
|
||||
public boolean getIgnoreMouseEventBoundaries() {
|
||||
if (ignore_mouse_event_boundaries) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (var child : children) {
|
||||
if (child.getIgnoreMouseEventBoundaries()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// for use when this panel want to attain global focus
|
||||
// such as when it is being dragged
|
||||
public void setIgnoreMouseEventBoundaries(boolean value) {
|
||||
ignore_mouse_event_boundaries = value;
|
||||
}
|
||||
|
||||
protected boolean auto_kill_focus = true;
|
||||
|
||||
@Override
|
||||
public void mouseMoved(double p_94758_, double p_94759_) {
|
||||
|
||||
}
|
||||
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouse_x, double mouse_y, int flag) {
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
if (ignore_mouse_event_boundaries)
|
||||
return mouseClickedInner(mouse_x, mouse_y, flag);
|
||||
|
||||
for (var child : children) {
|
||||
var pos = child.localToScreen();
|
||||
|
||||
if (child.getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + child.width >= mouse_x && pos.y <= mouse_y && pos.y + child.height >= mouse_y) {
|
||||
return child.mouseClicked(mouse_x, mouse_y, flag);
|
||||
} else if (child.auto_kill_focus) {
|
||||
child.killFocus();
|
||||
}
|
||||
}
|
||||
|
||||
return mouseClickedInner(mouse_x, mouse_y, flag);
|
||||
}
|
||||
|
||||
public boolean mouseClickedChecked(double mouse_x, double mouse_y, int flag) {
|
||||
var pos = localToScreen();
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + width >= mouse_x && pos.y <= mouse_y && pos.y + height >= mouse_y) {
|
||||
return mouseClicked(mouse_x, mouse_y, flag);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double mouse_x, double mouse_y, int flag) {
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
if (ignore_mouse_event_boundaries)
|
||||
return mouseReleasedInner(mouse_x, mouse_y, flag);
|
||||
|
||||
for (var child : children) {
|
||||
var pos = child.localToScreen();
|
||||
|
||||
if (child.getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + child.width >= mouse_x && pos.y <= mouse_y && pos.y + child.height >= mouse_y) {
|
||||
return child.mouseReleased(mouse_x, mouse_y, flag);
|
||||
}
|
||||
}
|
||||
|
||||
return mouseReleasedInner(mouse_x, mouse_y, flag);
|
||||
}
|
||||
|
||||
public boolean mouseReleasedChecked(double mouse_x, double mouse_y, int flag) {
|
||||
var pos = localToScreen();
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + width >= mouse_x && pos.y <= mouse_y && pos.y + height >= mouse_y) {
|
||||
return mouseReleased(mouse_x, mouse_y, flag);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
if (ignore_mouse_event_boundaries)
|
||||
return mouseDraggedInner(mouse_x, mouse_y, flag, drag_x, drag_y);
|
||||
|
||||
for (var child : children) {
|
||||
var pos = child.localToScreen();
|
||||
|
||||
if (child.getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + child.width >= mouse_x && pos.y <= mouse_y && pos.y + child.height >= mouse_y) {
|
||||
return child.mouseDragged(mouse_x, mouse_y, flag, drag_x, drag_y);
|
||||
}
|
||||
}
|
||||
|
||||
return mouseDraggedInner(mouse_x, mouse_y, flag, drag_x, drag_y);
|
||||
}
|
||||
|
||||
public boolean mouseDraggedChecked(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
var pos = localToScreen();
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + width >= mouse_x && pos.y <= mouse_y && pos.y + height >= mouse_y) {
|
||||
return mouseDragged(mouse_x, mouse_y, flag, drag_x, drag_y);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouse_x, double mouse_y, double scroll) {
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
for (var child : children) {
|
||||
var pos = child.localToScreen();
|
||||
|
||||
if (child.getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + child.width >= mouse_x && pos.y <= mouse_y && pos.y + child.height >= mouse_y) {
|
||||
return child.mouseScrolled(mouse_x, mouse_y, scroll);
|
||||
}
|
||||
}
|
||||
|
||||
return GuiEventListener.super.mouseScrolled(mouse_x, mouse_y, scroll);
|
||||
}
|
||||
|
||||
public boolean mouseScrolledChecked(double mouse_x, double mouse_y, double scroll) {
|
||||
var pos = localToScreen();
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + width >= mouse_x && pos.y <= mouse_y && pos.y + height >= mouse_y) {
|
||||
return mouseScrolled(mouse_x, mouse_y, scroll);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean keyPressedInternal(int p_94745_, int p_94746_, int p_94747_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int p_94745_, int p_94746_, int p_94747_) {
|
||||
if (!getVisible() || !getKeyboardInputEnabled())
|
||||
return false;
|
||||
|
||||
if (!focused_internal)
|
||||
return false;
|
||||
|
||||
if (focused)
|
||||
return keyPressedInternal(p_94745_, p_94746_, p_94747_);
|
||||
|
||||
for (var child : children) {
|
||||
if (child.keyPressed(p_94745_, p_94746_, p_94747_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean keyReleasedInternal(int p_94750_, int p_94751_, int p_94752_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyReleased(int p_94750_, int p_94751_, int p_94752_) {
|
||||
if (!getVisible() || !getKeyboardInputEnabled())
|
||||
return false;
|
||||
|
||||
if (!focused_internal)
|
||||
return false;
|
||||
|
||||
if (focused)
|
||||
return keyReleasedInternal(p_94750_, p_94751_, p_94752_);
|
||||
|
||||
for (var child : children) {
|
||||
if (child.keyReleased(p_94750_, p_94751_, p_94752_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char p_94732_, int p_94733_) {
|
||||
if (!getVisible() || !getKeyboardInputEnabled())
|
||||
return false;
|
||||
|
||||
for (var child : children) {
|
||||
if (child.charTyped(p_94732_, p_94733_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeFocus(boolean p_94756_) {
|
||||
if (!getVisible())
|
||||
return false;
|
||||
|
||||
return GuiEventListener.super.changeFocus(p_94756_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseOver(double mouse_x, double mouse_y) { // called to check whenever we are hovering at this
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
if (getIgnoreMouseEventBoundaries())
|
||||
return true;
|
||||
|
||||
var pos = localToScreen();
|
||||
return mouse_x >= pos.x && mouse_x <= pos.x + width && mouse_y >= pos.y && mouse_y + height <= pos.y;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
import ru.dbotthepony.mc.otm.screen.RenderHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class FramePanel extends EditablePanel implements NarratableEntry {
|
||||
protected Component title;
|
||||
|
||||
public FramePanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height, Component title) {
|
||||
super(screen, parent, x, y, width, height);
|
||||
this.title = title;
|
||||
setDockPadding(4, screen.getFont().lineHeight + 2, 4, 4);
|
||||
}
|
||||
|
||||
protected boolean dragging = false;
|
||||
protected double last_mouse_x = 0;
|
||||
protected double last_mouse_y = 0;
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
var pos = screenToLocal(mouse_x, mouse_y);
|
||||
|
||||
if (getParent() == null && pos.y() >= 0 && pos.y() <= 12) {
|
||||
setIgnoreMouseEventBoundaries(true);
|
||||
last_mouse_x = mouse_x;
|
||||
last_mouse_y = mouse_y;
|
||||
dragging = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.mouseClickedInner(mouse_x, mouse_y, flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
|
||||
if (dragging) {
|
||||
setIgnoreMouseEventBoundaries(false);
|
||||
|
||||
dragging = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.mouseReleasedInner(mouse_x, mouse_y, flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
if (dragging) {
|
||||
var real_drag_x = mouse_x - last_mouse_x;
|
||||
var real_drag_y = mouse_y - last_mouse_y;
|
||||
|
||||
last_mouse_x = mouse_x;
|
||||
last_mouse_y = mouse_y;
|
||||
|
||||
setPos(getX() + real_drag_x, getY() + real_drag_y);
|
||||
}
|
||||
|
||||
return super.mouseDraggedInner(mouse_x, mouse_y, flag, drag_x, drag_y);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
// background
|
||||
RenderHelper.drawWindowBackground(stack, parent_x, parent_y, getWidth(), getHeight());
|
||||
|
||||
// title
|
||||
screen.getFont().draw(stack, title, parent_x + 4, parent_y + 5, 4210752);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NarrationPriority narrationPriority() {
|
||||
return NarrationPriority.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNarration(NarrationElementOutput narrationElementOutput) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class MinecraftWidgetPanel<T extends AbstractWidget> extends EditablePanel {
|
||||
public interface WidgetFactory<T extends AbstractWidget> {
|
||||
T create(MinecraftWidgetPanel<T> panel);
|
||||
}
|
||||
|
||||
protected T widget;
|
||||
private final WidgetFactory<T> factory;
|
||||
|
||||
public T getWidget() {
|
||||
return widget;
|
||||
}
|
||||
|
||||
public MinecraftWidgetPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height, WidgetFactory<T> factory) {
|
||||
super(screen, parent, x, y, width, height);
|
||||
this.widget = factory.create(this);
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
protected void copyValues(T new_widget, T old_widget) {
|
||||
|
||||
}
|
||||
|
||||
private void recreate() {
|
||||
var new_widget = factory.create(this);
|
||||
new_widget.visible = getVisible();
|
||||
new_widget.x = (int) parent_x;
|
||||
new_widget.y = (int) parent_y;
|
||||
copyValues(new_widget, widget);
|
||||
widget = new_widget;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void widthUpdated(float new_value, float old_value) {
|
||||
recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void heightUpdated(float new_value, float old_value) {
|
||||
recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void visibilityChanges(boolean new_visible, boolean old_visible) {
|
||||
widget.visible = new_visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
widget.x = (int) parent_x;
|
||||
widget.y = (int) parent_y;
|
||||
|
||||
widget.render(stack, (int) mouse_x, (int) mouse_y, flag);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user