Reimplement pattern panel menu
This commit is contained in:
parent
b65bbab767
commit
7bd1de8171
src/main
java/ru/dbotthepony/mc/otm
capability
screen
resources/assets/overdrive_that_matters/textures/gui
@ -5,6 +5,7 @@ import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.registries.ForgeRegistry;
|
||||
import net.minecraftforge.registries.RegistryManager;
|
||||
|
||||
@ -28,6 +29,10 @@ public record PatternState(@Nonnull UUID id, @Nonnull Item item, double research
|
||||
return false;
|
||||
}
|
||||
|
||||
public ItemStack stack() {
|
||||
return new ItemStack(item, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
|
@ -21,18 +21,19 @@ import ru.dbotthepony.mc.otm.capability.PatternState;
|
||||
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
|
||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
|
||||
import ru.dbotthepony.mc.otm.network.PatternReplicationRequestPacket;
|
||||
import ru.dbotthepony.mc.otm.screen.panels.*;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_ALWAYS;
|
||||
import static org.lwjgl.opengl.GL11.GL_LESS;
|
||||
|
||||
public class MatterPanelScreen extends MatteryScreen<MatterPanelMenu> {
|
||||
private static final int modal_width = 213;
|
||||
private static final int modal_height = 110;
|
||||
|
||||
private boolean open_task_list = false;
|
||||
private static final int MODAL_WIDTH = 213;
|
||||
private static final int MODAL_HEIGHT = 110;
|
||||
|
||||
protected static final ResourceLocation CONTAINER = new ResourceLocation(OverdriveThatMatters.MOD_ID, "textures/gui/matter_panel.png");
|
||||
|
||||
@ -47,599 +48,362 @@ public class MatterPanelScreen extends MatteryScreen<MatterPanelMenu> {
|
||||
imageHeight = 187;
|
||||
|
||||
titleLabelY = 5;
|
||||
|
||||
p_97741_.networkTaskWatcher(task -> {
|
||||
if (open_task != null && open_task.equals(task)) {
|
||||
open_task = task;
|
||||
}
|
||||
}, task -> {
|
||||
if (open_task != null && open_task.equals(task)) {
|
||||
closeTask();
|
||||
|
||||
public static final int GRID_WIDTH = 8;
|
||||
public static final int GRID_HEIGHT = 9;
|
||||
|
||||
private final ArrayList<AbstractSlotPanel> pattern_slots = new ArrayList<>();
|
||||
private final ArrayList<AbstractSlotPanel> task_slots = new ArrayList<>();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected FramePanel makeMainFrame() {
|
||||
float width = GRID_WIDTH * AbstractSlotPanel.REGULAR_DIMENSIONS + ScrollBarPanel.WIDTH + FramePanel.PADDING * 2 + 8;
|
||||
float height = GRID_HEIGHT * AbstractSlotPanel.REGULAR_DIMENSIONS + FramePanel.PADDING_TOP + FramePanel.PADDING;
|
||||
|
||||
var scroll_panel = new ScrollBarPanel(this, null, 0, 0, 0);
|
||||
|
||||
var frame = new FramePanel(this, null, 0, 0, width, height, getTitle()) {
|
||||
@Override
|
||||
protected boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
|
||||
return scroll_panel.mouseScrolledInner(mouse_x, mouse_y, scroll);
|
||||
}
|
||||
};
|
||||
|
||||
var patterns_tab = frame.addTab(FramePanel.FrameTabPosition.TOP, () -> {
|
||||
for (var slot : pattern_slots) {
|
||||
slot.setVisible(true);
|
||||
}
|
||||
}, () -> {
|
||||
for (var slot : pattern_slots) {
|
||||
slot.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
var tasks_tab = frame.addTab(FramePanel.FrameTabPosition.TOP, () -> {
|
||||
for (var slot : task_slots) {
|
||||
slot.setVisible(true);
|
||||
}
|
||||
}, () -> {
|
||||
for (var slot : task_slots) {
|
||||
slot.setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
scroll_panel.setParent(frame);
|
||||
scroll_panel.setDocking(Dock.RIGHT);
|
||||
scroll_panel.setupRowMultiplier(() -> {
|
||||
if (tasks_tab.isActive()) {
|
||||
return menu.tasks.size() / 9;
|
||||
}
|
||||
|
||||
return menu.patterns.size() / 9;
|
||||
});
|
||||
|
||||
var grid = new GridPanel(this, frame, 0, 0, GRID_WIDTH * AbstractSlotPanel.REGULAR_DIMENSIONS, 0, GRID_WIDTH, GRID_HEIGHT) {
|
||||
@Override
|
||||
protected boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
|
||||
return scroll_panel.mouseScrolledInner(mouse_x, mouse_y, scroll);
|
||||
}
|
||||
};
|
||||
|
||||
grid.setDocking(Dock.LEFT);
|
||||
grid.setDockMargin(4, 0, 0, 0);
|
||||
|
||||
for (int i = 0; i < GRID_WIDTH * GRID_HEIGHT; i++) {
|
||||
int slot = i;
|
||||
|
||||
pattern_slots.add(new AbstractSlotPanel(this, grid, 0, 0) {
|
||||
@Nonnull
|
||||
@Override
|
||||
protected ItemStack getItemStack() {
|
||||
if (slot >= menu.patterns.size()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
return menu.patterns.get(slot).stack();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Component> getItemStackTooltip(ItemStack stack) {
|
||||
if (slot >= menu.patterns.size()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
return getPatternTooltip(super.getItemStackTooltip(stack), menu.patterns.get(slot));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
|
||||
return scroll_panel.mouseScrolledInner(mouse_x, mouse_y, scroll);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
if (slot >= menu.patterns.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
openPattern(menu.patterns.get(slot));
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
task_slots.add(new AbstractSlotPanel(this, grid, 0, 0) {
|
||||
@Nonnull
|
||||
@Override
|
||||
protected ItemStack getItemStack() {
|
||||
if (slot >= menu.tasks.size()) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
var task = menu.tasks.get(slot);
|
||||
|
||||
return task.stack(Math.max(task.required(), 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Component> getItemStackTooltip(ItemStack stack) {
|
||||
if (slot >= menu.tasks.size()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
return getTaskTooltip(super.getItemStackTooltip(stack), menu.tasks.get(slot));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
|
||||
return scroll_panel.mouseScrolledInner(mouse_x, mouse_y, scroll);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
if (slot >= menu.tasks.size()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
openTask(menu.tasks.get(slot));
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private PatternState open_pattern;
|
||||
private MatterTask open_task;
|
||||
private EditBox input_amount;
|
||||
|
||||
private Button inc_8;
|
||||
private Button inc_64;
|
||||
private Button inc_256;
|
||||
|
||||
private Button dec_8;
|
||||
private Button dec_64;
|
||||
private Button dec_256;
|
||||
|
||||
private Button send_modal;
|
||||
private Button cancel_modal;
|
||||
|
||||
private Button cancel_task;
|
||||
private Button close_task;
|
||||
|
||||
private PatternState hovered_pattern;
|
||||
private MatterTask hovered_task;
|
||||
|
||||
private double scroller_position = 0;
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
int x = (width - modal_width) / 2;
|
||||
int y = (height - modal_height) / 2;
|
||||
|
||||
// окно на создание запроса
|
||||
int top_level = 15;
|
||||
int button_width = 40;
|
||||
int right = 5 + button_width;
|
||||
int box_width = modal_width - 5 - 5 - 30;
|
||||
|
||||
inc_8 = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.increase_by", 8), (btn) -> onChangeAmountPress(8));
|
||||
right += 2 + button_width;
|
||||
|
||||
inc_64 = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.increase_by", 64), (btn) -> onChangeAmountPress(64));
|
||||
right += 2 + button_width;
|
||||
|
||||
inc_256 = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.increase_by", 256), (btn) -> onChangeAmountPress(256));
|
||||
right = 5 + button_width;
|
||||
|
||||
top_level += 24;
|
||||
|
||||
input_amount = new EditBox(font, x + modal_width - 5 - box_width, y + top_level, box_width, 16, new TranslatableComponent("otm.container.matter_panel.number_input"));
|
||||
input_amount.setMaxLength(6);
|
||||
input_amount.setValue("1");
|
||||
input_amount.visible = false;
|
||||
|
||||
top_level += 20;
|
||||
|
||||
dec_8 = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.decrease_by", 8), (btn) -> onChangeAmountPress(-8));
|
||||
right += 2 + button_width;
|
||||
|
||||
dec_64 = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.decrease_by", 64), (btn) -> onChangeAmountPress(-64));
|
||||
right += 2 + button_width;
|
||||
|
||||
dec_256 = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.decrease_by", 256), (btn) -> onChangeAmountPress(-256));
|
||||
|
||||
top_level += 24;
|
||||
right = 5 + button_width;
|
||||
|
||||
cancel_modal = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.cancel"), (btn) -> closePattern());
|
||||
right += 2 + button_width;
|
||||
|
||||
send_modal = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.send"), (btn) -> onSend());
|
||||
|
||||
inc_8.visible = false;
|
||||
inc_64.visible = false;
|
||||
inc_256.visible = false;
|
||||
|
||||
dec_8.visible = false;
|
||||
dec_64.visible = false;
|
||||
dec_256.visible = false;
|
||||
|
||||
send_modal.visible = false;
|
||||
cancel_modal.visible = false;
|
||||
|
||||
addWidget(input_amount);
|
||||
addWidget(inc_8);
|
||||
addWidget(inc_64);
|
||||
addWidget(inc_256);
|
||||
addWidget(dec_8);
|
||||
addWidget(dec_64);
|
||||
addWidget(dec_256);
|
||||
addWidget(send_modal);
|
||||
addWidget(cancel_modal);
|
||||
|
||||
// окно на отмену запроса
|
||||
right = 5 + button_width;
|
||||
top_level = modal_height - 8 - 20;
|
||||
|
||||
close_task = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.close"), (btn) -> closeTask());
|
||||
|
||||
button_width = 90;
|
||||
right += 2 + button_width;
|
||||
cancel_task = new Button(x + modal_width - right, y + top_level, button_width, 20, new TranslatableComponent("otm.container.matter_panel.cancel_task"), (btn) -> cancelTask());
|
||||
|
||||
close_task.visible = false;
|
||||
cancel_task.visible = false;
|
||||
|
||||
addWidget(close_task);
|
||||
addWidget(cancel_task);
|
||||
for (var slot : task_slots) {
|
||||
slot.setVisible(false);
|
||||
}
|
||||
|
||||
private void onChangeAmountPress(int amount) {
|
||||
return frame;
|
||||
}
|
||||
|
||||
private List<Component> getTaskTooltip(List<Component> input, MatterTask task) {
|
||||
input.add(new TranslatableComponent("otm.gui.matter_task.total", task.total()).withStyle(ChatFormatting.GRAY));
|
||||
input.add(new TranslatableComponent("otm.gui.matter_task.required", task.required()).withStyle(ChatFormatting.GRAY));
|
||||
input.add(new TranslatableComponent("otm.gui.matter_task.in_progress", task.in_progress()).withStyle(ChatFormatting.GRAY));
|
||||
input.add(new TranslatableComponent("otm.gui.matter_task.finished", task.finished()).withStyle(ChatFormatting.GRAY));
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
private List<Component> getPatternTooltip(List<Component> input, PatternState pattern) {
|
||||
input.add(new TranslatableComponent("otm.item.pattern.research", String.format("%.2f", pattern.research_percent() * 100d)).withStyle(ChatFormatting.AQUA));
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
private void openTask(MatterTask task) {
|
||||
var task_frame = new FramePanel(this, null, 0, 0, MODAL_WIDTH, MODAL_HEIGHT, new TranslatableComponent("otm.container.matter_panel.task")) {
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (!menu.tasks.contains(task)) {
|
||||
remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var row_1 = new EditablePanel(this, task_frame);
|
||||
var row_2 = new EditablePanel(this, task_frame);
|
||||
|
||||
row_1.setHeight(18);
|
||||
row_2.setHeight(20);
|
||||
|
||||
row_1.setDocking(Dock.TOP);
|
||||
row_2.setDocking(Dock.TOP);
|
||||
|
||||
row_1.setDockMargin(0, 2, 0, 0);
|
||||
row_2.setDockMargin(0, 2, 0, 0);
|
||||
|
||||
var slot = new AbstractSlotPanel(this, row_1, 0, 0) {
|
||||
@Nonnull
|
||||
@Override
|
||||
protected ItemStack getItemStack() {
|
||||
var task1_index = menu.tasks.indexOf(task);
|
||||
|
||||
if (task1_index != -1) {
|
||||
var task1 = menu.tasks.get(task1_index);
|
||||
return task1.stack(Math.max(task1.required(), 1));
|
||||
}
|
||||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Component> getItemStackTooltip(ItemStack stack) {
|
||||
var task1_index = menu.tasks.indexOf(task);
|
||||
List<Component> get_list = super.getItemStackTooltip(stack);
|
||||
|
||||
if (task1_index != -1) {
|
||||
getTaskTooltip(get_list, menu.tasks.get(task1_index));
|
||||
}
|
||||
|
||||
return get_list;
|
||||
}
|
||||
};
|
||||
|
||||
slot.setDocking(Dock.LEFT);
|
||||
|
||||
var button = new ButtonPanel(this, row_2, 0, 0, 40, 20, new TranslatableComponent("otm.container.matter_panel.close"));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
button.bindOnPress(task_frame::remove);
|
||||
|
||||
button = new ButtonPanel(this, row_2, 0, 0, 80, 20, new TranslatableComponent("otm.container.matter_panel.cancel_task"));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
button.bindOnPress(() -> {
|
||||
menu.requestTaskCancel(task.id());
|
||||
task_frame.remove();
|
||||
});
|
||||
|
||||
task_frame.toScreenCenter();
|
||||
addPanel(task_frame);
|
||||
}
|
||||
|
||||
private void openPattern(PatternState state) {
|
||||
var pattern_frame = new FramePanel(this, null, 0, 0, MODAL_WIDTH, MODAL_HEIGHT, new TranslatableComponent("otm.container.matter_panel.label"));
|
||||
var row_1 = new EditablePanel(this, pattern_frame);
|
||||
var row_2 = new EditablePanel(this, pattern_frame);
|
||||
var row_3 = new EditablePanel(this, pattern_frame);
|
||||
var row_4 = new EditablePanel(this, pattern_frame);
|
||||
|
||||
row_1.setDocking(Dock.TOP);
|
||||
row_2.setDocking(Dock.TOP);
|
||||
row_3.setDocking(Dock.TOP);
|
||||
row_4.setDocking(Dock.TOP);
|
||||
|
||||
row_1.setHeight(20);
|
||||
row_2.setHeight(20);
|
||||
row_3.setHeight(20);
|
||||
row_4.setHeight(20);
|
||||
|
||||
row_1.setDockMargin(0, 2, 0, 0);
|
||||
row_2.setDockMargin(0, 2, 0, 0);
|
||||
row_3.setDockMargin(0, 2, 0, 0);
|
||||
row_4.setDockMargin(0, 2, 0, 0);
|
||||
|
||||
var slot = new AbstractSlotPanel(this, row_2, 0, 0) {
|
||||
@Nonnull
|
||||
@Override
|
||||
protected ItemStack getItemStack() {
|
||||
return new ItemStack(state.item(), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Component> getItemStackTooltip(ItemStack stack) {
|
||||
return getPatternTooltip(super.getItemStackTooltip(stack), state);
|
||||
}
|
||||
};
|
||||
|
||||
var input_amount = new EditBoxPanel(this, row_2, 0, 0, 10, 20, new TextComponent("Input amount")) {
|
||||
@Override
|
||||
protected void factorize(EditBox widget, boolean recreation) {
|
||||
super.factorize(widget, recreation);
|
||||
|
||||
widget.setMaxLength(6);
|
||||
|
||||
if (!recreation) {
|
||||
widget.setValue("1");
|
||||
}
|
||||
}
|
||||
|
||||
private void increase(int amount) {
|
||||
int value = 1;
|
||||
|
||||
try {
|
||||
value = Integer.parseInt(input_amount.getValue());
|
||||
value = Integer.parseInt(getOrCreateWidget().getValue());
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
|
||||
if (value == 1 && amount > 0)
|
||||
input_amount.setValue(Integer.toString(amount));
|
||||
getOrCreateWidget().setValue(Integer.toString(amount));
|
||||
else
|
||||
input_amount.setValue(Integer.toString(Math.max(1, Math.min(99999, value + amount))));
|
||||
getOrCreateWidget().setValue(Integer.toString(Math.max(1, Math.min(99999, value + amount))));
|
||||
}
|
||||
};
|
||||
|
||||
private void onSend() {
|
||||
var button = new ButtonPanel(this, row_1, 0, 0, 40, 20, new TranslatableComponent("otm.container.matter_panel.increase_by", 8));
|
||||
button.bindOnPress(() -> input_amount.increase(8));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
|
||||
button = new ButtonPanel(this, row_1, 0, 0, 40, 20, new TranslatableComponent("otm.container.matter_panel.increase_by", 64));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.bindOnPress(() -> input_amount.increase(64));
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
|
||||
button = new ButtonPanel(this, row_1, 0, 0, 40, 20, new TranslatableComponent("otm.container.matter_panel.increase_by", 256));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.bindOnPress(() -> input_amount.increase(256));
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
|
||||
slot.setDocking(Dock.LEFT);
|
||||
slot.setDockMargin(0, 0, 4, 0);
|
||||
input_amount.setDocking(Dock.FILL);
|
||||
|
||||
button = new ButtonPanel(this, row_3, 0, 0, 40, 20, new TranslatableComponent("otm.container.matter_panel.decrease_by", 8));
|
||||
button.bindOnPress(() -> input_amount.increase(-8));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
|
||||
button = new ButtonPanel(this, row_3, 0, 0, 40, 20, new TranslatableComponent("otm.container.matter_panel.decrease_by", 64));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.bindOnPress(() -> input_amount.increase(-64));
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
|
||||
button = new ButtonPanel(this, row_3, 0, 0, 40, 20, new TranslatableComponent("otm.container.matter_panel.decrease_by", 256));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.bindOnPress(() -> input_amount.increase(-256));
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
|
||||
button = new ButtonPanel(this, row_4, 0, 0, 40, 20, new TranslatableComponent("otm.container.matter_panel.cancel"));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.bindOnPress(pattern_frame::remove);
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
|
||||
button = new ButtonPanel(this, row_4, 0, 0, 82, 20, new TranslatableComponent("otm.container.matter_panel.send"));
|
||||
button.setDocking(Dock.RIGHT);
|
||||
button.bindOnPress(() -> {
|
||||
int value = 1;
|
||||
|
||||
try {
|
||||
value = Integer.parseInt(input_amount.getValue());
|
||||
value = Integer.parseInt(input_amount.getOrCreateWidget().getValue());
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
|
||||
MatteryNetworking.CHANNEL.sendToServer(new PatternReplicationRequestPacket(open_pattern, value));
|
||||
closePattern();
|
||||
}
|
||||
MatteryNetworking.CHANNEL.sendToServer(new PatternReplicationRequestPacket(state, value));
|
||||
pattern_frame.remove();
|
||||
});
|
||||
|
||||
private void closePattern() {
|
||||
open_pattern = null;
|
||||
input_amount.visible = false;
|
||||
input_amount.changeFocus(false);
|
||||
inc_8.visible = false;
|
||||
inc_64.visible = false;
|
||||
inc_256.visible = false;
|
||||
button.setDockMargin(2, 0, 0, 0);
|
||||
|
||||
send_modal.visible = false;
|
||||
cancel_modal.visible = false;
|
||||
|
||||
dec_8.visible = false;
|
||||
dec_64.visible = false;
|
||||
dec_256.visible = false;
|
||||
}
|
||||
|
||||
private void openTask(MatterTask task) {
|
||||
open_task = task;
|
||||
|
||||
close_task.visible = true;
|
||||
cancel_task.visible = true;
|
||||
}
|
||||
|
||||
private void closeTask() {
|
||||
open_task = null;
|
||||
|
||||
close_task.visible = false;
|
||||
cancel_task.visible = false;
|
||||
}
|
||||
|
||||
private void cancelTask() {
|
||||
menu.requestTaskCancel(open_task.id());
|
||||
closeTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void containerTick() {
|
||||
super.containerTick();
|
||||
|
||||
input_amount.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(Minecraft p_96575_, int p_96576_, int p_96577_) {
|
||||
var input_amount = this.input_amount;
|
||||
|
||||
super.resize(p_96575_, p_96576_, p_96577_);
|
||||
|
||||
if (open_task != null) {
|
||||
openTask(open_task);
|
||||
}
|
||||
|
||||
if (open_pattern != null) {
|
||||
openPattern(open_pattern);
|
||||
}
|
||||
|
||||
if (input_amount != null) {
|
||||
this.input_amount.setValue(input_amount.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
protected void renderForeground(PoseStack stack, int mouseX, int mouseY, float p_98421_) {
|
||||
if (open_pattern != null) {
|
||||
RenderSystem.disableDepthTest();
|
||||
|
||||
input_amount.render(stack, mouseX, mouseY, p_98421_);
|
||||
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.depthFunc(GL_ALWAYS);
|
||||
|
||||
inc_8.render(stack, mouseX, mouseY, p_98421_);
|
||||
|
||||
inc_64.render(stack, mouseX, mouseY, p_98421_);
|
||||
|
||||
inc_256.render(stack, mouseX, mouseY, p_98421_);
|
||||
|
||||
dec_8.render(stack, mouseX, mouseY, p_98421_);
|
||||
dec_64.render(stack, mouseX, mouseY, p_98421_);
|
||||
dec_256.render(stack, mouseX, mouseY, p_98421_);
|
||||
dec_8.render(stack, mouseX, mouseY, p_98421_);
|
||||
|
||||
send_modal.render(stack, mouseX, mouseY, p_98421_);
|
||||
cancel_modal.render(stack, mouseX, mouseY, p_98421_);
|
||||
|
||||
RenderSystem.depthFunc(GL_LESS);
|
||||
} else if (open_task != null) {
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.depthFunc(GL_ALWAYS);
|
||||
|
||||
cancel_task.render(stack, mouseX, mouseY, p_98421_);
|
||||
close_task.render(stack, mouseX, mouseY, p_98421_);
|
||||
|
||||
RenderSystem.depthFunc(GL_LESS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderLabels(PoseStack p_97808_, int p_97809_, int p_97810_) {}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<Component> getTooltipFromItem(ItemStack p_96556_) {
|
||||
List<Component> get_list = super.getTooltipFromItem(p_96556_);
|
||||
|
||||
if (hovered_pattern != null) {
|
||||
get_list.add(new TranslatableComponent("otm.item.pattern.research", String.format("%.2f", hovered_pattern.research_percent() * 100d)).withStyle(ChatFormatting.AQUA));
|
||||
} else if (hovered_task != null) {
|
||||
get_list.add(new TranslatableComponent("otm.gui.matter_task.total", hovered_task.total()).withStyle(ChatFormatting.GRAY));
|
||||
get_list.add(new TranslatableComponent("otm.gui.matter_task.required", hovered_task.required()).withStyle(ChatFormatting.GRAY));
|
||||
get_list.add(new TranslatableComponent("otm.gui.matter_task.in_progress", hovered_task.in_progress()).withStyle(ChatFormatting.GRAY));
|
||||
get_list.add(new TranslatableComponent("otm.gui.matter_task.finished", hovered_task.finished()).withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
|
||||
return get_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderTooltip(PoseStack pose, int mouseX, int mouseY) {
|
||||
if (open_pattern != null) {
|
||||
int x = (width - modal_width) / 2 + 7;
|
||||
int y = input_amount.y + 1;
|
||||
|
||||
if (mouseX >= x && mouseX <= x + 16 && mouseY >= y && mouseY <= y + 16) {
|
||||
this.renderTooltip(pose, new ItemStack(open_pattern.item(), 1), mouseX, mouseY);
|
||||
return;
|
||||
}
|
||||
} else if (hovered_pattern != null) {
|
||||
this.renderTooltip(pose, new ItemStack(hovered_pattern.item(), 1), mouseX, mouseY);
|
||||
return;
|
||||
} else if (hovered_task != null) {
|
||||
this.renderTooltip(pose, new ItemStack(hovered_task.item(), hovered_task.total()), mouseX, mouseY);
|
||||
return;
|
||||
}
|
||||
|
||||
super.renderTooltip(pose, mouseX, mouseY);
|
||||
}
|
||||
|
||||
private void openPattern(PatternState state) {
|
||||
open_pattern = state;
|
||||
input_amount.setValue("1");
|
||||
// input_amount.setFocus(true); // bugged
|
||||
scrolling = false;
|
||||
|
||||
input_amount.visible = true;
|
||||
inc_8.visible = true;
|
||||
inc_64.visible = true;
|
||||
inc_256.visible = true;
|
||||
|
||||
dec_8.visible = true;
|
||||
dec_64.visible = true;
|
||||
dec_256.visible = true;
|
||||
|
||||
send_modal.visible = true;
|
||||
cancel_modal.visible = true;
|
||||
}
|
||||
|
||||
private double scroller_position_regular = 0;
|
||||
private double scroller_position_tasks = 0;
|
||||
|
||||
private void openTaskList() {
|
||||
open_task_list = true;
|
||||
scroller_position_regular = scroller_position;
|
||||
scroller_position = scroller_position_tasks;
|
||||
|
||||
}
|
||||
|
||||
private void closeTaskList() {
|
||||
open_task_list = false;
|
||||
scroller_position_tasks = scroller_position;
|
||||
scroller_position = scroller_position_regular;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouse_x, double mouse_y, int p_97750_) {
|
||||
if (open_task == null && open_pattern == null) {
|
||||
if (hovered_pattern != null) {
|
||||
openPattern(hovered_pattern);
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
return true;
|
||||
} else if (hovered_task != null) {
|
||||
openTask(hovered_task);
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int button_x = leftPos + 157;
|
||||
int button_y = topPos + 20 + (int) ((scroller_position / maxScroll()) * 145);
|
||||
int button_width = 12;
|
||||
int button_height = 15;
|
||||
|
||||
scrolling = maxScroll() > 0 && mouse_x >= button_x && button_x + button_width >= mouse_x && mouse_y >= button_y && button_y + button_height >= mouse_y;
|
||||
|
||||
if (open_task == null && open_pattern == null) {
|
||||
if (open_task_list) {
|
||||
button_x = leftPos;
|
||||
button_y = topPos - 28;
|
||||
button_width = 28;
|
||||
button_height = 30;
|
||||
|
||||
if (mouse_x >= button_x && button_x + button_width >= mouse_x && mouse_y >= button_y && button_y + button_height >= mouse_y) {
|
||||
closeTaskList();
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
}
|
||||
} else {
|
||||
button_x = leftPos + 28;
|
||||
button_y = topPos - 28;
|
||||
button_width = 28;
|
||||
button_height = 30;
|
||||
|
||||
if (mouse_x >= button_x && button_x + button_width >= mouse_x && mouse_y >= button_y && button_y + button_height >= mouse_y) {
|
||||
openTaskList();
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseClicked(mouse_x, mouse_y, p_97750_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double p_97812_, double p_97813_, int p_97814_) {
|
||||
scrolling = false;
|
||||
return super.mouseReleased(p_97812_, p_97813_, p_97814_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouse_x, double mouse_y, double scroll) {
|
||||
if (open_pattern != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (super.mouseScrolled(mouse_x, mouse_y, scroll)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
scroller_position = Math.max(0, Math.min(maxScroll(), scroller_position - scroll));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
if (scrolling && maxScroll() > 0) {
|
||||
if (mouse_y < topPos + 20) {
|
||||
scroller_position = 0;
|
||||
} else if (mouse_y > topPos + 20 + 160) {
|
||||
scroller_position = maxScroll();
|
||||
} else {
|
||||
scroller_position = maxScroll() * (mouse_y - topPos - 20) / 160d;
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseDragged(mouse_x, mouse_y, flag, drag_x, drag_y);
|
||||
}
|
||||
|
||||
private boolean scrolling = false;
|
||||
|
||||
private int maxScroll() {
|
||||
if (open_task_list) {
|
||||
if (menu.tasks.size() < 16) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int) Math.floor(menu.tasks.size() / 8d - 2d);
|
||||
}
|
||||
|
||||
if (menu.patterns.size() < 16) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int) Math.floor(menu.patterns.size() / 8d - 2d);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBg(PoseStack pose, float p_97788_, int mouseX, int mouseY) {
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.setShaderTexture(0, CONTAINER_BACKGROUND());
|
||||
|
||||
if (open_task_list) {
|
||||
// список паттернов
|
||||
blit(pose, leftPos, topPos - 28, 176, 65, 28, 30);
|
||||
} else {
|
||||
// список задач
|
||||
blit(pose, leftPos + 28, topPos - 28, 204, 65, 28, 30);
|
||||
}
|
||||
|
||||
super.renderBg(pose, p_97788_, mouseX, mouseY);
|
||||
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.setShaderTexture(0, CONTAINER_BACKGROUND());
|
||||
|
||||
if (maxScroll() > 0) {
|
||||
if (scrolling) {
|
||||
blit(pose, leftPos + 157, topPos + 20 + (int) ((scroller_position / maxScroll()) * 145), 188, 0, 12, 15);
|
||||
} else {
|
||||
blit(pose, leftPos + 157, topPos + 20 + (int) ((scroller_position / maxScroll()) * 145), 176, 0, 12, 15);
|
||||
}
|
||||
} else {
|
||||
blit(pose, leftPos + 157, topPos + 20, 176, 0, 12, 15);
|
||||
}
|
||||
|
||||
if (open_task_list) {
|
||||
// список задач
|
||||
blit(pose, leftPos + 28, topPos - 28, 204, 33, 28, 32);
|
||||
} else {
|
||||
// список паттернов
|
||||
blit(pose, leftPos, topPos - 28, 176, 33, 28, 32);
|
||||
}
|
||||
|
||||
this.font.draw(pose, this.title, (float) (leftPos + this.titleLabelX), (float) (topPos + this.titleLabelY), 4210752);
|
||||
|
||||
hovered_pattern = null;
|
||||
hovered_task = null;
|
||||
|
||||
int cells_width = 8;
|
||||
int cells_height = 9;
|
||||
|
||||
int render_x = leftPos + 10;
|
||||
int render_y = topPos + 20;
|
||||
int cell_x = 0;
|
||||
int cell_y = 0;
|
||||
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
if (open_task_list) {
|
||||
for (int index = ((int) scroller_position) * 9; index < menu.tasks.size(); index++) {
|
||||
var state = menu.tasks.get(index);
|
||||
var itemstack = new ItemStack(state.item(), Math.max(1, state.required()));
|
||||
|
||||
// player, itemstack, x, y, ??????????
|
||||
this.itemRenderer.renderAndDecorateItem(this.minecraft.player, itemstack, render_x, render_y, -1);
|
||||
// font, itemstack, x, y, string
|
||||
this.itemRenderer.renderGuiItemDecorations(this.font, itemstack, render_x, render_y, null);
|
||||
|
||||
if (hovered_task == null && mouseX >= render_x && mouseX <= render_x + 16 && mouseY >= render_y && mouseY <= render_y + 16) {
|
||||
hovered_task = state;
|
||||
}
|
||||
|
||||
cell_x++;
|
||||
render_x += 18;
|
||||
|
||||
if (cell_x >= cells_width) {
|
||||
render_x = leftPos + 10;
|
||||
render_y += 18;
|
||||
cell_x = 0;
|
||||
cell_y++;
|
||||
|
||||
if (cell_y >= cells_height)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int index = ((int) scroller_position) * 9; index < menu.patterns.size(); index++) {
|
||||
var state = menu.patterns.get(index);
|
||||
var itemstack = new ItemStack(state.item(), 1);
|
||||
|
||||
// player, itemstack, x, y, ??????????
|
||||
this.itemRenderer.renderAndDecorateItem(this.minecraft.player, itemstack, render_x, render_y, -1);
|
||||
// font, itemstack, x, y, string
|
||||
this.itemRenderer.renderGuiItemDecorations(this.font, itemstack, render_x, render_y, null);
|
||||
|
||||
if (hovered_pattern == null && mouseX >= render_x && mouseX <= render_x + 16 && mouseY >= render_y && mouseY <= render_y + 16) {
|
||||
hovered_pattern = state;
|
||||
}
|
||||
|
||||
cell_x++;
|
||||
render_x += 18;
|
||||
|
||||
if (cell_x >= cells_width) {
|
||||
render_x = leftPos + 10;
|
||||
render_y += 18;
|
||||
cell_x = 0;
|
||||
cell_y++;
|
||||
|
||||
if (cell_y >= cells_height)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (open_pattern != null || open_task != null) {
|
||||
RenderSystem.depthFunc(GL_ALWAYS);
|
||||
|
||||
this.renderBackground(pose);
|
||||
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
RenderSystem.setShaderTexture(0, CONTAINER_BACKGROUND());
|
||||
// PoseStack, x, y, image_start_x, image_start_y, rect_size_x, rect_size_y
|
||||
|
||||
int x = (width - modal_width) / 2;
|
||||
int y = (height - modal_height) / 2;
|
||||
|
||||
// заголовок
|
||||
int dy = 0;
|
||||
this.blit(pose, x, y, 0, 188, modal_width, 4);
|
||||
dy += 4;
|
||||
|
||||
for (; dy < modal_height - 10; dy += 5)
|
||||
this.blit(pose, x, y + dy, 0, 192, modal_width, 5);
|
||||
|
||||
this.blit(pose, x, y + dy, 0, 197, modal_width, 4);
|
||||
|
||||
if (open_pattern != null) {
|
||||
// фон слота
|
||||
this.blit(pose, x + 6, input_amount.y, 176, 15, 18, 18);
|
||||
} else {
|
||||
this.blit(pose, x + 6, y + 19, 176, 15, 18, 18);
|
||||
}
|
||||
|
||||
ItemStack itemstack;
|
||||
|
||||
if (open_pattern != null) {
|
||||
itemstack = new ItemStack(open_pattern.item(), 1);
|
||||
} else {
|
||||
itemstack = new ItemStack(open_task.item(), 1);
|
||||
}
|
||||
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
if (open_pattern != null) {
|
||||
// player, itemstack, x, y, ??????????
|
||||
this.itemRenderer.renderAndDecorateItem(this.minecraft.player, itemstack, x + 7, input_amount.y + 1, 100);
|
||||
// font, itemstack, x, y, string
|
||||
this.itemRenderer.renderGuiItemDecorations(this.font, itemstack, x + 7, input_amount.y + 1, null);
|
||||
} else {
|
||||
// player, itemstack, x, y, ??????????
|
||||
this.itemRenderer.renderAndDecorateItem(this.minecraft.player, itemstack, x + 7, y + 20, 100);
|
||||
// font, itemstack, x, y, string
|
||||
// this.itemRenderer.renderGuiItemDecorations(this.font, itemstack, x + 7, input_amount.y + 1, null);
|
||||
}
|
||||
|
||||
if (open_pattern != null) {
|
||||
this.font.draw(pose, new TranslatableComponent("otm.container.matter_panel.label"), (float) (x + 6), (float) (y + 5), 4210752);
|
||||
this.font.draw(pose, new TranslatableComponent("otm.item.pattern.line", itemstack.getDisplayName(), String.format("%.2f", open_pattern.research_percent() * 100d)), (float) (x + 6), (float) (cancel_modal.y), ChatFormatting.AQUA.getColor());
|
||||
} else {
|
||||
this.font.draw(pose, new TranslatableComponent("otm.container.matter_panel.task"), (float) (x + 6), (float) (y + 5), 4210752);
|
||||
this.font.draw(pose, new TranslatableComponent("otm.container.matter_panel.task_line", itemstack.getDisplayName(), open_task.in_progress(), open_task.finished(), open_task.total()), (float) (x + 27), (float) (y + 20), 4210752);
|
||||
this.font.draw(pose, new TextComponent(open_task.id().toString().substring(0, 8) + "..."), (float) (x + 27), (float) (y + 30), 4210752);
|
||||
}
|
||||
|
||||
RenderSystem.depthFunc(GL_LESS);
|
||||
}
|
||||
addPanel(pattern_frame);
|
||||
pattern_frame.toScreenCenter();
|
||||
popup(pattern_frame);
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +105,7 @@ public abstract class MatteryScreen<T extends MatteryMenu> extends AbstractConta
|
||||
protected final ArrayList<EditablePanel> panels = new ArrayList<>();
|
||||
public FramePanel inventory_frame;
|
||||
public FramePanel main_frame;
|
||||
private boolean made_main_frame = false;
|
||||
|
||||
public MatteryScreen(T menu, Inventory inventory, Component title) {
|
||||
super(menu, inventory, title);
|
||||
@ -125,22 +126,6 @@ public abstract class MatteryScreen<T extends MatteryMenu> extends AbstractConta
|
||||
slot);
|
||||
}
|
||||
}
|
||||
|
||||
main_frame = makeMainFrame();
|
||||
|
||||
if (main_frame != null) {
|
||||
addPanel(main_frame);
|
||||
|
||||
for (var widget : menu.mattery_widgets) {
|
||||
new MatteryWidgetPanel(this, main_frame, widget);
|
||||
}
|
||||
|
||||
for (var slot : menu.main_slots) {
|
||||
new SlotPanel<>(this, main_frame, slot);
|
||||
}
|
||||
}
|
||||
|
||||
movePanels();
|
||||
}
|
||||
|
||||
public void addPanel(EditablePanel panel) {
|
||||
@ -148,6 +133,10 @@ public abstract class MatteryScreen<T extends MatteryMenu> extends AbstractConta
|
||||
panels.add(panel);
|
||||
}
|
||||
|
||||
public void removePanel(EditablePanel panel) {
|
||||
panels.remove(panel);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected FramePanel makeMainFrame() {
|
||||
return new FramePanel(this, null, 0, 0, 18 * 9 + 16, 100, getTitle());
|
||||
@ -208,16 +197,18 @@ public abstract class MatteryScreen<T extends MatteryMenu> extends AbstractConta
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double p_97748_, double p_97749_, int p_97750_) {
|
||||
var happen_to_click = false;
|
||||
|
||||
for (int i = panels.size() - 1; i >= 0; i--) {
|
||||
var panel = panels.get(i);
|
||||
|
||||
if (panel.mouseClickedChecked(p_97748_, p_97749_, p_97750_)) {
|
||||
return true;
|
||||
if (happen_to_click) {
|
||||
panel.killFocus();
|
||||
} else if (panel.mouseClickedChecked(p_97748_, p_97749_, p_97750_)) {
|
||||
happen_to_click = true;
|
||||
}
|
||||
}
|
||||
|
||||
// this.slotClicked(null, -999, p_97750_, ClickType.THROW);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -263,6 +254,32 @@ public abstract class MatteryScreen<T extends MatteryMenu> extends AbstractConta
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyReleased(int p_94715_, int p_94716_, int p_94717_) {
|
||||
for (int i = panels.size() - 1; i >= 0; i--) {
|
||||
var panel = panels.get(i);
|
||||
|
||||
if (panel.keyReleased(p_94715_, p_94716_, p_94717_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char p_94683_, int p_94684_) {
|
||||
for (int i = panels.size() - 1; i >= 0; i--) {
|
||||
var panel = panels.get(i);
|
||||
|
||||
if (panel.charTyped(p_94683_, p_94684_)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int p_97765_, int p_97766_, int p_97767_) {
|
||||
InputConstants.Key mouseKey = InputConstants.getKey(p_97765_, p_97766_);
|
||||
@ -319,6 +336,25 @@ public abstract class MatteryScreen<T extends MatteryMenu> extends AbstractConta
|
||||
|
||||
@Override
|
||||
public void render(PoseStack pose, int mouse_x, int mouse_y, float flag) {
|
||||
if (!made_main_frame) {
|
||||
made_main_frame = true;
|
||||
main_frame = makeMainFrame();
|
||||
|
||||
if (main_frame != null) {
|
||||
addPanel(main_frame);
|
||||
|
||||
for (var widget : menu.mattery_widgets) {
|
||||
new MatteryWidgetPanel(this, main_frame, widget);
|
||||
}
|
||||
|
||||
for (var slot : menu.main_slots) {
|
||||
new SlotPanel<>(this, main_frame, slot);
|
||||
}
|
||||
}
|
||||
|
||||
movePanels();
|
||||
}
|
||||
|
||||
int render_x = this.leftPos;
|
||||
int render_y = this.topPos;
|
||||
|
||||
@ -381,7 +417,8 @@ public abstract class MatteryScreen<T extends MatteryMenu> extends AbstractConta
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
|
||||
// forge's hard limit on tooltip Z position
|
||||
// forge's hard limit tooltip Z position to 500 units
|
||||
// so if we have anything drawn above 500 units, lift it up
|
||||
if (depth > 500) {
|
||||
pose.pushPose();
|
||||
pose.translate(0, 0, depth - 500);
|
||||
@ -391,8 +428,12 @@ public abstract class MatteryScreen<T extends MatteryMenu> extends AbstractConta
|
||||
if (this.hoveredSlot != null && this.hoveredSlot.hasItem()) {
|
||||
this.renderTooltip(pose, this.hoveredSlot.getItem(), mouse_x, mouse_y);
|
||||
} else {
|
||||
for (var panel : panels) {
|
||||
panel.renderTooltips(pose, mouse_x, mouse_y, flag);
|
||||
for (int i = panels.size() - 1; i >= 0; i--) {
|
||||
var panel = panels.get(i);
|
||||
|
||||
if (panel.renderTooltips(pose, mouse_x, mouse_y, flag)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
||||
/**
|
||||
* I am too lazy to learn how Mojang's API works
|
||||
* so I just recreate part of GMod's API in here
|
||||
*
|
||||
* also contains texture widgets
|
||||
*/
|
||||
public class RenderHelper {
|
||||
private static final Matrix4f identity = new Matrix4f();
|
||||
@ -182,6 +184,8 @@ public class RenderHelper {
|
||||
public record SkinElement(ResourceLocation texture, float image_x, float image_y, float rect_w, float rect_h, float defined_width, float defined_height) {
|
||||
public void render(PoseStack stack, float x, float y, float width, float height) {
|
||||
RenderSystem.setShaderTexture(0, texture);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
|
||||
drawTexturedRectUV(
|
||||
stack,
|
||||
@ -195,6 +199,57 @@ public class RenderHelper {
|
||||
(image_y + rect_h) / defined_height);
|
||||
}
|
||||
|
||||
public void render(PoseStack stack, float x, float y) {
|
||||
RenderSystem.setShaderTexture(0, texture);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
|
||||
drawTexturedRectUV(
|
||||
stack,
|
||||
x,
|
||||
y,
|
||||
rect_w,
|
||||
rect_h,
|
||||
image_x / defined_width,
|
||||
image_y / defined_height,
|
||||
(image_x + rect_w) / defined_width,
|
||||
(image_y + rect_h) / defined_height);
|
||||
}
|
||||
|
||||
public void renderW(PoseStack stack, float x, float y, float width) {
|
||||
RenderSystem.setShaderTexture(0, texture);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
|
||||
drawTexturedRectUV(
|
||||
stack,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
rect_h,
|
||||
image_x / defined_width,
|
||||
image_y / defined_height,
|
||||
(image_x + rect_w) / defined_width,
|
||||
(image_y + rect_h) / defined_height);
|
||||
}
|
||||
|
||||
public void renderH(PoseStack stack, float x, float y, float height) {
|
||||
RenderSystem.setShaderTexture(0, texture);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
|
||||
drawTexturedRectUV(
|
||||
stack,
|
||||
x,
|
||||
y,
|
||||
rect_w,
|
||||
height,
|
||||
image_x / defined_width,
|
||||
image_y / defined_height,
|
||||
(image_x + rect_w) / defined_width,
|
||||
(image_y + rect_h) / defined_height);
|
||||
}
|
||||
|
||||
public void renderRaw(PoseStack stack, float x, float y, float width, float height) {
|
||||
// RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
// RenderSystem.setShaderTexture(0, texture);
|
||||
@ -210,9 +265,25 @@ public class RenderHelper {
|
||||
(image_x + rect_w) / defined_width,
|
||||
(image_y + rect_h) / defined_height);
|
||||
}
|
||||
|
||||
public void renderRaw(PoseStack stack, float x, float y) {
|
||||
// RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
// RenderSystem.setShaderTexture(0, texture);
|
||||
|
||||
drawTexturedRectUV(
|
||||
stack,
|
||||
x,
|
||||
y,
|
||||
rect_w,
|
||||
rect_h,
|
||||
image_x / defined_width,
|
||||
image_y / defined_height,
|
||||
(image_x + rect_w) / defined_width,
|
||||
(image_y + rect_h) / defined_height);
|
||||
}
|
||||
}
|
||||
|
||||
public static final SkinElement upper_left_window_corner = new SkinElement(
|
||||
public static final SkinElement top_left_window_corner = new SkinElement(
|
||||
WIDGETS,
|
||||
18,
|
||||
0,
|
||||
@ -222,7 +293,7 @@ public class RenderHelper {
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement upper_right_window_corner = new SkinElement(
|
||||
public static final SkinElement top_right_window_corner = new SkinElement(
|
||||
WIDGETS,
|
||||
24,
|
||||
0,
|
||||
@ -294,14 +365,110 @@ public class RenderHelper {
|
||||
|
||||
public static final SkinElement window_background = new SkinElement(
|
||||
WIDGETS,
|
||||
22,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
30,
|
||||
12,
|
||||
6,
|
||||
6,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement scroll_bar_top = new SkinElement(
|
||||
WIDGETS,
|
||||
18,
|
||||
57,
|
||||
14,
|
||||
2,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement scroll_bar_bottom = new SkinElement(
|
||||
WIDGETS,
|
||||
18,
|
||||
63,
|
||||
14,
|
||||
2,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement scroll_bar_body = new SkinElement(
|
||||
WIDGETS,
|
||||
18,
|
||||
58,
|
||||
14,
|
||||
6,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement scroll_bar_button = new SkinElement(
|
||||
WIDGETS,
|
||||
18,
|
||||
12,
|
||||
12,
|
||||
15,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement scroll_bar_button_hover = new SkinElement(
|
||||
WIDGETS,
|
||||
18,
|
||||
27,
|
||||
12,
|
||||
15,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement scroll_bar_button_press = new SkinElement(
|
||||
WIDGETS,
|
||||
18,
|
||||
42,
|
||||
12,
|
||||
15,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement tab_right_connection = new SkinElement(
|
||||
WIDGETS,
|
||||
30,
|
||||
0,
|
||||
3,
|
||||
5,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement tab_left_connection = new SkinElement(
|
||||
WIDGETS,
|
||||
33,
|
||||
0,
|
||||
3,
|
||||
5,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static final SkinElement tab_background = new SkinElement(
|
||||
WIDGETS,
|
||||
30,
|
||||
6,
|
||||
6,
|
||||
6,
|
||||
256,
|
||||
256
|
||||
);
|
||||
|
||||
public static void drawScrollBarBackground(PoseStack stack, float x, float y, float height) {
|
||||
scroll_bar_body.render(stack, x, y + 2, 14, height - 4);
|
||||
scroll_bar_top.render(stack, x, y, 14, 2);
|
||||
scroll_bar_bottom.render(stack, x, y + height - 2, 14, 2);
|
||||
}
|
||||
|
||||
public static void drawRegularSlot(
|
||||
PoseStack stack,
|
||||
float x,
|
||||
@ -343,8 +510,8 @@ public class RenderHelper {
|
||||
bottom_window_border.renderRaw(stack, x + 4, y + height - 3, width - 8, 3);
|
||||
|
||||
// corners
|
||||
upper_left_window_corner.renderRaw(stack, x, y, 6, 6);
|
||||
upper_right_window_corner.renderRaw(stack, x + width - 6, y, 6, 6);
|
||||
top_left_window_corner.renderRaw(stack, x, y, 6, 6);
|
||||
top_right_window_corner.renderRaw(stack, x + width - 6, y, 6, 6);
|
||||
|
||||
bottom_left_window_corner.renderRaw(stack, x, y + height - 6, 6, 6);
|
||||
bottom_right_window_corner.renderRaw(stack, x + width - 6, y + height - 6, 6, 6);
|
||||
|
@ -0,0 +1,113 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
||||
import ru.dbotthepony.mc.otm.menu.slot.MatterySlot;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
import ru.dbotthepony.mc.otm.screen.RGBAColor;
|
||||
import ru.dbotthepony.mc.otm.screen.RenderHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractSlotPanel extends EditablePanel {
|
||||
public AbstractSlotPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height) {
|
||||
super(screen, parent, x, y, width, height);
|
||||
}
|
||||
|
||||
public AbstractSlotPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y) {
|
||||
super(screen, parent, x, y, REGULAR_DIMENSIONS, REGULAR_DIMENSIONS);
|
||||
}
|
||||
|
||||
public static final RGBAColor SLOT_HIGHLIGHT = new RGBAColor(255, 255, 255, 100);
|
||||
public static final RGBAColor SLOT_HIGHLIGHT_DRAG = new RGBAColor(200, 200, 200, 150);
|
||||
|
||||
public static final int REGULAR_DIMENSIONS = 18;
|
||||
|
||||
protected void renderSlotBackground(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
RenderHelper.drawRegularSlot(stack, 0, 0);
|
||||
}
|
||||
|
||||
protected void renderRegular(PoseStack stack, ItemStack itemstack) {
|
||||
renderRegular(stack, itemstack, null);
|
||||
}
|
||||
|
||||
protected void renderRegular(PoseStack stack, ItemStack itemstack, @Nullable String count_override) {
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
|
||||
float height = 0;
|
||||
|
||||
if (!itemstack.isEmpty()) {
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
var system_stack = RenderSystem.getModelViewStack();
|
||||
|
||||
system_stack.pushPose();
|
||||
system_stack.translate(parent_x + 1, parent_y + 1, 0);
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
|
||||
// Thanks Mojang
|
||||
// Very cool
|
||||
// (for int x, int y, which are then cast into doubles anyway)
|
||||
screen.getItemRenderer().blitOffset = accumulated_depth - 100; // force item to draw only 50 units "above" background
|
||||
screen.getItemRenderer().renderAndDecorateItem(Minecraft.getInstance().player, itemstack, 0, 0, (int) (parent_x + parent_y * 1000) /* some kind of indexing ? */);
|
||||
screen.getItemRenderer().renderGuiItemDecorations(screen.getFont(), itemstack, 0, 0, count_override);
|
||||
|
||||
// too big accumulations can lead to Z near clipping issues
|
||||
accumulate3DHeight(101);
|
||||
height = 101;
|
||||
|
||||
system_stack.popPose();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
}
|
||||
|
||||
if (is_hovered) {
|
||||
stack.pushPose();
|
||||
stack.translate(0, 0, height);
|
||||
RenderHelper.setDrawColor(SLOT_HIGHLIGHT);
|
||||
RenderHelper.drawRect(stack, 1, 1, getWidth() - 1, getHeight() - 1);
|
||||
stack.popPose();
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
abstract protected ItemStack getItemStack();
|
||||
|
||||
protected List<Component> getItemStackTooltip(ItemStack stack) {
|
||||
return screen.getTooltipFromItem(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
renderSlotBackground(stack, mouse_x, mouse_y, flag);
|
||||
|
||||
renderRegular(stack, getItemStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean innerRenderTooltips(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
if (is_hovered) {
|
||||
var itemstack = getItemStack();
|
||||
|
||||
if (!itemstack.isEmpty()) {
|
||||
Font font = net.minecraftforge.client.RenderProperties.get(itemstack).getFont(itemstack);
|
||||
net.minecraftforge.fmlclient.gui.GuiUtils.preItemToolTip(itemstack);
|
||||
screen.renderComponentToolTip(stack, getItemStackTooltip(itemstack), (int) mouse_x, (int) mouse_y, (font == null ? screen.getFont() : font));
|
||||
net.minecraftforge.fmlclient.gui.GuiUtils.postItemToolTip();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ButtonPanel extends MinecraftWidgetPanel<Button> {
|
||||
protected Runnable press_callback;
|
||||
|
||||
public ButtonPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height, Component label) {
|
||||
super(screen, parent, x, y, width, height, (panel) -> {
|
||||
return new Button(0, 0, (int) panel.getWidth(), (int) panel.getHeight(), label, (btn) -> ((ButtonPanel) panel).onPress()) {
|
||||
@Override
|
||||
public boolean isHovered() {
|
||||
return panel.is_hovered;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public void bindOnPress(Runnable runnable) {
|
||||
press_callback = runnable;
|
||||
}
|
||||
|
||||
protected void onPress() {
|
||||
if (press_callback != null) {
|
||||
press_callback.run();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ 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.OverdriveThatMatters;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -11,7 +12,12 @@ 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(), 0, 0, (int) panel.getWidth(), (int) panel.getHeight(), component);
|
||||
return new EditBox(screen.getFont(), 0, 0, (int) panel.getWidth(), (int) panel.getHeight(), component) {
|
||||
@Override
|
||||
public boolean isHovered() {
|
||||
return panel.is_hovered;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@ -20,14 +26,30 @@ public class EditBoxPanel extends MinecraftWidgetPanel<EditBox> {
|
||||
new_widget.setValue(old_widget.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (widget != null)
|
||||
widget.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void factorize(EditBox widget, boolean recreation) {
|
||||
widget.setFocus(focused);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFocusChanged(boolean new_focused, boolean old_focused) {
|
||||
widget.setFocus(new_focused);
|
||||
OverdriveThatMatters.LOGGER.info("Focus {}", new_focused);
|
||||
getOrCreateWidget().setFocus(new_focused);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
if (super.mouseClickedInner(mouse_x, mouse_y, flag)) {
|
||||
requestFocus();
|
||||
return widget.mouseClicked(mouse_x, mouse_y, flag);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,13 @@ package ru.dbotthepony.mc.otm.screen.panels;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Superclass of all panels
|
||||
@ -28,9 +30,12 @@ public class EditablePanel implements GuiEventListener {
|
||||
protected boolean focused = false;
|
||||
private boolean focused_internal = false;
|
||||
|
||||
// updated from render
|
||||
// tells whenever is mouse within this panel's boundaries
|
||||
// doesn't tell whenever it is hovered directly above and not on children
|
||||
|
||||
/**
|
||||
* updated from render;
|
||||
* tells whenever is mouse within this panel's boundaries;
|
||||
* doesn't tell whenever it is hovered directly above and not on it's children
|
||||
*/
|
||||
public boolean is_hovered = false;
|
||||
|
||||
// relative to parent
|
||||
@ -38,10 +43,18 @@ public class EditablePanel implements GuiEventListener {
|
||||
private float x;
|
||||
private float y;
|
||||
|
||||
// minimal coordinates, can be negative
|
||||
private float bound_x;
|
||||
private float bound_y;
|
||||
|
||||
// updated inside performLayout depending on dock
|
||||
private float width;
|
||||
private float height;
|
||||
|
||||
// maximal coordinates, can be negative
|
||||
private float bound_width;
|
||||
private float bound_height;
|
||||
|
||||
// updated on each rendered frame
|
||||
protected float parent_x;
|
||||
protected float parent_y;
|
||||
@ -86,6 +99,10 @@ public class EditablePanel implements GuiEventListener {
|
||||
invalidateLayout();
|
||||
}
|
||||
|
||||
public EditablePanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent) {
|
||||
this(screen, parent, 0, 0, 10, 10);
|
||||
}
|
||||
|
||||
public float getRenderX() {
|
||||
return parent_x;
|
||||
}
|
||||
@ -98,8 +115,15 @@ public class EditablePanel implements GuiEventListener {
|
||||
|
||||
}
|
||||
|
||||
protected void innerRenderTooltips(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
|
||||
/**
|
||||
* @param stack
|
||||
* @param mouse_x
|
||||
* @param mouse_y
|
||||
* @param flag
|
||||
* @return whenever have we drawn a tooltip
|
||||
*/
|
||||
protected boolean innerRenderTooltips(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,7 +150,6 @@ public class EditablePanel implements GuiEventListener {
|
||||
if (parent == null) {
|
||||
parent_x = x;
|
||||
parent_y = y;
|
||||
|
||||
} else {
|
||||
is_hovered = parent.is_hovered && mouse_x >= parent_x && mouse_x <= parent_x + width && mouse_y >= parent_y && mouse_y <= parent_y + height;
|
||||
}
|
||||
@ -169,20 +192,26 @@ public class EditablePanel implements GuiEventListener {
|
||||
* @param mouse_y
|
||||
* @param flag
|
||||
*/
|
||||
public void renderTooltips(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
public boolean renderTooltips(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
if (!getVisible()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
innerRenderTooltips(stack, mouse_x, mouse_y, flag);
|
||||
if (innerRenderTooltips(stack, mouse_x, mouse_y, flag)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (var child : children) {
|
||||
if (child.getVisible()) {
|
||||
child.innerRenderTooltips(stack, mouse_x, mouse_y, flag);
|
||||
if (child.renderTooltips(stack, mouse_x, mouse_y, flag)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setDocking(Dock docking) {
|
||||
if (docking != this.docking) {
|
||||
this.docking = docking;
|
||||
@ -202,11 +231,11 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
}
|
||||
|
||||
public DockProperty getDock_margin() {
|
||||
public DockProperty getDockMargin() {
|
||||
return dock_margin;
|
||||
}
|
||||
|
||||
public DockProperty getDock_padding() {
|
||||
public DockProperty getDockPadding() {
|
||||
return dock_padding;
|
||||
}
|
||||
|
||||
@ -331,6 +360,14 @@ public class EditablePanel implements GuiEventListener {
|
||||
|
||||
if (old_visible != new_visible) {
|
||||
visibilityChanges(new_visible, old_visible);
|
||||
|
||||
if (parent != null) {
|
||||
parent.invalidateLayout();
|
||||
}
|
||||
|
||||
if (new_visible) {
|
||||
killFocus();
|
||||
}
|
||||
}
|
||||
|
||||
updateVisible();
|
||||
@ -347,14 +384,20 @@ public class EditablePanel implements GuiEventListener {
|
||||
return this;
|
||||
|
||||
for (var child : children) {
|
||||
if (child.focused) {
|
||||
return child.getHierarchicalFocus();
|
||||
var get_focus = child.getHierarchicalFocus();
|
||||
|
||||
if (get_focus != null) {
|
||||
return get_focus;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void onHierarchicalFocusChanged(boolean new_focused, boolean old_focused) {
|
||||
|
||||
}
|
||||
|
||||
protected void onFocusChanged(boolean new_focused, boolean old_focused) {
|
||||
|
||||
}
|
||||
@ -364,7 +407,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
focused_internal = hasHierarchicalFocus();
|
||||
|
||||
if (focused_internal != old_value) {
|
||||
onFocusChanged(focused_internal, old_value);
|
||||
onHierarchicalFocusChanged(focused_internal, old_value);
|
||||
}
|
||||
|
||||
for (var child : children) {
|
||||
@ -382,7 +425,9 @@ public class EditablePanel implements GuiEventListener {
|
||||
|
||||
public void setFocused(boolean focused) {
|
||||
if (this.focused != focused) {
|
||||
var old = this.focused;
|
||||
this.focused = focused;
|
||||
onFocusChanged(focused, old);
|
||||
getRootPanel().updateFocused();
|
||||
}
|
||||
}
|
||||
@ -408,15 +453,19 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
}
|
||||
|
||||
public void killFocus() {
|
||||
if (this.focused_internal) {
|
||||
var child = getHierarchicalFocus();
|
||||
|
||||
while (child != null) {
|
||||
child.setFocused(false);
|
||||
child = getHierarchicalFocus();
|
||||
private void killFocusInernal() {
|
||||
for (var child : children) {
|
||||
child.killFocusInernal();
|
||||
}
|
||||
|
||||
if (focused) {
|
||||
setFocused(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void killFocus() {
|
||||
if (this.focused_internal) {
|
||||
killFocusInernal();
|
||||
getRootPanel().updateFocused();
|
||||
}
|
||||
}
|
||||
@ -534,6 +583,26 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
}
|
||||
|
||||
public List<EditablePanel> getChildren() {
|
||||
return List.copyOf(children);
|
||||
}
|
||||
|
||||
protected ArrayList<EditablePanel> getChildrenInternal() {
|
||||
return children;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public EditablePanel childAtIndex(int index) {
|
||||
if (index < 0 || index >= children.size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return children.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Align and rescale children here
|
||||
*/
|
||||
protected void performLayout() {
|
||||
var dock_left = dock_padding.left;
|
||||
var dock_right = dock_padding.right;
|
||||
@ -542,12 +611,20 @@ public class EditablePanel implements GuiEventListener {
|
||||
|
||||
// determine sizes
|
||||
for (var child : children) {
|
||||
if (child.getVisible()) {
|
||||
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;
|
||||
}
|
||||
|
||||
bound_x = Math.min(bound_x, child.x);
|
||||
bound_y = Math.min(bound_y, child.y);
|
||||
|
||||
bound_width = Math.max(bound_width, child.x + child.width);
|
||||
bound_height = Math.max(bound_height, child.y + child.height);
|
||||
}
|
||||
}
|
||||
|
||||
var dock_left2 = dock_padding.left;
|
||||
@ -557,6 +634,7 @@ public class EditablePanel implements GuiEventListener {
|
||||
|
||||
// apply values
|
||||
for (var child : children) {
|
||||
if (child.getVisible()) {
|
||||
switch (child.docking) {
|
||||
case TOP -> {
|
||||
child.setPos(dock_left + child.dock_margin.left, dock_top2 + child.dock_margin.top);
|
||||
@ -585,6 +663,34 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
}
|
||||
|
||||
for (var child : children) {
|
||||
if (child.getVisible()) {
|
||||
if (child.docking == Dock.FILL) {
|
||||
child.setDimensions(
|
||||
dock_left2 + child.dock_margin.left,
|
||||
dock_top2 + child.dock_margin.top,
|
||||
width - child.dock_margin.left - child.dock_margin.right - dock_right2 - dock_left2,
|
||||
height - child.dock_margin.bottom - child.dock_margin.top - dock_bottom2 - dock_top2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bound_x = 0;
|
||||
bound_y = 0;
|
||||
bound_width = 0;
|
||||
bound_height = 0;
|
||||
|
||||
for (var child : children) {
|
||||
if (child.getVisible()) {
|
||||
bound_x = Math.min(bound_x, child.x);
|
||||
bound_y = Math.min(bound_y, child.y);
|
||||
|
||||
bound_width = Math.max(bound_width, child.x + child.width);
|
||||
bound_height = Math.max(bound_height, child.y + child.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean accept_mouse_input = true;
|
||||
private boolean accept_keyboard_input = true;
|
||||
private boolean ignore_mouse_event_boundaries = false;
|
||||
@ -636,6 +742,16 @@ public class EditablePanel implements GuiEventListener {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean withinBounds(double mouse_x, double mouse_y) {
|
||||
var pos = localToScreen();
|
||||
return pos.x <= mouse_x && pos.x + width >= mouse_x && pos.y <= mouse_y && pos.y + height >= mouse_y;
|
||||
}
|
||||
|
||||
public boolean withinExtendedBounds(double mouse_x, double mouse_y) {
|
||||
var pos = localToScreen(bound_x, bound_y);
|
||||
return pos.x <= mouse_x && pos.x + bound_width >= mouse_x && pos.y <= mouse_y && pos.y + bound_height >= mouse_y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouse_x, double mouse_y, int flag) {
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
@ -645,10 +761,8 @@ public class EditablePanel implements GuiEventListener {
|
||||
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);
|
||||
if (child.mouseClickedChecked(mouse_x, mouse_y, flag)) {
|
||||
return true;
|
||||
} else if (child.auto_kill_focus) {
|
||||
child.killFocus();
|
||||
}
|
||||
@ -658,17 +772,28 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
|
||||
public boolean mouseClickedChecked(double mouse_x, double mouse_y, int flag) {
|
||||
if (!getVisible())
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
var pos = localToScreen();
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + width >= mouse_x && pos.y <= mouse_y && pos.y + height >= mouse_y) {
|
||||
if (getIgnoreMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
|
||||
if (getMouseInputEnabled() && parent == null)
|
||||
screen.popup(this);
|
||||
|
||||
mouseClicked(mouse_x, mouse_y, flag);
|
||||
return true;
|
||||
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
|
||||
for (var child : children) {
|
||||
if (child.mouseClickedChecked(mouse_x, mouse_y, flag)) {
|
||||
return true;
|
||||
} else if (child.auto_kill_focus) {
|
||||
child.killFocus();
|
||||
}
|
||||
}
|
||||
|
||||
if (auto_kill_focus)
|
||||
killFocus();
|
||||
} else if (auto_kill_focus) {
|
||||
killFocus();
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -687,10 +812,8 @@ public class EditablePanel implements GuiEventListener {
|
||||
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);
|
||||
if (child.mouseReleasedChecked(mouse_x, mouse_y, flag)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,14 +821,18 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
|
||||
public boolean mouseReleasedChecked(double mouse_x, double mouse_y, int flag) {
|
||||
if (!getVisible())
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
var pos = localToScreen();
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + width >= mouse_x && pos.y <= mouse_y && pos.y + height >= mouse_y) {
|
||||
if (getIgnoreMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
|
||||
mouseReleased(mouse_x, mouse_y, flag);
|
||||
return true;
|
||||
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
|
||||
for (var child : children) {
|
||||
if (child.mouseReleasedChecked(mouse_x, mouse_y, flag)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -724,10 +851,8 @@ public class EditablePanel implements GuiEventListener {
|
||||
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);
|
||||
if (child.mouseDraggedChecked(mouse_x, mouse_y, flag, drag_x, drag_y)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -735,44 +860,57 @@ public class EditablePanel implements GuiEventListener {
|
||||
}
|
||||
|
||||
public boolean mouseDraggedChecked(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
if (!getVisible())
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
var pos = localToScreen();
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + width >= mouse_x && pos.y <= mouse_y && pos.y + height >= mouse_y) {
|
||||
if (getIgnoreMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
|
||||
mouseDragged(mouse_x, mouse_y, flag, drag_x, drag_y);
|
||||
return true;
|
||||
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
|
||||
for (var child : children) {
|
||||
if (child.mouseDraggedChecked(mouse_x, mouse_y, flag, drag_x, drag_y)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouse_x, double mouse_y, double scroll) {
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
if (ignore_mouse_event_boundaries)
|
||||
return mouseScrolledInner(mouse_x, mouse_y, scroll);
|
||||
|
||||
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);
|
||||
if (child.mouseScrolledChecked(mouse_x, mouse_y, scroll)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return GuiEventListener.super.mouseScrolled(mouse_x, mouse_y, scroll);
|
||||
return mouseScrolledInner(mouse_x, mouse_y, scroll);
|
||||
}
|
||||
|
||||
public boolean mouseScrolledChecked(double mouse_x, double mouse_y, double scroll) {
|
||||
if (!getVisible())
|
||||
if (!getVisible() || !getMouseInputEnabled())
|
||||
return false;
|
||||
|
||||
var pos = localToScreen();
|
||||
|
||||
if (getIgnoreMouseEventBoundaries() || pos.x <= mouse_x && pos.x + width >= mouse_x && pos.y <= mouse_y && pos.y + height >= mouse_y) {
|
||||
if (getIgnoreMouseEventBoundaries() || withinBounds(mouse_x, mouse_y)) {
|
||||
mouseScrolled(mouse_x, mouse_y, scroll);
|
||||
return true;
|
||||
} else if (withinExtendedBounds(mouse_x, mouse_y)) {
|
||||
for (var child : children) {
|
||||
if (child.mouseScrolledChecked(mouse_x, mouse_y, scroll)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -826,11 +964,21 @@ public class EditablePanel implements GuiEventListener {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean charTypedInternal(char p_94732_, int p_94733_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char p_94732_, int p_94733_) {
|
||||
if (!getVisible() || !getKeyboardInputEnabled())
|
||||
return false;
|
||||
|
||||
if (!focused_internal)
|
||||
return false;
|
||||
|
||||
if (focused)
|
||||
return charTypedInternal(p_94732_, p_94733_);
|
||||
|
||||
for (var child : children) {
|
||||
if (child.charTyped(p_94732_, p_94733_)) {
|
||||
return true;
|
||||
@ -863,4 +1011,25 @@ public class EditablePanel implements GuiEventListener {
|
||||
public void tick() {
|
||||
|
||||
}
|
||||
|
||||
private boolean is_removed = false;
|
||||
|
||||
protected void onRemoved() {
|
||||
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if (is_removed) {
|
||||
return;
|
||||
}
|
||||
|
||||
killFocus();
|
||||
screen.removePanel(this);
|
||||
|
||||
for (var child : children) {
|
||||
child.remove();
|
||||
}
|
||||
|
||||
onRemoved();
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,188 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraft.client.gui.narration.NarrationElementOutput;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
import ru.dbotthepony.mc.otm.screen.RenderHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class FramePanel extends EditablePanel implements NarratableEntry {
|
||||
public enum FrameTabPosition {
|
||||
TOP(28, 28,28, 32),
|
||||
LEFT(28, 28, 32, 28),
|
||||
RIGHT(28, 28, 32, 28),
|
||||
BOTTOM(28, 28, 28, 32);
|
||||
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
public final int active_width;
|
||||
public final int active_height;
|
||||
|
||||
FrameTabPosition(int width, int height, int active_width, int active_height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.active_width = active_width;
|
||||
this.active_height = active_height;
|
||||
}
|
||||
}
|
||||
|
||||
public class FrameTabPanel extends EditablePanel {
|
||||
public final FrameTabPosition tab_position;
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
protected boolean active = false;
|
||||
protected boolean initial = false;
|
||||
|
||||
protected Runnable on_open;
|
||||
protected Runnable on_close;
|
||||
|
||||
public FrameTabPanel(FrameTabPosition position, Runnable on_open, Runnable on_close) {
|
||||
super(FramePanel.this.screen, FramePanel.this, 0, 0, position.width, position.height);
|
||||
tab_position = position;
|
||||
this.on_open = on_open;
|
||||
this.on_close = on_close;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
if (tab_position == FrameTabPosition.TOP) {
|
||||
int width;
|
||||
int height;
|
||||
|
||||
if (active) {
|
||||
width = tab_position.active_width;
|
||||
height = tab_position.active_height;
|
||||
|
||||
RenderHelper.window_background.render(stack, 2, 2, width - 4, height - 2);
|
||||
} else {
|
||||
width = tab_position.width;
|
||||
height = tab_position.height;
|
||||
|
||||
RenderHelper.tab_background.render(stack, 2, 2, width - 4, height - 2);
|
||||
}
|
||||
|
||||
RenderHelper.top_window_border.renderW(stack, 3, 0, width - 6);
|
||||
RenderHelper.left_window_border.renderH(stack, 0, 3, height - 4);
|
||||
RenderHelper.right_window_border.renderH(stack, width - RenderHelper.right_window_border.rect_w(), 3, height - 4);
|
||||
|
||||
RenderHelper.top_left_window_corner.render(stack, 0, 0);
|
||||
RenderHelper.top_right_window_corner.render(stack, width - RenderHelper.top_right_window_corner.rect_w(), 0);
|
||||
|
||||
if (active) {
|
||||
if (!initial) {
|
||||
RenderHelper.tab_left_connection.render(stack, 0, height - RenderHelper.tab_left_connection.rect_h() - 1);
|
||||
}
|
||||
|
||||
RenderHelper.tab_right_connection.render(stack, width - RenderHelper.tab_right_connection.rect_w(), height - RenderHelper.tab_left_connection.rect_h() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
if (active) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (var tab : top_tabs) {
|
||||
if (tab != this) {
|
||||
if (tab.active) {
|
||||
tab.on_close.run();
|
||||
tab.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var tab : left_tabs) {
|
||||
if (tab != this) {
|
||||
if (tab.active) {
|
||||
tab.on_close.run();
|
||||
tab.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var tab : right_tabs) {
|
||||
if (tab != this) {
|
||||
if (tab.active) {
|
||||
tab.on_close.run();
|
||||
tab.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var tab : bottom_tabs) {
|
||||
if (tab != this) {
|
||||
if (tab.active) {
|
||||
tab.on_close.run();
|
||||
tab.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
active = true;
|
||||
on_open.run();
|
||||
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected final ArrayList<FrameTabPanel> top_tabs = new ArrayList<>();
|
||||
protected final ArrayList<FrameTabPanel> left_tabs = new ArrayList<>();
|
||||
protected final ArrayList<FrameTabPanel> right_tabs = new ArrayList<>();
|
||||
protected final ArrayList<FrameTabPanel> bottom_tabs = new ArrayList<>();
|
||||
|
||||
public FrameTabPanel addTab(FrameTabPosition position, Runnable on_open, Runnable on_close) {
|
||||
var tab = new FrameTabPanel(position, on_open, on_close);
|
||||
|
||||
if (top_tabs.size() == 0 && left_tabs.size() == 0 && right_tabs.size() == 0 && bottom_tabs.size() == 0) {
|
||||
tab.active = true;
|
||||
}
|
||||
|
||||
switch (position) {
|
||||
case TOP -> top_tabs.add(tab);
|
||||
case LEFT -> left_tabs.add(tab);
|
||||
case RIGHT -> right_tabs.add(tab);
|
||||
case BOTTOM -> bottom_tabs.add(tab);
|
||||
}
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performLayout() {
|
||||
for (int i = 0; i < top_tabs.size(); i++) {
|
||||
var tab = top_tabs.get(i);
|
||||
tab.setPos(i * FrameTabPosition.TOP.width, -FrameTabPosition.TOP.height);
|
||||
|
||||
tab.initial = i == 0;
|
||||
}
|
||||
|
||||
super.performLayout();
|
||||
}
|
||||
|
||||
protected Component title;
|
||||
|
||||
public static final int PADDING = 4;
|
||||
public static final int PADDING_TOP = 14;
|
||||
|
||||
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, 14, 4, 4);
|
||||
setDockPadding(PADDING, PADDING_TOP, PADDING, PADDING);
|
||||
}
|
||||
|
||||
protected boolean dragging = false;
|
||||
@ -86,4 +251,8 @@ public class FramePanel extends EditablePanel implements NarratableEntry {
|
||||
public void updateNarration(NarrationElementOutput narrationElementOutput) {
|
||||
|
||||
}
|
||||
|
||||
public void toScreenCenter() {
|
||||
setPos(screen.width / 2 - (int) (getWidth() / 2), screen.height / 2 - (int) (getHeight() / 2));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class GridPanel extends EditablePanel {
|
||||
protected int grid_width;
|
||||
protected int grid_height;
|
||||
|
||||
public GridPanel(
|
||||
@Nonnull MatteryScreen<?> screen,
|
||||
@Nullable EditablePanel parent,
|
||||
float x,
|
||||
float y,
|
||||
float width,
|
||||
float height,
|
||||
int grid_width,
|
||||
int grid_height
|
||||
) {
|
||||
super(screen, parent, x, y, width, height);
|
||||
this.grid_width = grid_width;
|
||||
this.grid_height = grid_height;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performLayout() {
|
||||
super.performLayout();
|
||||
|
||||
float current_x = 0;
|
||||
float current_y = 0;
|
||||
float line_y = 0;
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (int row = 0; row < grid_height; row++) {
|
||||
for (int column = 0; column < grid_width; column++) {
|
||||
var child = childAtIndex(index);
|
||||
|
||||
if (child == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (child.getVisible()) {
|
||||
line_y = Math.max(line_y, child.getHeight());
|
||||
child.setPos(current_x, current_y);
|
||||
current_x += child.getWidth();
|
||||
} else {
|
||||
column--;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
current_y += line_y;
|
||||
current_x = 0;
|
||||
line_y = 0;
|
||||
|
||||
if (childAtIndex(index) == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -24,12 +24,16 @@ public class MatteryWidgetPanel extends EditablePanel {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerRenderTooltips(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
protected boolean innerRenderTooltips(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
if (is_hovered) {
|
||||
var tooltips = widget.getTooltip();
|
||||
|
||||
if (tooltips != null)
|
||||
if (tooltips != null) {
|
||||
screen.renderComponentTooltip(stack, tooltips, (int) mouse_x, (int) mouse_y);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ 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.OverdriveThatMatters;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -17,27 +18,36 @@ public class MinecraftWidgetPanel<T extends AbstractWidget> extends EditablePane
|
||||
protected T widget;
|
||||
private final WidgetFactory<T> factory;
|
||||
|
||||
@Nullable
|
||||
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) {
|
||||
protected void copyValues(@Nonnull T new_widget, @Nonnull T old_widget) {
|
||||
|
||||
}
|
||||
|
||||
private void recreate() {
|
||||
if (widget == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var new_widget = factory.create(this);
|
||||
new_widget.visible = getVisible();
|
||||
new_widget.x = (int) parent_x;
|
||||
new_widget.y = (int) parent_y;
|
||||
|
||||
if (widget != null)
|
||||
copyValues(new_widget, widget);
|
||||
|
||||
widget = new_widget;
|
||||
|
||||
factorize(widget, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -52,11 +62,60 @@ public class MinecraftWidgetPanel<T extends AbstractWidget> extends EditablePane
|
||||
|
||||
@Override
|
||||
protected void visibilityChanges(boolean new_visible, boolean old_visible) {
|
||||
if (widget != null)
|
||||
widget.visible = new_visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override in final classes to define values
|
||||
*
|
||||
* @param widget
|
||||
*/
|
||||
protected void factorize(T widget, boolean recreation) {
|
||||
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public T getOrCreateWidget() {
|
||||
if (widget != null)
|
||||
return widget;
|
||||
|
||||
widget = factory.create(this);
|
||||
widget.visible = getVisible();
|
||||
factorize(widget, false);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
widget.render(stack, (int) mouse_x, (int) mouse_y, flag);
|
||||
getOrCreateWidget().render(stack, (int) mouse_x, (int) mouse_y, flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean charTypedInternal(char p_94732_, int p_94733_) {
|
||||
return getOrCreateWidget().charTyped(p_94732_, p_94733_);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean keyPressedInternal(int p_94745_, int p_94746_, int p_94747_) {
|
||||
return getOrCreateWidget().keyPressed(p_94745_, p_94746_, p_94747_);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean keyReleasedInternal(int p_94750_, int p_94751_, int p_94752_) {
|
||||
return getOrCreateWidget().keyReleased(p_94750_, p_94751_, p_94752_);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
var pos = screenToLocal(mouse_x, mouse_y);
|
||||
return getOrCreateWidget().mouseClicked(pos.x(), pos.y(), flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
|
||||
var pos = screenToLocal(mouse_x, mouse_y);
|
||||
return getOrCreateWidget().mouseReleased(pos.x(), pos.y(), flag);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,171 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
import ru.dbotthepony.mc.otm.screen.RenderHelper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ScrollBarPanel extends EditablePanel {
|
||||
public class ScrollBarButtonPanel extends EditablePanel {
|
||||
public ScrollBarButtonPanel() {
|
||||
super(ScrollBarPanel.this.screen, ScrollBarPanel.this, 1, 1, 12, 15);
|
||||
}
|
||||
|
||||
private boolean is_scrolling;
|
||||
|
||||
public boolean isScrolling() {
|
||||
return is_scrolling;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
if (is_scrolling) {
|
||||
RenderHelper.scroll_bar_button_press.render(stack, 0, 0);
|
||||
} else if (is_hovered) {
|
||||
RenderHelper.scroll_bar_button_hover.render(stack, 0, 0);
|
||||
} else {
|
||||
RenderHelper.scroll_bar_button.render(stack, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private double last_mouse_y;
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int flag) {
|
||||
is_scrolling = true;
|
||||
setIgnoreMouseEventBoundaries(true);
|
||||
last_mouse_y = mouse_y;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseReleasedInner(double mouse_x, double mouse_y, int flag) {
|
||||
if (is_scrolling) {
|
||||
is_scrolling = false;
|
||||
setIgnoreMouseEventBoundaries(false);
|
||||
scroll = getScroll();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
|
||||
return ScrollBarPanel.this.mouseScrolledInner(mouse_x, mouse_y, scroll);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean mouseDraggedInner(double mouse_x, double mouse_y, int flag, double drag_x, double drag_y) {
|
||||
if (is_scrolling) {
|
||||
var diff = mouse_y - last_mouse_y;
|
||||
last_mouse_y = mouse_y;
|
||||
setScrollInternal((float) (scroll + diff / ScrollBarPanel.this.getHeight()));
|
||||
updateScrollBarPosition();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static final int WIDTH = 14;
|
||||
|
||||
public final ScrollBarButtonPanel scroll_button = new ScrollBarButtonPanel();
|
||||
public Consumer<Float> scroll_callback;
|
||||
|
||||
@Nonnull
|
||||
public Supplier<Float> scroll_multiplier = () -> 0.1f;
|
||||
|
||||
public ScrollBarPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float height) {
|
||||
super(screen, parent, x, y, WIDTH, height);
|
||||
}
|
||||
|
||||
public void setupRowMultiplier(Supplier<Integer> row_supplier) {
|
||||
scroll_multiplier = () -> {
|
||||
int rows = row_supplier.get();
|
||||
|
||||
if (rows < 1) {
|
||||
return 0f;
|
||||
}
|
||||
|
||||
return 1f / rows;
|
||||
};
|
||||
}
|
||||
|
||||
protected float scroll;
|
||||
|
||||
protected void onScrolled(float new_scroll, float old_scroll) {
|
||||
if (scroll_callback != null)
|
||||
scroll_callback.accept(new_scroll);
|
||||
}
|
||||
|
||||
public float getScroll() {
|
||||
return scroll < 0 ? 0 : scroll > 1 ? 1 : scroll;
|
||||
}
|
||||
|
||||
public void setScroll(float scroll) {
|
||||
var previous = this.scroll;
|
||||
|
||||
this.scroll = scroll < 0 ? 0 : scroll > 1 ? 1 : scroll;
|
||||
|
||||
if (previous != this.scroll) {
|
||||
onScrolled(this.scroll, previous);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setScrollInternal(float scroll) {
|
||||
var previous = getScroll();
|
||||
this.scroll = scroll;
|
||||
var current = getScroll();
|
||||
|
||||
if (previous != current) {
|
||||
onScrolled(current, previous);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateScrollBarPosition() {
|
||||
scroll_button.setY(1 + (getHeight() - 2 - scroll_button.getHeight()) * getScroll());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performLayout() {
|
||||
super.performLayout();
|
||||
|
||||
updateScrollBarPosition();
|
||||
}
|
||||
|
||||
public void translateScrollValue(int new_max, int old_max) {
|
||||
if (new_max < 1 || old_max < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
scroll = (scroll * old_max) / new_max;
|
||||
}
|
||||
|
||||
public int getScroll(int max_rows) {
|
||||
if (max_rows <= 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int) Math.floor(getScroll() * (max_rows - 1) + 0.5);
|
||||
}
|
||||
|
||||
// public is for emulating input from outside
|
||||
@Override
|
||||
public boolean mouseScrolledInner(double mouse_x, double mouse_y, double scroll) {
|
||||
setScrollInternal((float) (this.scroll + scroll * scroll_multiplier.get()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void innerRender(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
RenderHelper.drawScrollBarBackground(stack, 0, 0, getHeight());
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ import ru.dbotthepony.mc.otm.screen.RenderHelper;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class SlotPanel<T extends MatterySlot> extends EditablePanel {
|
||||
public class SlotPanel<T extends MatterySlot> extends AbstractSlotPanel {
|
||||
public final T slot;
|
||||
|
||||
public SlotPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height, T slot) {
|
||||
@ -31,9 +31,6 @@ public class SlotPanel<T extends MatterySlot> extends EditablePanel {
|
||||
this(screen, parent, slot.x, slot.y, 18, 18, slot);
|
||||
}
|
||||
|
||||
public final RGBAColor SLOT_HIGHLIGHT = new RGBAColor(255, 255, 255, 100);
|
||||
public final RGBAColor SLOT_HIGHLIGHT_DRAG = new RGBAColor(200, 200, 200, 150);
|
||||
|
||||
@Override
|
||||
protected boolean mouseClickedInner(double mouse_x, double mouse_y, int button) {
|
||||
screen.onSlotClicked(slot, button);
|
||||
@ -52,43 +49,10 @@ public class SlotPanel<T extends MatterySlot> extends EditablePanel {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void renderSlotBackground(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
RenderHelper.drawRegularSlot(stack, 0, 0);
|
||||
}
|
||||
|
||||
protected void renderRegular(PoseStack stack, ItemStack itemstack, String count_override) {
|
||||
if (!itemstack.isEmpty()) {
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
var system_stack = RenderSystem.getModelViewStack();
|
||||
|
||||
system_stack.pushPose();
|
||||
system_stack.translate(parent_x + 1, parent_y + 1, 0);
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
|
||||
// Thanks Mojang
|
||||
// Very cool
|
||||
// (for int x, int y, which are then cast into doubles anyway)
|
||||
screen.getItemRenderer().blitOffset = accumulated_depth - 100; // force item to draw only 50 units "above" background
|
||||
screen.getItemRenderer().renderAndDecorateItem(Minecraft.getInstance().player, itemstack, 0, 0, (int) (parent_x + parent_y * 1000) /* some kind of indexing ? */);
|
||||
screen.getItemRenderer().renderGuiItemDecorations(screen.getFont(), itemstack, 0, 0, count_override);
|
||||
|
||||
// too big accumulations can lead to Z near clipping issues
|
||||
accumulate3DHeight(100);
|
||||
|
||||
system_stack.popPose();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
}
|
||||
|
||||
if (is_hovered) {
|
||||
screen.hoveredSlot = slot;
|
||||
|
||||
stack.pushPose();
|
||||
stack.translate(0, 0, 101);
|
||||
RenderHelper.setDrawColor(SLOT_HIGHLIGHT);
|
||||
RenderHelper.drawRect(stack, 1, 1, getWidth() - 1, getHeight() - 1);
|
||||
stack.popPose();
|
||||
}
|
||||
@Nonnull
|
||||
@Override
|
||||
protected ItemStack getItemStack() {
|
||||
return slot.getItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -130,5 +94,15 @@ public class SlotPanel<T extends MatterySlot> extends EditablePanel {
|
||||
}
|
||||
|
||||
renderRegular(stack, itemstack, count_override);
|
||||
|
||||
if (is_hovered) {
|
||||
screen.hoveredSlot = slot;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean innerRenderTooltips(PoseStack stack, float mouse_x, float mouse_y, float flag) {
|
||||
// no op, screen does it for us (completely)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
package ru.dbotthepony.mc.otm.screen.panels;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import ru.dbotthepony.mc.otm.screen.MatteryScreen;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SupplierSlotPanel extends AbstractSlotPanel {
|
||||
protected Supplier<ItemStack> stack_getter;
|
||||
|
||||
public SupplierSlotPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, float width, float height, Supplier<ItemStack> supplier) {
|
||||
super(screen, parent, x, y, width, height);
|
||||
stack_getter = supplier;
|
||||
}
|
||||
|
||||
public SupplierSlotPanel(@Nonnull MatteryScreen<?> screen, @Nullable EditablePanel parent, float x, float y, Supplier<ItemStack> supplier) {
|
||||
this(screen, parent, x, y, REGULAR_DIMENSIONS, REGULAR_DIMENSIONS, supplier);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected ItemStack getItemStack() {
|
||||
return stack_getter.get();
|
||||
}
|
||||
}
|
Binary file not shown.
Before ![]() (image error) Size: 1.9 KiB After ![]() (image error) Size: 2.1 KiB ![]() ![]() |
BIN
src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf
(Stored with Git LFS)
BIN
src/main/resources/assets/overdrive_that_matters/textures/gui/widgets.xcf
(Stored with Git LFS)
Binary file not shown.
Loading…
Reference in New Issue
Block a user