mirror of
https://github.com/Shiewk/Widgets.git
synced 2026-04-28 11:34:17 +02:00
Add helpful context menus (right click) to the position editing screen
- Right click on widget: Opening widget settings, setting anchor or deactivating the widget - Right click on empty space: Enabling widgets
This commit is contained in:
@@ -56,6 +56,6 @@ public enum Anchor {
|
||||
return anchor;
|
||||
}
|
||||
}
|
||||
return Anchor.TOP_LEFT;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +59,20 @@ public abstract class ModWidget {
|
||||
settings.offsetX += dx;
|
||||
settings.offsetY += dy;
|
||||
}
|
||||
|
||||
public void setPos(Anchor anchor, int offsetX, int offsetY){
|
||||
getSettings().setPos(anchor, offsetX, offsetY);
|
||||
}
|
||||
|
||||
public void setAbsolutePos(int x, int y, int scaledWindowWidth, int scaledWindowHeight) {
|
||||
Anchor anchor = Anchor.getAnchor(scaledWindowWidth, scaledWindowHeight, x, y);
|
||||
if (anchor == null) {
|
||||
throw new IllegalArgumentException("Provided coordinates have no corresponding anchor");
|
||||
}
|
||||
settings.setPos(
|
||||
anchor,
|
||||
x - anchor.getAlignStartPosX(scaledWindowWidth),
|
||||
y - anchor.getAlignStartPosY(scaledWindowHeight)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package de.shiewk.widgets.client.screen;
|
||||
|
||||
import de.shiewk.widgets.utils.WidgetUtils;
|
||||
import net.minecraft.client.gui.Click;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.cursor.StandardCursors;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ContextMenuScreen extends Screen {
|
||||
|
||||
public record Option(Text title, boolean highlighted, Runnable action){
|
||||
|
||||
public Option(Text title, Runnable action){
|
||||
this(title, false, action);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final Screen parent;
|
||||
private int menuX;
|
||||
private int menuY;
|
||||
private final List<Option> options;
|
||||
|
||||
private int menuWidth;
|
||||
private int menuHeight;
|
||||
|
||||
public ContextMenuScreen(Text title, Screen parent, int menuX, int menuY, List<Option> options) {
|
||||
super(title);
|
||||
this.parent = parent;
|
||||
this.menuX = menuX;
|
||||
this.menuY = menuY;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
menuWidth = computeMenuWidth();
|
||||
menuHeight = computeMenuHeight();
|
||||
|
||||
if (menuX + menuWidth > width){
|
||||
menuX = width - menuWidth;
|
||||
}
|
||||
if (menuY + menuHeight > height){
|
||||
menuY = height - menuHeight;
|
||||
}
|
||||
}
|
||||
|
||||
private int computeMenuHeight() {
|
||||
return options.size() * (9 + 6) + 1;
|
||||
}
|
||||
|
||||
private int computeMenuWidth() {
|
||||
int max = 0;
|
||||
for (Option option : options) {
|
||||
int width = textRenderer.getWidth(option.title);
|
||||
if (width > max){
|
||||
max = width;
|
||||
}
|
||||
}
|
||||
return max + 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
client.setScreen(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(Click click, boolean doubled) {
|
||||
if (!isInBounds(click.x(), click.y())){
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
int opt = (int) (click.y() - menuY - 1) / 15;
|
||||
if (opt < options.size()){
|
||||
Option option = options.get(opt);
|
||||
close();
|
||||
WidgetUtils.playSound(SoundEvents.BLOCK_COPPER_BULB_TURN_OFF);
|
||||
option.action.run();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isInBounds(double x, double y) {
|
||||
return x > menuX && y > menuY && x < menuX + menuWidth && y < menuY + menuHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float deltaTicks) {
|
||||
super.render(context, mouseX, mouseY, deltaTicks);
|
||||
parent.render(context, -67, -67, deltaTicks);
|
||||
context.drawStrokedRectangle(
|
||||
menuX,
|
||||
menuY,
|
||||
menuWidth,
|
||||
menuHeight,
|
||||
0x67ffffff
|
||||
);
|
||||
context.fill(
|
||||
menuX,
|
||||
menuY,
|
||||
menuX + menuWidth,
|
||||
menuY + menuHeight,
|
||||
0xff000000
|
||||
);
|
||||
renderMenu(context, mouseX, mouseY);
|
||||
}
|
||||
|
||||
public void renderMenu(DrawContext context, int mouseX, int mouseY){
|
||||
int y = menuY + 1;
|
||||
for (Option option : options) {
|
||||
boolean hover = isInBounds(mouseX, mouseY) && mouseY >= y && mouseY < y + 15;
|
||||
if (hover){
|
||||
context.fill(
|
||||
menuX,
|
||||
y,
|
||||
menuX + menuWidth,
|
||||
y + 15,
|
||||
0x30_ff_ff_ff
|
||||
);
|
||||
context.setCursor(StandardCursors.POINTING_HAND);
|
||||
}
|
||||
context.drawText(textRenderer, option.title, menuX + 5, y + 3, option.highlighted ? 0xff_00_ff_ff : 0xff_ff_ff_ff, false);
|
||||
y += 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,17 +4,21 @@ import de.shiewk.widgets.Anchor;
|
||||
import de.shiewk.widgets.ModWidget;
|
||||
import de.shiewk.widgets.WidgetSettings;
|
||||
import de.shiewk.widgets.client.WidgetManager;
|
||||
import de.shiewk.widgets.utils.WidgetUtils;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.client.gui.Click;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.cursor.StandardCursors;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.tooltip.Tooltip;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Util;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class EditWidgetPositionsScreen extends AnimatedScreen {
|
||||
@@ -202,14 +206,16 @@ public class EditWidgetPositionsScreen extends AnimatedScreen {
|
||||
mouseX,
|
||||
mouseY
|
||||
);
|
||||
Vector2i topLeft = anchor.getTopLeft(scaledWindowWidth, scaledWindowHeight);
|
||||
context.fill(
|
||||
topLeft.x,
|
||||
topLeft.y,
|
||||
topLeft.x + scaledWindowWidth / 3,
|
||||
topLeft.y + scaledWindowHeight / 3,
|
||||
0x08ffffff
|
||||
);
|
||||
if (anchor != null) {
|
||||
Vector2i topLeft = anchor.getTopLeft(scaledWindowWidth, scaledWindowHeight);
|
||||
context.fill(
|
||||
topLeft.x,
|
||||
topLeft.y,
|
||||
topLeft.x + scaledWindowWidth / 3,
|
||||
topLeft.y + scaledWindowHeight / 3,
|
||||
0x08ffffff
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -245,6 +251,99 @@ public class EditWidgetPositionsScreen extends AnimatedScreen {
|
||||
selectedWidget = hoveredWidget;
|
||||
focusedExtraX = (int) (click.x() - hoveredWidget.getX(scaledWindowWidth));
|
||||
focusedExtraY = (int) (click.y() - hoveredWidget.getY(scaledWindowHeight));
|
||||
} else if (click.button() == 1){
|
||||
int x = (int) click.x();
|
||||
int y = (int) click.y();
|
||||
ModWidget hovered = hoveredWidget;
|
||||
WidgetUtils.playSound(SoundEvents.BLOCK_COPPER_BULB_TURN_ON);
|
||||
if (hovered != null){
|
||||
client.setScreen(new ContextMenuScreen(
|
||||
Text.empty(),
|
||||
this,
|
||||
x,
|
||||
y,
|
||||
List.of(
|
||||
new ContextMenuScreen.Option(
|
||||
Text.translatable("widgets.ui.editPositions.menu.widgetSettings"),
|
||||
() -> client.setScreen(new WidgetSettingsScreen(
|
||||
this,
|
||||
hovered,
|
||||
this.onEdit
|
||||
))
|
||||
),
|
||||
new ContextMenuScreen.Option(
|
||||
Text.translatable("widgets.ui.editPositions.menu.setAnchor"),
|
||||
() -> {
|
||||
List<ContextMenuScreen.Option> options = new ObjectArrayList<>(Anchor.values().length);
|
||||
for (Anchor anchor : Anchor.values()) {
|
||||
options.add(new ContextMenuScreen.Option(
|
||||
Text.translatable("widgets.ui.anchor." + anchor.name().toLowerCase()),
|
||||
hovered.getSettings().anchor == anchor,
|
||||
() -> {
|
||||
hovered.setPos(
|
||||
anchor,
|
||||
hovered.getX(scaledWindowWidth) - anchor.getAlignStartPosX(scaledWindowWidth),
|
||||
hovered.getY(scaledWindowHeight) - anchor.getAlignStartPosY(scaledWindowHeight)
|
||||
);
|
||||
onEdit.accept(hovered);
|
||||
}
|
||||
));
|
||||
}
|
||||
// Add widget context menu
|
||||
client.setScreen(new ContextMenuScreen(
|
||||
Text.empty(),
|
||||
this,
|
||||
x,
|
||||
y,
|
||||
options
|
||||
));
|
||||
}
|
||||
),
|
||||
new ContextMenuScreen.Option(
|
||||
Text.translatable("widgets.ui.editPositions.menu.removeWidget"),
|
||||
() -> {
|
||||
hovered.getSettings().toggleEnabled(hovered);
|
||||
onEdit.accept(hovered);
|
||||
}
|
||||
)
|
||||
)
|
||||
));
|
||||
} else {
|
||||
client.setScreen(new ContextMenuScreen(
|
||||
Text.empty(),
|
||||
this,
|
||||
x,
|
||||
y,
|
||||
List.of(
|
||||
new ContextMenuScreen.Option(
|
||||
Text.translatable("widgets.ui.editPositions.menu.addWidget"),
|
||||
() -> {
|
||||
List<ContextMenuScreen.Option> options = new ObjectArrayList<>();
|
||||
for (ModWidget widget : WidgetManager.getAllWidgets()) {
|
||||
if (!widget.getSettings().isEnabled()){
|
||||
options.add(new ContextMenuScreen.Option(
|
||||
widget.getName(),
|
||||
() -> {
|
||||
widget.getSettings().setEnabled(widget, true);
|
||||
widget.setAbsolutePos(x, y, scaledWindowWidth, scaledWindowHeight);
|
||||
onEdit.accept(widget);
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
// Add widget context menu
|
||||
client.setScreen(new ContextMenuScreen(
|
||||
Text.empty(),
|
||||
this,
|
||||
x,
|
||||
y,
|
||||
options
|
||||
));
|
||||
}
|
||||
)
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
||||
return super.mouseClicked(click, doubled);
|
||||
}
|
||||
@@ -263,6 +362,9 @@ public class EditWidgetPositionsScreen extends AnimatedScreen {
|
||||
if (click.x() <= wx + ww + deltaX && click.x() >= wx + deltaX){
|
||||
if (click.y() <= wy + wh + deltaY && click.y() >= wy + deltaY){
|
||||
Anchor anchor = Anchor.getAnchor(scaledWindowWidth, scaledWindowHeight, (int) click.x(), (int) click.y());
|
||||
if (anchor == null) {
|
||||
return false;
|
||||
}
|
||||
int newOffX = (int) (click.x() - anchor.getAlignStartPosX(scaledWindowWidth)) - focusedExtraX;
|
||||
int newOffY = (int) (click.y() - anchor.getAlignStartPosY(scaledWindowHeight)) - focusedExtraY;
|
||||
|
||||
|
||||
@@ -2,24 +2,26 @@ package de.shiewk.widgets.client.screen;
|
||||
|
||||
import de.shiewk.widgets.ModWidget;
|
||||
import de.shiewk.widgets.client.screen.components.WidgetSettingsEditWidget;
|
||||
import net.minecraft.client.gui.*;
|
||||
import net.minecraft.client.gui.Click;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.ClickableWidget;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class WidgetSettingsScreen extends AnimatedScreen {
|
||||
private static final Text previewText = Text.translatable("widgets.ui.preview");
|
||||
private final ModWidget widget;
|
||||
private final Runnable onChange;
|
||||
public WidgetSettingsScreen(Screen parent, ModWidget widget) {
|
||||
public WidgetSettingsScreen(Screen parent, ModWidget widget, Consumer<ModWidget> changedWidgetConsumer) {
|
||||
super(Text.translatable("widgets.ui.widgetSettings", widget.getName()), parent, 500);
|
||||
this.widget = widget;
|
||||
onChange = () -> {
|
||||
widget.onSettingsChanged(widget.getSettings());
|
||||
if (parent instanceof WidgetConfigScreen widgetConfigScreen){
|
||||
widgetConfigScreen.changedSettings(widget);
|
||||
}
|
||||
changedWidgetConsumer.accept(widget);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public class WidgetWidget extends ClickableWidget {
|
||||
@Override
|
||||
public boolean mouseClicked(Click click, boolean doubled) {
|
||||
if (isMouseOver(click.x(), click.y())){
|
||||
client.setScreen(new WidgetSettingsScreen(client.currentScreen, widget));
|
||||
client.setScreen(new WidgetSettingsScreen(client.currentScreen, widget, onEdit));
|
||||
return true;
|
||||
} else if (isMouseOverToggle(click.x(), click.y())){
|
||||
this.toggleWidget();
|
||||
|
||||
Reference in New Issue
Block a user