1
mirror of https://github.com/Shiewk/Widgets.git synced 2026-04-28 11:34:17 +02:00

Initial Commit (1.0)

This commit is contained in:
Shy
2024-09-07 18:54:20 +02:00
commit 6ef0f3758d
42 changed files with 2893 additions and 0 deletions
@@ -0,0 +1,39 @@
package de.shiewk.widgets.client.screen;
import de.shiewk.widgets.WidgetUtils;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import net.minecraft.util.Util;
public abstract class AnimatedScreen extends Screen {
protected final Screen parent;
private final int animationDurationMs;
private final long creationTime = Util.getMeasuringTimeNano();
protected AnimatedScreen(Text title, Screen parent, int animationDurationMs) {
super(title);
this.parent = parent;
this.animationDurationMs = animationDurationMs;
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
double timeMs = (Util.getMeasuringTimeNano() - creationTime) / 1000000d;
final boolean shouldAnimate = timeMs < animationDurationMs;
if (shouldAnimate){
double translation = WidgetUtils.computeEasing(timeMs / animationDurationMs) * this.width;
context.getMatrices().push();
context.getMatrices().translate(-translation, 0, 0);
parent.render(context, (int) (mouseX + translation), mouseY, delta);
context.getMatrices().translate(this.width, 0, 0);
mouseX -= (int) translation;
}
super.render(context, mouseX, mouseY, delta);
this.renderScreenContents(context, mouseX, mouseY, delta);
if (shouldAnimate){
context.getMatrices().pop();
}
}
public abstract void renderScreenContents(DrawContext context, int mouseX, int mouseY, float delta);
}
@@ -0,0 +1,198 @@
package de.shiewk.widgets.client.screen;
import de.shiewk.widgets.Dimensionable;
import de.shiewk.widgets.ModWidget;
import de.shiewk.widgets.WidgetSettings;
import de.shiewk.widgets.client.WidgetManager;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import net.minecraft.util.Util;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.util.function.Consumer;
import static de.shiewk.widgets.WidgetUtils.translateToScreen;
import static de.shiewk.widgets.WidgetUtils.translateToWidgetSettingsValue;
public class EditWidgetPositionsScreen extends AnimatedScreen {
private record Alignment(int x, int y, int width, int height) implements Dimensionable {
@Override
public double getX(int mx) {
return x;
}
@Override
public double getY(int my) {
return y;
}
}
private final Screen parent;
private final Consumer<ModWidget> onEdit;
private boolean alignX = true;
private boolean alignY = true;
public EditWidgetPositionsScreen(Screen parent, Consumer<ModWidget> onEdit) {
super(Text.translatable("widgets.ui.editPositions"), parent, 500);
this.parent = parent;
this.onEdit = onEdit;
}
@Override
public void close() {
assert client != null;
client.setScreen(parent);
}
private record AlignResult(double result, boolean isEnd){}
private @Nullable AlignResult alignX(double x, int width, ModWidget widget){
double endX = x + width;
int factor = alignX ? 2 : 0;
for (Dimensionable rect : this.getAlignments(widget)) {
if (rect == widget) continue;
final double nwx = rect.getX(this.width);
final double nww = rect.width();
if (endX < nwx + factor && endX > nwx - factor){
return new AlignResult(nwx - width, true);
} else if (x < nwx + factor && x > nwx - factor){
return new AlignResult(nwx, false);
} else if (endX < nwx+nww + factor && endX > nwx + nww - factor){
return new AlignResult(nwx + nww - width, true);
} else if (x < nwx+nww + factor && x > nwx + nww - factor){
return new AlignResult(nwx + nww, false);
}
}
return null;
}
private Iterable<? extends Dimensionable> getAlignments(Dimensionable rel) {
ObjectArrayList<Dimensionable> alignments = new ObjectArrayList<>();
for (ModWidget widget : WidgetManager.getEnabledWidgets()) {
alignments.add(widget);
}
alignments.add(new Alignment(2, 2, this.width / 2 - 2, this.height / 2 - 2));
alignments.add(new Alignment(this.width / 2, this.height / 2, this.width / 2 - 2, this.height / 2 - 2));
alignments.add(new Alignment(2, this.height / 2, this.width / 2 - 2, this.height / 2 - 2));
alignments.add(new Alignment(this.width / 2, 2, this.width / 2 - 2, this.height / 2 - 2));
alignments.add(new Alignment(this.width / 2 - rel.width() / 2, this.height / 2 - rel.height() / 2, rel.width(), rel.height()));
return alignments;
}
private @Nullable AlignResult alignY(double y, int height, ModWidget widget){
double endY = y + height;
int factor = alignY ? 2 : 0;
for (Dimensionable rect : this.getAlignments(widget)) {
if (rect == widget) continue;
final double nwy = rect.getY(this.height);
final double nwh = rect.height();
if (endY < nwy + factor && endY > nwy - factor){
return new AlignResult(nwy - height, true);
} else if (y < nwy + factor && y > nwy - factor){
return new AlignResult(nwy, false);
} else if (endY < nwy+nwh + factor && endY > nwy + nwh - factor){
return new AlignResult(nwy + nwh - height, true);
} else if (y < nwy+nwh + factor && y > nwy + nwh - factor){
return new AlignResult(nwy + nwh, false);
}
}
return null;
}
private static final int SELECT_COLOR = Color.GREEN.getRGB(), ALIGN_COLOR = Color.ORANGE.getRGB(), ALIGN_DISABLED_COLOR = Color.GRAY.getRGB();
private ModWidget selectedWidget = null;
private ModWidget hoveredWidget = null;
@Override
public void renderScreenContents(DrawContext context, int mouseX, int mouseY, float delta) {
assert client != null;
for (ModWidget widget : WidgetManager.getEnabledWidgets()) {
final WidgetSettings settings = widget.getSettings();
final int ww = widget.width();
double wx = Math.min(translateToScreen(settings.posX, this.width), this.width - ww);
final int wh = widget.height();
double wy = Math.min(translateToScreen(settings.posY, this.height), this.height - wh);
if (selectedWidget == widget){
final AlignResult alignedX = alignX(wx, ww, widget);
if (alignedX != null){
context.drawVerticalLine((int) (!alignedX.isEnd() ? alignedX.result() : alignedX.result() + ww), 0, this.height, alignX ? ALIGN_COLOR : ALIGN_DISABLED_COLOR);
wx = alignedX.result();
}
final AlignResult alignedY = alignY(wy, wh, widget);
if (alignedY != null){
context.drawHorizontalLine(0, this.width, (int) (!alignedY.isEnd() ? alignedY.result() : alignedY.result() + wh), alignY ? ALIGN_COLOR : ALIGN_DISABLED_COLOR);
wy = alignedY.result();
}
}
if (hoveredWidget == null || hoveredWidget == widget){
if (mouseX <= wx + ww && mouseX >= wx && mouseY <= wy + wh && mouseY >= wy){
if (hoveredWidget == null){
hoveredWidget = widget;
}
} else {
hoveredWidget = null;
}
}
if (selectedWidget == null ? hoveredWidget == widget : selectedWidget == widget){
context.drawBorder((int) Math.round(wx-1), (int) Math.round(wy-1), ww+2, wh+2, SELECT_COLOR);
context.drawBorder((int) Math.round(wx), (int) Math.round(wy), ww, wh, SELECT_COLOR);
}
widget.render(context, Util.getMeasuringTimeNano(), textRenderer, (int) Math.round(wx), (int) Math.round(wy));
}
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
if (button == 0 && selectedWidget != null){
final AlignResult alignedX = alignX(translateToScreen(selectedWidget.getSettings().posX, this.width), selectedWidget.width(), selectedWidget);
if (alignedX != null){
selectedWidget.getSettings().setPosX(translateToWidgetSettingsValue(alignedX.result(), this.width), selectedWidget.width(), this.width);
}
final AlignResult alignedY = alignY(translateToScreen(selectedWidget.getSettings().posY, this.height), selectedWidget.height(), selectedWidget);
if (alignedY != null){
selectedWidget.getSettings().setPosY(translateToWidgetSettingsValue(alignedY.result(), this.height), selectedWidget.height(), this.height);
}
onEdit.accept(selectedWidget);
selectedWidget = null;
}
return super.mouseReleased(mouseX, mouseY, button);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (button == 0 && hoveredWidget != null){
selectedWidget = hoveredWidget;
}
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
if (button == 0){
assert client != null;
final ModWidget widget = selectedWidget;
if (widget != null){
final WidgetSettings settings = widget.getSettings();
final int ww = widget.width();
final int wx = (int) Math.min(translateToScreen(settings.posX, this.width), this.width - ww);
final int wh = widget.height();
final int wy = (int) Math.min(translateToScreen(settings.posY, this.height), this.height - wh);
if (mouseX <= wx + ww + deltaX && mouseX >= wx + deltaX){
if (mouseY <= wy + wh + deltaY && mouseY >= wy + deltaY){
double newPosX = settings.posX + translateToWidgetSettingsValue(deltaX, this.width);
double newPosY = settings.posY + translateToWidgetSettingsValue(deltaY, this.height);
settings.setPosX(newPosX, ww, this.width);
settings.setPosY(newPosY, wh, this.height);
return true;
}
}
}
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
}
@@ -0,0 +1,129 @@
package de.shiewk.widgets.client.screen;
import de.shiewk.widgets.ModWidget;
import de.shiewk.widgets.WidgetUtils;
import de.shiewk.widgets.client.WidgetManager;
import de.shiewk.widgets.client.screen.components.WidgetListWidget;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AxisGridWidget;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text;
import net.minecraft.util.Util;
import java.util.ArrayList;
import java.util.Objects;
import java.util.function.Consumer;
public class WidgetConfigScreen extends Screen {
private final Screen parent;
private final long creationTime = Util.getMeasuringTimeNano();
private String search = "";
private WidgetListWidget widgetList = null;
private final ArrayList<ModWidget> widgetsEdited = new ArrayList<>();
private final Consumer<ModWidget> onWidgetEdit = this::changedSettings;
private double getScreenTimeMs(){
return (Util.getMeasuringTimeNano() - creationTime) / 1000000d;
}
public WidgetConfigScreen(Screen parent) {
super(Text.translatable("widgets.ui.config"));
this.parent = parent;
}
@Override
public void close() {
WidgetManager.saveWidgets(widgetsEdited);
for (ModWidget widget : widgetsEdited) {
widget.onSettingsChanged(widget.getSettings());
}
assert client != null;
client.setScreen(parent);
}
@Override
protected void init() {
super.init();
AxisGridWidget agw = new AxisGridWidget(3, height - 22, width - 6, 20, AxisGridWidget.DisplayAxis.HORIZONTAL);
final TextFieldWidget searchField = new TextFieldWidget(textRenderer, this.width - 160, 20, Text.empty());
searchField.setPlaceholder(Text.translatable("widgets.ui.search"));
searchField.setChangedListener(this::search);
if (this.widgetList != null){
searchField.setText(this.getSearchQuery());
}
agw.add(searchField);
agw.add(new ButtonWidget.Builder(Text.translatable("widgets.ui.editPositions"), this::switchToEditPositions).build());
agw.refreshPositions();
agw.forEachChild(this::addDrawableChild);
if (Objects.equals(search, "")){
search("");
}
}
private String getSearchQuery() {
return search;
}
public void setSearchQuery(String search) {
this.search = search;
}
private void search(String query) {
this.setSearchQuery(query);
widgetList = new WidgetListWidget(0, 0, width-4, height-24, Text.translatable("widgets.ui.config"), client, WidgetManager.getAllWidgets().stream().filter(this::searchQueryMatches).toList(), textRenderer, this.onWidgetEdit);
}
private void switchToEditPositions(ButtonWidget widget) {
widget.active = false;
assert client != null;
client.setScreen(new EditWidgetPositionsScreen(this, this.onWidgetEdit));
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (super.mouseClicked(mouseX, mouseY, button)){
return true;
} else return widgetList.mouseClicked(mouseX, mouseY, button);
}
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
if (super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)){
return true;
} else return widgetList.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
assert client != null;
final double time = getScreenTimeMs();
if (time < 400){
context.getMatrices().push();
final float v = (float) WidgetUtils.computeEasing(time / 400d);
context.getMatrices().translate(width / 2d - (width * v / 2d), height / 2d - (height * v / 2d), 0);
context.getMatrices().scale(v, v, 1);
}
super.render(context, mouseX, mouseY, delta);
if (widgetList != null){
widgetList.render(context, mouseX, mouseY, delta);
}
if (time < 400){
context.getMatrices().pop();
}
}
private boolean searchQueryMatches(ModWidget widget) {
return widget.getName().getString().contains(search) || widget.getDescription().getString().contains(search) || widget.getId().toString().contains(search);
}
public void changedSettings(ModWidget widget) {
if (!widgetsEdited.contains(widget)){
widgetsEdited.add(widget);
}
}
}
@@ -0,0 +1,50 @@
package de.shiewk.widgets.client.screen;
import de.shiewk.widgets.ModWidget;
import de.shiewk.widgets.client.screen.components.WidgetSettingsEditWidget;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import net.minecraft.util.Util;
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) {
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);
}
};
}
@Override
protected void init() {
super.init();
addDrawableChild(new WidgetSettingsEditWidget(0, 0, this.width / 2 - 8, this.height, textRenderer, widget, this.onChange));
}
@Override
public void renderScreenContents(DrawContext context, int mouseX, int mouseY, float delta) {
context.drawText(textRenderer, previewText, this.width * 3 / 4 - textRenderer.getWidth(previewText) / 2, this.height / 50, 0xffffffff, false);
widget.render(context, Util.getMeasuringTimeNano(), textRenderer, this.width * 3 / 4 - widget.width() / 2, this.height / 2 - widget.height() / 2);
}
@Override
public void close() {
assert client != null;
client.setScreen(parent);
}
@Override
public void tick() {
super.tick();
if (!widget.getSettings().isEnabled()){
widget.tick();
}
}
}
@@ -0,0 +1,92 @@
package de.shiewk.widgets.client.screen.components;
import de.shiewk.widgets.ModWidget;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.gui.screen.narration.NarrationPart;
import net.minecraft.client.gui.widget.GridWidget;
import net.minecraft.client.gui.widget.ScrollableWidget;
import net.minecraft.client.gui.widget.SimplePositioningWidget;
import net.minecraft.text.Text;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class WidgetListWidget extends ScrollableWidget {
private final MinecraftClient client;
private final List<ModWidget> widgets;
private final List<WidgetWidget> elements = new ArrayList<>();
private final TextRenderer textRenderer;
private final Consumer<ModWidget> onEdit;
public WidgetListWidget(int x, int y, int width, int height, Text message, MinecraftClient client, List<ModWidget> widgets, TextRenderer textRenderer, Consumer<ModWidget> onEdit) {
super(x, y, width, height, message);
this.client = client;
this.widgets = widgets;
this.textRenderer = textRenderer;
this.onEdit = onEdit;
init();
}
private void init(){
GridWidget gw = new GridWidget();
gw.getMainPositioner().margin(4, 4, 4, 4);
final GridWidget.Adder adder = gw.createAdder(this.width / 208);
for (ModWidget widget : widgets) {
adder.add(new WidgetWidget(0, 0, 200, 100, client, widget, textRenderer, onEdit));
}
gw.refreshPositions();
SimplePositioningWidget.setPos(gw, 0, 0, this.width, this.getContentsHeight(), 0.5F, 0.5F);
gw.forEachChild(w -> this.addWidget((WidgetWidget) w));
}
protected void addWidget(WidgetWidget drawableElement) {
this.elements.add(drawableElement);
}
@Override
protected int getContentsHeight() {
final int rowSize = this.width / 208;
final int rows = widgets.size() % rowSize == 0 ? widgets.size() / rowSize : widgets.size() / rowSize + 1;
return 10 + (rows * 108);
}
@Override
protected double getDeltaYPerScroll() {
return 35;
}
@Override
protected void renderContents(DrawContext context, int mouseX, int mouseY, float delta) {
for (WidgetWidget element : elements) {
element.render(context, mouseX, (int) (mouseY + getScrollY()), delta);
}
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
mouseY += getScrollY();
for (Element element : elements) {
if (element.mouseClicked(mouseX, mouseY, 0)){
return true;
}
}
return false;
}
@Override
protected void appendClickableNarrations(NarrationMessageBuilder builder) {
for (ModWidget widget : widgets) {
builder.put(NarrationPart.HINT, widget.getName());
}
}
@Override
protected void drawBox(DrawContext context, int x, int y, int width, int height) {}
}
@@ -0,0 +1,135 @@
package de.shiewk.widgets.client.screen.components;
import de.shiewk.widgets.ModWidget;
import de.shiewk.widgets.WidgetSettingOption;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.gui.widget.ScrollableWidget;
import net.minecraft.text.Text;
import java.awt.*;
public class WidgetSettingsEditWidget extends ScrollableWidget {
private static final int COLOR_FG = Color.WHITE.getRGB(), COLOR_BG = new Color(0, 0, 0, 60).getRGB();
private final TextRenderer textRenderer;
private final ModWidget widget;
private final Runnable onChange;
private WidgetSettingOption focus = null;
private int contentsHeight = 10;
public WidgetSettingsEditWidget(int x, int y, int width, int height, TextRenderer textRenderer, ModWidget widget, Runnable onChange) {
super(x, y, width, height, Text.empty());
this.textRenderer = textRenderer;
this.widget = widget;
this.onChange = onChange;
for (WidgetSettingOption customSetting : widget.getSettings().getCustomSettings()) {
customSetting.setFocused(false);
}
}
@Override
protected int getContentsHeight() {
return this.contentsHeight;
}
@Override
protected double getDeltaYPerScroll() {
return 20;
}
@Override
protected void renderContents(DrawContext context, int mouseX, int mouseY, float delta) {
context.getMatrices().push();
context.getMatrices().scale(2, 2, 2);
context.drawText(textRenderer, widget.getName(), this.width / 4 - textRenderer.getWidth(widget.getName()) / 2, this.height / 100, COLOR_FG, true);
context.getMatrices().pop();
int y = textRenderer.fontHeight * 2 + this.height / 50 + 5;
for (WidgetSettingOption setting : widget.getSettings().getCustomSettings()) {
if (this.width - setting.getWidth() > textRenderer.getWidth(setting.getName()) + 20){
setting.setX(this.getX() + this.width - setting.getWidth() - 5);
setting.setY(y);
context.drawText(textRenderer, setting.getName(), getX() + 10, y + (setting.getHeight() / 2), COLOR_FG, true);
} else {
setting.setX(this.getX() + this.width / 2 - setting.getWidth() / 2);
setting.setY(y + 9 + 5);
context.drawText(textRenderer, setting.getName(), getX() + getWidth() / 2 - textRenderer.getWidth(setting.getName()) / 2, y, COLOR_FG, true);
y += 9 + 5;
}
setting.render(context, mouseX, (int) (mouseY + getScrollY()), delta);
y += setting.getHeight();
y += 5;
}
this.contentsHeight = y;
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
mouseY += getScrollY();
for (WidgetSettingOption customSetting : widget.getSettings().getCustomSettings()) {
if (mouseX >= customSetting.getX() && mouseX <= customSetting.getX() + customSetting.getWidth()
&& mouseY >= customSetting.getY() && mouseY <= customSetting.getY() + customSetting.getHeight()){
focus = customSetting;
customSetting.setFocused(true);
if (customSetting.mouseClicked(mouseX, mouseY + getScrollY(), button)){
onChange.run();
return true;
}
}
}
return super.mouseClicked(mouseX, mouseY - getScrollY(), button);
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
for (WidgetSettingOption customSetting : widget.getSettings().getCustomSettings()) {
if (customSetting.mouseReleased(mouseX, mouseY + getScrollY(), button)){
onChange.run();
return true;
}
}
return super.mouseReleased(mouseX, mouseY, button);
}
@Override
public boolean charTyped(char chr, int modifiers) {
if (this.focus != null){
if (this.focus.charTyped(chr, modifiers)){
onChange.run();
return true;
}
}
return super.charTyped(chr, modifiers);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (this.focus != null){
if (this.focus.keyPressed(keyCode, scanCode, modifiers)){
onChange.run();
return true;
}
}
return super.keyPressed(keyCode, scanCode, modifiers);
}
@Override
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
if (this.focus != null){
if (this.focus.keyReleased(keyCode, scanCode, modifiers)){
onChange.run();
return true;
}
}
return super.keyReleased(keyCode, scanCode, modifiers);
}
@Override
protected void appendClickableNarrations(NarrationMessageBuilder builder) {
}
@Override
protected void drawBox(DrawContext context, int x, int y, int width, int height) {
context.fill(x, y, x+width, y+height, COLOR_BG);
}
}
@@ -0,0 +1,130 @@
package de.shiewk.widgets.client.screen.components;
import de.shiewk.widgets.ModWidget;
import de.shiewk.widgets.WidgetUtils;
import de.shiewk.widgets.client.screen.WidgetSettingsScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.text.OrderedText;
import net.minecraft.text.Text;
import net.minecraft.util.Util;
import java.awt.*;
import java.util.Iterator;
import java.util.function.Consumer;
public class WidgetWidget extends ClickableWidget {
protected static final int COLOR_BG = new Color(0, 0, 0, 80).getRGB(),
COLOR_BG_HOVER = new Color(40, 40, 40, 80).getRGB(),
COLOR_FG = Color.WHITE.getRGB(),
COLOR_DISABLED = new Color(200, 0, 0, 200).getRGB(),
COLOR_DISABLED_HOVER = new Color(255, 0, 0, 200).getRGB(),
COLOR_ENABLED = new Color(0, 200, 0, 200).getRGB(),
COLOR_ENABLED_HOVER = new Color(0, 255, 0, 200).getRGB();
private final MinecraftClient client;
private final ModWidget widget;
private final TextRenderer textRenderer;
private final Consumer<ModWidget> onEdit;
private long toggleTime = 0;
public WidgetWidget(int x, int y, int width, int height, MinecraftClient client, ModWidget widget, TextRenderer textRenderer, Consumer<ModWidget> onEdit) {
super(x, y, width, height, widget.getName());
this.client = client;
this.widget = widget;
this.textRenderer = textRenderer;
this.onEdit = onEdit;
}
@Override
public boolean isMouseOver(double mouseX, double mouseY) {
return this.active && this.visible && mouseX >= (double)this.getX() && mouseY >= (double)this.getY() && mouseX < (double)(this.getX() + this.width) && mouseY < (double)(this.getY() + this.height - 24);
}
@Override
protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
boolean hover = this.isMouseOver(mouseX, mouseY);
boolean widgetEnabled = widget.getSettings().isEnabled();
context.fill(this.getX(), this.getY(), this.getX() + this.getWidth(), this.getY() + this.getHeight(), hover ? COLOR_BG_HOVER : COLOR_BG);
context.getMatrices().push();
context.getMatrices().scale(2, 2, 1);
int titleSize = textRenderer.getWidth(widget.getName());
context.drawText(textRenderer, widget.getName(), getX() / 2 + getWidth() / 4 - titleSize / 2, getY() / 2 + 4, COLOR_FG, false);
context.getMatrices().pop();
int y = this.getY() + 12 + textRenderer.fontHeight * 2;
for (Iterator<OrderedText> it = textRenderer.wrapLines(widget.getDescription(), this.getWidth() - 10).iterator(); it.hasNext(); y += 9) {
OrderedText t = it.next();
context.drawText(textRenderer, t, getX() + 5 + ((getWidth() - 5) / 2) - (textRenderer.getWidth(t) / 2), y, COLOR_FG, false);
}
this.renderToggleButton(context, mouseX, mouseY, delta, widgetEnabled);
}
@Override
protected boolean clicked(double mouseX, double mouseY) {
if (isMouseOver(mouseX, mouseY)){
client.setScreen(new WidgetSettingsScreen(client.currentScreen, widget));
return true;
} else if (isMouseOverToggle(mouseX, mouseY)){
this.toggleWidget();
return true;
} else {
return false;
}
}
private void toggleWidget() {
widget.getSettings().toggleEnabled(widget);
toggleTime = Util.getMeasuringTimeNano();
onEdit.accept(widget);
}
private void renderToggleButton(DrawContext context, int mouseX, int mouseY, float delta, boolean widgetEnabled){
boolean hoverToggle = this.isMouseOverToggle(mouseX, mouseY);
final int toggleColor;
final int toggleColorInvert;
if (hoverToggle){
if (widgetEnabled){
toggleColor = COLOR_ENABLED_HOVER;
toggleColorInvert = COLOR_DISABLED_HOVER;
} else {
toggleColor = COLOR_DISABLED_HOVER;
toggleColorInvert = COLOR_ENABLED_HOVER;
}
} else {
if (widgetEnabled){
toggleColor = COLOR_ENABLED;
toggleColorInvert = COLOR_DISABLED;
} else {
toggleColor = COLOR_DISABLED;
toggleColorInvert = COLOR_ENABLED;
}
}
if (toggleTime > Util.getMeasuringTimeNano() - 250000000){
context.fill(this.getX(), this.getY() + this.getHeight() - 24, this.getX() + this.getWidth(), this.getY() + this.getHeight(), toggleColorInvert);
context.fill(this.getX(), this.getY() + this.getHeight() - 24, (int) (WidgetUtils.computeEasing((Util.getMeasuringTimeNano() - toggleTime) / 250000000d) * this.getWidth() + this.getX()), this.getY() + this.getHeight(), toggleColor);
} else {
context.fill(this.getX(), this.getY() + this.getHeight() - 24, this.getX() + this.getWidth(), this.getY() + this.getHeight(), toggleColor);
}
context.drawCenteredTextWithShadow(textRenderer, Text.translatable(widgetEnabled ? "widgets.ui.enabled" : "widgets.ui.disabled"), this.getX() + (this.getWidth() / 2), this.getY() + this.getHeight() - 16, COLOR_FG);
}
private boolean isMouseOverToggle(double mouseX, double mouseY) {
return this.active && this.visible && mouseX >= this.getX() && mouseY >= (this.getY() + this.height - 24) && mouseX < (this.getX() + this.width) && mouseY < (this.getY() + this.height);
}
@Override
protected void appendClickableNarrations(NarrationMessageBuilder builder) {
}
public ModWidget getWidget() {
return widget;
}
}