mejoras a interfaz 1

This commit is contained in:
retuci0 committed 2025-09-04 12:35:36 +02:00
1 parent 589279342d
commit e7d872d75e
25 files changed
+866 -212

No files matched your search

+2 -1
View File
@@ -40,4 +40,5 @@ replay_*.log
*.jfr *.jfr
todo.txt todo.txt
test.java test.java
cambios.md
+23
View File
@@ -0,0 +1,23 @@
# v1.3
## novedades
### adiciones
- barra de búsqueda: filtra los ajustes de todos los paneles de ajustes, por nombre y descripción
- barra de deslizamiento
- módulo de jugador falso: invoca una entidad de jugador falsa, por motivos de testeo
### arreglos / mejoras
- mejoras a la interfaz
- ahora el color de los widgets depende del color principal
- ahora solo se puede seleccionar un objeto de la interfaz a la vez
- cambiada la posición de los títulos de los marcos
- el color del prefijo de las notificaciones por chat ahora depende de los ajustes de color
- ya no se muestra el prefijo equivocado en notificaciones por chat al meterse a un mundo por primera vez
## problemas reconocidos
- ...
@@ -34,6 +34,7 @@ import net.fabricmc.api.ClientModInitializer;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.TitleScreen;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@@ -51,7 +52,7 @@ public class CameraTweaks implements ClientModInitializer {
public static MinecraftClient mc; public static MinecraftClient mc;
private Screen prevScreen; private Screen prevScreen;
private boolean settingsApplied = false; public boolean settingsApplied = false;
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
@@ -100,7 +101,7 @@ public class CameraTweaks implements ClientModInitializer {
public void onKeyPress(int key, int action) { public void onKeyPress(int key, int action) {
ModuleManager.INSTANCE.getEnabledModules().forEach(module -> module.onKey(key, action)); ModuleManager.INSTANCE.getEnabledModules().forEach(module -> module.onKey(key, action));
boolean anyFocused = isAnySettingButtonFocused(); boolean anyFocused = isAnySettingButtonFocused() || ClickGUI.INSTANCE.getSearchBar().isFocused();
ClickGUI.INSTANCE.setAnyFocused(anyFocused); ClickGUI.INSTANCE.setAnyFocused(anyFocused);
if (action == GLFW.GLFW_PRESS) { if (action == GLFW.GLFW_PRESS) {
@@ -150,10 +151,13 @@ public class CameraTweaks implements ClientModInitializer {
private void handleClickGUIKey(int key, boolean anyFocused) { private void handleClickGUIKey(int key, boolean anyFocused) {
if (key != ClientSettingsFrame.guiSettings.getKey() || anyFocused) return; if (key != ClientSettingsFrame.guiSettings.getKey() || anyFocused) return;
if (mc.currentScreen != ClickGUI.INSTANCE) { // al parecer esto hace que con la tecla de la interfaz puedas ir cambiando de splash text en la pantalla del título
// pero me ha hecho gracia así que así se queda
if (mc.currentScreen != ClickGUI.INSTANCE && !(mc.currentScreen instanceof TitleScreen)) {
prevScreen = mc.currentScreen; prevScreen = mc.currentScreen;
mc.setScreen(ClickGUI.INSTANCE); mc.setScreen(ClickGUI.INSTANCE);
} else { } else {
ClickGUI.INSTANCE.close();
mc.setScreen(prevScreen); mc.setScreen(prevScreen);
} }
} }
@@ -2,12 +2,14 @@ package me.retucio.camtweaks.mixin;
import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.camtweaks.module.ModuleManager; import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.modules.AntiInvis;
import me.retucio.camtweaks.module.modules.Freecam; import me.retucio.camtweaks.module.modules.Freecam;
import me.retucio.camtweaks.module.modules.Freelook; import me.retucio.camtweaks.module.modules.Freelook;
import me.retucio.camtweaks.module.modules.Nametags; import me.retucio.camtweaks.module.modules.Nametags;
import me.retucio.camtweaks.util.ChatUtil; import me.retucio.camtweaks.util.ChatUtil;
import net.minecraft.entity.*; import net.minecraft.entity.*;
import net.minecraft.entity.passive.TameableEntity; import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.PersistentProjectileEntity; import net.minecraft.entity.projectile.PersistentProjectileEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
@@ -19,6 +21,7 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import static me.retucio.camtweaks.CameraTweaks.mc; import static me.retucio.camtweaks.CameraTweaks.mc;
@@ -111,4 +114,12 @@ public abstract class EntityMixin {
if ((Object) this instanceof LivingEntity entity && entity.isBaby()) return original.copy().append(" (baby)"); if ((Object) this instanceof LivingEntity entity && entity.isBaby()) return original.copy().append(" (baby)");
return original; return original;
} }
// otros
@Inject(method = "isInvisibleTo", at = @At("RETURN"), cancellable = true)
public void renderInvisPlayers(PlayerEntity player, CallbackInfoReturnable<Boolean> cir) {
if (ModuleManager.INSTANCE.getModuleByClass(AntiInvis.class).isEnabled()) cir.setReturnValue(false);
}
} }
@@ -24,11 +24,13 @@ public class ModuleManager {
// por orden alfabético y todo, flipas // por orden alfabético y todo, flipas
private void addModules() { private void addModules() {
modules.add(new AntiInvis());
modules.add(new BlockOutline()); modules.add(new BlockOutline());
modules.add(new BossbarStack()); modules.add(new BossbarStack());
modules.add(new ChatPlus()); modules.add(new ChatPlus());
modules.add(new CritsPlus()); modules.add(new CritsPlus());
modules.add(new DamageOverlay()); modules.add(new DamageOverlay());
modules.add(new FakePlayer());
modules.add(new Freecam()); modules.add(new Freecam());
modules.add(new Freelook()); modules.add(new Freelook());
modules.add(new Fullbright()); modules.add(new Fullbright());
@@ -0,0 +1,14 @@
package me.retucio.camtweaks.module.modules;
import me.retucio.camtweaks.module.Module;
/** continúa en:
* @see me.retucio.camtweaks.mixin.EntityMixin
*/
public class AntiInvis extends Module {
public AntiInvis() {
super("anti invis", "te permite ver a los jugadores invisibles");
}
}
@@ -0,0 +1,44 @@
package me.retucio.camtweaks.module.modules;
import com.mojang.authlib.GameProfile;
import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.StringSetting;
import net.minecraft.client.network.OtherClientPlayerEntity;
import net.minecraft.entity.Entity;
import java.util.UUID;
public class FakePlayer extends Module {
public StringSetting name = addSetting(new StringSetting("nombre", "qué nombre asignarle al jugador", "apio boy", 22));
private OtherClientPlayerEntity player = null;
public FakePlayer() {
super("jugador falso", "invoca una entidad de jugador falsa por motivos de testeo");
}
@Override
public void onEnable() {
if (mc.world == null) return;
player = new OtherClientPlayerEntity(mc.world, new GameProfile(UUID.randomUUID(), name.getValue()));
// player.copyPositionAndRotation(mc.player);
player.copyFrom(mc.player);
mc.world.addEntity(player);
super.onEnable();
}
@Override
public void onDisable() {
if (mc.world == null || player == null) return;
player.setRemoved(Entity.RemovalReason.KILLED);
player.onRemoved();
player = null;
super.onDisable();
}
}
@@ -6,7 +6,6 @@ import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.TickEvent; import me.retucio.camtweaks.event.events.TickEvent;
import me.retucio.camtweaks.event.events.camtweaks.LoadClickGUIEvent; import me.retucio.camtweaks.event.events.camtweaks.LoadClickGUIEvent;
import me.retucio.camtweaks.event.events.camtweaks.LoadCommandManagerEvent; import me.retucio.camtweaks.event.events.camtweaks.LoadCommandManagerEvent;
import me.retucio.camtweaks.event.events.camtweaks.LoadModuleManagerEvent;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.ModuleManager; import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.module.settings.BooleanSetting; import me.retucio.camtweaks.module.settings.BooleanSetting;
@@ -18,24 +17,32 @@ import org.lwjgl.glfw.GLFW;
import java.awt.*; import java.awt.*;
import static me.retucio.camtweaks.CameraTweaks.LOGGER;
import static me.retucio.camtweaks.util.Colors.*;
// módulo no visible solo para los ajustes de la interfaz (y del cliente en general) // módulo no visible solo para los ajustes de la interfaz (y del cliente en general)
public class GUI extends Module { public class GUI extends Module {
public BooleanSetting rainbow = addSetting(new BooleanSetting("gaming", "gaming", false)); public BooleanSetting rainbow = addSetting(new BooleanSetting("gaming", "gaming", false));
public NumberSetting rainbowSpeed = addSetting(new NumberSetting("velocidad del gaming", "velocidad, del gaming.", public NumberSetting rainbowSpeed = addSetting(new NumberSetting("velocidad del gaming", "velocidad, del gaming.",
1000, 0, 10000, 2)); 1000, 0, 10000, 2));
public NumberSetting saturation = addSetting(new NumberSetting("saturación del gaming", "saturación, del gaming",
1, 0, 1, 0.01));
public NumberSetting brightness = addSetting(new NumberSetting("brillo del gaming", "brillo, del gaming",
0.8, 0, 1, 0.01));
public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo en el RGB del marco", 0, 0, 255, 1)); public NumberSetting red = addSetting(new NumberSetting("rojo", "cantidad de rojo en el RGB del marco", 70, 0, 255, 1));
public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde en el RGB del marco", 0, 0, 255, 1)); public NumberSetting green = addSetting(new NumberSetting("verde", "cantidad de verde en el RGB del marco", 20, 0, 255, 1));
public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul en el RGB del marco", 255, 0, 255, 1)); public NumberSetting blue = addSetting(new NumberSetting("azul", "cantidad de azul en el RGB del marco", 210, 0, 255, 1));
public NumberSetting alpha = addSetting(new NumberSetting("alpha", "opacidad del marco", 180, 0, 255, 1)); public NumberSetting alpha = addSetting(new NumberSetting("alpha", "opacidad del marco", 230, 0, 255, 1));
// números negativos para deslizamiento inverso, 0 para desactivar // números negativos para deslizamiento inverso, 0 para desactivar
public NumberSetting scrollSens = addSetting(new NumberSetting("sensibilidad del scroll", "qué tan sensible es la interfaz a la rueda del ratón", public NumberSetting scrollSens = addSetting(new NumberSetting("sensibilidad del scroll", "qué tan sensible es la interfaz a la rueda del ratón",
5, -15, 15, 0.5)); 5, -15, 15, 0.5));
public BooleanSetting scrollBar = addSetting(new BooleanSetting("barra de desplazamiento", "renderizar una barra de desplazamiento a la derecha de la interfaz", true));
public BooleanSetting searchBar = addSetting(new BooleanSetting("barra de búsqueda", "renderizar una barra de búsqueda que filtra resultados en todos los marcos abiertos", true));
public BooleanSetting matchCase = addSetting(new BooleanSetting("distinguir mayúsculas", "la búsqueda es sensible a mayúsculas y minúsculas", false));
// ^^^ no sé de qué sirve porque está todo en minúsculas pero bueno
public BooleanSetting blur = addSetting(new BooleanSetting("desenfoque", "desenfocar el fondo mientras la interfaz está abierta", true));
public StringSetting commandPrefix = addSetting(new StringSetting("prefijo", "prefijo de los comandos", "$", 10)); public StringSetting commandPrefix = addSetting(new StringSetting("prefijo", "prefijo de los comandos", "$", 10));
public StringSetting chatName = addSetting(new StringSetting("nombre", "qué nombre usar en notificaciones por el chat", "smegma", 20)); public StringSetting chatName = addSetting(new StringSetting("nombre", "qué nombre usar en notificaciones por el chat", "smegma", 20));
@@ -53,6 +60,8 @@ public class GUI extends Module {
keyMode.setVisible(false); keyMode.setVisible(false);
notify.setVisible(false); notify.setVisible(false);
searchBar.onUpdate(v -> matchCase.setVisible(v));
} }
@SubscribeEvent @SubscribeEvent
@@ -81,6 +90,8 @@ public class GUI extends Module {
} }
rainbowSpeed.setVisible(v); rainbowSpeed.setVisible(v);
saturation.setVisible(v);
brightness.setVisible(v);
red.setVisible(!v); red.setVisible(!v);
green.setVisible(!v); green.setVisible(!v);
blue.setVisible(!v); blue.setVisible(!v);
@@ -99,30 +110,30 @@ public class GUI extends Module {
if (rainbow.isEnabled()) { if (rainbow.isEnabled()) {
float speed = (float) (rainbowSpeed.getMax() - rainbowSpeed.getValue()); float speed = (float) (rainbowSpeed.getMax() - rainbowSpeed.getValue());
float hue = (System.currentTimeMillis() % (long) speed) / speed; float hue = (System.currentTimeMillis() % (long) speed) / speed;
Color color = Color.getHSBColor(hue, 1f, 1f); Color color = Color.getHSBColor(hue, saturation.getFloatValue(), brightness.getFloatValue());
frameHeadRed = color.getRed(); Colors.red = color.getRed();
frameHeadGreen = color.getGreen(); Colors.green = color.getGreen();
frameHeadBlue = color.getBlue(); Colors.blue = color.getBlue();
updateFrameHeadColor(); updateColor();
} }
} }
private void applyRGBAColorUpdates() { private void applyRGBAColorUpdates() {
frameHeadRed = red.getIntValue(); Colors.red = red.getIntValue();
frameHeadGreen = green.getIntValue(); Colors.green = green.getIntValue();
frameHeadBlue = blue.getIntValue(); Colors.blue = blue.getIntValue();
frameHeadAlpha = alpha.getIntValue(); Colors.alpha = alpha.getIntValue();
updateFrameHeadColor(); updateColor();
} }
private void updateFrameHeadColor() { private void updateColor() {
Colors.frameHeadColor = new Color( Colors.updateAllColors(new Color(
frameHeadRed, Colors.red,
frameHeadGreen, Colors.green,
frameHeadBlue, Colors.blue,
frameHeadAlpha Colors.alpha
).getRGB(); ));
} }
} }
@@ -9,7 +9,9 @@ public abstract class AbstractSetting {
private final String name; private final String name;
private final String description; private final String description;
private boolean visible = true; private boolean visible = true;
private boolean searchMatch = true;
private Module module; private Module module;
@@ -26,6 +28,14 @@ public abstract class AbstractSetting {
this.visible = visible; this.visible = visible;
} }
public boolean isSearchMatch() {
return searchMatch;
}
public void setSearchMatch(boolean searchMatch) {
this.searchMatch = searchMatch;
}
public String getName() { public String getName() {
return name; return name;
} }
@@ -2,16 +2,22 @@ package me.retucio.camtweaks.ui;
import me.retucio.camtweaks.CameraTweaks; import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.SubscribeEvent; import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.KeyEvent;
import me.retucio.camtweaks.event.events.MouseClickEvent; import me.retucio.camtweaks.event.events.MouseClickEvent;
import me.retucio.camtweaks.event.events.MouseScrollEvent; import me.retucio.camtweaks.event.events.MouseScrollEvent;
import me.retucio.camtweaks.event.events.camtweaks.SettingsFrameEvent; import me.retucio.camtweaks.event.events.camtweaks.SettingsFrameEvent;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.settings.AbstractSetting;
import me.retucio.camtweaks.ui.buttons.ListButton; import me.retucio.camtweaks.ui.buttons.ListButton;
import me.retucio.camtweaks.ui.buttons.SettingButton; import me.retucio.camtweaks.ui.buttons.SettingButton;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame; import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.ui.frames.ModuleFrame; import me.retucio.camtweaks.ui.frames.ModuleFrame;
import me.retucio.camtweaks.ui.frames.SettingsFrame; import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.ui.widgets.ScrollBarWidget;
import me.retucio.camtweaks.ui.widgets.SearchBarWidget;
import me.retucio.camtweaks.util.ChatUtil;
import me.retucio.camtweaks.util.KeyUtil; import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@@ -27,11 +33,17 @@ public class ClickGUI extends Screen {
public static ClickGUI INSTANCE; public static ClickGUI INSTANCE;
private boolean anyFocused; private boolean anyFocused;
private Object selected = null;
private final ModuleFrame modulesFrame = new ModuleFrame(20, 30, 100, 20); private final ModuleFrame modulesFrame = new ModuleFrame(20, 30, 100, 20);
private final List<SettingsFrame> settingsFrames = new ArrayList<>(); private final List<SettingsFrame> settingsFrames = new ArrayList<>();
private final ClientSettingsFrame guiSettingsFrame = new ClientSettingsFrame(200, 30, 100, 20); private final ClientSettingsFrame guiSettingsFrame = new ClientSettingsFrame(200, 30, 100, 20);
private final ScrollBarWidget scrollBar = new ScrollBarWidget();
private final SearchBarWidget searchBar = new SearchBarWidget(340, 16, 300, 20);
private final MinecraftClient mc = MinecraftClient.getInstance();
public ClickGUI() { public ClickGUI() {
super(Text.of("interfaz")); super(Text.of("interfaz"));
settingsFrames.add(guiSettingsFrame); settingsFrames.add(guiSettingsFrame);
@@ -40,6 +52,21 @@ public class ClickGUI extends Screen {
@Override @Override
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) { public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
scrollBar.setWindowHeight(mc.getWindow().getScaledHeight());
scrollBar.setContentHeight(calculateContentHeight());
scrollBar.render(ctx, mouseX, mouseY);
int scrollOffset = scrollBar.getScrollOffset();
searchBar.updateRenderY(scrollOffset);
searchBar.render(ctx, mouseX, mouseY, delta);
searchBar.updatePosition(mouseX, mouseY);
// actualizar la posición de renderizado vertical de los marcos cada tick
modulesFrame.updateRenderY(scrollOffset);
for (SettingsFrame sf : settingsFrames)
sf.updateRenderY(scrollOffset);
// renderizar el marco de los ajustes de cada módulo que lo tenga abierto. se abre haciendo clic derecho sobre el módulo // renderizar el marco de los ajustes de cada módulo que lo tenga abierto. se abre haciendo clic derecho sobre el módulo
for (SettingsFrame sf : settingsFrames.reversed()) { for (SettingsFrame sf : settingsFrames.reversed()) {
sf.render(ctx, mouseX, mouseY, delta); sf.render(ctx, mouseX, mouseY, delta);
@@ -50,11 +77,27 @@ public class ClickGUI extends Screen {
modulesFrame.render(ctx, mouseX, mouseY, delta); modulesFrame.render(ctx, mouseX, mouseY, delta);
modulesFrame.updatePosition(mouseX, mouseY); modulesFrame.updatePosition(mouseX, mouseY);
for (SettingsFrame sf : settingsFrames)
sf.drawTooltips(ctx, mouseX, mouseY);
filterSearchResults();
super.render(ctx, mouseX, mouseY, delta); super.render(ctx, mouseX, mouseY, delta);
} }
private int calculateContentHeight() {
int bottom = modulesFrame.y + modulesFrame.h + modulesFrame.totalHeight;
for (SettingsFrame frame : settingsFrames)
bottom = Math.max(bottom, frame.y + frame.h + frame.totalHeight);
return bottom + 20; // padding
}
@Override @Override
public boolean mouseClicked(double mouseX, double mouseY, int button) { public boolean mouseClicked(double mouseX, double mouseY, int button) {
scrollBar.mouseClicked(mouseX, mouseY, button);
searchBar.mouseClicked(mouseX, mouseY, button);
// detectar clics sobre los marcos // detectar clics sobre los marcos
modulesFrame.mouseClicked(mouseX, mouseY, button); modulesFrame.mouseClicked(mouseX, mouseY, button);
for (SettingsFrame sf : new ArrayList<>(settingsFrames)) for (SettingsFrame sf : new ArrayList<>(settingsFrames))
@@ -65,6 +108,9 @@ public class ClickGUI extends Screen {
@Override @Override
public boolean mouseReleased(double mouseX, double mouseY, int button) { public boolean mouseReleased(double mouseX, double mouseY, int button) {
scrollBar.mouseReleased(mouseX, mouseY, button);
searchBar.mouseReleased(mouseX, mouseY, button);
// registrar cuándo se suelta el clic, en cada marco respectivamente // registrar cuándo se suelta el clic, en cada marco respectivamente
modulesFrame.mouseReleased(mouseX, mouseY, button); modulesFrame.mouseReleased(mouseX, mouseY, button);
for (SettingsFrame sf : new ArrayList<>(settingsFrames)) for (SettingsFrame sf : new ArrayList<>(settingsFrames))
@@ -72,14 +118,21 @@ public class ClickGUI extends Screen {
return super.mouseReleased(mouseX, mouseY, button); return super.mouseReleased(mouseX, mouseY, button);
} }
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
scrollBar.mouseDragged(mouseY);
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
@SubscribeEvent
public void onKey(KeyEvent event) {
searchBar.onKey(event.getKey(), event.getAction());
}
@SubscribeEvent @SubscribeEvent
public void onMouseScroll(MouseScrollEvent event) { public void onMouseScroll(MouseScrollEvent event) {
// subir y bajar la pantalla con la rueda del ratón // subir y bajar la pantalla con la rueda del ratón
if (CameraTweaks.mc.currentScreen != this) return; scrollBar.onMouseScroll(event.getVertical() * guiSettings.scrollSens.getValue());
modulesFrame.y += (int) (event.getVertical() * guiSettings.scrollSens.getValue());
for (SettingsFrame sf : settingsFrames)
sf.y += (int) (event.getVertical() * guiSettings.scrollSens.getValue());
} }
@SubscribeEvent @SubscribeEvent
@@ -91,12 +144,40 @@ public class ClickGUI extends Screen {
int minY = Math.min(modulesFrame.y, settingsFrames.stream().mapToInt(sf -> sf.y).min().orElse(modulesFrame.y)); int minY = Math.min(modulesFrame.y, settingsFrames.stream().mapToInt(sf -> sf.y).min().orElse(modulesFrame.y));
int maxY = Math.max(modulesFrame.y + modulesFrame.h, settingsFrames.stream().mapToInt(sf -> sf.y + sf.h).max().orElse(modulesFrame.y + modulesFrame.h)); int maxY = Math.max(modulesFrame.y + modulesFrame.h, settingsFrames.stream().mapToInt(sf -> sf.y + sf.h).max().orElse(modulesFrame.y + modulesFrame.h));
int correction = minY < 0 ? -minY + 4 : (maxY > h ? h - maxY - 4 : 0); int correction = minY < 0 ? -minY + 4 : (maxY > h ? h - maxY - 4 : 0);
if (correction != 0) { if (correction != 0) {
modulesFrame.y += correction; modulesFrame.y += correction;
settingsFrames.forEach(sf -> sf.y += correction); settingsFrames.forEach(sf -> sf.y += correction);
} }
} }
public void filterSearchResults() {
if (!guiSettings.searchBar.isEnabled()) return;
String searchInput = searchBar.getSearchInput().trim();
if (!guiSettings.matchCase.isEnabled()) searchInput = searchInput.toLowerCase();
for (SettingsFrame sf : settingsFrames) {
for (SettingButton sb : sf.getButtons()) {
AbstractSetting setting = sb.getSetting();
if (searchInput.isEmpty()) {
setting.setSearchMatch(true);
continue;
}
String name = setting.getName();
String description = setting.getDescription();
if (!guiSettings.matchCase.isEnabled()) {
name = name.toLowerCase();
description = description.toLowerCase();
}
setting.setSearchMatch(name.contains(searchInput) || description.contains(searchInput));
}
}
}
public void openSettingsFrame(Module module, int x, int y) { public void openSettingsFrame(Module module, int x, int y) {
// abrir un marco donde se encuentran los ajustes del módulo deseado // abrir un marco donde se encuentran los ajustes del módulo deseado
if (isSettingsFrameOpen(module)) return; // permitir un solo marco de ajustes por módulo if (isSettingsFrameOpen(module)) return; // permitir un solo marco de ajustes por módulo
@@ -119,6 +200,7 @@ public class ClickGUI extends Screen {
if (sf.module == module) { if (sf.module == module) {
CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Close(sf)); CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Close(sf));
toRemove.add(sf); toRemove.add(sf);
unselect(sf);
} }
} }
settingsFrames.removeAll(toRemove); settingsFrames.removeAll(toRemove);
@@ -130,6 +212,8 @@ public class ClickGUI extends Screen {
.anyMatch(sf -> sf.module.getName().equals(module.getName())); .anyMatch(sf -> sf.module.getName().equals(module.getName()));
} }
public void refreshListButtons() { public void refreshListButtons() {
for (SettingsFrame frame : settingsFrames) for (SettingsFrame frame : settingsFrames)
for (SettingButton button : frame.getButtons()) for (SettingButton button : frame.getButtons())
@@ -137,12 +221,39 @@ public class ClickGUI extends Screen {
lb.refreshDummy(); lb.refreshDummy();
} }
// no pausar el juego cuando se abre la interfaz
// métodos del súper
@Override
public void close() { // evitar que al reabrir la interfaz sin previamente haber soltado el clic, se sigan arrastrando objetos
modulesFrame.mouseReleased(0, 0, 0);
settingsFrames.forEach(sf -> sf.mouseRelease(0, 0, 0));
scrollBar.mouseReleased(0, 0, 0);
searchBar.mouseReleased(0, 0, 0);
unselect(selected);
super.close();
}
@Override @Override
public boolean shouldPause() { public boolean shouldPause() {
// no pausar el juego cuando se abre la interfaz
return false; return false;
} }
@Override
public boolean shouldCloseOnEsc() {
return super.shouldCloseOnEsc() && !anyFocused;
}
@Override
protected void applyBlur(DrawContext context) {
if (guiSettings.blur.isEnabled()) super.applyBlur(context);
}
// getters y setters de widgets
public ModuleFrame getModulesFrame() { public ModuleFrame getModulesFrame() {
return modulesFrame; return modulesFrame;
} }
@@ -151,16 +262,42 @@ public class ClickGUI extends Screen {
return guiSettingsFrame; return guiSettingsFrame;
} }
public List<SettingsFrame> getSettingsFrames() {
return settingsFrames;
}
public SearchBarWidget getSearchBar() {
return searchBar;
}
public void setAnyFocused(boolean anyFocused) { public void setAnyFocused(boolean anyFocused) {
this.anyFocused = anyFocused; this.anyFocused = anyFocused;
} }
@Override
public boolean shouldCloseOnEsc() { // selección de widgets
return super.shouldCloseOnEsc() && !anyFocused;
public Object getSelected() {
return selected;
} }
public List<SettingsFrame> getSettingsFrames() { public void setSelected(Object object) {
return settingsFrames; this.selected = object;
}
public boolean canSelect(Object object) {
return getSelected() == null || getSelected() == object;
}
public boolean trySelect(Object object) {
if (canSelect(object)) {
setSelected(object);
return true;
}
return false;
}
public void unselect(Object object) {
if (selected == object) setSelected(null);
} }
} }
@@ -1,6 +1,7 @@
package me.retucio.camtweaks.ui.buttons; package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.KeySetting; import me.retucio.camtweaks.module.settings.KeySetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame; import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors; import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil; import me.retucio.camtweaks.util.KeyUtil;
@@ -23,23 +24,17 @@ public class BindButton extends SettingButton {
@Override @Override
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) { public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
int bgColor = isHovered((int) mouseX, (int) mouseY) int bgColor = isHovered((int) mouseX, (int) mouseY)
? Colors.hoveredSettingButtonColor ? Colors.buttonColor.brighter().getRGB()
: Colors.settingButtonColor; : Colors.buttonColor.getRGB();
ctx.fill(x, y, x + w, y + height, bgColor); ctx.fill(x, y, x + w, y + h, bgColor);
String label = setting.getName() + ": " + (listening ? "..." : setting.getKeyName()); String label = setting.getName() + ": " + (listening ? "..." : setting.getKeyName());
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true); ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
if (isHovered((int) mouseX, (int) mouseY)) {
Screen currentScreen = parent.mc.currentScreen;
if (currentScreen != null)
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
}
} }
@Override @Override
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY)) { if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) listening = !listening; if (button == 0) listening = !listening;
else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT))
setting.reset(); setting.reset();
@@ -67,5 +62,7 @@ public class BindButton extends SettingButton {
} }
@Override @Override
public void mouseReleased(double mouseX, double mouseY, int button) {} public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
}
} }
@@ -1,6 +1,7 @@
package me.retucio.camtweaks.ui.buttons; package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.EnumSetting; import me.retucio.camtweaks.module.settings.EnumSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame; import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors; import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil; import me.retucio.camtweaks.util.KeyUtil;
@@ -26,16 +27,18 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
@Override @Override
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) { public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
int bgColor = isHovered((int) mouseX, (int) mouseY) int bgColor = isHovered((int) mouseX, (int) mouseY)
? Colors.hoveredSettingButtonColor ? Colors.buttonColor.brighter().getRGB()
: Colors.settingButtonColor; : Colors.buttonColor.getRGB();
ctx.fill(x, y, x + w, y + height, bgColor); // fondo del botón ctx.fill(x, y, x + w, y + h, bgColor); // fondo del botón
// texto del botón: nombre + valor de texto del enum // texto del botón: nombre + valor de texto del enum
String label = setting.getName() + ": " + setting.getValue().toString(); String label = setting.getName() + ": " + setting.getValue().toString();
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true); ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
}
// tooltip @Override
public void drawTooltip(DrawContext ctx, double mouseX, double mouseY) {
if (isHovered((int) mouseX, (int) mouseY)) { if (isHovered((int) mouseX, (int) mouseY)) {
Screen currentScreen = parent.mc.currentScreen; Screen currentScreen = parent.mc.currentScreen;
if (currentScreen != null) { if (currentScreen != null) {
@@ -56,10 +59,9 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
} }
} }
@Override @Override
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY)) { if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) { if (button == 0) {
setting.cycle(); // clic izquierdo -> ciclar setting.cycle(); // clic izquierdo -> ciclar
} else if (button == 1) { } else if (button == 1) {
@@ -67,7 +69,7 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT))
setting.reset(); setting.reset();
else else
setting.cycleBackwards(); // simplemente clic derecho -> ciclar valores pero hacia atrás setting.cycleBackwards(); // solamente clic derecho -> ciclar valores pero hacia atrás
} }
} }
} }
@@ -77,5 +79,7 @@ public class CycleButton<E extends Enum<E>> extends SettingButton {
} }
@Override @Override
public void mouseReleased(double mouseX, double mouseY, int button) {} public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
}
} }
@@ -8,6 +8,7 @@ import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors; import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil; import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.*; import java.util.*;
@@ -45,18 +46,24 @@ public class ListButton<T> extends SettingButton {
@Override @Override
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) { public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
int bgColor = isHovered(mouseX, mouseY) int bgColor = isHovered(mouseX, mouseY)
? Colors.hoveredSettingButtonColor ? Colors.buttonColor.brighter().getRGB()
: Colors.settingButtonColor; : Colors.buttonColor.getRGB();
ctx.fill(x, y, x + w, y + height, bgColor); ctx.fill(x, y, x + w, y + h, bgColor);
String label = setting.getName() + " (" + countEnabled() + "/" + setting.getOptions().size() + ")"; String label = setting.getName() + " (" + countEnabled() + "/" + setting.getOptions().size() + ")";
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true); ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
} }
@Override
public void drawTooltip(DrawContext ctx, double mouseX, double mouseY) {
if (isHovered(mouseX, mouseY))
ctx.drawTooltip(Text.of(setting.getDescription() + "( " + countEnabled() + " de " + setting.getOptions().size() + ")"), (int) mouseX, (int) mouseY);
}
@Override @Override
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered(mouseX, mouseY)) { if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
// click izquierdo / derecho: abrir marco // click izquierdo / derecho: abrir marco
if (button <= 1 && !KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) { if (button <= 1 && !KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) {
if (ClickGUI.INSTANCE.isSettingsFrameOpen(dummy)) { if (ClickGUI.INSTANCE.isSettingsFrameOpen(dummy)) {
@@ -106,5 +113,7 @@ public class ListButton<T> extends SettingButton {
} }
@Override @Override
public void mouseReleased(double mouseX, double mouseY, int button) {} public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
}
} }
@@ -24,44 +24,51 @@ public class ModuleButton {
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) { public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
ctx.fill( // dibujar el contorno del botón ctx.fill( // dibujar el contorno del botón
parent.x + 2, parent.y + offset + 3, parent.x + 2, parent.renderY + offset + 3,
parent.x + parent.w - 2 , parent.y + height + offset, parent.x + parent.w - 2 , parent.renderY + height + offset,
determineColor(mouseX, mouseY)); determineColor(mouseX, mouseY));
ctx.drawText( // dibujar el nombre del módulo ctx.drawText( // dibujar el nombre del módulo
parent.mc.textRenderer, module.getName(), parent.mc.textRenderer, module.getName(),
parent.x + 5, parent.y + offset + (height / 2) - (parent.mc.textRenderer.fontHeight / 2) + 2, parent.x + 5, parent.renderY + offset + (height / 2) - (parent.mc.textRenderer.fontHeight / 2) + 2,
-1, true); -1, true);
// dibujar "tooltips" (cajas de texto) al pasar el puntero encima del botón, para mostrar su descripción // dibujar "tooltips" (cajas de texto) al pasar el puntero encima del botón, para mostrar su descripción
if (isHovered((int) mouseX, (int) mouseY)) { if (isHovered((int) mouseX, (int) mouseY))
Screen currentScreen = parent.mc.currentScreen; ctx.drawTooltip(Text.of(module.getDescription()), (int) mouseX, (int) mouseY + 20);
if (currentScreen != null)
ctx.drawTooltip(Text.of(module.getDescription()), (int) mouseX, (int) mouseY + 20);
}
} }
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
if (button == 0) {// clic izquierdo para activar / desactivar el módulo if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
module.toggle(); if (button == 0) { // clic izquierdo para activar / desactivar el módulo
} else if (button == 1) { // clic derecho para el marco de ajustes (también lo cierra si está abierto) module.toggle();
if (ClickGUI.INSTANCE.isSettingsFrameOpen(module)) } else if (button == 1) { // clic derecho para el marco de ajustes (también lo cierra si está abierto)
ClickGUI.INSTANCE.closeSettingsFrame(module); if (ClickGUI.INSTANCE.isSettingsFrameOpen(module))
else ClickGUI.INSTANCE.closeSettingsFrame(module);
ClickGUI.INSTANCE.openSettingsFrame(module, else
parent.x + parent.w + 120, parent.y + offset); ClickGUI.INSTANCE.openSettingsFrame(module,
parent.x + parent.w + 120, parent.renderY + offset);
}
} }
} }
public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
}
// verifica si el puntero del ratón se encuentra sobre el botón del módulo // verifica si el puntero del ratón se encuentra sobre el botón del módulo
public boolean isHovered(int mouseX, int mouseY) { public boolean isHovered(int mouseX, int mouseY) {
return mouseX > parent.x && mouseX < parent.x + parent.w && mouseY > parent.y + offset && mouseY < parent.y + height + offset; return ClickGUI.INSTANCE.canSelect(this)
&& mouseX > parent.x
&& mouseX < parent.x + parent.w
&& mouseY > parent.renderY + offset
&& mouseY < parent.renderY + height + offset;
} }
public int determineColor(double mouseX, double mouseY) { public int determineColor(double mouseX, double mouseY) {
// determina el color del botón, dependiendo de si está el puntero encima y si está activado // determina el color del botón, dependiendo de si está el puntero encima y si está activado
if (module.isEnabled()) if (module.isEnabled())
return isHovered((int) mouseX, (int) mouseY) ? Colors.enabledHoveredModuleButtonColor : Colors.enabledModuleButtonColor; return isHovered((int) mouseX, (int) mouseY) ? Colors.mainColor.brighter().getRGB() : Colors.mainColor.getRGB();
return isHovered((int) mouseX, (int) mouseY) ? Colors.hoveredModuleButtonColor : Colors.moduleButtonColor; return isHovered((int) mouseX, (int) mouseY) ? Colors.buttonColor.brighter().getRGB() : Colors.buttonColor.getRGB();
} }
} }
@@ -1,8 +1,11 @@
package me.retucio.camtweaks.ui.buttons; package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.AbstractSetting; import me.retucio.camtweaks.module.settings.AbstractSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame; import me.retucio.camtweaks.ui.frames.SettingsFrame;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
// clase base para los botones de los ajustes // clase base para los botones de los ajustes
public abstract class SettingButton { public abstract class SettingButton {
@@ -10,7 +13,6 @@ public abstract class SettingButton {
protected final AbstractSetting setting; protected final AbstractSetting setting;
protected final SettingsFrame parent; protected final SettingsFrame parent;
protected int offset; protected int offset;
protected final int height = 15;
protected int x, y, w, h; protected int x, y, w, h;
@@ -24,11 +26,18 @@ public abstract class SettingButton {
public abstract void mouseClicked(double mouseX, double mouseY, int button); public abstract void mouseClicked(double mouseX, double mouseY, int button);
public abstract void mouseReleased(double mouseX, double mouseY, int button); public abstract void mouseReleased(double mouseX, double mouseY, int button);
// dibujar "tooltips" (cajitas de texto bajo el puntero del ratón) con la descripción para asistir al usuario en el caso de que tenga down
public void drawTooltip(DrawContext ctx, double mouseX, double mouseY) {
if (isHovered((int) mouseX, (int) mouseY))
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
}
protected boolean isHovered(double mouseX, double mouseY) { protected boolean isHovered(double mouseX, double mouseY) {
return isHovered((int) mouseX, (int) mouseY); return isHovered((int) mouseX, (int) mouseY);
} }
protected boolean isHovered(int mouseX, int mouseY) { protected boolean isHovered(int mouseX, int mouseY) {
if (!ClickGUI.INSTANCE.canSelect(this)) return false;
return mouseX > x && mouseX < x + w && return mouseX > x && mouseX < x + w &&
mouseY > y && mouseY < y + h; mouseY > y && mouseY < y + h;
} }
@@ -3,6 +3,7 @@ package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.event.SubscribeEvent; import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.KeyEvent; import me.retucio.camtweaks.event.events.KeyEvent;
import me.retucio.camtweaks.module.settings.NumberSetting; import me.retucio.camtweaks.module.settings.NumberSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame; import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.ui.frames.SettingsFrame; import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors; import me.retucio.camtweaks.util.Colors;
@@ -12,6 +13,7 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.awt.*;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS; import static me.retucio.camtweaks.CameraTweaks.EVENT_BUS;
@@ -32,12 +34,20 @@ public class SliderButton extends SettingButton {
@Override @Override
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) { public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
ctx.fill(x, y, x + w, y + height, Colors.moduleButtonColor); Color bgColor = Colors.buttonColor;
Color fillingColor = Colors.mainColor;
// calcular cómo de llena tendría que estar el "slider" if (isHovered(mouseX, mouseY)) {
bgColor = bgColor.brighter();
fillingColor = fillingColor.brighter();
}
ctx.fill(x, y, x + w, y + h, bgColor.getRGB());
// calcular cómo de lleno tendría que estar el "slider"
double percent = (setting.getValue() - setting.getMin()) / (setting.getMax() - setting.getMin()); double percent = (setting.getValue() - setting.getMin()) / (setting.getMax() - setting.getMin());
int filled = (int) (percent * w); int filled = (int) (percent * w);
ctx.fill(x, y, x + filled, y + height, Colors.sliderFillingColor); ctx.fill(x, y, x + filled, y + h, fillingColor.getRGB());
String label = setting.getName() + ": " + df.format(setting.getValue()); String label = setting.getName() + ": " + df.format(setting.getValue());
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true); ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
@@ -49,18 +59,11 @@ public class SliderButton extends SettingButton {
newVal = Math.round(newVal / setting.getIncrement()) * setting.getIncrement(); newVal = Math.round(newVal / setting.getIncrement()) * setting.getIncrement();
setting.setValue((float) newVal); setting.setValue((float) newVal);
} }
// dibujar "tooltips" (cajas de texto) al pasar el puntero encima del botón, para mostrar su descripción
if (isHovered((int) mouseX, (int) mouseY)) {
Screen currentScreen = parent.mc.currentScreen;
if (currentScreen != null)
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
}
} }
@Override @Override
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY)) { if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) dragging = true; // arrastrar con el clic izquierdo if (button == 0) dragging = true; // arrastrar con el clic izquierdo
else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) // restablecer al valor por defecto con shift izquerdo + clic derecho else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) // restablecer al valor por defecto con shift izquerdo + clic derecho
setting.reset(); setting.reset();
@@ -69,6 +72,7 @@ public class SliderButton extends SettingButton {
@Override @Override
public void mouseReleased(double mouseX, double mouseY, int button) { public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
if (button == 0) dragging = false; if (button == 0) dragging = false;
} }
@@ -1,6 +1,7 @@
package me.retucio.camtweaks.ui.buttons; package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.StringSetting; import me.retucio.camtweaks.module.settings.StringSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame; import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors; import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil; import me.retucio.camtweaks.util.KeyUtil;
@@ -8,6 +9,8 @@ import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import static me.retucio.camtweaks.CameraTweaks.mc;
// botón para los ajustes que requieran introducir texto // botón para los ajustes que requieran introducir texto
public class TextButton extends SettingButton { public class TextButton extends SettingButton {
@@ -23,23 +26,18 @@ public class TextButton extends SettingButton {
@Override @Override
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) { public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
int bgColor = isHovered((int) mouseX, (int) mouseY) int bgColor = isHovered((int) mouseX, (int) mouseY)
? Colors.hoveredSettingButtonColor ? Colors.buttonColor.brighter().getRGB()
: Colors.settingButtonColor; : Colors.buttonColor.getRGB();
ctx.fill(x, y, x + w, y + height, bgColor); ctx.fill(x, y, x + w, y + h, bgColor);
String label = setting.getName() + ": " + (typing ? buffer + "_" : setting.getValue()); String label = setting.getName() + ": " + (typing ? buffer + "_" : setting.getValue());
ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true); ctx.drawText(parent.mc.textRenderer, label, x + 5, y + 3, -1, true);
if (isHovered((int) mouseX, (int) mouseY)) {
if (parent.mc.currentScreen != null)
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
}
} }
@Override @Override
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY)) { if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) { if (button == 0) {
typing = true; typing = true;
buffer.setLength(0); buffer.setLength(0);
@@ -53,6 +51,11 @@ public class TextButton extends SettingButton {
} }
} }
@Override
public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
}
public void onKey(int key, int action) { public void onKey(int key, int action) {
if (!typing || action == GLFW.GLFW_RELEASE) return; if (!typing || action == GLFW.GLFW_RELEASE) return;
@@ -79,6 +82,7 @@ public class TextButton extends SettingButton {
private void charTyped(char c) { private void charTyped(char c) {
if (!typing) return; if (!typing) return;
buffer.append(c); buffer.append(c);
if (mc.textRenderer.getWidth(setting.getName() + ": " + buffer + "_") > w - 8) onBackspace();
} }
public boolean isFocused() { public boolean isFocused() {
@@ -92,7 +96,4 @@ public class TextButton extends SettingButton {
private void onBackspace() { private void onBackspace() {
if (!buffer.isEmpty()) buffer.deleteCharAt(buffer.length() - 1); if (!buffer.isEmpty()) buffer.deleteCharAt(buffer.length() - 1);
} }
@Override
public void mouseReleased(double mouseX, double mouseY, int button) {}
} }
@@ -1,6 +1,7 @@
package me.retucio.camtweaks.ui.buttons; package me.retucio.camtweaks.ui.buttons;
import me.retucio.camtweaks.module.settings.BooleanSetting; import me.retucio.camtweaks.module.settings.BooleanSetting;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.frames.SettingsFrame; import me.retucio.camtweaks.ui.frames.SettingsFrame;
import me.retucio.camtweaks.util.Colors; import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil; import me.retucio.camtweaks.util.KeyUtil;
@@ -28,33 +29,27 @@ public class ToggleButton extends SettingButton {
: Colors.disabledToggleButtonColor; : Colors.disabledToggleButtonColor;
if (isHovered((int) mouseX, (int) mouseY)) if (isHovered((int) mouseX, (int) mouseY))
color = color.brighter(); // simplemente utilizar el método "built-in" de Java para hacer el botón más claro cuando el puntero se encuentra encima de él color = color.brighter();
// quizás debería de utilizar .brighter() más, en vez de dar valores personalizados
ctx.fill(x, y, x + w, y + height, color.getRGB()); ctx.fill(x, y, x + w, y + h, color.getRGB());
ctx.drawText(parent.mc.textRenderer, setting.getName(), x + 5, y + 3, -1, true); ctx.drawText(parent.mc.textRenderer, setting.getName(), x + 5, y + 3, -1, true);
// dibujar "tooltips" (cajas de texto) al pasar el puntero encima del botón, para mostrar su descripción
if (isHovered((int) mouseX, (int) mouseY)) {
Screen currentScreen = parent.mc.currentScreen;
if (currentScreen != null)
ctx.drawTooltip(Text.of(setting.getDescription()), (int) mouseX, (int) mouseY + 20);
}
} }
@Override @Override
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY)) { if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) setting.toggle(); // clic izquierdo para alternar if (button == 0) setting.toggle(); // clic izquierdo para alternar
else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) // shift izquierdo + clic derecho para restablecer al valor por defecto else if (button == 1 && KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) // shift izquierdo + clic derecho para restablecer al valor por defecto
setting.reset(); setting.reset();
} }
} }
@Override
public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
}
public BooleanSetting getSetting() { public BooleanSetting getSetting() {
return setting; return setting;
} }
@Override
public void mouseReleased(double mouseX, double mouseY, int button) {}
} }
@@ -3,6 +3,7 @@ package me.retucio.camtweaks.ui.frames;
import me.retucio.camtweaks.CameraTweaks; import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.events.camtweaks.GUISettingsFrameEvent; import me.retucio.camtweaks.event.events.camtweaks.GUISettingsFrameEvent;
import me.retucio.camtweaks.module.modules.GUI; import me.retucio.camtweaks.module.modules.GUI;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.buttons.SettingButton; import me.retucio.camtweaks.ui.buttons.SettingButton;
import me.retucio.camtweaks.util.Colors; import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
@@ -13,7 +14,7 @@ public class ClientSettingsFrame extends SettingsFrame {
public static final GUI guiSettings = new GUI(); public static final GUI guiSettings = new GUI();
public boolean extended = false; public boolean extended = false;
private String title = "ajustes del mod -"; private final String title = "ajustes del mod";
public ClientSettingsFrame(int x, int y, int w, int h) { public ClientSettingsFrame(int x, int y, int w, int h) {
super(guiSettings, x, y, w, h); super(guiSettings, x, y, w, h);
@@ -22,42 +23,48 @@ public class ClientSettingsFrame extends SettingsFrame {
@Override @Override
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) { public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
updateWidth(); updateWidth();
ctx.fill(x, y, x + w, y + h, Colors.frameHeadColor); ctx.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
ctx.drawText(mc.textRenderer, title, ctx.drawText(mc.textRenderer, title,
x + (w / 2) - (mc.textRenderer.getWidth(title) / 2), x + 8,
y + (h / 2) - (mc.textRenderer.fontHeight / 2), renderY + (h / 2) - (mc.textRenderer.fontHeight / 2),
-1, true);
ctx.drawText(mc.textRenderer, extended ? "-" : "+",
x + w - mc.textRenderer.getWidth("+") - 8,
renderY + (h / 2) - (mc.textRenderer.fontHeight / 2),
-1, true); -1, true);
List<SettingButton> visibleButtons = settingButtons.stream() List<SettingButton> visibleButtons = settingButtons.stream()
.filter(sb -> sb.getSetting().isVisible()) .filter(sb -> sb.getSetting().isVisible() && sb.getSetting().isSearchMatch())
.toList(); .toList();
if (extended) { if (extended) {
int currentY = y + h + 3; int currentY = renderY + h + 3;
ctx.fill(x, currentY - 2, x + w, currentY + visibleButtons.size() * h, Colors.frameBGColor); totalHeight = visibleButtons.size() * h;
ctx.fill(x, currentY - 2, x + w, currentY + totalHeight, Colors.frameBGColor.getRGB());
for (SettingButton sb : visibleButtons) { for (SettingButton sb : visibleButtons) {
sb.setX(x + 4); sb.setX(x + 4);
sb.setY(currentY); sb.setY(currentY);
sb.setW(w - 8); sb.setW(w - 8);
sb.setH(h); sb.setH(h - h / 4);
sb.render(ctx, mouseX, mouseY, delta); sb.render(ctx, mouseX, mouseY, delta);
sb.drawTooltip(ctx, mouseX, mouseY);
currentY += h; currentY += h;
} }
} } else totalHeight = 0;
} }
@Override @Override
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered(mouseX, mouseY)) { if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) { if (button == 0) {
dragging = true; dragging = true;
dragX = (int) (mouseX - x); dragX = (int) (mouseX - x);
dragY = (int) (mouseY - y); dragY = (int) (mouseY - y);
} else if (button == 1) { } else if (button == 1) {
extended = !extended; extended = !extended;
title = extended ? "ajustes del mod -" : "ajustes del mod +";
CameraTweaks.EVENT_BUS.post(new GUISettingsFrameEvent.Extend()); CameraTweaks.EVENT_BUS.post(new GUISettingsFrameEvent.Extend());
} }
} }
@@ -69,9 +76,10 @@ public class ClientSettingsFrame extends SettingsFrame {
@Override @Override
public void mouseRelease(double mouseX, double mouseY, int button) { public void mouseRelease(double mouseX, double mouseY, int button) {
if (button == 0 && dragging) { ClickGUI.INSTANCE.unselect(this);
if (button == 0 && dragging)
CameraTweaks.EVENT_BUS.post(new GUISettingsFrameEvent.Move()); CameraTweaks.EVENT_BUS.post(new GUISettingsFrameEvent.Move());
}
super.mouseRelease(mouseX, mouseY, button); super.mouseRelease(mouseX, mouseY, button);
} }
} }
@@ -4,10 +4,13 @@ import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.events.camtweaks.ModuleFrameEvent; import me.retucio.camtweaks.event.events.camtweaks.ModuleFrameEvent;
import me.retucio.camtweaks.module.Module; import me.retucio.camtweaks.module.Module;
import me.retucio.camtweaks.module.ModuleManager; import me.retucio.camtweaks.module.ModuleManager;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.buttons.ModuleButton; import me.retucio.camtweaks.ui.buttons.ModuleButton;
import me.retucio.camtweaks.util.Colors; import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -15,9 +18,12 @@ import java.util.List;
// marco para los módulos // marco para los módulos
public class ModuleFrame { public class ModuleFrame {
public int x, y, w, h, dragX, dragY; public int x, y, w, h;
public int renderY;
public int dragX, dragY;
public int totalHeight = 0;
public boolean dragging, extended; public boolean dragging, extended;
public String title = "módulos -"; public final String title = "módulos";
private final List<ModuleButton> moduleButtons = new ArrayList<>(); private final List<ModuleButton> moduleButtons = new ArrayList<>();
@@ -40,6 +46,10 @@ public class ModuleFrame {
} }
} }
public void updateRenderY(int scrollOffset) {
renderY = y - scrollOffset;
}
void updateWidth() { void updateWidth() {
// asegurarse de que todos los botones caben en el marco, haciendo que la anchura se ajuste al texto más largo // asegurarse de que todos los botones caben en el marco, haciendo que la anchura se ajuste al texto más largo
if (mc.textRenderer == null) return; if (mc.textRenderer == null) return;
@@ -55,61 +65,68 @@ public class ModuleFrame {
public void render(DrawContext ctx, int mouseX, int mouseY, float delta) { public void render(DrawContext ctx, int mouseX, int mouseY, float delta) {
updateWidth(); updateWidth();
ctx.fill(x, y, x + w, y + h, Colors.frameHeadColor); // cabeza del marco ctx.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); // cabeza del marco
// título del marco // título del marco
ctx.drawText(mc.textRenderer, title, ctx.drawText(mc.textRenderer, Text.literal(Formatting.BOLD + title),
x + (w / 2) - (mc.textRenderer.getWidth(title) / 2), x + 8,
y + ( h /2) - (mc.textRenderer.fontHeight / 2), renderY + (h / 2) - (mc.textRenderer.fontHeight / 2),
-1, true);
ctx.drawText(mc.textRenderer, extended ? "-" : "+",
x + w - mc.textRenderer.getWidth("+") - 8, // '+' y '-' tienen la misma anchura, o sea que no importa cuál use
renderY + (h / 2) - (mc.textRenderer.fontHeight / 2),
-1, true); -1, true);
// dibujar sus módulos solo si está extendido // dibujar sus módulos solo si está extendido
if (extended) { if (extended) {
int totalHeight = moduleButtons.size() * h + 3; totalHeight = moduleButtons.size() * h + 3;
ctx.fill( // fondo para los botones ctx.fill( // fondo para los botones
x, y + h + 1, x, renderY + h + 1,
x + w, y + h + totalHeight, x + w, renderY + h + totalHeight,
Colors.frameBGColor); Colors.frameBGColor.getRGB());
// dibujar los botones para cada módulo // dibujar los botones para cada módulo
for (ModuleButton moduleButton : moduleButtons) for (ModuleButton moduleButton : moduleButtons)
moduleButton.render(ctx, mouseX, mouseY, delta); moduleButton.render(ctx, mouseX, mouseY, delta);
} } else totalHeight = 0;
} }
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
// registrar clics // registrar clics
if (isHovered(mouseX, mouseY)) { if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) { // clic izquierdo para arrastrarlo if (button == 0) { // clic izquierdo para arrastrarlo
dragging = true; dragging = true;
dragX = (int) (mouseX - x); dragX = (int) (mouseX - x);
dragY = (int) (mouseY - y); dragY = (int) (mouseY - y);
} else if (button == 1) { // clic derecho para extenderlo } else if (button == 1) { // clic derecho para extenderlo
extended = !extended; extended = !extended;
title = extended ? "módulos -" : "módulos +";
CameraTweaks.EVENT_BUS.post(new ModuleFrameEvent.Extend()); CameraTweaks.EVENT_BUS.post(new ModuleFrameEvent.Extend());
} }
} }
if (!extended) return; // solo dejar clicar en los módulos si el marco está extendido if (!extended) return; // solo dejar clicar en los módulos si el marco está extendido
for (ModuleButton moduleButton : moduleButtons) { for (ModuleButton moduleButton : moduleButtons)
if (moduleButton.isHovered((int) mouseX, (int) mouseY)) {
moduleButton.mouseClicked(mouseX, mouseY, button); moduleButton.mouseClicked(mouseX, mouseY, button);
break;
}
}
} }
// detectar cuándo se suelta el clic // detectar cuándo se suelta el clic
public void mouseReleased(double mouseX, double mouseY, int button) { public void mouseReleased(double mouseX, double mouseY, int button) {
if (button == 0 && dragging) { ClickGUI.INSTANCE.unselect(this);
if (button == 0 && dragging)
dragging = false; dragging = false;
for (ModuleButton moduleButton : moduleButtons) {
if (moduleButton.isHovered((int) mouseX, (int) mouseY))
moduleButton.mouseReleased(mouseX, mouseY, button);
} }
CameraTweaks.EVENT_BUS.post(new ModuleFrameEvent.Move());
if (isHovered(mouseX, mouseY))
CameraTweaks.EVENT_BUS.post(new ModuleFrameEvent.Move());
} }
// verificar si el puntero del ratón se encuentra encima // verificar si el puntero del ratón se encuentra encima
public boolean isHovered(double mouseX, double mouseY) { public boolean isHovered(double mouseX, double mouseY) {
return mouseX > x && mouseX < x + w && mouseY > y && mouseY < y + h; return mouseX > x && mouseX < x + w && mouseY > renderY && mouseY < renderY + h;
} }
// actualizar la posición al arrastrar el marco // actualizar la posición al arrastrar el marco
@@ -13,6 +13,7 @@ import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -23,9 +24,13 @@ public class SettingsFrame {
public final Module module; public final Module module;
final List<SettingButton> settingButtons = new ArrayList<>(); final List<SettingButton> settingButtons = new ArrayList<>();
public List<SettingButton> visibleButtons = new ArrayList<>();
public int x, y, w, h; public int x, y, w, h;
boolean dragging; public int renderY;
int dragX, dragY; int dragX, dragY;
boolean dragging;
public int totalHeight = 0;
public final MinecraftClient mc = MinecraftClient.getInstance(); public final MinecraftClient mc = MinecraftClient.getInstance();
@@ -63,7 +68,11 @@ public class SettingsFrame {
} default -> {} } default -> {}
} }
} }
title = "ajustes de " + module.getName() + " -"; title = "ajustes de " + module.getName();
visibleButtons = settingButtons.stream()
.filter(sb -> sb.getSetting().isVisible())
.toList();
} }
public void addButton(SettingButton button) { public void addButton(SettingButton button) {
@@ -76,35 +85,42 @@ public class SettingsFrame {
// cabezal // cabezal
int centerX = x + w / 2; int centerX = x + w / 2;
int centerY = y + h / 2; int centerY = renderY + h / 2;
int titleX = x + 8;
int titleWidth = mc.textRenderer.getWidth(title);
int titleX = centerX - titleWidth / 2;
int titleY = centerY - mc.textRenderer.fontHeight / 2; int titleY = centerY - mc.textRenderer.fontHeight / 2;
int headerColor = module.isEnabled() int headerColor = module.isEnabled()
? Colors.enabledToggleButtonColor.getRGB() ? Colors.enabledToggleButtonColor.getRGB()
: Colors.disabledToggleButtonColor.getRGB(); : Colors.disabledToggleButtonColor.getRGB();
ctx.fill(x, y, x + w, y + h, headerColor); int closeButtonColor = isCloseButtonHovered(mouseX, mouseY)
? Color.RED.getRGB()
: -1;
if (!module.shouldSaveSettings()) headerColor = (int) module.getSettings().stream().filter(s -> ((BooleanSetting) s).isEnabled()).count() > 0
? Colors.enabledToggleButtonColor.getRGB()
: Colors.disabledToggleButtonColor.getRGB();
ctx.fill(x, renderY, x + w, renderY + h, headerColor);
ctx.drawText(mc.textRenderer, title, titleX, titleY, -1, true); ctx.drawText(mc.textRenderer, title, titleX, titleY, -1, true);
ctx.drawText(mc.textRenderer, "×", x + w - mc.textRenderer.getWidth("×") - 8, titleY, closeButtonColor, true);
// descripción // descripción
List<SettingButton> visibleButtons = settingButtons.stream() visibleButtons = settingButtons.stream()
.filter(sb -> sb.getSetting().isVisible()) .filter(sb -> sb.getSetting().isVisible() && sb.getSetting().isSearchMatch())
.toList(); .toList();
List<String> descLines = wrapDescription(module.getDescription(), w - 8); List<String> descLines = wrapDescription(module.getDescription(), w - 8);
int lineSpacing = 2; int lineSpacing = 2;
int descHeight = descLines.size() * mc.textRenderer.fontHeight + (descLines.size() - 1) * lineSpacing; int descHeight = descLines.size() * mc.textRenderer.fontHeight + (descLines.size() - 1) * lineSpacing;
int descBoxTop = y + h + 5; int descBoxTop = renderY + h + 5;
int descBoxBottom = descBoxTop + descHeight + 8; int descBoxBottom = descBoxTop + descHeight + 8;
int totalHeight = descHeight + 8 + h * visibleButtons.size() + 4; totalHeight = descHeight + 8 + h * visibleButtons.size() + 4;
ctx.fill(x, descBoxTop - 4, x + w, descBoxTop + totalHeight, Colors.frameBGColor); ctx.fill(x, descBoxTop - 4, x + w, descBoxTop + totalHeight, Colors.frameBGColor.getRGB());
ctx.fill(x + 4, descBoxTop, x + w - 4, descBoxBottom, Colors.settingButtonColor); ctx.fill(x + 4, descBoxTop, x + w - 4, descBoxBottom, Colors.buttonColor.getRGB());
int firstLineY = descBoxTop + ((descBoxBottom - descBoxTop) - descHeight) / 2; int firstLineY = descBoxTop + ((descBoxBottom - descBoxTop) - descHeight) / 2;
for (int i = 0; i < descLines.size(); i++) { for (int i = 0; i < descLines.size(); i++) {
@@ -119,16 +135,24 @@ public class SettingsFrame {
sb.setX(x + 4); sb.setX(x + 4);
sb.setY(startButtonY); sb.setY(startButtonY);
sb.setW(w - 8); sb.setW(w - 8);
sb.setH(h - 6); sb.setH(h - h / 4);
sb.render(ctx, mouseX, mouseY, delta); sb.render(ctx, mouseX, mouseY, delta);
startButtonY += h; startButtonY += h;
} }
} }
public void drawTooltips(DrawContext ctx, double mouseX, double mouseY) {
for (SettingButton sb : visibleButtons)
sb.drawTooltip(ctx, mouseX, mouseY);
}
public void mouseClicked(double mouseX, double mouseY, int button) { public void mouseClicked(double mouseX, double mouseY, int button) {
if (isHovered(mouseX, mouseY)) { if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) { if (isCloseButtonHovered(mouseX, mouseY)) {
ClickGUI.INSTANCE.closeSettingsFrame(this.module);
return;
} if (button == 0) {
dragging = true; dragging = true;
dragX = (int) (mouseX - x); dragX = (int) (mouseX - x);
dragY = (int) (mouseY - y); dragY = (int) (mouseY - y);
@@ -143,6 +167,7 @@ public class SettingsFrame {
} }
public void mouseRelease(double mouseX, double mouseY, int button) { public void mouseRelease(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
if (button == 0) { if (button == 0) {
dragging = false; dragging = false;
CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Move(this)); CameraTweaks.EVENT_BUS.post(new SettingsFrameEvent.Move(this));
@@ -160,7 +185,12 @@ public class SettingsFrame {
public boolean isHovered(double mouseX, double mouseY) { public boolean isHovered(double mouseX, double mouseY) {
return mouseX > x && mouseX < x + w && return mouseX > x && mouseX < x + w &&
mouseY > y && mouseY < y + h; mouseY > renderY && mouseY < renderY + h;
}
public boolean isCloseButtonHovered(double mouseX, double mouseY) {
return mouseX > x + w - mc.textRenderer.getWidth("×") - 12 && mouseX < x + w - 4
&& mouseY > renderY + 4 && mouseY < renderY + h - 4;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
@@ -183,7 +213,7 @@ public class SettingsFrame {
int textWidth = mc.textRenderer.getWidth(text); int textWidth = mc.textRenderer.getWidth(text);
maxWidth = Math.max(maxWidth, textWidth); maxWidth = Math.max(maxWidth, textWidth);
} }
this.w = maxWidth + 22; this.w = maxWidth + 30;
} }
private List<String> wrapDescription(String text, int maxWidth) { private List<String> wrapDescription(String text, int maxWidth) {
@@ -209,4 +239,8 @@ public class SettingsFrame {
public List<SettingButton> getButtons() { public List<SettingButton> getButtons() {
return settingButtons; return settingButtons;
} }
public void updateRenderY(int scrollOffset) {
renderY = y - scrollOffset;
}
} }
@@ -0,0 +1,115 @@
package me.retucio.camtweaks.ui.widgets;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.util.Colors;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import java.awt.*;
public class ScrollBarWidget {
private boolean dragging;
private int dragY, scrollStart;
private int scrollOffset = 0;
private int contentHeight, windowHeight;
private final MinecraftClient mc = MinecraftClient.getInstance();
public ScrollBarWidget() {}
public void render(DrawContext ctx, double mouseX, double mouseY) {
if (contentHeight <= windowHeight || !ClientSettingsFrame.guiSettings.scrollBar.isEnabled()) return;
int trackX1 = mc.getWindow().getScaledWidth() - 10;
int trackX2 = trackX1 + 10;
ctx.fill(trackX1, 0, trackX2, windowHeight, Colors.buttonColor.getRGB());
int thumbHeight = getThumbHeight();
int thumbY = getThumbY();
Color thumbColor = isThumbHovered(mouseX, mouseY)
? Colors.mainColor.brighter()
: Colors.mainColor;
if (dragging) thumbColor = Colors.mainColor.darker();
ctx.fill(trackX1 + 1, thumbY + 1, trackX2 - 1, thumbY + thumbHeight - 1, thumbColor.getRGB());
}
public void mouseClicked(double mouseX, double mouseY, int button) {
if (button != 0 || !ClientSettingsFrame.guiSettings.scrollBar.isEnabled()) return;
if (isThumbHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
dragging = true;
dragY = (int) mouseY;
scrollStart = scrollOffset;
}
}
public void mouseReleased(double mouseX, double mouseY, int button) {
ClickGUI.INSTANCE.unselect(this);
dragging = false;
}
public void mouseDragged(double mouseY) {
if (!dragging || !ClientSettingsFrame.guiSettings.scrollBar.isEnabled()) return;
int thumbHeight = getThumbHeight();
int trackHeight = windowHeight - thumbHeight;
float ratio = (float) (contentHeight - windowHeight) / trackHeight;
int deltaY = (int) mouseY - dragY;
scrollOffset = scrollStart + (int) (deltaY * ratio);
clampOffset();
}
public void onMouseScroll(double amount) {
if (contentHeight <= windowHeight) return;
scrollOffset -= (int) amount * 20;
clampOffset();
}
private boolean isThumbHovered(double mouseX, double mouseY) {
if (!ClickGUI.INSTANCE.canSelect(this)) return false;
int trackX1 = mc.getWindow().getScaledWidth() - 10;
int trackX2 = trackX1 + 10;
int thumbY = getThumbY();
int thumbHeight = getThumbHeight();
return mouseX >= trackX1 && mouseX <= trackX2 && mouseY >= thumbY && mouseY <= thumbY + thumbHeight;
}
private void clampOffset() {
if (contentHeight <= windowHeight)
scrollOffset = 0;
else
scrollOffset = Math.max(0, Math.min(contentHeight - windowHeight, scrollOffset));
}
private int getThumbY() {
int thumbHeight = getThumbHeight();
float scrollProgress = (float) scrollOffset / (contentHeight - windowHeight);
return (int) (scrollProgress * (windowHeight - thumbHeight));
}
private int getThumbHeight() {
float visibleRatio = (float) windowHeight / contentHeight;
return Math.max(20, (int) (windowHeight * visibleRatio));
}
public int getScrollOffset() {
return scrollOffset;
}
public void setContentHeight(int h) {
this.contentHeight = h;
clampOffset();
}
public void setWindowHeight(int h) {
this.windowHeight = h;
clampOffset();
}
}
@@ -0,0 +1,156 @@
package me.retucio.camtweaks.ui.widgets;
import me.retucio.camtweaks.ui.ClickGUI;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
import me.retucio.camtweaks.util.ChatUtil;
import me.retucio.camtweaks.util.Colors;
import me.retucio.camtweaks.util.KeyUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import org.lwjgl.glfw.GLFW;
import java.awt.Color;
public class SearchBarWidget {
private boolean dragging;
private int dragX, dragY;
private int x, y;
private final int w, h;
private int renderY;
private boolean focused;
private final StringBuilder buffer = new StringBuilder();
private final MinecraftClient mc = MinecraftClient.getInstance();
public SearchBarWidget(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
public void render(DrawContext ctx, double mouseX, double mouseY, float delta) {
if (!ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return;
Color textFieldColor = isTextFieldHovered(mouseX, mouseY)
? Colors.buttonColor.brighter()
: Colors.buttonColor;
if (focused) textFieldColor = Colors.buttonColor.darker();
// bordes de la barra, para no obstruir la transparencia del campo de texto
ctx.fill(x, renderY, x + 20, renderY + h, Colors.mainColor.getRGB());
ctx.fill(x, renderY, x + w, renderY + 2, Colors.mainColor.getRGB());
ctx.fill(x, renderY + h, x + w, renderY + h - 2, Colors.mainColor.getRGB());
ctx.fill(x + w - 20, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
ctx.fill(x + 20, renderY + 2, x + w - 20, renderY + h - 2, textFieldColor.getRGB());
// dibujar líneas en la parte agarrable, para indicárselo al usuario
for (int i = 0; i < 4; i++)
ctx.drawHorizontalLine(x + 4, x + 16, renderY + 3 * i + 5, Color.LIGHT_GRAY.getRGB());
// texto
Text label = Text.literal(focused ? buffer + "_" : (buffer.isEmpty() ? Formatting.ITALIC + "buscar..." : buffer.toString()));
ctx.drawText(mc.textRenderer, label,
x + 24, renderY + h / 2 - mc.textRenderer.fontHeight / 2,
(buffer.isEmpty() && !focused) ? Color.LIGHT_GRAY.getRGB() : -1, true);
// botón para borrar búsqueda actual
ctx.drawText(mc.textRenderer, "×", x + w - mc.textRenderer.getWidth("×") - 6, renderY + (h / 2) - mc.textRenderer.fontHeight / 2,
isClearButtonHovered(mouseX, mouseY) ? Color.RED.getRGB() : -1, true);
}
public void mouseClicked(double mouseX, double mouseY, int button) {
if (button != 0 || !ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return;
if (isHandleHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
dragging = true;
dragX = (int) mouseX - x;
dragY = (int) mouseY - y;
} else if (isClearButtonHovered(mouseX, mouseY)) {
buffer.setLength(0);
}
focused = isTextFieldHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this);
}
public void mouseReleased(double mouseX, double mouseY, int button) {
if (!ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return;
ClickGUI.INSTANCE.unselect(this);
if (button == 0 && dragging) dragging = false;
}
public void onKey(int key, int action) {
if (!ClientSettingsFrame.guiSettings.searchBar.isEnabled()) return;
if (!focused || action == GLFW.GLFW_RELEASE) return;
switch (key) {
case GLFW.GLFW_KEY_ENTER -> focused = false;
case GLFW.GLFW_KEY_ESCAPE -> {
buffer.setLength(0);
focused = false;
}
case GLFW.GLFW_KEY_BACKSPACE -> onBackspace();
default -> {
String c = KeyUtil.getKeyName(key);
if (c.length() == 1) {
if (KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT) || KeyUtil.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT))
charTyped(KeyUtil.shiftKey(c).charAt(0));
else
charTyped(c.toLowerCase().charAt(0));
}
}
}
}
public void onBackspace() {
if (!buffer.isEmpty()) buffer.deleteCharAt(buffer.length() - 1);
}
public void charTyped(char c) {
if (!focused) return;
buffer.append(c);
if (mc.textRenderer.getWidth(buffer.toString()) > w - 30) onBackspace();
}
public String getSearchInput() {
return buffer.toString();
}
public boolean isHandleHovered(double mouseX, double mouseY) {
return ClickGUI.INSTANCE.canSelect(this)
&& mouseX > x && mouseX < x + 18
&& mouseY > renderY && mouseY < renderY + h;
}
public boolean isTextFieldHovered(double mouseX, double mouseY) {
return ClickGUI.INSTANCE.canSelect(this)
&& mouseX > x + 20 && mouseX < x + w - 20
&& mouseY > renderY + 2 && mouseY < renderY + h - 2;
}
public boolean isClearButtonHovered(double mouseX, double mouseY) {
return ClickGUI.INSTANCE.canSelect(this)
&& mouseX > x + w - 15 && mouseX < x + w - 3
&& mouseY > renderY + 3 && mouseY < renderY + h - 5;
}
public boolean isFocused() {
return focused && ClientSettingsFrame.guiSettings.searchBar.isEnabled();
}
public void updateRenderY(int scrollOffset) {
renderY = y - scrollOffset;
}
public void updatePosition(double mouseX, double mouseY) {
if (dragging) {
x = (int) (mouseX - dragX);
y = (int) (mouseY - dragY);
}
}
}
@@ -1,5 +1,6 @@
package me.retucio.camtweaks.util; package me.retucio.camtweaks.util;
import me.retucio.camtweaks.CameraTweaks;
import me.retucio.camtweaks.event.SubscribeEvent; import me.retucio.camtweaks.event.SubscribeEvent;
import me.retucio.camtweaks.event.events.camtweaks.LoadModuleManagerEvent; import me.retucio.camtweaks.event.events.camtweaks.LoadModuleManagerEvent;
import me.retucio.camtweaks.ui.frames.ClientSettingsFrame; import me.retucio.camtweaks.ui.frames.ClientSettingsFrame;
@@ -15,17 +16,16 @@ public class ChatUtil {
@SubscribeEvent @SubscribeEvent
public static void onLoadModuleManager(LoadModuleManagerEvent event) { public static void onLoadModuleManager(LoadModuleManagerEvent event) {
prefix = Formatting.GREEN + "[" + ClientSettingsFrame.guiSettings.chatName.getValue() + "] "; prefix = Colors.getFormatting(Colors.mainColor) + "[" + ClientSettingsFrame.guiSettings.chatName.getValue() + "] ";
} }
public static void addMessage(String text) { public static void addMessage(String text) {
if (mc.inGameHud == null) return; addMessage(Text.of(text));
mc.inGameHud.getChatHud().addMessage(Text.of(text));
} }
public static void addMessage(Text text) { public static void addMessage(Text text) {
if (mc.inGameHud == null) return; if (mc.inGameHud == null || !CameraTweaks.INSTANCE.settingsApplied) return;
mc.inGameHud.getChatHud().addMessage(text); mc.inGameHud.getChatHud().addMessage(text);
} }
@@ -34,31 +34,31 @@ public class ChatUtil {
} }
public static void addMessageWithPrefix(Text text) { public static void addMessageWithPrefix(Text text) {
addMessage(Text.literal(prefix + Formatting.RESET).append(text)); addMessage(Text.literal(getPrefix() + Formatting.RESET).append(text));
} }
public static void info(String text) { public static void info(String text) {
addMessage(Text.literal(prefix + Formatting.RESET + text)); addMessage(Text.literal(getPrefix() + Formatting.RESET + text));
} }
public static void info(Text text) { public static void info(Text text) {
addMessage(Text.literal(prefix + Formatting.RESET).append(text)); addMessage(Text.literal(getPrefix() + Formatting.RESET).append(text));
} }
public static void warn(String text) { public static void warn(String text) {
addMessage(Text.literal(prefix + Formatting.YELLOW + text)); addMessage(Text.literal(getPrefix() + Formatting.YELLOW + text));
} }
public static void warn(Text text) { public static void warn(Text text) {
addMessage(Text.literal(prefix + Formatting.YELLOW).append(text)); addMessage(Text.literal(getPrefix() + Formatting.YELLOW).append(text));
} }
public static void error(String text) { public static void error(String text) {
addMessage(Text.literal(prefix + Formatting.RED + text)); addMessage(Text.literal(getPrefix() + Formatting.RED + text));
} }
public static void error(Text text) { public static void error(Text text) {
addMessage(Text.literal(prefix + Formatting.RED).append(text)); addMessage(Text.literal(getPrefix() + Formatting.RED).append(text));
} }
public static void sendServerMessage(String text) { public static void sendServerMessage(String text) {
@@ -74,16 +74,20 @@ public class ChatUtil {
return prefix; return prefix;
} }
public static String getPrefixNoFormatting() { public static String getJustPrefix() {
return prefix.split(Formatting.GREEN.toString())[1]; return ClientSettingsFrame.guiSettings.chatName.getValue();
// return "[" + ClickGUISettingsFrame.guiSettings.chatName.getValue() + "] ";
} }
public static String getPrefixNoFormatting() {
return getPrefix().split(Colors.getFormatting(Colors.mainColor).toString())[1];
}
public static void updatePrefix(String newPrefix) { public static void updatePrefix(String newPrefix) {
prefix = Formatting.GREEN + "[" + newPrefix + "] "; prefix = Colors.getFormatting(Colors.mainColor) + "[" + newPrefix + "] ";
} }
public static String getDefaultPrefix() { public static String getDefaultPrefix() {
return Formatting.GREEN + "[smegma] "; return Colors.getFormatting(Colors.mainColor) + "[smegma] ";
} }
} }
@@ -1,39 +1,76 @@
package me.retucio.camtweaks.util; package me.retucio.camtweaks.util;
import net.minecraft.util.Formatting;
import java.awt.*; import java.awt.*;
import static me.retucio.camtweaks.ui.frames.ClientSettingsFrame.guiSettings; import static me.retucio.camtweaks.ui.frames.ClientSettingsFrame.guiSettings;
// clase para los colores, para no repetirme (regla DRY) // clase para los colores
// si se ve especificado como color en algún lado "-1", significa blanco // si se ve especificado como color en algún lado "-1", significa blanco
public class Colors { public class Colors {
public static int frameHeadRed = guiSettings.red.getIntValue(); public static int red = guiSettings.red.getIntValue();
public static int frameHeadGreen = guiSettings.green.getIntValue(); public static int green = guiSettings.green.getIntValue();
public static int frameHeadBlue = guiSettings.blue.getIntValue(); public static int blue = guiSettings.blue.getIntValue();
public static int frameHeadAlpha = guiSettings.alpha.getIntValue(); public static int alpha = guiSettings.alpha.getIntValue();
public static int frameHeadColor = new Color( public static Color mainColor;
frameHeadRed, public static Color frameBGColor = new Color(40, 40, 40, 75);
frameHeadGreen, public static Color buttonColor = new Color(75, 75, 75, 100);
frameHeadBlue, public static Color enabledToggleButtonColor;
frameHeadAlpha public static Color disabledToggleButtonColor;
).getRGB();
public static int frameBGColor = new Color(60, 60, 60, 70).getRGB(); static {
updateAllColors(new Color(red, green, blue, alpha));
}
public static int enabledHoveredModuleButtonColor = new Color(20, 20, 255, 180).getRGB(); public static void updateAllColors(Color color) {
public static int enabledModuleButtonColor = new Color(0, 0, 255, 180).getRGB(); mainColor = color;
public static int hoveredModuleButtonColor = new Color(30, 30, 30, 100).getRGB(); enabledToggleButtonColor = mixWithMainColor(new Color(10, 150, 10), 0.8f);
public static int moduleButtonColor = new Color(40, 40, 40, 75).getRGB(); disabledToggleButtonColor = mixWithMainColor(new Color(150, 10, 10), 0.8f);
public static int hoveredSettingButtonColor = new Color(30, 30, 30, 100).getRGB(); ChatUtil.updatePrefix(ChatUtil.getJustPrefix());
public static int settingButtonColor = new Color(40, 40, 40, 75).getRGB(); }
public static int sliderFillingColor = new Color(60, 120, 220, 180).getRGB();
// necesitan ser de tipo java.awt.Color para utilizar el método .brighter() public static Color mixWithMainColor(Color color, float ratio) {
public static Color enabledToggleButtonColor = new Color(0, 180, 0, 180); return mix(mainColor, color, ratio);
public static Color disabledToggleButtonColor = new Color(120, 30, 30, 150); }
public static Color mix(Color c1, Color c2, float ratio) {
float r = c1.getRed() * (1 - ratio) + c2.getRed() * ratio;
float g = c1.getGreen() * (1 - ratio) + c2.getGreen() * ratio;
float b = c1.getBlue() * (1 - ratio) + c2.getBlue() * ratio;
return new Color((int) r, (int) g, (int) b, alpha);
}
public static Formatting getFormatting(Color color) {
return nearest(color);
}
public static Formatting nearest(Color input) {
Formatting nearest = null;
double minDistance = Double.MAX_VALUE;
for (Formatting formatting : Formatting.values()) {
if (formatting.getColorValue() == null) continue; // saltarse los modificadores
Color candidate = new Color(formatting.getColorValue());
double dist = colorDistance(input, candidate);
if (dist < minDistance) {
minDistance = dist;
nearest = formatting;
}
}
return nearest;
}
private static double colorDistance(Color c1, Color c2) {
int rDiff = c1.getRed() - c2.getRed();
int gDiff = c1.getGreen() - c2.getGreen();
int bDiff = c1.getBlue() - c2.getBlue();
return rDiff * rDiff + gDiff * gDiff + bDiff * bDiff;
}
} }