Compare commits
10
Commits
b81a4dda98
...
2cfd93c197
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cfd93c197 | ||
|
|
1ddfd9d024 | ||
|
|
5e44a71054 | ||
|
|
5dd4b17db5 | ||
|
|
3379acef80 | ||
|
|
f07750cdcb | ||
|
|
d73895ac7c | ||
|
|
7eb8b6a120 | ||
|
|
3e4985c6bc | ||
|
|
53dfa37b64 |
@@ -2,6 +2,7 @@ package org.saturnclient.client;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.saturnclient.client.player.SaturnPlayer;
|
||||
import org.saturnclient.common.provider.Providers;
|
||||
@@ -15,15 +16,48 @@ public class ServiceClient {
|
||||
private static Session session;
|
||||
public static UUID uuid;
|
||||
|
||||
public static void initialize() {
|
||||
new Thread(() -> {
|
||||
if (authenticate()) {
|
||||
Cloaks.initialize();
|
||||
Hats.initialize();
|
||||
Providers.saturn.logInfo("Saturn Session initialization complete");
|
||||
} else {
|
||||
Providers.saturn.logError("Failed to authenticate with the server");
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static boolean connectTimeout() {
|
||||
try {
|
||||
session = Session.connect("wss://saturn-server.selimaj.dev", 10, TimeUnit.SECONDS);
|
||||
session = Session.connect("wss://saturn-server.selimaj.dev", 2, TimeUnit.MINUTES);
|
||||
return true;
|
||||
} catch (TimeoutException e) {
|
||||
System.out.println("Session Server timeout");
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean connectMultiTimeout() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (connectTimeout()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Providers.saturn.logError("Failed to authenticate (attempt " + (i + 1) + ")");
|
||||
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean authenticate() {
|
||||
MinecraftClientRef client = Providers.saturn.getClient();
|
||||
|
||||
@@ -49,7 +83,7 @@ public class ServiceClient {
|
||||
|
||||
Providers.saturn.logInfo("Authenticating with UUID: " + uuid);
|
||||
|
||||
if (!connectTimeout()) {
|
||||
if (!connectMultiTimeout()) {
|
||||
Providers.saturn.logError("Unable to authenticate: Session Server Timeout");
|
||||
return false;
|
||||
}
|
||||
@@ -77,6 +111,9 @@ public class ServiceClient {
|
||||
}
|
||||
|
||||
public static void setCloak(String itemId) {
|
||||
if (session == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
session.request(ServiceMethods.SetCloak, itemId).whenComplete((msg, throwable) -> {
|
||||
if (throwable != null) {
|
||||
@@ -96,6 +133,9 @@ public class ServiceClient {
|
||||
}
|
||||
|
||||
public static void setHat(String itemId) {
|
||||
if (session == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
session.request(ServiceMethods.SetHat, itemId).whenComplete((msg, throwable) -> {
|
||||
if (throwable != null) {
|
||||
@@ -115,6 +155,9 @@ public class ServiceClient {
|
||||
}
|
||||
|
||||
public static void buyCloak(String itemId) {
|
||||
if (session == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
session.request(ServiceMethods.BuyCloak, itemId).whenComplete((msg, throwable) -> {
|
||||
if (throwable != null) {
|
||||
@@ -129,6 +172,9 @@ public class ServiceClient {
|
||||
}
|
||||
|
||||
public static void buyHat(String itemId) {
|
||||
if (session == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
session.request(ServiceMethods.BuyHat, itemId).whenComplete((msg, throwable) -> {
|
||||
if (throwable != null) {
|
||||
@@ -143,6 +189,9 @@ public class ServiceClient {
|
||||
}
|
||||
|
||||
public static void emote(String emote) {
|
||||
if (session == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
session.request(ServiceMethods.Emote,
|
||||
new ServiceMethods.Types.EmoteRequest(emote, SaturnPlayer.getExternalUUIDAsString()))
|
||||
@@ -157,6 +206,9 @@ public class ServiceClient {
|
||||
}
|
||||
|
||||
public static void eventHandlers() {
|
||||
if (session == null)
|
||||
return;
|
||||
|
||||
session.onNotification(ServiceMethods.EmoteEvent, (data) -> {
|
||||
if (data == null) {
|
||||
return;
|
||||
@@ -182,6 +234,9 @@ public class ServiceClient {
|
||||
}
|
||||
|
||||
public static SaturnPlayer getPlayer(UUID uuid, String name) {
|
||||
if (session == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
ServiceMethods.Types.Player player = session.request(ServiceMethods.GetPlayer, uuid.toString()).join();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.saturnclient.common.ref.game;
|
||||
|
||||
import org.saturnclient.common.ref.asset.IdentifierRef;
|
||||
import org.saturnclient.common.ref.asset.SpriteRef;
|
||||
|
||||
public interface EffectRef {
|
||||
@@ -7,6 +8,10 @@ public interface EffectRef {
|
||||
|
||||
SpriteRef getIcon();
|
||||
|
||||
default IdentifierRef getIconId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isInfinite();
|
||||
|
||||
String getInfiniteText();
|
||||
|
||||
@@ -1,91 +1,154 @@
|
||||
package org.saturnclient.mod.mods;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.saturnclient.common.provider.Providers;
|
||||
import org.saturnclient.common.provider.GLFWProvider;
|
||||
import org.saturnclient.config.property.BoolProperty;
|
||||
import org.saturnclient.config.property.FloatProperty;
|
||||
import org.saturnclient.config.property.IntProperty;
|
||||
import org.saturnclient.config.property.KeybindingProperty;
|
||||
import org.saturnclient.config.property.Property;
|
||||
import org.saturnclient.config.property.SelectProperty;
|
||||
import org.saturnclient.mod.Mod;
|
||||
import org.saturnclient.mod.ModSpec;
|
||||
import org.saturnclient.common.feature.RenderFeature;
|
||||
import org.saturnclient.common.provider.GLFWProvider;
|
||||
import org.saturnclient.ui.anim.Animation;
|
||||
|
||||
/**
|
||||
* FreelookMod lets the player look around freely (in third-person)
|
||||
* without changing the direction their character walks.
|
||||
*
|
||||
* Camera perspective is controlled through {@link RenderFeature} so
|
||||
* that the feature itself contains no direct Minecraft API calls.
|
||||
*/
|
||||
public class FreelookMod extends Mod {
|
||||
|
||||
// --- Properties ---
|
||||
private static final BoolProperty enabled = Property.bool(false);
|
||||
private static final BoolProperty toggle = Property.bool(true);
|
||||
public static final KeybindingProperty freelookKey = Property.keybinding(GLFWProvider.GLFW_KEY_H);
|
||||
private static final KeybindingProperty freelookKey = Property.keybinding(GLFWProvider.GLFW_KEY_H);
|
||||
|
||||
/** Whether freelook is currently active (read by the camera mixin). */
|
||||
public static boolean isFreeLooking = false;
|
||||
public static final FloatProperty zoomLevel = Property.floatProp(2.0f);
|
||||
public static final IntProperty zoomInDuration = Property.integer(500);
|
||||
public static final IntProperty zoomOutDuration = Property.integer(300);
|
||||
public static final SelectProperty curve = Property.select(1, "Ease In Out Cubic", "Ease Out Cubic", "Ease In Out Back");
|
||||
|
||||
// --- State Variables ---
|
||||
private static boolean isFreeLooking = false;
|
||||
private static boolean targetFreeLook = false;
|
||||
private static boolean wasFirstPerson = false;
|
||||
|
||||
// --- Animation State ---
|
||||
private static long animationStartTime = System.currentTimeMillis();
|
||||
|
||||
public FreelookMod() {
|
||||
super(
|
||||
new ModSpec("Freelook", "freelook")
|
||||
.description("Look around freely without moving your character")
|
||||
.tags("Movement", "Camera")
|
||||
.version("v0.2.0")
|
||||
.version("v0.3.1")
|
||||
.requires(Providers.feature::render),
|
||||
enabled.named("Enabled"),
|
||||
toggle.named("Toggle freelook"),
|
||||
freelookKey.named("Freelook Keybinding"));
|
||||
freelookKey.named("Freelook Keybinding"),
|
||||
zoomLevel.named("Zoom Level"),
|
||||
zoomInDuration.named("Zoom In Duration"),
|
||||
zoomOutDuration.named("Zoom Out Duration"),
|
||||
curve.named("Curve"));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Mod contract
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (toggle.value) {
|
||||
if (freelookKey.wasKeyPressed()) {
|
||||
if (isFreeLooking)
|
||||
stopFreelook();
|
||||
else
|
||||
startFreelook();
|
||||
}
|
||||
} else if (freelookKey.isKeyPressed()) {
|
||||
if (!isFreeLooking)
|
||||
startFreelook();
|
||||
} else if (isFreeLooking) {
|
||||
stopFreelook();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
if (!e && isFreeLooking)
|
||||
stopFreelook();
|
||||
}
|
||||
// --- Lifecycle Methods ---
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled.value;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Helpers
|
||||
// ---------------------------------------------------------------
|
||||
@Override
|
||||
public void onEnabled(boolean e) {
|
||||
enabled.value = e;
|
||||
if (!e && isFreeLooking) {
|
||||
stopFreelook();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
handleInput();
|
||||
|
||||
// If we are returning to normal and animation finished, snap back to 1st person
|
||||
if (!targetFreeLook && wasFirstPerson && getProgress() <= 0.0f) {
|
||||
Providers.feature.render().setFirstPerson();
|
||||
wasFirstPerson = false;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Internal Logic ---
|
||||
|
||||
private void handleInput() {
|
||||
if (toggle.value) {
|
||||
if (freelookKey.wasKeyPressed()) {
|
||||
targetFreeLook = !targetFreeLook;
|
||||
toggleFreelookState(targetFreeLook);
|
||||
}
|
||||
} else {
|
||||
boolean isDown = freelookKey.isKeyPressed();
|
||||
if (isDown != targetFreeLook) { // state changed
|
||||
targetFreeLook = isDown;
|
||||
toggleFreelookState(targetFreeLook);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleFreelookState(boolean active) {
|
||||
if (active) {
|
||||
startFreelook();
|
||||
} else {
|
||||
stopFreelook();
|
||||
}
|
||||
}
|
||||
|
||||
private void startFreelook() {
|
||||
RenderFeature render = Providers.feature.render();
|
||||
wasFirstPerson = render.isFirstPerson();
|
||||
render.setThirdPersonBack();
|
||||
isFreeLooking = true;
|
||||
animationStartTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void stopFreelook() {
|
||||
if (wasFirstPerson) {
|
||||
Providers.feature.render().setFirstPerson();
|
||||
if (isFreeLooking) {
|
||||
isFreeLooking = false;
|
||||
animationStartTime = System.currentTimeMillis();
|
||||
}
|
||||
isFreeLooking = false;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Math Utilities ---
|
||||
|
||||
private static float getProgress() {
|
||||
if (!wasFirstPerson) return 0.0f;
|
||||
|
||||
int duration = isFreeLooking ? zoomInDuration.value : zoomOutDuration.value;
|
||||
long now = System.currentTimeMillis();
|
||||
float rawProgress = (now - animationStartTime) / (float) duration;
|
||||
|
||||
return isFreeLooking ? clamp(rawProgress, 0.0f, 1.0f) : clamp(1.0f - rawProgress, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
private static float clamp(float value, float min, float max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
|
||||
// --- Public API / Getters for External Hooks ---
|
||||
|
||||
public static boolean isFreeLooking() {
|
||||
return isFreeLooking || getProgress() > 0;
|
||||
}
|
||||
|
||||
public static boolean shouldZoomOut() {
|
||||
return enabled.value && wasFirstPerson && isFreeLooking();
|
||||
}
|
||||
|
||||
public static float getZoomLevel() {
|
||||
float progress = getProgress();
|
||||
|
||||
Function<Double, Double> curveFn = Animation.getCurve(curve.value);
|
||||
double curved = curveFn.apply((double) progress);
|
||||
|
||||
return zoomLevel.value - (float) curved * (zoomLevel.value - 1.0f);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import java.util.List;
|
||||
|
||||
import org.saturnclient.common.provider.FeatureProvider;
|
||||
import org.saturnclient.common.provider.Providers;
|
||||
import org.saturnclient.common.ref.asset.SpriteRef;
|
||||
import org.saturnclient.common.ref.game.EffectRef;
|
||||
import org.saturnclient.config.property.BoolProperty;
|
||||
import org.saturnclient.config.property.Property;
|
||||
@@ -63,7 +64,12 @@ public class StatusEffectsMod extends Mod implements HudMod {
|
||||
if (!effect.shouldShowIcon())
|
||||
continue;
|
||||
|
||||
scope.drawSpriteStretched(effect.getIcon(), 0, 18 * row, 16, 16);
|
||||
SpriteRef sprite = effect.getIcon();
|
||||
if (sprite == null) {
|
||||
scope.drawTexture(effect.getIconId(), 0, 18 * row, 0, 0, 16, 16);
|
||||
} else {
|
||||
scope.drawSpriteStretched(sprite, 0, 18 * row, 16, 16);
|
||||
}
|
||||
scope.drawText(0.5f, durationString(effect),
|
||||
18, 18 * row + 3,
|
||||
layout.font.value, -1);
|
||||
|
||||
@@ -1,30 +1,28 @@
|
||||
package org.saturnclient.mod.mods;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.saturnclient.common.provider.GLFWProvider;
|
||||
import org.saturnclient.config.property.BoolProperty;
|
||||
import org.saturnclient.config.property.FloatProperty;
|
||||
import org.saturnclient.config.property.IntProperty;
|
||||
import org.saturnclient.config.property.KeybindingProperty;
|
||||
import org.saturnclient.config.property.Property;
|
||||
import org.saturnclient.config.property.SelectProperty;
|
||||
import org.saturnclient.mod.Mod;
|
||||
import org.saturnclient.mod.ModSpec;
|
||||
import org.saturnclient.ui.anim.Animation;
|
||||
|
||||
/**
|
||||
* ZoomMod multiplies the camera's field-of-view to create an
|
||||
* optical-zoom effect.
|
||||
*
|
||||
* The FOV override is applied inside a mixin that polls
|
||||
* {@link #shouldZoom()} and {@link #getZoomLevel()} each frame.
|
||||
* No FeatureProvider is needed — there is no per-tick engine query.
|
||||
*/
|
||||
public class ZoomMod extends Mod {
|
||||
|
||||
private static final BoolProperty enabled = Property.bool(false);
|
||||
private static final BoolProperty toggle = Property.bool(false);
|
||||
public static final KeybindingProperty zoomKey = Property.keybinding(GLFWProvider.GLFW_KEY_C);
|
||||
public static final FloatProperty zoomLevel = Property.floatProp(3.0f);
|
||||
|
||||
/** Whether zoom is currently active (read by the FOV mixin). */
|
||||
public static boolean isZooming = false;
|
||||
public static final IntProperty zoomInDuration = Property.integer(700);
|
||||
public static final IntProperty zoomOutDuration = Property.integer(300);
|
||||
public static final SelectProperty curve = Property.select(1, "Ease In Out Cubic", "Ease Out Cubic",
|
||||
"Ease In Out Back");
|
||||
|
||||
public ZoomMod() {
|
||||
super(
|
||||
@@ -35,15 +33,31 @@ public class ZoomMod extends Mod {
|
||||
enabled.named("Enabled"),
|
||||
toggle.named("Toggle zoom"),
|
||||
zoomKey.named("Zoom Keybinding"),
|
||||
zoomLevel.named("Zoom Level"));
|
||||
zoomLevel.named("Zoom Level"),
|
||||
zoomInDuration.named("Zoom In Duration"),
|
||||
zoomOutDuration.named("Zoom Out Duration"),
|
||||
curve.named("Curve"));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Mod fields
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/** Zooming state */
|
||||
public static boolean isZooming = false;
|
||||
|
||||
/** Animation state */
|
||||
private static float progress = 0f; // 0 → 1
|
||||
private static long lastTime = System.currentTimeMillis();
|
||||
private static boolean lastTarget = false; // remember previous zoom state
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Mod contract
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
// Update target zoom state
|
||||
if (toggle.value) {
|
||||
if (zoomKey.wasKeyPressed()) {
|
||||
isZooming = !isZooming;
|
||||
@@ -71,11 +85,41 @@ public class ZoomMod extends Mod {
|
||||
|
||||
/** Returns {@code true} when the FOV override should be applied. */
|
||||
public static boolean shouldZoom() {
|
||||
return enabled.value && isZooming;
|
||||
return enabled.value && (isZooming || progress > 0f);
|
||||
}
|
||||
|
||||
public static int getZoomDuration() {
|
||||
if (isZooming) {
|
||||
return zoomInDuration.value;
|
||||
} else {
|
||||
return zoomOutDuration.value;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the zoom divisor (e.g. 3.0 → one-third of normal FOV). */
|
||||
public static float getZoomLevel() {
|
||||
return zoomLevel.value;
|
||||
// Detect target change and reset timer
|
||||
if (isZooming != lastTarget) {
|
||||
lastTime = System.currentTimeMillis();
|
||||
lastTarget = isZooming;
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
float delta = (now - lastTime) / (float) getZoomDuration();
|
||||
lastTime = now;
|
||||
|
||||
// Animate progress toward target
|
||||
if (isZooming) {
|
||||
progress = Math.min(1f, progress + delta);
|
||||
} else {
|
||||
progress = Math.max(0f, progress - delta);
|
||||
}
|
||||
|
||||
// Apply curve
|
||||
Function<Double, Double> curveFn = Animation.getCurve(curve.value);
|
||||
double curved = curveFn.apply((double) progress);
|
||||
|
||||
// Map to zoom level
|
||||
return 1.0f + (float) curved * (zoomLevel.value - 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,9 @@ public interface RenderScope {
|
||||
default void drawRoundedRectangle(int x, int y, int width, int height, int radius, int color) {
|
||||
if (color == 0)
|
||||
return;
|
||||
radius = Math.min(radius, Math.min(width, height));
|
||||
|
||||
radius = Math.min(radius, width / 2);
|
||||
radius = Math.min(radius, height / 2);
|
||||
|
||||
String svg = String.format(
|
||||
"<svg xmlns='http://www.w3.org/2000/svg' width='%d' height='%d'>" +
|
||||
@@ -45,8 +47,9 @@ public interface RenderScope {
|
||||
InputStream svgStream = new ByteArrayInputStream(svg.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
drawTexture(SvgTexture.getSvg(svgStream,
|
||||
IdentifierRef.ofSaturn("textures/gui/tmp_rect/rounded_" + width + "_" + height + "_" + radius),
|
||||
width * 3, height * 3), x, y, 0, 0, width, height, color);
|
||||
IdentifierRef.ofSaturn(
|
||||
"textures/gui/tmp_rect/rounded_" + width + "_" + height + "_" + radius),
|
||||
width * 4, height * 4), x, y, 0, 0, width, height, color);
|
||||
}
|
||||
|
||||
void drawBorder(int x, int y, int width, int height, int color);
|
||||
|
||||
@@ -10,21 +10,22 @@ public abstract class Animation {
|
||||
public int delay = 0;
|
||||
public Function<Double, Double> curve = Curve::easeInOutCubic;
|
||||
|
||||
public static Function<Double, Double> getCurve(int curve) {
|
||||
switch (curve) {
|
||||
case 0:
|
||||
return Curve::easeInOutCubic;
|
||||
case 1:
|
||||
return Curve::easeOutCubic;
|
||||
case 2:
|
||||
return Curve::easeInOutBack;
|
||||
default:
|
||||
return Curve::easeOutCubic;
|
||||
}
|
||||
}
|
||||
|
||||
Animation(AnimationConfig config) {
|
||||
this.duration = config.duration.value;
|
||||
switch (config.curve.value) {
|
||||
case 0:
|
||||
this.curve = Curve::easeInOutCubic;
|
||||
break;
|
||||
case 1:
|
||||
this.curve = Curve::easeOutCubic;
|
||||
break;
|
||||
case 2:
|
||||
this.curve = Curve::easeInOutBack;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.curve = getCurve(config.curve.value);
|
||||
}
|
||||
|
||||
Animation(int duration) {
|
||||
|
||||
@@ -64,19 +64,18 @@ public abstract class Input extends Element {
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
checkReset();
|
||||
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, 0xFF000000);
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, 10, Theme.PRIMARY.value);
|
||||
|
||||
int scrollOffset = getScrollOffset();
|
||||
String visibleText = getVisibleText(scrollOffset);
|
||||
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
|
||||
renderScope.drawText(0.6f, visibleText, 4, 4, Theme.FONT.value, textColor);
|
||||
renderScope.drawText(0.6f, visibleText, 4, 4, Theme.FONT.value, Theme.PRIMARY_FG.value);
|
||||
|
||||
if (focused) {
|
||||
int cursorX = 4 +
|
||||
(int) (Fonts.getWidth(visibleText.substring(0, cursorPosition - scrollOffset), Theme.FONT.value)
|
||||
* 0.6f);
|
||||
|
||||
renderScope.drawRectangle(cursorX, 2, 1, height - 4, 0xFFFFFFFF);
|
||||
renderScope.drawRectangle(cursorX, 2, 1, height - 4, Theme.ACCENT.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ public class Toggle extends Element {
|
||||
|
||||
@Override
|
||||
public void render(RenderScope renderScope, ElementContext ctx) {
|
||||
renderScope.drawRoundedRectangle(0, 0, width, height, height,
|
||||
renderScope.drawRoundedRectangle(0, 0, 60, 30, Theme.WIDGET_RADIUS.value,
|
||||
Theme.withAlpha(0.5f, prop.value ? Theme.ACCENT.value : Theme.PRIMARY.value));
|
||||
renderScope.drawRoundedRectangle(prop.value ? 30 : 0, 0, 30, 30, 30,
|
||||
renderScope.drawRoundedRectangle(prop.value ? 30 : 0, 0, 30, 30, Theme.WIDGET_RADIUS.value,
|
||||
prop.value ? Theme.ACCENT.value : Theme.PRIMARY.value);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user