Compare commits
6
Commits
1f69a3ecb4
...
f0398c7011
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0398c7011 | ||
|
|
7fc42b34d8 | ||
|
|
9b6a55d66c | ||
|
|
3568996138 | ||
|
|
ebd0a76f0c | ||
|
|
6ab84a1051 |
@@ -4,6 +4,7 @@ import cc.fros.Fros;
|
||||
import cc.fros.features.Feature;
|
||||
import cc.fros.features.gui.items.buttons.ModuleButton;
|
||||
import cc.fros.features.modules.Module;
|
||||
import cc.fros.features.modules.client.ClickGuiModule;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
@@ -84,27 +85,39 @@ public class FrosGui extends Screen {
|
||||
}
|
||||
|
||||
context.fill(0, 0, context.guiWidth(), context.guiHeight(), new Color(0, 0, 0, 120).hashCode());
|
||||
this.widgets.forEach(components -> components.drawScreen(context, mouseX, mouseY, delta));
|
||||
|
||||
// scale the whole clickgui; widgets work in layout units so mouse
|
||||
// coordinates are divided back down before they reach them
|
||||
float scale = ClickGuiModule.scale();
|
||||
int layoutX = (int) (mouseX / scale);
|
||||
int layoutY = (int) (mouseY / scale);
|
||||
context.pose().pushMatrix();
|
||||
context.pose().scale(scale, scale);
|
||||
this.widgets.forEach(components -> components.drawScreen(context, layoutX, layoutY, delta));
|
||||
context.pose().popMatrix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(MouseButtonEvent click, boolean doubled) {
|
||||
this.widgets.forEach(components -> components.mouseClicked((int) click.x(), (int) click.y(), click.button()));
|
||||
float scale = ClickGuiModule.scale();
|
||||
this.widgets.forEach(components -> components.mouseClicked((int) (click.x() / scale), (int) (click.y() / scale), click.button()));
|
||||
return super.mouseClicked(click, doubled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(MouseButtonEvent click) {
|
||||
this.widgets.forEach(components -> components.mouseReleased((int) click.x(), (int) click.y(), click.button()));
|
||||
float scale = ClickGuiModule.scale();
|
||||
this.widgets.forEach(components -> components.mouseReleased((int) (click.x() / scale), (int) (click.y() / scale), click.button()));
|
||||
return super.mouseReleased(click);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
|
||||
int step = Math.max(1, Math.round((float) (10 / ClickGuiModule.scale())));
|
||||
if (verticalAmount < 0) {
|
||||
this.widgets.forEach(component -> component.setY(component.getY() - 10));
|
||||
this.widgets.forEach(component -> component.setY(component.getY() - step));
|
||||
} else if (verticalAmount > 0) {
|
||||
this.widgets.forEach(component -> component.setY(component.getY() + 10));
|
||||
this.widgets.forEach(component -> component.setY(component.getY() + step));
|
||||
}
|
||||
return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
|
||||
}
|
||||
@@ -133,10 +146,6 @@ public class FrosGui extends Screen {
|
||||
return this.widgets;
|
||||
}
|
||||
|
||||
public int getTextOffset() {
|
||||
return -6;
|
||||
}
|
||||
|
||||
public static Color getColorClipboard() {
|
||||
return colorClipboard;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import cc.fros.Fros;
|
||||
import cc.fros.features.Feature;
|
||||
import cc.fros.features.gui.items.buttons.ModuleButton;
|
||||
import cc.fros.features.modules.Module;
|
||||
import cc.fros.features.modules.client.ClickGuiModule;
|
||||
import cc.fros.features.modules.client.HudModule;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
@@ -40,27 +41,37 @@ public class HudEditorScreen extends Screen {
|
||||
@Override
|
||||
public void render(GuiGraphics context, int mouseX, int mouseY, float delta) {
|
||||
anyHover = false;
|
||||
this.components.forEach(component -> component.drawScreen(context, mouseX, mouseY, delta));
|
||||
// same ui scale treatment as the clickgui
|
||||
float scale = ClickGuiModule.scale();
|
||||
int layoutX = (int) (mouseX / scale);
|
||||
int layoutY = (int) (mouseY / scale);
|
||||
context.pose().pushMatrix();
|
||||
context.pose().scale(scale, scale);
|
||||
this.components.forEach(component -> component.drawScreen(context, layoutX, layoutY, delta));
|
||||
context.pose().popMatrix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(MouseButtonEvent click, boolean doubled) {
|
||||
this.components.forEach(component -> component.mouseClicked((int) click.x(), (int) click.y(), click.button()));
|
||||
float scale = ClickGuiModule.scale();
|
||||
this.components.forEach(component -> component.mouseClicked((int) (click.x() / scale), (int) (click.y() / scale), click.button()));
|
||||
return super.mouseClicked(click, doubled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(MouseButtonEvent click) {
|
||||
this.components.forEach(component -> component.mouseReleased((int) click.x(), (int) click.y(), click.button()));
|
||||
float scale = ClickGuiModule.scale();
|
||||
this.components.forEach(component -> component.mouseReleased((int) (click.x() / scale), (int) (click.y() / scale), click.button()));
|
||||
return super.mouseReleased(click);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
|
||||
int step = Math.max(1, Math.round((float) (10 / ClickGuiModule.scale())));
|
||||
if (verticalAmount < 0) {
|
||||
this.components.forEach(component -> component.setY(component.getY() - 10));
|
||||
this.components.forEach(component -> component.setY(component.getY() - step));
|
||||
} else if (verticalAmount > 0) {
|
||||
this.components.forEach(component -> component.setY(component.getY() + 10));
|
||||
this.components.forEach(component -> component.setY(component.getY() + step));
|
||||
}
|
||||
return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,8 @@ public class Widget
|
||||
RenderUtil.rect(context, this.x, headerTop, this.x + this.width, panelBottom, 0x99000000, 1.0f);
|
||||
context.fill(this.x, headerBottom - 1, this.x + this.width, headerBottom, accent);
|
||||
|
||||
drawString(this.getName(), (float) this.x + 3.0f, (float) this.y - 4.0f - (float) FrosGui.getClickGui().getTextOffset(), -1);
|
||||
drawString(this.getName(), (float) this.x + 3.0f,
|
||||
(headerTop + headerBottom) / 2f - FrosFont.visualCenter(), -1);
|
||||
ScissorUtil.enable(context, x, 0, x + width, mc.getWindow().getGuiScaledHeight());
|
||||
|
||||
if (this.open) {
|
||||
@@ -215,6 +216,6 @@ public class Widget
|
||||
}
|
||||
|
||||
protected void drawString(String text, double x, double y, int color) {
|
||||
FrosFont.draw(context, text, (int) x, (int) y, color, true);
|
||||
FrosFont.draw(context, text, (int) x, (int) y, color);
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,12 @@ public class Item
|
||||
}
|
||||
|
||||
protected void drawString(GuiGraphics context, String text, double x, double y, int color) {
|
||||
FrosFont.draw(context, text, (int) x, (int) y, color, true);
|
||||
FrosFont.draw(context, text, (int) x, (int) y, color);
|
||||
}
|
||||
|
||||
/** y coordinate that visually centers text inside this item */
|
||||
protected float textY() {
|
||||
return this.y + this.height / 2f - FrosFont.visualCenter();
|
||||
}
|
||||
|
||||
public boolean isHovering(int mouseX, int mouseY) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package cc.fros.features.gui.items.buttons;
|
||||
|
||||
import cc.fros.Fros;
|
||||
import cc.fros.features.gui.FrosGui;
|
||||
import cc.fros.features.modules.client.ClickGuiModule;
|
||||
import cc.fros.features.settings.Bind;
|
||||
import cc.fros.features.settings.Setting;
|
||||
@@ -29,10 +28,10 @@ public class BindButton
|
||||
int color = ClickGuiModule.getInstance().color.getValue().getRGB();
|
||||
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515) : (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())));
|
||||
if (this.isListening) {
|
||||
drawString(context, "Press a Key...", this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), -1);
|
||||
drawString(context, "Press a Key...", this.x + 2.3f, textY(), -1);
|
||||
} else {
|
||||
String str = KeyboardUtil.getKeyName(setting.getValue());
|
||||
drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + str, this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
|
||||
drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + str, this.x + 2.3f, textY(), this.getState() ? -1 : -5592406);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package cc.fros.features.gui.items.buttons;
|
||||
|
||||
|
||||
import cc.fros.Fros;
|
||||
import cc.fros.features.gui.FrosGui;
|
||||
import cc.fros.features.modules.client.ClickGuiModule;
|
||||
import cc.fros.features.settings.Setting;
|
||||
import cc.fros.util.render.RenderUtil;
|
||||
@@ -23,7 +22,7 @@ public class BooleanButton
|
||||
@Override
|
||||
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
|
||||
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515));
|
||||
drawString(context, this.getName(), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
|
||||
drawString(context, this.getName(), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,7 +22,7 @@ public class Button
|
||||
@Override
|
||||
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
|
||||
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515));
|
||||
drawString(context, this.getName(), this.x + 2.3f, this.y - 2.0f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
|
||||
drawString(context, this.getName(), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,7 +44,7 @@ public class ColorButton extends Button {
|
||||
this.x + (float) this.width + 5.0f, this.y + (float) this.height - 2.5f,
|
||||
new Color(currentColor.getRGB(), false).getRGB());
|
||||
|
||||
drawString(context, this.getName(), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), -1);
|
||||
drawString(context, this.getName(), this.x + 2.3f, textY(), -1);
|
||||
|
||||
if (open) {
|
||||
float yOffset = this.height + 1;
|
||||
@@ -121,12 +121,12 @@ public class ColorButton extends Button {
|
||||
int buttonWidth = availableWidth / 2;
|
||||
RenderUtil.rect(context, pickerX, this.y + yOffset, pickerX + buttonWidth, this.y + yOffset + 14,
|
||||
hoveringCopy ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha()) : 0x11555555);
|
||||
drawString(context, "Copy", pickerX + buttonWidth / 2.0 - FrosFont.width("Copy") / 2.0, this.y + yOffset + 3, -1);
|
||||
drawString(context, "Copy", pickerX + buttonWidth / 2.0 - FrosFont.width("Copy") / 2.0, this.y + yOffset + 7f - FrosFont.visualCenter(), -1);
|
||||
hoveringCopy = isHoveringArea(mouseX, mouseY, pickerX, this.y + yOffset, pickerX + buttonWidth, this.y + yOffset + 14);
|
||||
|
||||
RenderUtil.rect(context, pickerX + buttonWidth + 1, this.y + yOffset, pickerX + buttonWidth * 2 + 1, this.y + yOffset + 14,
|
||||
hoveringPaste ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha()) : 0x11555555);
|
||||
drawString(context, "Paste", pickerX + buttonWidth + buttonWidth / 2.0 - FrosFont.width("Paste") / 2.0 + 1, this.y + yOffset + 3, -1);
|
||||
drawString(context, "Paste", pickerX + buttonWidth + buttonWidth / 2.0 - FrosFont.width("Paste") / 2.0 + 1, this.y + yOffset + 7f - FrosFont.visualCenter(), -1);
|
||||
hoveringPaste = isHoveringArea(mouseX, mouseY, pickerX + buttonWidth + 1, this.y + yOffset, pickerX + buttonWidth * 2 + 1, this.y + yOffset + 14);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package cc.fros.features.gui.items.buttons;
|
||||
|
||||
|
||||
import cc.fros.Fros;
|
||||
import cc.fros.features.gui.FrosGui;
|
||||
import cc.fros.features.modules.client.ClickGuiModule;
|
||||
import cc.fros.features.settings.Setting;
|
||||
import cc.fros.util.render.RenderUtil;
|
||||
@@ -24,7 +23,7 @@ public class EnumButton
|
||||
@Override
|
||||
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
|
||||
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515));
|
||||
drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + (this.setting.currentEnumName().equalsIgnoreCase("ABC") ? "ABC" : this.setting.currentEnumName()), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
|
||||
drawString(context, this.setting.getName() + " " + ChatFormatting.GRAY + (this.setting.currentEnumName().equalsIgnoreCase("ABC") ? "ABC" : this.setting.currentEnumName()), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,7 +32,7 @@ public class Slider
|
||||
this.dragSetting(mouseX, mouseY);
|
||||
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, !(this.dragging || this.isHovering(mouseX, mouseY)) ? 0x11555555 : -2007673515);
|
||||
RenderUtil.rect(context, this.x, this.y, (this.setting.getValue()).floatValue() <= this.min.floatValue() ? this.x : this.x + ((float) this.width + 7.4f) * this.partialMultiplier(), this.y + (float) this.height - 0.5f, !(this.dragging || this.isHovering(mouseX, mouseY)) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha()));
|
||||
drawString(context, this.getName() + " " + ChatFormatting.GRAY + (this.setting.getValue() instanceof Float ? this.setting.getValue() : Double.valueOf((this.setting.getValue()).doubleValue())), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), -1);
|
||||
drawString(context, this.getName() + " " + ChatFormatting.GRAY + (this.setting.getValue() instanceof Float ? this.setting.getValue() : Double.valueOf((this.setting.getValue()).doubleValue())), this.x + 2.3f, textY(), -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package cc.fros.features.gui.items.buttons;
|
||||
|
||||
import cc.fros.Fros;
|
||||
import cc.fros.features.gui.FrosGui;
|
||||
import cc.fros.features.modules.client.ClickGuiModule;
|
||||
import cc.fros.features.settings.Setting;
|
||||
import cc.fros.util.models.Timer;
|
||||
@@ -38,9 +37,9 @@ public class StringButton
|
||||
public void drawScreen(GuiGraphics context, int mouseX, int mouseY, float partialTicks) {
|
||||
RenderUtil.rect(context, this.x, this.y, this.x + (float) this.width + 7.4f, this.y + (float) this.height - 0.5f, this.getState() ? (!this.isHovering(mouseX, mouseY) ? Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().color.getValue().getAlpha()) : Fros.colorManager.getColorWithAlpha(y, ClickGuiModule.getInstance().topColor.getValue().getAlpha())) : (!this.isHovering(mouseX, mouseY) ? 0x11555555 : -2007673515));
|
||||
if (this.isListening) {
|
||||
drawString(context, this.currentString.string() + getIdleSign(), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
|
||||
drawString(context, this.currentString.string() + getIdleSign(), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406);
|
||||
} else {
|
||||
drawString(context, (this.setting.getName().equals("Buttons") ? "Buttons " : (this.setting.getName().equals("Prefix") ? "Prefix " + ChatFormatting.GRAY : "")) + this.setting.getValue(), this.x + 2.3f, this.y - 1.7f - (float) FrosGui.getClickGui().getTextOffset(), this.getState() ? -1 : -5592406);
|
||||
drawString(context, (this.setting.getName().equals("Buttons") ? "Buttons " : (this.setting.getName().equals("Prefix") ? "Prefix " + ChatFormatting.GRAY : "")) + this.setting.getValue(), this.x + 2.3f, textY(), this.getState() ? -1 : -5592406);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@ import static cc.fros.features.commands.MessageSignatures.GENERAL;
|
||||
public class ClickGuiModule extends Module {
|
||||
private static ClickGuiModule INSTANCE;
|
||||
|
||||
public final Setting<Boolean> minecraftFont = bool("MinecraftFont", false);
|
||||
public final Setting<String> font = str("Font", "SansSerif");
|
||||
public final Setting<Integer> fontSize = num("FontSize", 10, 6, 24);
|
||||
public final Setting<Float> guiScale = num("GUIScale", 1.0f, 0.5f, 2.0f);
|
||||
public final Setting<String> prefix = str("Prefix", ".");
|
||||
public final Setting<Color> color = color("Color", 0, 0, 255, 180);
|
||||
public final Setting<Color> topColor = color("TopColor", 0, 0, 150, 240);
|
||||
@@ -30,8 +30,7 @@ public class ClickGuiModule extends Module {
|
||||
public ClickGuiModule() {
|
||||
super("ClickGui", "Opens the ClickGui", Module.Category.CLIENT);
|
||||
setBind(GLFW.GLFW_KEY_RIGHT_SHIFT);
|
||||
font.setVisibility(v -> !minecraftFont.getValue());
|
||||
fontSize.setVisibility(v -> !minecraftFont.getValue() && !font.getValue().isEmpty());
|
||||
fontSize.setVisibility(v -> !font.getValue().isEmpty());
|
||||
rainbowHue.setVisibility(v -> rainbow.getValue());
|
||||
rainbowBrightness.setVisibility(v -> rainbow.getValue());
|
||||
rainbowSaturation.setVisibility(v -> rainbow.getValue());
|
||||
@@ -75,4 +74,9 @@ public class ClickGuiModule extends Module {
|
||||
public static ClickGuiModule getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/** ui scale factor applied to the client's own hud and clickgui */
|
||||
public static float scale() {
|
||||
return INSTANCE == null ? 1f : Math.max(0.5f, INSTANCE.guiScale.getValue());
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,16 @@ import cc.fros.util.render.RenderUtil;
|
||||
import net.minecraft.client.gui.screens.ChatScreen;
|
||||
import org.joml.Vector2f;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class HudModule extends Module {
|
||||
public final Setting<Vector2f> pos = vec2f("Position", 0.5f, 0.5f);
|
||||
|
||||
/** grid snap lines (gui units) for dragged hud elements */
|
||||
private static final float SNAP_GRID = 4f;
|
||||
/** how close a dragged element gets to another's edge/center before it attracts */
|
||||
private static final float SNAP_RANGE = 4f;
|
||||
|
||||
private float dragX, dragY, width, height;
|
||||
private boolean dragging, button;
|
||||
|
||||
@@ -30,19 +37,36 @@ public abstract class HudModule extends Module {
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
float scaledHeight = getHeight() * ClickGuiModule.scale();
|
||||
float heightWithChat = mc.getWindow().getGuiScaledHeight() - 14;
|
||||
float baseY = mc.getWindow().getGuiScaledHeight() * pos.getValue().y();
|
||||
float combined = baseY + getHeight();
|
||||
float combined = baseY + scaledHeight;
|
||||
|
||||
if (mc.screen instanceof ChatScreen) {
|
||||
baseY = Math.min(combined, heightWithChat) - getHeight();
|
||||
baseY = Math.min(combined, heightWithChat) - scaledHeight;
|
||||
}
|
||||
return baseY;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onRender2DHud(Render2DEvent e) {
|
||||
render(e);
|
||||
float scale = ClickGuiModule.scale();
|
||||
if (scale == 1f) {
|
||||
render(e);
|
||||
return;
|
||||
}
|
||||
// scale the element about its own position anchor so content,
|
||||
// editor box and hover label all grow together
|
||||
float anchorX = getX();
|
||||
float anchorY = getY();
|
||||
e.getContext().pose().pushMatrix();
|
||||
e.getContext().pose().translate(anchorX * (1f - scale), anchorY * (1f - scale));
|
||||
e.getContext().pose().scale(scale, scale);
|
||||
try {
|
||||
render(e);
|
||||
} finally {
|
||||
e.getContext().pose().popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -75,12 +99,16 @@ public abstract class HudModule extends Module {
|
||||
}
|
||||
|
||||
if (dragging) {
|
||||
float finalX = Math.min(Math.max(getMouseX() - dragX, 0),
|
||||
mc.getWindow().getGuiScaledWidth() - width);
|
||||
float finalY = Math.min(Math.max(getMouseY() - dragY, 0),
|
||||
mc.getWindow().getGuiScaledHeight() - height);
|
||||
float scale = ClickGuiModule.scale();
|
||||
float maxX = mc.getWindow().getGuiScaledWidth() - width * scale;
|
||||
float maxY = mc.getWindow().getGuiScaledHeight() - height * scale;
|
||||
float rawX = Math.min(Math.max(getMouseX() - dragX, 0), maxX);
|
||||
float rawY = Math.min(Math.max(getMouseY() - dragY, 0), maxY);
|
||||
// snap to other elements first, grid otherwise, then re-clamp
|
||||
float snappedX = Math.min(Math.max(snapAxis(rawX, width * scale, true, scale), 0), maxX);
|
||||
float snappedY = Math.min(Math.max(snapAxis(rawY, height * scale, false, scale), 0), maxY);
|
||||
|
||||
pos.setValue(new Vector2f(finalX, finalY)
|
||||
pos.setValue(new Vector2f(snappedX, snappedY)
|
||||
.div(mc.getWindow().getGuiScaledWidth(), mc.getWindow().getGuiScaledHeight()));
|
||||
}
|
||||
} else {
|
||||
@@ -95,12 +123,14 @@ public abstract class HudModule extends Module {
|
||||
if (shouldDrawDescription) {
|
||||
int textWidth = FrosFont.width(getName());
|
||||
int textHeight = FrosFont.lineHeight();
|
||||
float scale = ClickGuiModule.scale();
|
||||
float textX = x + width + 5;
|
||||
if (textX + textWidth > mc.getWindow().getGuiScaledWidth()) {
|
||||
// the label is drawn inside the element's scale transform
|
||||
if (x + (textX + textWidth - x) * scale > mc.getWindow().getGuiScaledWidth()) {
|
||||
textX = x - 5 - textWidth;
|
||||
}
|
||||
FrosFont.draw(e.getContext(), getName(),
|
||||
(int) textX, (int) (y + height / 2f - textHeight / 2f), -1, true);
|
||||
(int) textX, (int) (y + height / 2f - textHeight / 2f), -1);
|
||||
HudEditorScreen.getInstance().anyHover = true;
|
||||
}
|
||||
|
||||
@@ -129,9 +159,47 @@ public abstract class HudModule extends Module {
|
||||
float y = getY();
|
||||
int mouseX = getMouseX();
|
||||
int mouseY = getMouseY();
|
||||
float scale = ClickGuiModule.scale();
|
||||
|
||||
return mouseX >= x - 1 && mouseX <= x + width + 1 &&
|
||||
mouseY >= y - 1 && mouseY <= y + height + 1;
|
||||
return mouseX >= x - 1 && mouseX <= x + width * scale + 1 &&
|
||||
mouseY >= y - 1 && mouseY <= y + height * scale + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drags on to another visible hud element's left/center/right (or
|
||||
* top/middle/bottom) when within {@link #SNAP_RANGE}; otherwise rounds
|
||||
* onto the {@link #SNAP_GRID} grid so everything stays tidy.
|
||||
*/
|
||||
private float snapAxis(float position, float size, boolean horizontal, float scale) {
|
||||
float bestDelta = 0f;
|
||||
boolean aligned = false;
|
||||
|
||||
for (HudModule other : hudModules()) {
|
||||
if (other == this || !other.isEnabled()) continue;
|
||||
float otherPos = horizontal ? other.getX() : other.getY();
|
||||
float otherSize = horizontal ? other.getWidth() * scale : other.getHeight() * scale;
|
||||
float[] mine = {position, position + size / 2f, position + size};
|
||||
float[] theirs = {otherPos, otherPos + otherSize / 2f, otherPos + otherSize};
|
||||
for (float mineAnchor : mine) {
|
||||
for (float theirAnchor : theirs) {
|
||||
float delta = theirAnchor - mineAnchor;
|
||||
if (Math.abs(delta) <= SNAP_RANGE && (!aligned || Math.abs(delta) < Math.abs(bestDelta))) {
|
||||
bestDelta = delta;
|
||||
aligned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aligned) return position + bestDelta;
|
||||
return Math.round(position / SNAP_GRID) * SNAP_GRID;
|
||||
}
|
||||
|
||||
private static List<HudModule> hudModules() {
|
||||
return Fros.moduleManager.stream()
|
||||
.filter(module -> module instanceof HudModule)
|
||||
.map(module -> (HudModule) module)
|
||||
.toList();
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
|
||||
@@ -72,7 +72,7 @@ public final class FrosFont {
|
||||
private static final List<Identifier> PENDING_RELEASE = new ArrayList<>();
|
||||
private static long lastQueuedAt;
|
||||
|
||||
private record Key(int color, String text) {
|
||||
private record Key(int color, String text, boolean shadow) {
|
||||
}
|
||||
|
||||
private record Glyph(Identifier id, int width, int height) {
|
||||
@@ -82,7 +82,9 @@ public final class FrosFont {
|
||||
private static FontMetrics metrics;
|
||||
private static String loadedName;
|
||||
private static float loadedSize = Float.NaN;
|
||||
private static int loadedScale = 1;
|
||||
private static float loadedScale = 1;
|
||||
/** raster pixels from the top of a line box to the middle of the cap band */
|
||||
private static float visualCenterRaster = 4f;
|
||||
private static long lastAttempt;
|
||||
private static int glyphCounter;
|
||||
|
||||
@@ -110,19 +112,21 @@ public final class FrosFont {
|
||||
|
||||
/** converts a raster pixel measurement to gui units */
|
||||
private static int toGui(int pixels) {
|
||||
return (pixels + loadedScale - 1) / loadedScale;
|
||||
return (int) Math.ceil(pixels / (double) loadedScale);
|
||||
}
|
||||
|
||||
private static int currentScale() {
|
||||
private static float currentScale() {
|
||||
try {
|
||||
return Math.max(1, (int) Math.round(mc.getWindow().getGuiScale()));
|
||||
// one raster pixel per screen pixel, following both mc's gui scale
|
||||
// and the client's own ui scale slider
|
||||
return Math.max(0.5f, (float) (mc.getWindow().getGuiScale() * ClickGuiModule.scale()));
|
||||
} catch (Exception e) {
|
||||
return 1;
|
||||
return 1f;
|
||||
}
|
||||
}
|
||||
|
||||
public static void draw(GuiGraphics context, String text, int x, int y, int color) {
|
||||
draw(context, text, x, y, color, false);
|
||||
draw(context, text, x, y, color, true);
|
||||
}
|
||||
|
||||
public static void draw(GuiGraphics context, String text, int x, int y, int color, boolean shadow) {
|
||||
@@ -132,29 +136,28 @@ public final class FrosFont {
|
||||
context.drawString(mc.font, text, x, y, color, shadow);
|
||||
return;
|
||||
}
|
||||
if (shadow) drawGlyphs(context, text, x + 1, y + 1, shadowColor(color));
|
||||
drawGlyphs(context, text, x, y, color);
|
||||
if (shadow) drawGlyphs(context, text, x + 1, y + 1, color, true);
|
||||
drawGlyphs(context, text, x, y, color, false);
|
||||
}
|
||||
|
||||
public static void draw(GuiGraphics context, Component component, int x, int y, int color) {
|
||||
if (component == null) return;
|
||||
sync();
|
||||
if (awtFont == null) {
|
||||
context.drawString(mc.font, component, x, y, color);
|
||||
context.drawString(mc.font, component, x, y, color, true);
|
||||
return;
|
||||
}
|
||||
draw(context, toCodeString(component), x, y, color, false);
|
||||
draw(context, toCodeString(component), x, y, color);
|
||||
}
|
||||
|
||||
// --- loading ---
|
||||
|
||||
private static void sync() {
|
||||
ClickGuiModule gui = ClickGuiModule.getInstance();
|
||||
boolean vanilla = gui != null && gui.minecraftFont.getValue();
|
||||
String name = gui == null || vanilla ? "" : gui.font.getValue();
|
||||
String name = gui == null ? "" : gui.font.getValue();
|
||||
int size = gui == null ? 10 : gui.fontSize.getValue();
|
||||
if (name == null) name = "";
|
||||
int scale = currentScale();
|
||||
float scale = currentScale();
|
||||
|
||||
boolean changed = !Objects.equals(name, loadedName) || size != loadedSize || scale != loadedScale;
|
||||
if (!changed) {
|
||||
@@ -166,7 +169,7 @@ public final class FrosFont {
|
||||
reset(name, size, scale, changed);
|
||||
}
|
||||
|
||||
private static void reset(String name, float size, int scale, boolean verbose) {
|
||||
private static void reset(String name, float size, float scale, boolean verbose) {
|
||||
loadedName = name;
|
||||
loadedSize = size;
|
||||
loadedScale = scale;
|
||||
@@ -210,10 +213,33 @@ public final class FrosFont {
|
||||
Graphics2D graphics = probe.createGraphics();
|
||||
graphics.setFont(awtFont);
|
||||
metrics = graphics.getFontMetrics();
|
||||
// distance from the top of the line box to the middle of the cap band:
|
||||
// drawString puts the baseline at metrics.getAscent(), and "A" spans
|
||||
// from the baseline up to the cap line
|
||||
java.awt.geom.Rectangle2D capBounds = awtFont
|
||||
.createGlyphVector(graphics.getFontRenderContext(), "A")
|
||||
.getVisualBounds();
|
||||
float capHeight = (float) capBounds.getHeight();
|
||||
if (capHeight <= 0f || capHeight > metrics.getAscent()) {
|
||||
capHeight = metrics.getAscent();
|
||||
}
|
||||
visualCenterRaster = metrics.getAscent() - capHeight / 2f;
|
||||
graphics.dispose();
|
||||
if (verbose) LOGGER.info("{} ({}pt)", source, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Distance from the top of a line box down to the visual center of its
|
||||
* text (middle of the cap band), in gui units. lets callers center labels
|
||||
* by what the eye sees instead of the line box, and behaves the same for
|
||||
* the custom font and the vanilla fallback.
|
||||
*/
|
||||
public static float visualCenter() {
|
||||
sync();
|
||||
if (awtFont == null) return mc.font.lineHeight / 2f - 1f;
|
||||
return visualCenterRaster / loadedScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves java's logical fonts (guaranteed on every os) and any font
|
||||
* family already installed on the system, without needing a file.
|
||||
@@ -286,12 +312,12 @@ public final class FrosFont {
|
||||
|
||||
// --- rasterizing ---
|
||||
|
||||
private static void drawGlyphs(GuiGraphics context, String text, int x, int y, int color) {
|
||||
private static void drawGlyphs(GuiGraphics context, String text, int x, int y, int color, boolean shadow) {
|
||||
flushReleases();
|
||||
Key key = new Key(color, text);
|
||||
Key key = new Key(color, text, shadow);
|
||||
Glyph glyph = GLYPHS.get(key);
|
||||
if (glyph == null) {
|
||||
glyph = createGlyph(text, color);
|
||||
glyph = createGlyph(text, color, shadow);
|
||||
if (glyph == null) return;
|
||||
GLYPHS.put(key, glyph);
|
||||
}
|
||||
@@ -308,11 +334,11 @@ public final class FrosFont {
|
||||
context.pose().popMatrix();
|
||||
}
|
||||
|
||||
private static Glyph createGlyph(String text, int baseColor) {
|
||||
private static Glyph createGlyph(String text, int baseColor, boolean shadow) {
|
||||
String plain = stripCodes(text);
|
||||
if (plain.isEmpty()) return null;
|
||||
|
||||
int pad = loadedScale;
|
||||
int pad = Math.max(1, Math.round(loadedScale));
|
||||
int width = Math.max(1, metrics.stringWidth(plain));
|
||||
int height = metrics.getHeight();
|
||||
int imageWidth = width + 2 * pad;
|
||||
@@ -322,7 +348,7 @@ public final class FrosFont {
|
||||
Graphics2D graphics = image.createGraphics();
|
||||
graphics.setFont(awtFont);
|
||||
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
drawSegments(graphics, text, baseColor);
|
||||
drawSegments(graphics, text, baseColor, shadow);
|
||||
graphics.dispose();
|
||||
|
||||
NativeImage nativeImage = new NativeImage(imageWidth, imageHeight, false);
|
||||
@@ -344,8 +370,8 @@ public final class FrosFont {
|
||||
return new Glyph(id, imageWidth, imageHeight);
|
||||
}
|
||||
|
||||
private static void drawSegments(Graphics2D graphics, String text, int baseColor) {
|
||||
int baseline = metrics.getAscent() + loadedScale;
|
||||
private static void drawSegments(Graphics2D graphics, String text, int baseColor, boolean shadow) {
|
||||
int baseline = metrics.getAscent() + Math.round(loadedScale);
|
||||
int cursor = 1;
|
||||
int current = baseColor;
|
||||
int segmentStart = 0;
|
||||
@@ -353,7 +379,10 @@ public final class FrosFont {
|
||||
|
||||
while (i < text.length()) {
|
||||
if (text.charAt(i) == '\u00A7' && i + 1 < text.length()) {
|
||||
cursor = flush(graphics, text, segmentStart, i, cursor, current, baseline);
|
||||
// colored segments darken like vanilla's shadows do, instead
|
||||
// of punching through at full brightness
|
||||
cursor = flush(graphics, text, segmentStart, i, cursor,
|
||||
shadow ? shadowColor(current) : current, baseline);
|
||||
|
||||
char code = Character.toLowerCase(text.charAt(i + 1));
|
||||
i += 2;
|
||||
@@ -381,7 +410,8 @@ public final class FrosFont {
|
||||
}
|
||||
i++;
|
||||
}
|
||||
flush(graphics, text, segmentStart, text.length(), cursor, current, baseline);
|
||||
flush(graphics, text, segmentStart, text.length(), cursor,
|
||||
shadow ? shadowColor(current) : current, baseline);
|
||||
}
|
||||
|
||||
private static int flush(Graphics2D graphics, String text, int start, int end, int cursor, int color, int baseline) {
|
||||
|
||||
Reference in New Issue
Block a user