Scissor and draggable canvas panel for android research window
This commit is contained in:
parent
e7b810f1a8
commit
e79bdb4326
@ -115,7 +115,27 @@ public class AndroidStationScreen extends MatteryScreen<AndroidStationMenu> impl
|
||||
|
||||
autoAttachToFrame(frame);
|
||||
|
||||
var grid = new GridPanel(this, frame, 0, 0, GRID_WIDTH * 22, 0, GRID_WIDTH, GRID_HEIGHT);
|
||||
var canvas = new DraggableCanvasPanel(this, frame, 0, 0, GRID_WIDTH * 22, 0);
|
||||
|
||||
var grid = new GridPanel(this, canvas, 0, 0, 0, 0, GRID_WIDTH, GRID_HEIGHT) {
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
// pass event to canvas
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
|
||||
// pass event to canvas
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
// pass event to canvas
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
minecraft.player.getCapability(MatteryCapability.ANDROID).ifPresent(_cap -> {
|
||||
if (_cap instanceof AndroidCapabilityPlayer cap) {
|
||||
@ -129,7 +149,8 @@ public class AndroidStationScreen extends MatteryScreen<AndroidStationMenu> impl
|
||||
}
|
||||
});
|
||||
|
||||
grid.setDock(Dock.RIGHT);
|
||||
canvas.setDock(Dock.RIGHT);
|
||||
grid.setDock(Dock.FILL);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
@ -3,10 +3,13 @@ package ru.dbotthepony.mc.otm.screen;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
import com.mojang.math.Matrix4f;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_ALWAYS;
|
||||
import static org.lwjgl.opengl.GL11.GL_LESS;
|
||||
|
||||
@ -553,4 +556,49 @@ public class RenderHelper {
|
||||
) {
|
||||
drawRect(stack.last().pose(), x, y, width, height);
|
||||
}
|
||||
|
||||
record ScissorRect(int x, int y, int width, int height) {}
|
||||
|
||||
private static final Stack<ScissorRect> SCISSOR = new Stack<>();
|
||||
|
||||
public static void ensureScissorStackEmpty() {
|
||||
if (!SCISSOR.empty()) {
|
||||
throw new IllegalStateException("Unbalanced scissor rects: Popping less than pushing");
|
||||
}
|
||||
}
|
||||
|
||||
public static void pushScissorRect(int x, int y, int width, int height) {
|
||||
if (!SCISSOR.empty()) {
|
||||
final var peek = SCISSOR.peek();
|
||||
x = Math.max(x, peek.x);
|
||||
y = Math.max(y, peek.y);
|
||||
width = Math.min(width, peek.width);
|
||||
height = Math.min(height, peek.height);
|
||||
}
|
||||
|
||||
SCISSOR.push(new ScissorRect(x, y, width, height));
|
||||
|
||||
final var window = Minecraft.getInstance().getWindow();
|
||||
y = window.getHeight() - y - height;
|
||||
|
||||
RenderSystem.enableScissor(x, y, width, height);
|
||||
}
|
||||
|
||||
public static void popScissorRect() {
|
||||
if (SCISSOR.empty()) {
|
||||
throw new IllegalStateException("Unbalanced scissor rects: Popping more than pushing");
|
||||
}
|
||||
|
||||
SCISSOR.pop();
|
||||
|
||||
if (SCISSOR.empty()) {
|
||||
RenderSystem.disableScissor();
|
||||
return;
|
||||
}
|
||||
|
||||
final var value = SCISSOR.peek();
|
||||
final var window = Minecraft.getInstance().getWindow();
|
||||
final var y = window.getHeight() - value.y - value.height;
|
||||
RenderSystem.enableScissor(value.x, y, value.width, value.height);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class DraggableCanvasPanel extends EditablePanel {
|
||||
public DraggableCanvasPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height) {
|
||||
super(screen, parent, x, y, width, height);
|
||||
scissor = true;
|
||||
}
|
||||
|
||||
public DraggableCanvasPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent) {
|
||||
super(screen, parent);
|
||||
scissor = true;
|
||||
}
|
||||
|
||||
protected boolean dragging = false;
|
||||
protected double last_mouse_x;
|
||||
protected double last_mouse_y;
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
dragging = true;
|
||||
last_mouse_x = mouse_x;
|
||||
last_mouse_y = mouse_y;
|
||||
setIgnoreMouseEventBoundaries(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
|
||||
dragging = false;
|
||||
setIgnoreMouseEventBoundaries(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
if (dragging) {
|
||||
x_offset -= last_mouse_x - mouse_x;
|
||||
y_offset -= last_mouse_y - mouse_y;
|
||||
|
||||
last_mouse_x = mouse_x;
|
||||
last_mouse_y = mouse_y;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -2,8 +2,12 @@ package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Vector3f;
|
||||
import com.mojang.math.Vector4f;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
import ru.dbotthepony.mc.otm.screen.RenderHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@ -56,6 +60,37 @@ public class EditablePanel implements GuiEventListener {
|
||||
protected float parent_x;
|
||||
protected float parent_y;
|
||||
|
||||
// allows to offset children by given amount of pixels
|
||||
protected float x_offset;
|
||||
protected float y_offset;
|
||||
|
||||
// whenever is to scissor render bounds
|
||||
protected boolean scissor = false;
|
||||
|
||||
public float getXOffset() {
|
||||
return x_offset;
|
||||
}
|
||||
|
||||
public void setXOffset(float x_offset) {
|
||||
this.x_offset = x_offset;
|
||||
}
|
||||
|
||||
public float getYOffset() {
|
||||
return y_offset;
|
||||
}
|
||||
|
||||
public void setYOffset(float y_offset) {
|
||||
this.y_offset = y_offset;
|
||||
}
|
||||
|
||||
public boolean getEnableScissor() {
|
||||
return scissor;
|
||||
}
|
||||
|
||||
public void setEnableScissor(boolean scissor) {
|
||||
this.scissor = scissor;
|
||||
}
|
||||
|
||||
protected float accumulated_depth = 0;
|
||||
|
||||
public float getMost3DHeight() {
|
||||
@ -151,8 +186,16 @@ public class EditablePanel implements GuiEventListener {
|
||||
is_hovered = parent.is_hovered && mouse_x >= parent_x && mouse_x < parent_x + width && mouse_y >= parent_y && mouse_y < parent_y + height;
|
||||
}
|
||||
|
||||
var scissor = this.scissor;
|
||||
|
||||
if (scissor) {
|
||||
var window = Minecraft.getInstance().getWindow();
|
||||
var scale = window.getGuiScale();
|
||||
RenderHelper.pushScissorRect((int) (parent_x * scale), (int) (parent_y * scale), (int) (width * scale), (int) (height * scale));
|
||||
}
|
||||
|
||||
stack.pushPose();
|
||||
stack.translate(parent_x, parent_y, accumulated_depth);
|
||||
stack.translate(parent_x + getXOffset(), parent_y + getYOffset(), accumulated_depth);
|
||||
innerRender(stack, mouse_x, mouse_y, flag);
|
||||
stack.popPose();
|
||||
|
||||
@ -161,14 +204,18 @@ public class EditablePanel implements GuiEventListener {
|
||||
for (var child : children) {
|
||||
if (child.getVisible()) {
|
||||
child.accumulated_depth = accumulated_depth + 1;
|
||||
child.parent_x = parent_x + child.x;
|
||||
child.parent_y = parent_y + child.y;
|
||||
child.parent_x = parent_x + child.x + getXOffset();
|
||||
child.parent_y = parent_y + child.y + getYOffset();
|
||||
|
||||
RenderSystem.setShaderColor(1F, 1F, 1F, 1F);
|
||||
most_depth = Math.max(most_depth, child.render(stack, mouse_x, mouse_y, flag));
|
||||
}
|
||||
}
|
||||
|
||||
if (scissor) {
|
||||
RenderHelper.popScissorRect();
|
||||
}
|
||||
|
||||
return most_depth;
|
||||
}
|
||||
|
||||
@ -278,8 +325,8 @@ public class EditablePanel implements GuiEventListener {
|
||||
var get_parent = getParent();
|
||||
|
||||
while (get_parent != null) {
|
||||
x += get_parent.getX();
|
||||
y += get_parent.getY();
|
||||
x += get_parent.getX() + get_parent.getXOffset();
|
||||
y += get_parent.getY() + get_parent.getYOffset();
|
||||
get_parent = get_parent.getParent();
|
||||
}
|
||||
|
||||
@ -741,7 +788,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean withinBounds(double mouse_x, double mouse_y) {
|
||||
@ -781,8 +828,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
if (getMouseInputEnabled() && parent == null)
|
||||
screen.popup(this);
|
||||
|
||||
mouseClicked(mouse_x, mouse_y, flag);
|
||||
return true;
|
||||
return mouseClicked(mouse_x, mouse_y, flag);
|
||||
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
|
||||
for (var child : children) {
|
||||
if (child.mouseClickedChecked(mouse_x, mouse_y, flag)) {
|
||||
@ -802,7 +848,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
|
||||
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -827,8 +873,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
return false;
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
|
||||
mouseReleased(mouse_x, mouse_y, flag);
|
||||
return true;
|
||||
return mouseReleased(mouse_x, mouse_y, flag);
|
||||
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
|
||||
for (var child : children) {
|
||||
if (child.mouseReleasedChecked(mouse_x, mouse_y, flag)) {
|
||||
@ -841,7 +886,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
|
||||
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -866,8 +911,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
return false;
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
|
||||
mouseDragged(mouse_x, mouse_y, flag, drag_x, drag_y);
|
||||
return true;
|
||||
return mouseDragged(mouse_x, mouse_y, flag, drag_x, drag_y);
|
||||
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
|
||||
for (var child : children) {
|
||||
if (child.mouseDraggedChecked(mouse_x, mouse_y, flag, drag_x, drag_y)) {
|
||||
@ -880,7 +924,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
|
||||
protected boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -905,8 +949,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
return false;
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
|
||||
mouseScrolled(mouse_x, mouse_y, scroll);
|
||||
return true;
|
||||
return mouseScrolled(mouse_x, mouse_y, scroll);
|
||||
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
|
||||
for (var child : children) {
|
||||
if (child.mouseScrolledChecked(mouse_x, mouse_y, scroll)) {
|
||||
@ -1011,7 +1054,9 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
|
||||
for (var child : children) {
|
||||
child.tick();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean is_removed = false;
|
||||
|
Loading…
Reference in New Issue
Block a user