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:
@@ -0,0 +1,8 @@
|
||||
package de.shiewk.widgets;
|
||||
|
||||
public interface Dimensionable {
|
||||
int width();
|
||||
int height();
|
||||
double getX(int mx);
|
||||
double getY(int my);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package de.shiewk.widgets;
|
||||
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import de.shiewk.widgets.client.screen.WidgetConfigScreen;
|
||||
|
||||
public class ModMenuConfig implements ModMenuApi {
|
||||
|
||||
@Override
|
||||
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||
return WidgetConfigScreen::new;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package de.shiewk.widgets;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class ModWidget implements Dimensionable {
|
||||
|
||||
private final Identifier id;
|
||||
private final WidgetSettings settings;
|
||||
|
||||
protected ModWidget(Identifier id, List<WidgetSettingOption> customSettings) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
this.id = id;
|
||||
this.settings = WidgetSettings.ofId(id, customSettings);
|
||||
}
|
||||
|
||||
public final Identifier getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public final WidgetSettings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
public abstract void render(DrawContext context, long measuringTimeNano, TextRenderer textRenderer, int posX, int posY);
|
||||
public abstract void tick();
|
||||
public abstract Text getName();
|
||||
public abstract Text getDescription();
|
||||
public abstract void onSettingsChanged(WidgetSettings settings);
|
||||
|
||||
@Override
|
||||
public double getX(int mx) {
|
||||
return (int) WidgetUtils.translateToScreen(settings.posX, mx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY(int my) {
|
||||
return (int) WidgetUtils.translateToScreen(settings.posY, my);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package de.shiewk.widgets;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import net.minecraft.client.gui.Drawable;
|
||||
import net.minecraft.client.gui.widget.ClickableWidget;
|
||||
import net.minecraft.client.gui.widget.Widget;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class WidgetSettingOption implements Drawable, Widget {
|
||||
private final String id;
|
||||
private final Text name;
|
||||
private int x = 0;
|
||||
private int y = 0;
|
||||
private boolean focused = false;
|
||||
|
||||
protected WidgetSettingOption(String id, Text name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public final String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public final Text getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public abstract JsonElement saveState();
|
||||
public abstract void loadState(JsonElement state);
|
||||
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button){
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean charTyped(char chr, int modifiers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void forEachChild(Consumer<ClickableWidget> consumer) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean isFocused() {
|
||||
return focused;
|
||||
}
|
||||
|
||||
public void setFocused(boolean focused) {
|
||||
this.focused = focused;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package de.shiewk.widgets;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import de.shiewk.widgets.client.WidgetManager;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static de.shiewk.widgets.WidgetUtils.translateToWidgetSettingsValue;
|
||||
import static de.shiewk.widgets.WidgetsMod.LOGGER;
|
||||
|
||||
public class WidgetSettings {
|
||||
public double posX = 0; // posx * 100 = screen width
|
||||
public double posY = 0; // posy * 100 = screen height
|
||||
private boolean enabled = false;
|
||||
private final ObjectArrayList<WidgetSettingOption> customSettings;
|
||||
|
||||
private WidgetSettings(JsonObject data, List<WidgetSettingOption> settings){
|
||||
customSettings = new ObjectArrayList<>(settings);
|
||||
if (data != null){
|
||||
final JsonElement enabled = data.get("enabled");
|
||||
this.enabled = enabled.isJsonPrimitive() && enabled.getAsJsonPrimitive().isBoolean() && enabled.getAsBoolean();
|
||||
final JsonElement x = data.get("x");
|
||||
this.posX = x.isJsonPrimitive() ? x.getAsJsonPrimitive().isNumber() ? x.getAsDouble() : 0 : 0;
|
||||
final JsonElement y = data.get("y");
|
||||
this.posY = y.isJsonPrimitive() ? y.getAsJsonPrimitive().isNumber() ? y.getAsDouble() : 0 : 0;
|
||||
final JsonElement s = data.get("settings");
|
||||
if (s != null && s.isJsonObject()){
|
||||
final JsonObject savedSettings = s.getAsJsonObject();
|
||||
for (WidgetSettingOption setting : this.customSettings) {
|
||||
final String settingId = setting.getId();
|
||||
if (savedSettings.has(settingId)){
|
||||
try {
|
||||
setting.loadState(savedSettings.get(settingId));
|
||||
} catch (Throwable e){
|
||||
LOGGER.error("Could not load setting '{}' from element {}:", settingId, savedSettings.get(settingId));
|
||||
LOGGER.error(e.toString());
|
||||
for (StackTraceElement element : e.getStackTrace()) {
|
||||
LOGGER.error(element.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static WidgetSettings ofId(Identifier id, List<WidgetSettingOption> customSettings){
|
||||
final JsonObject data = WidgetManager.loadWidget(id);
|
||||
return new WidgetSettings(data, customSettings);
|
||||
}
|
||||
|
||||
public void setPosX(double v, int widgetWidth, int maxWidth) {
|
||||
posX = MathHelper.clamp(v, 0, 100 - translateToWidgetSettingsValue(widgetWidth, maxWidth));
|
||||
}
|
||||
public void setPosY(double v, int widgetHeight, int maxHeight) {
|
||||
posY = MathHelper.clamp(v, 0, 100 - translateToWidgetSettingsValue(widgetHeight, maxHeight));
|
||||
}
|
||||
|
||||
public boolean isEnabled(){
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(ModWidget widget, boolean enabled){
|
||||
this.enabled = enabled;
|
||||
if (enabled){
|
||||
WidgetManager.enable(widget);
|
||||
} else {
|
||||
WidgetManager.disable(widget);
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleEnabled(ModWidget widget){
|
||||
setEnabled(widget, !enabled);
|
||||
}
|
||||
|
||||
public final JsonObject saveState(){
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("x", posX);
|
||||
object.addProperty("y", posY);
|
||||
object.addProperty("enabled", enabled);
|
||||
JsonObject customSettings = new JsonObject();
|
||||
for (WidgetSettingOption customSetting : this.customSettings) {
|
||||
customSettings.add(customSetting.getId(), customSetting.saveState());
|
||||
}
|
||||
object.add("settings", customSettings);
|
||||
return object;
|
||||
}
|
||||
|
||||
public WidgetSettingOption optionById(String id){
|
||||
for (WidgetSettingOption customSetting : customSettings) {
|
||||
if (customSetting.getId().equals(id)){
|
||||
return customSetting;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ObjectArrayList<WidgetSettingOption> getCustomSettings() {
|
||||
return customSettings.clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package de.shiewk.widgets;
|
||||
|
||||
public class WidgetUtils {
|
||||
|
||||
public static double translateToWidgetSettingsValue(double value, int max){
|
||||
return (value / max) * 100;
|
||||
}
|
||||
|
||||
public static double translateToScreen(double value, int max){
|
||||
return value / 100d * max;
|
||||
}
|
||||
|
||||
public static double computeEasing(double x) {
|
||||
return 1d - Math.pow(1d - x, 3.5d);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package de.shiewk.widgets;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class WidgetsMod implements ModInitializer {
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger("Widgets");
|
||||
public static final String MOD_ID = "widgets";
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package de.shiewk.widgets.client;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import de.shiewk.widgets.ModWidget;
|
||||
import de.shiewk.widgets.WidgetsMod;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class WidgetManager {
|
||||
|
||||
static final ObjectArrayList<ModWidget> enabled = new ObjectArrayList<>(); // for performance
|
||||
private static final ObjectArrayList<ModWidget> allWidgets = new ObjectArrayList<>();
|
||||
|
||||
public static void register(ModWidget widget){
|
||||
allWidgets.add(widget);
|
||||
if (widget.getSettings().isEnabled()){
|
||||
enable(widget);
|
||||
}
|
||||
}
|
||||
|
||||
public static ObjectArrayList<ModWidget> getEnabledWidgets() {
|
||||
return new ObjectArrayList<>(enabled);
|
||||
}
|
||||
|
||||
public static ObjectArrayList<ModWidget> getAllWidgets() {
|
||||
return new ObjectArrayList<>(allWidgets);
|
||||
}
|
||||
|
||||
public static void enable(ModWidget widget) {
|
||||
enabled.add(widget);
|
||||
}
|
||||
|
||||
public static void disable(ModWidget widget) {
|
||||
enabled.remove(widget);
|
||||
}
|
||||
|
||||
static Function<Identifier, File> saveFileFactory;
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
public static void saveWidgets(List<ModWidget> widgets) {
|
||||
for (ModWidget widget : widgets) {
|
||||
WidgetsMod.LOGGER.info("Saving widget {}", widget.getId());
|
||||
final File saveFile = saveFileFactory.apply(widget.getId());
|
||||
try {
|
||||
if (saveFile.getParentFile().isDirectory() || saveFile.getParentFile().mkdirs()){
|
||||
if (saveFile.isFile() || saveFile.createNewFile()){
|
||||
try (FileWriter fw = new FileWriter(saveFile)){
|
||||
try (JsonWriter jw = new JsonWriter(fw)){
|
||||
Streams.write(widget.getSettings().saveState(), jw);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WidgetsMod.LOGGER.error("Could not create file: {}", saveFile.getPath());
|
||||
}
|
||||
} else {
|
||||
WidgetsMod.LOGGER.error("Could not create directory: {}", saveFile.getParentFile().getPath());
|
||||
}
|
||||
} catch (IOException e){
|
||||
WidgetsMod.LOGGER.error("An I/O operation failed while saving widget {} ({})", widget, widget.getId());
|
||||
WidgetsMod.LOGGER.error(e.toString());
|
||||
for (StackTraceElement element : e.getStackTrace()) {
|
||||
WidgetsMod.LOGGER.error(String.valueOf(element));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable JsonObject loadWidget(Identifier id) {
|
||||
WidgetsMod.LOGGER.info("Loading widget data of {}", id);
|
||||
final File saveFile = saveFileFactory.apply(id);
|
||||
if (!saveFile.isFile()){
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
try (FileReader fr = new FileReader(saveFile)){
|
||||
return gson.fromJson(fr, JsonObject.class);
|
||||
}
|
||||
} catch (IOException e){
|
||||
WidgetsMod.LOGGER.error("An I/O operation failed while loading widget {}", id);
|
||||
WidgetsMod.LOGGER.error(e.toString());
|
||||
for (StackTraceElement element : e.getStackTrace()) {
|
||||
WidgetsMod.LOGGER.error(String.valueOf(element));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package de.shiewk.widgets.client;
|
||||
|
||||
import de.shiewk.widgets.ModWidget;
|
||||
import de.shiewk.widgets.WidgetSettings;
|
||||
import de.shiewk.widgets.client.screen.EditWidgetPositionsScreen;
|
||||
import de.shiewk.widgets.client.screen.WidgetConfigScreen;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.render.RenderTickCounter;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
|
||||
import static de.shiewk.widgets.WidgetUtils.translateToScreen;
|
||||
|
||||
public class WidgetRenderer implements HudRenderCallback, ClientTickEvents.StartTick, ClientLifecycleEvents.ClientStarted {
|
||||
|
||||
private static MinecraftClient client;
|
||||
|
||||
@Override
|
||||
public void onHudRender(DrawContext drawContext, RenderTickCounter tickCounter) {
|
||||
if (client.options.hudHidden) return;
|
||||
if (client.currentScreen instanceof EditWidgetPositionsScreen) return;
|
||||
final Profiler profiler = client.getProfiler();
|
||||
profiler.push("widgets");
|
||||
final TextRenderer textRenderer = client.textRenderer;
|
||||
final long timeNano = Util.getMeasuringTimeNano();
|
||||
final int windowWidth = drawContext.getScaledWindowWidth();
|
||||
final int windowHeight = drawContext.getScaledWindowHeight();
|
||||
|
||||
final ObjectArrayList<ModWidget> enabled = WidgetManager.enabled;
|
||||
for (int i = 0, enabledSize = enabled.size(); i < enabledSize; i++) {
|
||||
final ModWidget widget = enabled.get(i);
|
||||
profiler.push(widget.getId().toString());
|
||||
final WidgetSettings settings = widget.getSettings();
|
||||
widget.render(
|
||||
drawContext,
|
||||
timeNano,
|
||||
textRenderer,
|
||||
(int) Math.round(Math.min(translateToScreen(settings.posX, windowWidth), windowWidth - widget.width())),
|
||||
(int) Math.round(Math.min(translateToScreen(settings.posY, windowHeight), windowHeight - widget.height()))
|
||||
);
|
||||
profiler.pop();
|
||||
}
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTick(MinecraftClient client) {
|
||||
final Profiler profiler = (WidgetRenderer.client = client).getProfiler();
|
||||
profiler.push("widgets");
|
||||
|
||||
final ObjectArrayList<ModWidget> enabled = WidgetManager.enabled;
|
||||
for (int i = 0, enabledSize = enabled.size(); i < enabledSize; i++) {
|
||||
final ModWidget widget = enabled.get(i);
|
||||
profiler.push(widget.getId().toString());
|
||||
widget.tick();
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
profiler.pop();
|
||||
|
||||
if (WidgetsModClient.configKeyBinding.wasPressed()){
|
||||
client.setScreen(new WidgetConfigScreen(client.currentScreen));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClientStarted(MinecraftClient client) {
|
||||
for (ModWidget widget : WidgetManager.getAllWidgets()) {
|
||||
widget.onSettingsChanged(widget.getSettings());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package de.shiewk.widgets.client;
|
||||
|
||||
import de.shiewk.widgets.WidgetsMod;
|
||||
import de.shiewk.widgets.client.screen.WidgetConfigScreen;
|
||||
import de.shiewk.widgets.widgets.*;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
|
||||
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class WidgetsModClient implements ClientModInitializer {
|
||||
|
||||
static KeyBinding configKeyBinding;
|
||||
|
||||
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
HudRenderCallback.EVENT.register(new WidgetRenderer());
|
||||
ClientTickEvents.START_CLIENT_TICK.register(new WidgetRenderer());
|
||||
ClientLifecycleEvents.CLIENT_STARTED.register(new WidgetRenderer());
|
||||
|
||||
// manage widgets keybind
|
||||
configKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
||||
"widgets.key.config",
|
||||
InputUtil.Type.KEYSYM,
|
||||
GLFW.GLFW_KEY_RIGHT_SHIFT,
|
||||
"widgets.key.category"
|
||||
));
|
||||
|
||||
// in-game /widgetsmod command
|
||||
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) ->
|
||||
dispatcher.register(ClientCommandManager.literal("widgetsmod").executes(ctx -> {
|
||||
WidgetsMod.LOGGER.info("Ran in-game command");
|
||||
final MinecraftClient client = ctx.getSource().getClient();
|
||||
client.send(() -> client.setScreen(new WidgetConfigScreen(client.currentScreen)));
|
||||
return 0;
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
WidgetManager.saveFileFactory = id -> new File(MinecraftClient.getInstance().runDirectory.getPath() + "/config/widgets/" + id.getNamespace() + "/" + id.getPath() + ".json");
|
||||
|
||||
WidgetManager.register(new FPSWidget(Identifier.of(WidgetsMod.MOD_ID, "fps")));
|
||||
WidgetManager.register(new ClockWidget(Identifier.of(WidgetsMod.MOD_ID, "clock")));
|
||||
WidgetManager.register(new CoordinatesWidget(Identifier.of(WidgetsMod.MOD_ID, "coordinates")));
|
||||
WidgetManager.register(new BandwidthWidget(Identifier.of(WidgetsMod.MOD_ID, "bandwidth")));
|
||||
WidgetManager.register(new PingWidget(Identifier.of(WidgetsMod.MOD_ID, "ping")));
|
||||
WidgetManager.register(new ServerIPWidget(Identifier.of(WidgetsMod.MOD_ID, "server_ip")));
|
||||
WidgetManager.register(new PlayerCountWidget(Identifier.of(WidgetsMod.MOD_ID, "player_count")));
|
||||
WidgetManager.register(new CPSWidget(Identifier.of(WidgetsMod.MOD_ID, "cps")));
|
||||
}
|
||||
}
|
||||
@@ -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) {}
|
||||
}
|
||||
+135
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package de.shiewk.widgets.mixin;
|
||||
|
||||
import de.shiewk.widgets.widgets.CPSWidget;
|
||||
import net.minecraft.client.Mouse;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Mouse.class)
|
||||
public class MixinMouse {
|
||||
|
||||
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/Mouse;leftButtonClicked:Z"), method = "onMouseButton")
|
||||
public void onLeftClick(long window, int button, int action, int mods, CallbackInfo ci){
|
||||
if (action == 1) CPSWidget.clickLeft();
|
||||
}
|
||||
|
||||
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/Mouse;middleButtonClicked:Z"), method = "onMouseButton")
|
||||
public void onMiddleClick(long window, int button, int action, int mods, CallbackInfo ci){
|
||||
if (action == 1) CPSWidget.clickMiddle();
|
||||
}
|
||||
|
||||
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/Mouse;rightButtonClicked:Z"), method = "onMouseButton")
|
||||
public void onRightClick(long window, int button, int action, int mods, CallbackInfo ci){
|
||||
if (action == 1) CPSWidget.clickRight();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package de.shiewk.widgets.widgets;
|
||||
|
||||
import de.shiewk.widgets.WidgetSettings;
|
||||
import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.profiler.MultiValueDebugSampleLogImpl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BandwidthWidget extends BasicTextWidget {
|
||||
public BandwidthWidget(Identifier id) {
|
||||
super(id, List.of(
|
||||
new ToggleWidgetSetting("dynamic_color", Text.translatable("widgets.widgets.bandwidth.dynamicColor"), true)
|
||||
));
|
||||
}
|
||||
|
||||
private int t = 0;
|
||||
private boolean dynamicColor = false;
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
t++;
|
||||
if (t >= 20){
|
||||
t = 0;
|
||||
final MultiValueDebugSampleLogImpl packetSizeLog = MinecraftClient.getInstance().getDebugHud().getPacketSizeLog();
|
||||
final int logLength = packetSizeLog.getLength();
|
||||
final int avgCompileLength = 60;
|
||||
long size = 0;
|
||||
for (int i = logLength-1; i > logLength-avgCompileLength; i--) {
|
||||
if (i < 0) break;
|
||||
size += packetSizeLog.get(i);
|
||||
}
|
||||
long avgBytesPerSecond = size / avgCompileLength * 20;
|
||||
this.renderText = Text.of(formatByteSize(avgBytesPerSecond));
|
||||
if (this.dynamicColor){
|
||||
if (avgBytesPerSecond < 100000){
|
||||
this.textColor = 0x00ff00;
|
||||
} else if (avgBytesPerSecond < 750000) {
|
||||
this.textColor = 0xffff00;
|
||||
} else {
|
||||
this.textColor = 0xff3030;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String formatByteSize(long bytes) {
|
||||
if (bytes > 1000) {
|
||||
double mb = bytes / 100 / 10d;
|
||||
return mb + " KB/s";
|
||||
} else {
|
||||
return bytes + " B/s";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsChanged(WidgetSettings settings) {
|
||||
super.onSettingsChanged(settings);
|
||||
this.dynamicColor = ((ToggleWidgetSetting) settings.optionById("dynamic_color")).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return Text.translatable("widgets.widgets.bandwidth");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDescription() {
|
||||
return Text.translatable("widgets.widgets.bandwidth.description");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package de.shiewk.widgets.widgets;
|
||||
|
||||
import de.shiewk.widgets.ModWidget;
|
||||
import de.shiewk.widgets.WidgetSettingOption;
|
||||
import de.shiewk.widgets.WidgetSettings;
|
||||
import de.shiewk.widgets.widgets.settings.RGBAColorWidgetSetting;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BasicTextWidget extends ModWidget {
|
||||
protected Text renderText = Text.empty();
|
||||
|
||||
private static ObjectArrayList<WidgetSettingOption> getCustomSettings(List<WidgetSettingOption> otherCustomOptions) {
|
||||
final ObjectArrayList<WidgetSettingOption> list = new ObjectArrayList<>(otherCustomOptions);
|
||||
list.add(new RGBAColorWidgetSetting("backgroundcolor", Text.translatable("widgets.widgets.basictext.background"), 0, 0, 0, 80));
|
||||
list.add(new RGBAColorWidgetSetting("textcolor", Text.translatable("widgets.widgets.basictext.textcolor"), 255, 255, 255, 255));
|
||||
return list;
|
||||
}
|
||||
protected BasicTextWidget(Identifier id, List<WidgetSettingOption> otherCustomOptions) {
|
||||
super(id, getCustomSettings(otherCustomOptions));
|
||||
}
|
||||
|
||||
protected static final int
|
||||
DEFAULT_WIDTH = 80,
|
||||
DEFAULT_HEIGHT = 9 + 12,
|
||||
DEFAULT_BACKGROUND_COLOR = new Color(0, 0, 0, 80).getRGB(),
|
||||
DEFAULT_TEXT_COLOR = new Color(255, 255 ,255, 255).getRGB();
|
||||
|
||||
protected int backgroundColor = DEFAULT_BACKGROUND_COLOR, textColor = DEFAULT_TEXT_COLOR;
|
||||
|
||||
@Override
|
||||
public int width() {
|
||||
return DEFAULT_WIDTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int height() {
|
||||
return DEFAULT_HEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, long n, TextRenderer textRenderer, int posX, int posY) {
|
||||
context.fill(posX, posY, posX + width(), posY + height(), this.backgroundColor);
|
||||
context.drawCenteredTextWithShadow(textRenderer, renderText, posX + (width() / 2), posY + 6, this.textColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsChanged(WidgetSettings settings) {
|
||||
this.backgroundColor = ((RGBAColorWidgetSetting) settings.optionById("backgroundcolor")).getColor();
|
||||
this.textColor = ((RGBAColorWidgetSetting) settings.optionById("textcolor")).getColor();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package de.shiewk.widgets.widgets;
|
||||
|
||||
import de.shiewk.widgets.WidgetSettings;
|
||||
import de.shiewk.widgets.widgets.settings.EnumWidgetSetting;
|
||||
import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CPSWidget extends BasicTextWidget {
|
||||
|
||||
public static class Click {
|
||||
private int ticks = 0;
|
||||
|
||||
public int tick(){
|
||||
return ticks++;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean countLeftClicks = true;
|
||||
private static boolean countMiddleClicks = true;
|
||||
private static boolean countRightClicks = true;
|
||||
|
||||
private static final ObjectArrayList<Click> leftClicks = new ObjectArrayList<>();
|
||||
private static final ObjectArrayList<Click> middleClicks = new ObjectArrayList<>();
|
||||
private static final ObjectArrayList<Click> rightClicks = new ObjectArrayList<>();
|
||||
|
||||
private Appearance appearance = Appearance.UNIFIED;
|
||||
|
||||
public enum Appearance {
|
||||
SPLIT_PIPE("pipe"),
|
||||
SPLIT_SLASH("slash"),
|
||||
UNIFIED("unified");
|
||||
|
||||
public final String key;
|
||||
|
||||
Appearance(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
|
||||
public CPSWidget(Identifier id) {
|
||||
super(id, List.of(
|
||||
new EnumWidgetSetting<>("appearance", Text.translatable("widgets.widgets.cps.appearance"), Appearance.class, Appearance.UNIFIED, appearance -> Text.translatable("widgets.widgets.cps.appearance."+appearance.key)),
|
||||
new ToggleWidgetSetting("left", Text.translatable("widgets.widgets.cps.left"), true),
|
||||
new ToggleWidgetSetting("middle", Text.translatable("widgets.widgets.cps.middle"), false),
|
||||
new ToggleWidgetSetting("right", Text.translatable("widgets.widgets.cps.right"), true)
|
||||
));
|
||||
}
|
||||
|
||||
public static void clickLeft() {
|
||||
if (countLeftClicks){
|
||||
leftClicks.add(new Click());
|
||||
}
|
||||
}
|
||||
|
||||
public static void clickMiddle() {
|
||||
if (countMiddleClicks){
|
||||
middleClicks.add(new Click());
|
||||
}
|
||||
}
|
||||
|
||||
public static void clickRight() {
|
||||
if (countRightClicks){
|
||||
rightClicks.add(new Click());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int middle = 0;
|
||||
if (countLeftClicks) {
|
||||
leftClicks.removeIf(click -> click.tick() >= 20);
|
||||
left = leftClicks.size();
|
||||
}
|
||||
if (countRightClicks) {
|
||||
rightClicks.removeIf(click -> click.tick() >= 20);
|
||||
right = rightClicks.size();
|
||||
}
|
||||
if (countMiddleClicks) {
|
||||
middleClicks.removeIf(click -> click.tick() >= 20);
|
||||
middle = middleClicks.size();
|
||||
}
|
||||
switch (appearance){
|
||||
case UNIFIED -> renderText = Text.literal((left + right + middle) + " CPS");
|
||||
case SPLIT_PIPE, SPLIT_SLASH -> {
|
||||
final StringBuilder sb = getClickText(left, middle, right);
|
||||
renderText = Text.literal(sb + " CPS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private @NotNull StringBuilder getClickText(int left, int middle, int right) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (countLeftClicks){
|
||||
sb.append(left);
|
||||
}
|
||||
if (countMiddleClicks){
|
||||
if (!sb.isEmpty()){
|
||||
sb.append(appearance == Appearance.SPLIT_PIPE ? " | " : "/");
|
||||
}
|
||||
sb.append(middle);
|
||||
}
|
||||
if (countRightClicks){
|
||||
if (!sb.isEmpty()){
|
||||
sb.append(appearance == Appearance.SPLIT_PIPE ? " | " : "/");
|
||||
}
|
||||
sb.append(right);
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsChanged(WidgetSettings settings) {
|
||||
super.onSettingsChanged(settings);
|
||||
countLeftClicks = ((ToggleWidgetSetting) settings.optionById("left")).getValue();
|
||||
countMiddleClicks = ((ToggleWidgetSetting) settings.optionById("middle")).getValue();
|
||||
countRightClicks = ((ToggleWidgetSetting) settings.optionById("right")).getValue();
|
||||
appearance = (Appearance) ((EnumWidgetSetting<?>) settings.optionById("appearance")).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return Text.translatable("widgets.widgets.cps");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDescription() {
|
||||
return Text.translatable("widgets.widgets.cps.description");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package de.shiewk.widgets.widgets;
|
||||
|
||||
import de.shiewk.widgets.WidgetSettings;
|
||||
import de.shiewk.widgets.widgets.settings.EnumWidgetSetting;
|
||||
import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class ClockWidget extends BasicTextWidget {
|
||||
|
||||
private int width = DEFAULT_WIDTH;
|
||||
|
||||
public enum TimeOption {
|
||||
NO_TIME("none"),
|
||||
HOUR_24("24hour"),
|
||||
AM_PM("am_pm");
|
||||
|
||||
public final String key;
|
||||
|
||||
TimeOption(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
|
||||
public enum DateOption {
|
||||
NO_DATE(null),
|
||||
FULL_MONTH_DAY("MMMM dd"),
|
||||
DAY_FULL_MONTH("dd. MMMM"),
|
||||
ABB_MONTH_DAY("MMM dd"),
|
||||
DAY_ABB_MONTH("dd. MMM"),
|
||||
MONTH_DAY("MM/dd"),
|
||||
MONTH_DAY_2("dd.MM"),
|
||||
FULL_MONTH_DAY_YEAR("MMMM dd, y"),
|
||||
ABB_MONTH_DAY_YEAR("MMM dd, y"),
|
||||
DAY_FULL_MONTH_YEAR("dd. MMMM y"),
|
||||
DAY_ABB_MONTH_YEAR("dd. MMM y"),
|
||||
MONTH_DAY_YEAR("MM/dd/y"),
|
||||
MONTH_DAY_YEAR_2("dd.MM.y");
|
||||
|
||||
public final String format;
|
||||
|
||||
DateOption(String format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public Text getName(){
|
||||
return this.format == null ? Text.translatable("widgets.widgets.clock.dateFormat.none") : Text.of(new SimpleDateFormat(format).format(Date.from(Instant.now())));
|
||||
}
|
||||
}
|
||||
|
||||
public enum WeekOption {
|
||||
NO_DAY_OF_WEEK(null),
|
||||
ABBREVIATED("E"),
|
||||
FULL("EEEE");
|
||||
|
||||
public final String format;
|
||||
|
||||
WeekOption(String format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public Text getName(){
|
||||
return this.format == null ? Text.translatable("widgets.widgets.clock.weekFormat.none") : Text.of(new SimpleDateFormat(format).format(Date.from(Instant.now())));
|
||||
}
|
||||
}
|
||||
public ClockWidget(Identifier id) {
|
||||
super(id, List.of(
|
||||
new EnumWidgetSetting<>("hour_format",
|
||||
Text.translatable("widgets.widgets.clock.hourFormat"),
|
||||
TimeOption.class,
|
||||
TimeOption.HOUR_24,
|
||||
timeOption -> Text.translatable("widgets.widgets.clock.hourFormat."+timeOption.key)),
|
||||
new ToggleWidgetSetting("show_seconds",
|
||||
Text.translatable("widgets.widgets.clock.showSeconds"),
|
||||
true),
|
||||
new EnumWidgetSetting<>("date_format",
|
||||
Text.translatable("widgets.widgets.clock.dateFormat"),
|
||||
DateOption.class,
|
||||
DateOption.NO_DATE,
|
||||
DateOption::getName),
|
||||
new EnumWidgetSetting<>("week_format",
|
||||
Text.translatable("widgets.widgets.clock.weekFormat"),
|
||||
WeekOption.class,
|
||||
WeekOption.NO_DAY_OF_WEEK,
|
||||
WeekOption::getName)
|
||||
));
|
||||
}
|
||||
|
||||
private SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss aa EEEE");
|
||||
|
||||
@Override
|
||||
public int width() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
renderText = Text.literal(dateFormat.format(Date.from(Instant.now())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsChanged(WidgetSettings settings) {
|
||||
super.onSettingsChanged(settings);
|
||||
String datePattern = "HH:mm:ss";
|
||||
TimeOption timeOption = (TimeOption) ((EnumWidgetSetting<?>) settings.optionById("hour_format")).getValue();
|
||||
DateOption dateOption = (DateOption) ((EnumWidgetSetting<?>) settings.optionById("date_format")).getValue();
|
||||
WeekOption weekOption = (WeekOption) ((EnumWidgetSetting<?>) settings.optionById("week_format")).getValue();
|
||||
boolean showSeconds = ((ToggleWidgetSetting) settings.optionById("show_seconds")).getValue();
|
||||
if (timeOption == TimeOption.HOUR_24){
|
||||
datePattern = showSeconds ? "HH:mm:ss" : "HH:mm";
|
||||
} else if (timeOption == TimeOption.AM_PM){
|
||||
datePattern = showSeconds ? "hh:mm:ss aa" : "hh:mm aa";
|
||||
} else if (timeOption == TimeOption.NO_TIME){
|
||||
datePattern = "";
|
||||
}
|
||||
if (dateOption.format != null){
|
||||
if (datePattern.isEmpty()) {
|
||||
datePattern = dateOption.format + datePattern;
|
||||
} else {
|
||||
datePattern = dateOption.format + " " + datePattern;
|
||||
}
|
||||
}
|
||||
if (weekOption.format != null){
|
||||
if (datePattern.isEmpty()){
|
||||
datePattern = weekOption.format + datePattern;
|
||||
} else {
|
||||
datePattern = weekOption.format + ", " + datePattern;
|
||||
}
|
||||
}
|
||||
dateFormat = new SimpleDateFormat(datePattern);
|
||||
width = Math.max(DEFAULT_WIDTH, MinecraftClient.getInstance().textRenderer.getWidth(dateFormat.format(Date.from(Instant.now()))) + 20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return Text.translatable("widgets.widgets.clock");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDescription() {
|
||||
return Text.translatable("widgets.widgets.clock.description");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package de.shiewk.widgets.widgets;
|
||||
|
||||
import de.shiewk.widgets.ModWidget;
|
||||
import de.shiewk.widgets.WidgetSettings;
|
||||
import de.shiewk.widgets.widgets.settings.RGBAColorWidgetSetting;
|
||||
import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
public class CoordinatesWidget extends ModWidget {
|
||||
public CoordinatesWidget(Identifier id) {
|
||||
super(id, List.of(
|
||||
new ToggleWidgetSetting("x", Text.translatable("widgets.widgets.coordinates.showX"), true),
|
||||
new ToggleWidgetSetting("y", Text.translatable("widgets.widgets.coordinates.showY"), true),
|
||||
new ToggleWidgetSetting("z", Text.translatable("widgets.widgets.coordinates.showZ"), true),
|
||||
new RGBAColorWidgetSetting("backgroundcolor", Text.translatable("widgets.widgets.basictext.background"), 0, 0, 0, 80),
|
||||
new RGBAColorWidgetSetting("textcolor", Text.translatable("widgets.widgets.basictext.textcolor"), 255, 255, 255, 255)
|
||||
));
|
||||
}
|
||||
|
||||
private String textX = "X", textY = "Y", textZ = "Z";
|
||||
private int txc = 0, tyc = 0, tzc = 0;
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, long measuringTimeNano, TextRenderer textRenderer, int posX, int posY) {
|
||||
context.fill(posX, posY, posX + width(), posY + height(), this.backgroundColor);
|
||||
final int PADDING = CoordinatesWidget.PADDING;
|
||||
int y = PADDING;
|
||||
if (showX){
|
||||
y++;
|
||||
context.drawText(textRenderer, "X: ", posX + PADDING, posY + y, textColor, true);
|
||||
context.drawText(textRenderer, textX, posX + txc, posY + y, textColor, true);
|
||||
y += textRenderer.fontHeight + 1;
|
||||
}
|
||||
if (showY){
|
||||
y++;
|
||||
context.drawText(textRenderer, "Y: ", posX + PADDING, posY + y, textColor, true);
|
||||
context.drawText(textRenderer, textY, posX + tyc, posY + y, textColor, true);
|
||||
y += textRenderer.fontHeight + 1;
|
||||
}
|
||||
if (showZ){
|
||||
y++;
|
||||
context.drawText(textRenderer, "Z: ", posX + PADDING, posY + y, textColor, true);
|
||||
context.drawText(textRenderer, textZ, posX + tzc, posY + y, textColor, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
|
||||
txc = width() - textRenderer.getWidth(textX) - PADDING;
|
||||
tyc = width() - textRenderer.getWidth(textY) - PADDING;
|
||||
tzc = width() - textRenderer.getWidth(textZ) - PADDING;
|
||||
|
||||
final ClientPlayerEntity player = MinecraftClient.getInstance().player;
|
||||
if (player == null){
|
||||
textX = "?";
|
||||
textY = "?";
|
||||
textZ = "?";
|
||||
} else {
|
||||
textX = String.valueOf(player.getBlockX());
|
||||
textY = String.valueOf(player.getBlockY());
|
||||
textZ = String.valueOf(player.getBlockZ());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return Text.translatable("widgets.widgets.coordinates");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDescription() {
|
||||
return Text.translatable("widgets.widgets.coordinates.description");
|
||||
}
|
||||
|
||||
protected static final int
|
||||
WIDTH = 80,
|
||||
PADDING = 6,
|
||||
DEFAULT_BACKGROUND_COLOR = new Color(0, 0, 0, 80).getRGB(),
|
||||
DEFAULT_TEXT_COLOR = new Color(255, 255 ,255, 255).getRGB();
|
||||
|
||||
protected int backgroundColor = DEFAULT_BACKGROUND_COLOR, textColor = DEFAULT_TEXT_COLOR;
|
||||
protected boolean showX = true, showY = true, showZ = true;
|
||||
|
||||
@Override
|
||||
public void onSettingsChanged(WidgetSettings settings) {
|
||||
this.backgroundColor = ((RGBAColorWidgetSetting) settings.optionById("backgroundcolor")).getColor();
|
||||
this.textColor = ((RGBAColorWidgetSetting) settings.optionById("textcolor")).getColor();
|
||||
this.showX = ((ToggleWidgetSetting) settings.optionById("x")).getValue();
|
||||
this.showY = ((ToggleWidgetSetting) settings.optionById("y")).getValue();
|
||||
this.showZ = ((ToggleWidgetSetting) settings.optionById("z")).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int width() {
|
||||
return WIDTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int height() {
|
||||
int height = 2 * PADDING;
|
||||
if (showX) height += 11;
|
||||
if (showY) height += 11;
|
||||
if (showZ) height += 11;
|
||||
return height;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package de.shiewk.widgets.widgets;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FPSWidget extends BasicTextWidget {
|
||||
public FPSWidget(Identifier id) {
|
||||
super(id, List.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
this.renderText = Text.literal(MinecraftClient.getInstance().getCurrentFps() + " FPS");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return Text.translatable("widgets.widgets.fps");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDescription() {
|
||||
return Text.translatable("widgets.widgets.fps.description");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package de.shiewk.widgets.widgets;
|
||||
|
||||
import de.shiewk.widgets.WidgetSettings;
|
||||
import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.profiler.MultiValueDebugSampleLogImpl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PingWidget extends BasicTextWidget {
|
||||
|
||||
long lastPingQuery = 0;
|
||||
public PingWidget(Identifier id) {
|
||||
super(id, List.of(
|
||||
new ToggleWidgetSetting("dynamic_color", Text.translatable("widgets.widgets.ping.dynamicColor"), true)
|
||||
));
|
||||
}
|
||||
private boolean dynamicColor = false;
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
final ClientPlayNetworkHandler networkHandler = MinecraftClient.getInstance().getNetworkHandler();
|
||||
if (networkHandler != null){
|
||||
if (lastPingQuery < Util.getMeasuringTimeMs() - 5000){
|
||||
networkHandler.pingMeasurer.ping();
|
||||
lastPingQuery = Util.getMeasuringTimeMs();
|
||||
}
|
||||
final MultiValueDebugSampleLogImpl pingLog = networkHandler.pingMeasurer.log;
|
||||
final int logLength = pingLog.getLength();
|
||||
final int avgCompileLength = 3;
|
||||
long ping = 0;
|
||||
for (int i = logLength-1; i > logLength-avgCompileLength; i--) {
|
||||
if (i < 0) break;
|
||||
ping += pingLog.get(i);
|
||||
}
|
||||
long avgPing = ping / avgCompileLength;
|
||||
this.renderText = Text.of(avgPing + " ms");
|
||||
if (this.dynamicColor){
|
||||
if (avgPing < 50){
|
||||
this.textColor = 0x00ff00;
|
||||
} else if (avgPing < 120) {
|
||||
this.textColor = 0xffff00;
|
||||
} else {
|
||||
this.textColor = 0xff3030;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsChanged(WidgetSettings settings) {
|
||||
super.onSettingsChanged(settings);
|
||||
this.dynamicColor = ((ToggleWidgetSetting) settings.optionById("dynamic_color")).getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return Text.translatable("widgets.widgets.ping");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDescription() {
|
||||
return Text.translatable("widgets.widgets.ping.description");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package de.shiewk.widgets.widgets;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerCountWidget extends BasicTextWidget{
|
||||
public PlayerCountWidget(Identifier id) {
|
||||
super(id, List.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
final ClientPlayNetworkHandler networkHandler = MinecraftClient.getInstance().getNetworkHandler();
|
||||
String online = networkHandler == null ? "?" : String.valueOf(networkHandler.getPlayerUuids().size());
|
||||
this.renderText = Text.literal(Text.translatable("widgets.widgets.playerCount.online", online).getString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return Text.translatable("widgets.widgets.playerCount");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDescription() {
|
||||
return Text.translatable("widgets.widgets.playerCount.description");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package de.shiewk.widgets.widgets;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ServerInfo;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ServerIPWidget extends BasicTextWidget {
|
||||
public ServerIPWidget(Identifier id) {
|
||||
super(id, List.of());
|
||||
}
|
||||
|
||||
private int width;
|
||||
private int t = 0;
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
final ServerInfo serverEntry = MinecraftClient.getInstance().getCurrentServerEntry();
|
||||
if (serverEntry != null){
|
||||
this.renderText = Text.of(serverEntry.address);
|
||||
} else {
|
||||
this.renderText = Text.translatable("menu.singleplayer");
|
||||
}
|
||||
t++;
|
||||
if (t >= 20){
|
||||
t = 0;
|
||||
this.width = MinecraftClient.getInstance().textRenderer.getWidth(this.renderText) + 20;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int width() {
|
||||
return Math.max(super.width(), this.width);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getName() {
|
||||
return Text.translatable("widgets.widgets.serverIP");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDescription() {
|
||||
return Text.translatable("widgets.widgets.serverIP.description");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package de.shiewk.widgets.widgets.settings;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import de.shiewk.widgets.WidgetSettingOption;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class EnumWidgetSetting<T extends Enum<T>> extends WidgetSettingOption {
|
||||
|
||||
private final Class<T> enumClass;
|
||||
private T value;
|
||||
private final Function<T, Text> enumNameGetter;
|
||||
private int height = 0;
|
||||
private boolean mouseClick = false;
|
||||
private boolean changed = false;
|
||||
|
||||
public EnumWidgetSetting(String id, Text name, Class<T> enumClass, T defaultValue, Function<T, Text> enumNameGetter) {
|
||||
super(id, name);
|
||||
this.enumClass = enumClass;
|
||||
this.value = defaultValue;
|
||||
this.enumNameGetter = enumNameGetter;
|
||||
}
|
||||
|
||||
public T getValue(){
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement saveState() {
|
||||
return new JsonPrimitive(value.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(JsonElement state) {
|
||||
if (state.isJsonPrimitive() && state.getAsJsonPrimitive().isString()){
|
||||
final String name = state.getAsString();
|
||||
for (T constant : enumClass.getEnumConstants()) {
|
||||
if (constant.name().equals(name)){
|
||||
this.value = constant;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int COLOR_SELECTED = new Color(0, 0x5f, 0x68, 255).getRGB(),
|
||||
COLOR_UNSELECTED = new Color(0, 0, 0, 50).getRGB(),
|
||||
COLOR_UNSELECTED_HOVER = new Color(80, 80, 80, 50).getRGB(),
|
||||
COLOR_TEXT = new Color(255, 255, 255, 255).getRGB();
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
|
||||
int y = 0;
|
||||
int nx = 5;
|
||||
final int bx = getX() + getWidth();
|
||||
for (T constant : enumClass.getEnumConstants()) {
|
||||
final Text name = enumNameGetter.apply(constant);
|
||||
final int textRendererWidth = textRenderer.getWidth(name);
|
||||
if (nx != 5 && nx + textRendererWidth + 20 > this.getWidth()){
|
||||
y += 24;
|
||||
nx = 5;
|
||||
}
|
||||
final boolean hover = mouseX <= bx - nx && mouseX >= bx - nx - 10 - textRendererWidth && mouseY <= y + 19 + getY() && mouseY >= y + getY();
|
||||
context.fill(bx - 10 - textRendererWidth - nx, y + getY(), bx - nx, y + 19 + getY(), constant == value ? COLOR_SELECTED : hover ? COLOR_UNSELECTED_HOVER : COLOR_UNSELECTED);
|
||||
context.drawText(textRenderer, name, bx - nx - 5 - textRendererWidth, y + 5 + getY(), COLOR_TEXT, true);
|
||||
if (hover && mouseClick){
|
||||
this.value = constant;
|
||||
this.changed = true;
|
||||
}
|
||||
nx += textRendererWidth + 20;
|
||||
}
|
||||
|
||||
mouseClick = false;
|
||||
this.height = y + 34;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
mouseClick = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||
mouseClick = false;
|
||||
boolean changed = this.changed;
|
||||
this.changed = false;
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 200;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package de.shiewk.widgets.widgets.settings;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import de.shiewk.widgets.WidgetSettingOption;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class RGBAColorWidgetSetting extends WidgetSettingOption {
|
||||
public RGBAColorWidgetSetting(String id, Text name, int defaultR, int defaultG, int defaultB, int defaultAlpha) {
|
||||
super(id, name);
|
||||
this.r = defaultR;
|
||||
this.g = defaultG;
|
||||
this.b = defaultB;
|
||||
this.a = defaultAlpha;
|
||||
}
|
||||
|
||||
private int r;
|
||||
private int g;
|
||||
private int b;
|
||||
private int a;
|
||||
private boolean mouseClicked = false;
|
||||
private int sv = 0;
|
||||
|
||||
@Override
|
||||
public JsonElement saveState() {
|
||||
return new JsonPrimitive(getColor());
|
||||
}
|
||||
|
||||
public int getColor(){
|
||||
return new Color(r, g, b, a).getRGB();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(JsonElement state) {
|
||||
if (state.isJsonPrimitive() && state.getAsJsonPrimitive().isNumber()){
|
||||
final Color color = new Color(state.getAsJsonPrimitive().getAsInt(), true);
|
||||
this.r = color.getRed();
|
||||
this.g = color.getGreen();
|
||||
this.b = color.getBlue();
|
||||
this.a = color.getAlpha();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 28 + 127 + 7;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return 95;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
|
||||
int o = 0;
|
||||
for (int i = 0; i <= 255; i+=2) {
|
||||
context.drawVerticalLine(this.getX() + 5 + 7 + o, this.getY() + 5, this.getY() + 20, new Color(i, g, b, a).getRGB());
|
||||
context.drawVerticalLine(this.getX() + 5 + 7 + o, this.getY() + 25, this.getY() + 40, new Color(r, i, b, a).getRGB());
|
||||
context.drawVerticalLine(this.getX() + 5 + 7 + o, this.getY() + 45, this.getY() + 60, new Color(r, g, i, a).getRGB());
|
||||
context.drawVerticalLine(this.getX() + 5 + 7 + o, this.getY() + 65, this.getY() + 80, new Color(r, g, b, i).getRGB());
|
||||
o++;
|
||||
}
|
||||
|
||||
context.drawText(textRenderer, "R", this.getX() + 7 - textRenderer.getWidth("R"), this.getY() + 5 + 4, 0xffffff, true);
|
||||
context.drawText(textRenderer, "G", this.getX() + 7 - textRenderer.getWidth("G"), this.getY() + 25 + 4, 0xffffff, true);
|
||||
context.drawText(textRenderer, "B", this.getX() + 7 - textRenderer.getWidth("B"), this.getY() + 45 + 4, 0xffffff, true);
|
||||
context.drawText(textRenderer, "A", this.getX() + 7 - textRenderer.getWidth("A"), this.getY() + 65 + 4, 0xffffff, true);
|
||||
|
||||
context.drawText(textRenderer, String.valueOf(r), this.getX() + this.getWidth() - 19, this.getY() + 5 + 4, 0xffffff, true);
|
||||
context.drawText(textRenderer, String.valueOf(g), this.getX() + this.getWidth() - 19, this.getY() + 25 + 4, 0xffffff, true);
|
||||
context.drawText(textRenderer, String.valueOf(b), this.getX() + this.getWidth() - 19, this.getY() + 45 + 4, 0xffffff, true);
|
||||
context.drawText(textRenderer, String.valueOf(a), this.getX() + this.getWidth() - 19, this.getY() + 65 + 4, 0xffffff, true);
|
||||
|
||||
context.drawVerticalLine(this.getX() + 5 + 7 + r/2, this.getY() + 4, this.getY() + 21, 0xffffffff);
|
||||
context.drawVerticalLine(this.getX() + 5 + 7 + g/2, this.getY() + 24, this.getY() + 41, 0xffffffff);
|
||||
context.drawVerticalLine(this.getX() + 5 + 7 + b/2, this.getY() + 44, this.getY() + 61, 0xffffffff);
|
||||
context.drawVerticalLine(this.getX() + 5 + 7 + a/2, this.getY() + 64, this.getY() + 81, 0xffffffff);
|
||||
|
||||
if (mouseClicked){
|
||||
int col = MathHelper.clamp((mouseX - this.getX() - 5 - 7) * 2, 0, 255);
|
||||
if (sv == 0){
|
||||
if (mouseY > this.getY() + 5 && mouseY < this.getY() + 20){
|
||||
sv = 1;
|
||||
} else if (mouseY > this.getY() + 25 && mouseY < this.getY() + 40){
|
||||
sv = 2;
|
||||
} else if (mouseY > this.getY() + 45 && mouseY < this.getY() + 60){
|
||||
sv = 3;
|
||||
} else if (mouseY > this.getY() + 65 && mouseY < this.getY() + 80){
|
||||
sv = 4;
|
||||
}
|
||||
}
|
||||
switch (sv){
|
||||
case 1 -> r = col;
|
||||
case 2 -> g = col;
|
||||
case 3 -> b = col;
|
||||
case 4 -> a = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
this.mouseClicked = true;
|
||||
sv = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||
this.mouseClicked = false;
|
||||
final boolean c = this.sv != 0;
|
||||
this.sv = 0;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package de.shiewk.widgets.widgets.settings;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import de.shiewk.widgets.WidgetSettingOption;
|
||||
import de.shiewk.widgets.WidgetUtils;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class ToggleWidgetSetting extends WidgetSettingOption {
|
||||
|
||||
private boolean value;
|
||||
private long toggleTime = 0;
|
||||
|
||||
public ToggleWidgetSetting(String id, Text name, boolean defaultValue) {
|
||||
super(id, name);
|
||||
this.value = defaultValue;
|
||||
}
|
||||
|
||||
public boolean getValue(){
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement saveState() {
|
||||
return new JsonPrimitive(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadState(JsonElement state) {
|
||||
if (state.isJsonPrimitive() && state.getAsJsonPrimitive().isBoolean()){
|
||||
this.value = state.getAsBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
protected static final int COLOR_ENABLED = new Color(0, 255, 0, 255).getRGB(),
|
||||
COLOR_ENABLED_THUMB = new Color(0, 175, 0, 255).getRGB(),
|
||||
COLOR_DISABLED = new Color(255, 0, 0, 255).getRGB(),
|
||||
COLOR_DISABLED_THUMB = new Color(255, 200, 200, 255).getRGB();
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
int col = value ? COLOR_ENABLED : COLOR_DISABLED;
|
||||
int thumb = value ? COLOR_ENABLED_THUMB : COLOR_DISABLED_THUMB;
|
||||
int thumbLoc = (Util.getMeasuringTimeNano() - toggleTime) < 300000000f ?
|
||||
(int) (getX() + MathHelper.lerp(WidgetUtils.computeEasing((Util.getMeasuringTimeNano() - toggleTime) / 300000000f),
|
||||
value ? 2 : getWidth() - 4 - 12,
|
||||
value ? getWidth() - 4 - 12 : 2))
|
||||
: value ? getX() + getWidth() - 4 - 12 : getX() + 4;
|
||||
context.fill(getX() + 2, getY() + 2, getX() + getWidth() - 2, getY() + getHeight() - 2, col);
|
||||
context.fill(thumbLoc, getY() + 4, thumbLoc + 12, getY() + getHeight() - 4, thumb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
toggle();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void toggle(){
|
||||
this.value = !value;
|
||||
this.toggleTime = Util.getMeasuringTimeNano();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 50;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user