Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1'
implementation "meteordevelopment:orbit:0.2.3"
include "meteordevelopment:orbit:0.2.3"

implementation "io.github.humbleui:skija-shared:0.143.11"
include "io.github.humbleui:skija-shared:0.143.11"
implementation "io.github.humbleui:skija-windows-x64:0.143.11"
include "io.github.humbleui:skija-windows-x64:0.143.11"
implementation "io.github.humbleui:skija-linux-x64:0.143.11"
include "io.github.humbleui:skija-linux-x64:0.143.11"
implementation "io.github.humbleui:skija-linux-arm64:0.143.11"
include "io.github.humbleui:skija-linux-arm64:0.143.11"
implementation "io.github.humbleui:skija-macos-x64:0.143.11"
include "io.github.humbleui:skija-macos-x64:0.143.11"
implementation "io.github.humbleui:skija-macos-arm64:0.143.11"
include "io.github.humbleui:skija-macos-arm64:0.143.11"
}

processResources {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ loom_version=1.13-SNAPSHOT
fabric_kotlin_version=1.13.7+kotlin.2.2.21

# Mod Properties
mod_version=1.2.1
mod_version=1.2.2
maven_group=dev.oblongboot.sxp
archives_base_name=slayerxpoverlay

Expand Down
28 changes: 28 additions & 0 deletions src/main/java/dev/oblongboot/sxp/mixin/HotbarMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dev.oblongboot.sxp.mixin;

import dev.oblongboot.sxp.ui.SettingsScreen;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiGraphics;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(Gui.class)
public class HotbarMixin {
@Inject(method = "renderItemHotbar", at = @At("HEAD"), cancellable = true)
private void injectRenderHotbar(GuiGraphics guiGraphics, DeltaTracker deltaTracker, CallbackInfo ci) {
if (Minecraft.getInstance().screen instanceof SettingsScreen) {
ci.cancel();
}
}

@Inject(method = "renderCrosshair", at = @At("HEAD"), cancellable = true)
private void injectRenderCrosshair(GuiGraphics g, DeltaTracker d, CallbackInfo ci) {
if (Minecraft.getInstance().screen instanceof SettingsScreen) {
ci.cancel();
}
}
}
28 changes: 28 additions & 0 deletions src/main/java/dev/oblongboot/sxp/mixin/MinecraftMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package dev.oblongboot.sxp.mixin;

import net.minecraft.client.Minecraft;
import net.minecraft.client.main.GameConfig;
import dev.oblongboot.sxp.utils.skia.SkiaContext;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(Minecraft.class)
public class MinecraftMixin {

@Inject(method = "<init>", at = @At("TAIL"))
private void registerSkia(GameConfig gameConfig, CallbackInfo ci) {
int[] width = new int[1];
int[] height = new int[1];

long windowHandle = Minecraft.getInstance().getWindow().handle();
GLFW.glfwGetFramebufferSize(windowHandle, width, height);

int finalWidth = Math.max(width[0], 1);
int finalHeight = Math.max(height[0], 1);

SkiaContext.INSTANCE.initSkia(finalWidth, finalHeight);
}
}
27 changes: 27 additions & 0 deletions src/main/java/dev/oblongboot/sxp/mixin/WindowMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dev.oblongboot.sxp.mixin;

import com.mojang.blaze3d.platform.Window;
import dev.oblongboot.sxp.utils.skia.SkiaContext;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.TracyFrameCapture;

@Mixin(Window.class)
public class WindowMixin {

@Inject(method = "onFramebufferResize", at = @At("RETURN"))
private void onFramebufferResize(long window, int width, int height, CallbackInfo ci) {
int finalWidth = Math.max(width, 1);
int finalHeight = Math.max(height, 1);
System.out.println("Window resized to " + finalWidth + "x" + finalHeight);

SkiaContext.INSTANCE.initSkia(finalWidth, finalHeight);
}

@Inject(method = "updateDisplay", at = @At("HEAD"))
private void onUpdateDisplay(TracyFrameCapture capturer, CallbackInfo ci) {
SkiaContext.INSTANCE.draw();
}
}
4 changes: 2 additions & 2 deletions src/main/kotlin/dev/oblongboot/sxp/Slayerxpoverlay.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ object Slayerxpoverlay : ModInitializer {
try {
if (!shouldCheck) return@launch
shouldCheck = false
val updateAvailable = dev.oblongboot.sxp.utils.UpdateChecker.isUpdateAvailable("1.2.1")
val updateAvailable = dev.oblongboot.sxp.utils.UpdateChecker.isUpdateAvailable("1.2.2")
if (updateAvailable) {
Minecraft.getInstance().execute {
modMessage(
"A new version of SlayerXPOverlayFabric is available! " +
"You are running version v1.2.1. " +
"You are running version v1.2.2. " +
"Please check the GitHub page for the latest version."
)
}
Expand Down
37 changes: 27 additions & 10 deletions src/main/kotlin/dev/oblongboot/sxp/core/ButtonSetting.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,36 @@ class ButtonSetting(
description: String = "",
private val onClickAction: (() -> Unit)? = null
) : Setting<Boolean>(name, description, false) {
override var x = 0
override var y = 0
override val width = 240
override val height = 30

override fun render(ctx: GuiGraphics) {
val isHovered = isWithinBounds2(Render2D.Mouse.x.toInt(), Render2D.Mouse.y.toInt())
val baseColor = Color(50, 90, 150, 180)
val hoverColor = if (isHovered) baseColor.brighter() else baseColor
Render2D.drawWhateverTheFuckThisIs(ctx, x, y, width, height, 6, hoverColor)
Render2D.drawOutline(ctx, x, y, width, height, Color(0, 180, 255))
val textY = y + (height - Render2D.textRenderer.lineHeight) / 2
val textX = x + (width - Render2D.textRenderer.width(name)) / 2
override fun render(mouseX: Int, mouseY: Int) {
val skija = dev.oblongboot.sxp.utils.skia.SkijaRenderer
val isHovered = isWithinBounds2(mouseX, mouseY)
val baseColor = if (isHovered) skija.argb(160, 40, 80, 140) else skija.argb(100, 20, 40, 70)

skija.drawRoundedRect(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), 4f, baseColor)

if (isHovered) {
skija.drawRoundedGlow(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), 4f, skija.argb(60, 0, 120, 255), 10f, 1f)
}

val borderColor = if (isHovered) skija.argb(200, 0, 150, 255) else skija.argb(100, 0, 100, 200)
skija.drawRoundedRectBorderGradient(
x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), 4f, 1f,
borderColor, borderColor,
dev.oblongboot.sxp.utils.skia.SkijaRenderer.GradientDirection.TOP_LEFT_TO_BOTTOM_RIGHT
)

val font = dev.oblongboot.sxp.ui.SettingsScreen.elementFont
val textWidth = skija.getTextWidth(name, font)
val textY = y + height / 3.8f// - 5f
val textX = x + (width - textWidth) / 2f

Render2D.drawString(ctx, name, textX, textY, 1f, true)
val textColor = if (isHovered) skija.argb(255, 255, 255, 255) else skija.argb(255, 220, 230, 255)
skija.drawText(name, textX, textY, textColor, font)
}

override fun onClick(mouseX: Int, mouseY: Int): Boolean {
Expand All @@ -44,7 +61,7 @@ class ButtonSetting(
value = default
}

override fun onValueChanged(oldValue: Boolean, newValue: Boolean) {} // why am i even overrideing this
override fun onValueChanged(oldValue: Boolean, newValue: Boolean) {}

private fun isWithinBounds2(mouseX: Int, mouseY: Int): Boolean {
return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height
Expand Down
94 changes: 54 additions & 40 deletions src/main/kotlin/dev/oblongboot/sxp/core/CheckboxSetting.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class CheckboxSetting(
defaultSelected: Set<Int> = emptySet(),
description: String = ""
) : Setting<Set<Int>>(name, description, defaultSelected.toMutableSet()) {
override var x = 0
override var y = 0
override val width = 240
override val height = 30
private val optionHeight = 22
Expand All @@ -20,80 +22,92 @@ class CheckboxSetting(
private val animSpeed = 0.25f
private var expanded = false

override fun render(ctx: GuiGraphics) {
val baseColor = Color(50, 60, 90, 180)
val isHovered = isWithinBounds(Render2D.Mouse.x.toInt(), Render2D.Mouse.y.toInt())
val hoverColor = if (isHovered) baseColor.brighter() else baseColor
override fun render(mouseX: Int, mouseY: Int) {
val skija = dev.oblongboot.sxp.utils.skia.SkijaRenderer
val isHovered = isWithinBounds(mouseX, mouseY)
val baseColor = if (isHovered) skija.argb(160, 40, 80, 140) else skija.argb(100, 20, 40, 70)

val visibleOptionCount = options.size.coerceAtMost(maxVisibleOptions)
val targetHeight = if (expanded) visibleOptionCount * optionHeight else 0
animHeight += (targetHeight - animHeight) * animSpeed
Render2D.drawWhateverTheFuckThisIs(ctx, x, y, width, height, 6, hoverColor)
Render2D.drawOutline(ctx, x, y, width, height, Color(0, 180, 255))
val textY = y + (height - Render2D.textRenderer.lineHeight) / 2
Render2D.drawString(ctx, name, x + 10, textY, 1f, true)

skija.drawRoundedRect(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), 4f, baseColor)

if (isHovered) {
skija.drawRoundedGlow(x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), 4f, skija.argb(60, 0, 120, 255), 10f, 1f)
}

val borderColor = if (expanded || isHovered) skija.argb(255, 0, 150, 255) else skija.argb(150, 0, 100, 200)
skija.drawRoundedRectBorderGradient(
x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), 4f, 1f,
borderColor, borderColor,
dev.oblongboot.sxp.utils.skia.SkijaRenderer.GradientDirection.TOP_LEFT_TO_BOTTOM_RIGHT
)

val font = dev.oblongboot.sxp.ui.SettingsScreen.elementFont
val textY = y + height / 3.8f// - 5f
skija.drawText(name, x + 10f, textY, skija.argb(255, 255, 255, 255), font)

val selectedSummary = if (value.isNotEmpty()) "${value.size} selected" else "NONE"
Render2D.drawString(ctx, selectedSummary, x + width - 100, textY, 1f, true)
val tw = skija.getTextWidth(selectedSummary, font)
skija.drawText(selectedSummary, x + width - 35f - tw, textY, skija.argb(255, 180, 200, 230), font)

val arrowSymbol = if (expanded) "▲" else "▼"
Render2D.drawString(ctx, arrowSymbol, x + width - 15, textY, 1f, true)
val aw = skija.getTextWidth(arrowSymbol, font)
skija.drawText(arrowSymbol, x + width - 15f - aw/2f, textY, skija.argb(255, 255, 255, 255), font)

if (animHeight > 0.5f) {
val actualVisibleOptions = if (expanded) visibleOptionCount else 0

val maxScroll = (options.size - maxVisibleOptions).coerceAtLeast(0)
scrollOffset = scrollOffset.coerceIn(0, maxScroll)

val totalAnimHeight = animHeight
if (totalAnimHeight > 2f) {
skija.drawRoundedRect(x.toFloat(), (y + height).toFloat(), width.toFloat(), totalAnimHeight, 4f, skija.argb(220, 15, 25, 40))
skija.drawRoundedRectBorderGradient(x.toFloat(), (y + height).toFloat(), width.toFloat(), totalAnimHeight, 4f, 1f, skija.argb(100, 0, 100, 200), skija.argb(100, 0, 100, 200), dev.oblongboot.sxp.utils.skia.SkijaRenderer.GradientDirection.TOP_LEFT_TO_BOTTOM_RIGHT)
}

for (i in 0 until actualVisibleOptions) {
val optionIndex = i + scrollOffset
if (optionIndex >= options.size) break

val optionY = y + height + (i * optionHeight)
val optionHovered = isWithinBounds(
Render2D.Mouse.x.toInt(),
Render2D.Mouse.y.toInt(),
x,
optionY,
width,
optionHeight
)
val optionHovered = isWithinBounds(mouseX, mouseY, x, optionY, width, optionHeight)
val isSelected = value.contains(optionIndex)

val optionColor = when {
isSelected -> Color(0, 120, 80, 220)
optionHovered -> Color(70, 80, 100, 200)
else -> Color(50, 60, 80, 180)
if (optionHovered) {
skija.drawRoundedRect(x.toFloat(), optionY.toFloat(), width.toFloat(), optionHeight.toFloat(), 4f, skija.argb(80, 40, 80, 140))
}

Render2D.drawWhateverTheFuckThisIs(ctx, x, optionY, width, optionHeight, 3, optionColor)
Render2D.drawOutline(ctx, x, optionY, width, optionHeight, Color(0, 130, 200))


val boxX = x + 8
val boxSize = 14
val boxColor = if (isSelected) Color(0, 180, 80, 220) else Color(60, 60, 70, 180)
Render2D.drawWhateverTheFuckThisIs(ctx, boxX, optionY + 4, boxSize, boxSize, 3, boxColor)
Render2D.drawOutline(ctx, boxX, optionY + 4, boxSize, boxSize, Color.WHITE)
if (isSelected) Render2D.drawString(ctx, "✔", boxX + 3, optionY + 4, 1f, true)

val boxX = x + 8f
val boxSize = 14f
val boxY = optionY + (optionHeight - boxSize) / 2f

if (isSelected) {
skija.drawRoundedRectGradient(boxX, boxY, boxSize, boxSize, 2f, skija.argb(200, 0, 150, 255), skija.argb(200, 0, 100, 200))
} else {
skija.drawRoundedRect(boxX, boxY, boxSize, boxSize, 2f, skija.argb(100, 30, 40, 60))
skija.drawRoundedRectBorderGradient(boxX, boxY, boxSize, boxSize, 2f, 1f, skija.argb(150, 80, 100, 120), skija.argb(150, 60, 80, 100), dev.oblongboot.sxp.utils.skia.SkijaRenderer.GradientDirection.TOP_LEFT_TO_BOTTOM_RIGHT)
}

val textOffsetX = boxX + boxSize + 6
val textOffsetY = optionY + (optionHeight - Render2D.textRenderer.lineHeight) / 2
Render2D.drawString(ctx, options[optionIndex], textOffsetX, textOffsetY, 1f, true)
val textOffsetX = boxX + boxSize + 6f
val textOffsetY = optionY + optionHeight / 2f - 1f
val textColor = if (isSelected) skija.argb(255, 255, 255, 255) else skija.argb(220, 200, 200, 200)
skija.drawText(options[optionIndex], textOffsetX, textOffsetY, textColor, font)
}


if (options.size > maxVisibleOptions) {
val indicatorY = y + height + (actualVisibleOptions * optionHeight)
val smallFont = dev.oblongboot.sxp.ui.SettingsScreen.smallFont
if (scrollOffset > 0) {
Render2D.drawString(ctx, "↑", x + width - 20, y + height + 5, 1f, true)
skija.drawText("↑", x + width - 20f, y + height + 10f, skija.argb(200, 255, 255, 255), font)
}
if (scrollOffset < maxScroll) {
Render2D.drawString(ctx, "↓", x + width - 20, indicatorY - 15, 1f, true)
skija.drawText("↓", x + width - 20f, indicatorY - 5f, skija.argb(200, 255, 255, 255), font)
}
val positionText = "${scrollOffset + 1}-${(scrollOffset + actualVisibleOptions).coerceAtMost(options.size)} of ${options.size}"
Render2D.drawString(ctx, positionText, x + 5, indicatorY + 2, 0.8f, true)
skija.drawText(positionText, x + 5f, indicatorY + 2f, skija.argb(150, 200, 200, 200), smallFont)
}
}
}
Expand Down
Loading
Loading