aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-10-02 16:44:25 +0200
committerLinnea Gräf <nea@nea.moe>2024-10-02 16:44:25 +0200
commit67dd2f68d68ae48d7b9881a34502d6c25e335745 (patch)
treef950229b5a927cdc6912e0dbea8186220bde150a
parenta4eac70118fc25334c9352712fe3c7944b8bed1d (diff)
downloadFirmament-67dd2f68d68ae48d7b9881a34502d6c25e335745.tar.gz
Firmament-67dd2f68d68ae48d7b9881a34502d6c25e335745.tar.bz2
Firmament-67dd2f68d68ae48d7b9881a34502d6c25e335745.zip
Make storage overlay scrollbar draggable
-rw-r--r--src/main/java/moe/nea/firmament/mixins/customgui/PatchHandledScreen.java296
-rw-r--r--src/main/kotlin/features/inventory/storageoverlay/StorageOverlayCustom.kt153
-rw-r--r--src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt534
-rw-r--r--src/main/kotlin/util/customgui/CustomGui.kt109
4 files changed, 571 insertions, 521 deletions
diff --git a/src/main/java/moe/nea/firmament/mixins/customgui/PatchHandledScreen.java b/src/main/java/moe/nea/firmament/mixins/customgui/PatchHandledScreen.java
index cda87db..61fdcf8 100644
--- a/src/main/java/moe/nea/firmament/mixins/customgui/PatchHandledScreen.java
+++ b/src/main/java/moe/nea/firmament/mixins/customgui/PatchHandledScreen.java
@@ -27,143 +27,161 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(HandledScreen.class)
public class PatchHandledScreen<T extends ScreenHandler> extends Screen implements HasCustomGui {
- @Shadow
- @Final
- protected T handler;
- @Shadow
- protected int x;
- @Shadow
- protected int y;
- @Unique
- public CustomGui override;
- @Unique
- public boolean hasRememberedSlots = false;
-
- protected PatchHandledScreen(Text title) {
- super(title);
- }
-
- @Nullable
- @Override
- public CustomGui getCustomGui_Firmament() {
- return override;
- }
-
- @Override
- public void setCustomGui_Firmament(@Nullable CustomGui gui) {
- this.override = gui;
- }
-
- public boolean mouseScrolled_firmament(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
- return override != null && override.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
- }
-
- @Inject(method = "init", at = @At("TAIL"))
- private void onInit(CallbackInfo ci) {
- if (override != null) {
- override.onInit();
- }
- }
-
- @Inject(method = "drawForeground", at = @At("HEAD"), cancellable = true)
- private void onDrawForeground(DrawContext context, int mouseX, int mouseY, CallbackInfo ci) {
- if (override != null && !override.shouldDrawForeground())
- ci.cancel();
- }
-
-
- @Unique
- private Slot didBeforeSlotRender;
-
- @WrapOperation(
- method = "render",
- at = @At(
- value = "INVOKE",
- target = "Lnet/minecraft/util/collection/DefaultedList;get(I)Ljava/lang/Object;"))
- private Object beforeSlotRender(DefaultedList instance, int index, Operation<Object> original, @Local(argsOnly = true) DrawContext context) {
- var slot = (Slot) original.call(instance, index);
- if (override != null) {
- didBeforeSlotRender = slot;
- override.beforeSlotRender(context, slot);
- }
- return slot;
- }
-
- @Inject(method = "render",
- at = @At(value = "INVOKE", target = "Lnet/minecraft/util/collection/DefaultedList;size()I"))
- private void afterSlotRender(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
- if (override != null && didBeforeSlotRender != null) {
- override.afterSlotRender(context, didBeforeSlotRender);
- didBeforeSlotRender = null;
- }
- }
-
- @Inject(method = "isClickOutsideBounds", at = @At("HEAD"), cancellable = true)
- public void onIsClickOutsideBounds(double mouseX, double mouseY, int left, int top, int button, CallbackInfoReturnable<Boolean> cir) {
- if (override != null) {
- cir.setReturnValue(override.isClickOutsideBounds(mouseX, mouseY));
- }
- }
-
- @Inject(method = "isPointWithinBounds", at = @At("HEAD"), cancellable = true)
- public void onIsPointWithinBounds(int x, int y, int width, int height, double pointX, double pointY, CallbackInfoReturnable<Boolean> cir) {
- if (override != null) {
- cir.setReturnValue(override.isPointWithinBounds(x + this.x, y + this.y, width, height, pointX, pointY));
- }
- }
-
- @Inject(method = "isPointOverSlot", at = @At("HEAD"), cancellable = true)
- public void onIsPointOverSlot(Slot slot, double pointX, double pointY, CallbackInfoReturnable<Boolean> cir) {
- if (override != null) {
- cir.setReturnValue(override.isPointOverSlot(slot, this.x, this.y, pointX, pointY));
- }
- }
-
- @Inject(method = "render", at = @At("HEAD"))
- public void moveSlots(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
- if (override != null) {
- for (Slot slot : handler.slots) {
- if (!hasRememberedSlots) {
- ((CoordRememberingSlot) slot).rememberCoords_firmament();
- }
- override.moveSlot(slot);
- }
- hasRememberedSlots = true;
- } else {
- if (hasRememberedSlots) {
- for (Slot slot : handler.slots) {
- ((CoordRememberingSlot) slot).restoreCoords_firmament();
- }
- hasRememberedSlots = false;
- }
- }
- }
-
- @Inject(at = @At("HEAD"), method = "close", cancellable = true)
- private void onVoluntaryExit(CallbackInfo ci) {
- if (override != null) {
- if (!override.onVoluntaryExit())
- ci.cancel();
- }
- }
-
- @WrapWithCondition(method = "renderBackground", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawBackground(Lnet/minecraft/client/gui/DrawContext;FII)V"))
- public boolean preventDrawingBackground(HandledScreen instance, DrawContext drawContext, float delta, int mouseX, int mouseY) {
- if (override != null) {
- override.render(drawContext, delta, mouseX, mouseY);
- }
- return override == null;
- }
-
- @WrapOperation(
- method = "mouseClicked",
- at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;mouseClicked(DDI)Z"))
- public boolean overrideMouseClicks(HandledScreen instance, double mouseX, double mouseY, int button,
- Operation<Boolean> original) {
- if (override != null) {
- if (override.mouseClick(mouseX, mouseY, button))
- return true;
- }
- return original.call(instance, mouseX, mouseY, button);
- }
+ @Shadow
+ @Final
+ protected T handler;
+ @Shadow
+ protected int x;
+ @Shadow
+ protected int y;
+ @Unique
+ public CustomGui override;
+ @Unique
+ public boolean hasRememberedSlots = false;
+
+ protected PatchHandledScreen(Text title) {
+ super(title);
+ }
+
+ @Nullable
+ @Override
+ public CustomGui getCustomGui_Firmament() {
+ return override;
+ }
+
+ @Override
+ public void setCustomGui_Firmament(@Nullable CustomGui gui) {
+ this.override = gui;
+ }
+
+ public boolean mouseScrolled_firmament(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
+ return override != null && override.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
+ }
+
+ @Inject(method = "init", at = @At("TAIL"))
+ private void onInit(CallbackInfo ci) {
+ if (override != null) {
+ override.onInit();
+ }
+ }
+
+ @Inject(method = "drawForeground", at = @At("HEAD"), cancellable = true)
+ private void onDrawForeground(DrawContext context, int mouseX, int mouseY, CallbackInfo ci) {
+ if (override != null && !override.shouldDrawForeground())
+ ci.cancel();
+ }
+
+
+ @Unique
+ private Slot didBeforeSlotRender;
+
+ @WrapOperation(
+ method = "render",
+ at = @At(
+ value = "INVOKE",
+ target = "Lnet/minecraft/util/collection/DefaultedList;get(I)Ljava/lang/Object;"))
+ private Object beforeSlotRender(DefaultedList instance, int index, Operation<Object> original, @Local(argsOnly = true) DrawContext context) {
+ var slot = (Slot) original.call(instance, index);
+ if (override != null) {
+ didBeforeSlotRender = slot;
+ override.beforeSlotRender(context, slot);
+ }
+ return slot;
+ }
+
+ @Inject(method = "render",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/util/collection/DefaultedList;size()I"))
+ private void afterSlotRender(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
+ if (override != null && didBeforeSlotRender != null) {
+ override.afterSlotRender(context, didBeforeSlotRender);
+ didBeforeSlotRender = null;
+ }
+ }
+
+ @Inject(method = "isClickOutsideBounds", at = @At("HEAD"), cancellable = true)
+ public void onIsClickOutsideBounds(double mouseX, double mouseY, int left, int top, int button, CallbackInfoReturnable<Boolean> cir) {
+ if (override != null) {
+ cir.setReturnValue(override.isClickOutsideBounds(mouseX, mouseY));
+ }
+ }
+
+ @Inject(method = "isPointWithinBounds", at = @At("HEAD"), cancellable = true)
+ public void onIsPointWithinBounds(int x, int y, int width, int height, double pointX, double pointY, CallbackInfoReturnable<Boolean> cir) {
+ if (override != null) {
+ cir.setReturnValue(override.isPointWithinBounds(x + this.x, y + this.y, width, height, pointX, pointY));
+ }
+ }
+
+ @Inject(method = "isPointOverSlot", at = @At("HEAD"), cancellable = true)
+ public void onIsPointOverSlot(Slot slot, double pointX, double pointY, CallbackInfoReturnable<Boolean> cir) {
+ if (override != null) {
+ cir.setReturnValue(override.isPointOverSlot(slot, this.x, this.y, pointX, pointY));
+ }
+ }
+
+ @Inject(method = "render", at = @At("HEAD"))
+ public void moveSlots(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
+ if (override != null) {
+ for (Slot slot : handler.slots) {
+ if (!hasRememberedSlots) {
+ ((CoordRememberingSlot) slot).rememberCoords_firmament();
+ }
+ override.moveSlot(slot);
+ }
+ hasRememberedSlots = true;
+ } else {
+ if (hasRememberedSlots) {
+ for (Slot slot : handler.slots) {
+ ((CoordRememberingSlot) slot).restoreCoords_firmament();
+ }
+ hasRememberedSlots = false;
+ }
+ }
+ }
+
+ @Inject(at = @At("HEAD"), method = "close", cancellable = true)
+ private void onVoluntaryExit(CallbackInfo ci) {
+ if (override != null) {
+ if (!override.onVoluntaryExit())
+ ci.cancel();
+ }
+ }
+
+ @WrapWithCondition(method = "renderBackground", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawBackground(Lnet/minecraft/client/gui/DrawContext;FII)V"))
+ public boolean preventDrawingBackground(HandledScreen instance, DrawContext drawContext, float delta, int mouseX, int mouseY) {
+ if (override != null) {
+ override.render(drawContext, delta, mouseX, mouseY);
+ }
+ return override == null;
+ }
+
+ @WrapOperation(
+ method = "mouseClicked",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;mouseClicked(DDI)Z"))
+ public boolean overrideMouseClicks(HandledScreen instance, double mouseX, double mouseY, int button,
+ Operation<Boolean> original) {
+ if (override != null) {
+ if (override.mouseClick(mouseX, mouseY, button))
+ return true;
+ }
+ return original.call(instance, mouseX, mouseY, button);
+ }
+
+ @Inject(method = "mouseDragged", at = @At("HEAD"), cancellable = true)
+ public void overrideMouseDrags(double mouseX, double mouseY, int button, double deltaX, double deltaY, CallbackInfoReturnable<Boolean> cir) {
+ if (override != null) {
+ if (override.mouseDragged(mouseX, mouseY, button, deltaX, deltaY))
+ cir.setReturnValue(true);
+ }
+ }
+
+ @Inject(
+ method = "mouseReleased",
+ at = @At("HEAD"), cancellable = true)
+ public void overrideMouseReleases(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) {
+ if (override != null) {
+ if (override.mouseReleased(mouseX, mouseY, button))
+ cir.setReturnValue(true);
+ }
+ }
}
diff --git a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayCustom.kt b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayCustom.kt
index d0d9114..fc3c4ef 100644
--- a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayCustom.kt
+++ b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayCustom.kt
@@ -1,4 +1,3 @@
-
package moe.nea.firmament.features.inventory.storageoverlay
import me.shedaniel.math.Point
@@ -12,87 +11,95 @@ import moe.nea.firmament.mixins.accessor.AccessorHandledScreen
import moe.nea.firmament.util.customgui.CustomGui
class StorageOverlayCustom(
- val handler: StorageBackingHandle,
- val screen: GenericContainerScreen,
- val overview: StorageOverlayScreen,
+ val handler: StorageBackingHandle,
+ val screen: GenericContainerScreen,
+ val overview: StorageOverlayScreen,
) : CustomGui() {
- override fun onVoluntaryExit(): Boolean {
- overview.isExiting = true
- return super.onVoluntaryExit()
- }
+ override fun onVoluntaryExit(): Boolean {
+ overview.isExiting = true
+ return super.onVoluntaryExit()
+ }
+
+ override fun getBounds(): List<Rectangle> {
+ return overview.getBounds()
+ }
+
+ override fun afterSlotRender(context: DrawContext, slot: Slot) {
+ if (slot.inventory !is PlayerInventory)
+ context.disableScissor()
+ }
- override fun getBounds(): List<Rectangle> {
- return overview.getBounds()
- }
+ override fun beforeSlotRender(context: DrawContext, slot: Slot) {
+ if (slot.inventory !is PlayerInventory)
+ overview.createScissors(context)
+ }
- override fun afterSlotRender(context: DrawContext, slot: Slot) {
- if (slot.inventory !is PlayerInventory)
- context.disableScissor()
- }
+ override fun onInit() {
+ overview.init(MinecraftClient.getInstance(), screen.width, screen.height)
+ overview.init()
+ screen as AccessorHandledScreen
+ screen.x_Firmament = overview.measurements.x
+ screen.y_Firmament = overview.measurements.y
+ screen.backgroundWidth_Firmament = overview.measurements.totalWidth
+ screen.backgroundHeight_Firmament = overview.measurements.totalHeight
+ }
- override fun beforeSlotRender(context: DrawContext, slot: Slot) {
- if (slot.inventory !is PlayerInventory)
- overview.createScissors(context)
- }
+ override fun isPointOverSlot(slot: Slot, xOffset: Int, yOffset: Int, pointX: Double, pointY: Double): Boolean {
+ if (!super.isPointOverSlot(slot, xOffset, yOffset, pointX, pointY))
+ return false
+ if (slot.inventory !is PlayerInventory) {
+ if (!overview.getScrollPanelInner().contains(pointX, pointY))
+ return false
+ }
+ return true
+ }
- override fun onInit() {
- overview.init(MinecraftClient.getInstance(), screen.width, screen.height)
- overview.init()
- screen as AccessorHandledScreen
- screen.x_Firmament = overview.measurements.x
- screen.y_Firmament = overview.measurements.y
- screen.backgroundWidth_Firmament = overview.measurements.totalWidth
- screen.backgroundHeight_Firmament = overview.measurements.totalHeight
- }
+ override fun shouldDrawForeground(): Boolean {
+ return false
+ }
- override fun isPointOverSlot(slot: Slot, xOffset: Int, yOffset: Int, pointX: Double, pointY: Double): Boolean {
- if (!super.isPointOverSlot(slot, xOffset, yOffset, pointX, pointY))
- return false
- if (slot.inventory !is PlayerInventory) {
- if (!overview.getScrollPanelInner().contains(pointX, pointY))
- return false
- }
- return true
- }
+ override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
+ return overview.mouseReleased(mouseX, mouseY, button)
+ }
- override fun shouldDrawForeground(): Boolean {
- return false
- }
+ override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
+ return overview.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
+ }
- override fun mouseClick(mouseX: Double, mouseY: Double, button: Int): Boolean {
- return overview.mouseClicked(mouseX, mouseY, button, (handler as? StorageBackingHandle.Page)?.storagePageSlot)
- }
+ override fun mouseClick(mouseX: Double, mouseY: Double, button: Int): Boolean {
+ return overview.mouseClicked(mouseX, mouseY, button, (handler as? StorageBackingHandle.Page)?.storagePageSlot)
+ }
- override fun render(drawContext: DrawContext, delta: Float, mouseX: Int, mouseY: Int) {
- overview.drawBackgrounds(drawContext)
- overview.drawPages(drawContext,
- mouseX,
- mouseY,
- delta,
- (handler as? StorageBackingHandle.Page)?.storagePageSlot,
- screen.screenHandler.slots.take(screen.screenHandler.rows * 9).drop(9),
- Point((screen as AccessorHandledScreen).x_Firmament, screen.y_Firmament))
- overview.drawScrollBar(drawContext)
- }
+ override fun render(drawContext: DrawContext, delta: Float, mouseX: Int, mouseY: Int) {
+ overview.drawBackgrounds(drawContext)
+ overview.drawPages(drawContext,
+ mouseX,
+ mouseY,
+ delta,
+ (handler as? StorageBackingHandle.Page)?.storagePageSlot,
+ screen.screenHandler.slots.take(screen.screenHandler.rows * 9).drop(9),
+ Point((screen as AccessorHandledScreen).x_Firmament, screen.y_Firmament))
+ overview.drawScrollBar(drawContext)
+ }
- override fun moveSlot(slot: Slot) {
- val index = slot.index
- if (index in 0..<36) {
- val (x, y) = overview.getPlayerInventorySlotPosition(index)
- slot.x = x - (screen as AccessorHandledScreen).x_Firmament
- slot.y = y - screen.y_Firmament
- } else {
- slot.x = -100000
- slot.y = -100000
- }
- }
+ override fun moveSlot(slot: Slot) {
+ val index = slot.index
+ if (index in 0..<36) {
+ val (x, y) = overview.getPlayerInventorySlotPosition(index)
+ slot.x = x - (screen as AccessorHandledScreen).x_Firmament
+ slot.y = y - screen.y_Firmament
+ } else {
+ slot.x = -100000
+ slot.y = -100000
+ }
+ }
- override fun mouseScrolled(
- mouseX: Double,
- mouseY: Double,
- horizontalAmount: Double,
- verticalAmount: Double
- ): Boolean {
- return overview.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)
- }
+ override fun mouseScrolled(
+ mouseX: Double,
+ mouseY: Double,
+ horizontalAmount: Double,
+ verticalAmount: Double
+ ): Boolean {
+ return overview.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount)
+ }
}
diff --git a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt
index 13c6974..58c894a 100644
--- a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt
+++ b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt
@@ -1,4 +1,3 @@
-
package moe.nea.firmament.features.inventory.storageoverlay
import me.shedaniel.math.Point
@@ -8,289 +7,308 @@ import net.minecraft.client.gui.screen.Screen
import net.minecraft.screen.slot.Slot
import net.minecraft.text.Text
import net.minecraft.util.Identifier
-import moe.nea.firmament.annotations.Subscribe
-import moe.nea.firmament.events.CommandEvent
import moe.nea.firmament.util.MC
-import moe.nea.firmament.util.ScreenUtil
import moe.nea.firmament.util.assertTrueOr
class StorageOverlayScreen : Screen(Text.literal("")) {
- companion object {
- val PLAYER_WIDTH = 184
- val PLAYER_HEIGHT = 91
- val PLAYER_Y_INSET = 3
- val SLOT_SIZE = 18
- val PADDING = 10
- val PAGE_WIDTH = SLOT_SIZE * 9
- val HOTBAR_X = 12
- val HOTBAR_Y = 67
- val MAIN_INVENTORY_Y = 9
- val SCROLL_BAR_WIDTH = 8
- val SCROLL_BAR_HEIGHT = 16
- }
+ companion object {
+ val PLAYER_WIDTH = 184
+ val PLAYER_HEIGHT = 91
+ val PLAYER_Y_INSET = 3
+ val SLOT_SIZE = 18
+ val PADDING = 10
+ val PAGE_WIDTH = SLOT_SIZE * 9
+ val HOTBAR_X = 12
+ val HOTBAR_Y = 67
+ val MAIN_INVENTORY_Y = 9
+ val SCROLL_BAR_WIDTH = 8
+ val SCROLL_BAR_HEIGHT = 16
+ }
+
+ var isExiting: Boolean = false
+ var scroll: Float = 0F
+ var pageWidthCount = StorageOverlay.TConfig.columns
+
+ inner class Measurements {
+ val innerScrollPanelWidth = PAGE_WIDTH * pageWidthCount + (pageWidthCount - 1) * PADDING
+ val overviewWidth = innerScrollPanelWidth + 3 * PADDING + SCROLL_BAR_WIDTH
+ val x = width / 2 - overviewWidth / 2
+ val overviewHeight = minOf(3 * 18 * 6, height - PLAYER_HEIGHT - minOf(80, height / 10))
+ val innerScrollPanelHeight = overviewHeight - PADDING * 2
+ val y = height / 2 - (overviewHeight + PLAYER_HEIGHT) / 2
+ val playerX = width / 2 - PLAYER_WIDTH / 2
+ val playerY = y + overviewHeight - PLAYER_Y_INSET
+ val totalWidth = overviewWidth
+ val totalHeight = overviewHeight - PLAYER_Y_INSET + PLAYER_HEIGHT
+ }
+
+ var measurements = Measurements()
- var isExiting: Boolean = false
- var scroll: Float = 0F
- var pageWidthCount = StorageOverlay.TConfig.columns
+ var lastRenderedInnerHeight = 0
+ public override fun init() {
+ super.init()
+ pageWidthCount = StorageOverlay.TConfig.columns
+ .coerceAtMost((width - PADDING) / (PAGE_WIDTH + PADDING))
+ .coerceAtLeast(1)
+ measurements = Measurements()
+ scroll = scroll.coerceAtMost(getMaxScroll()).coerceAtLeast(0F)
+ }
- inner class Measurements {
- val innerScrollPanelWidth = PAGE_WIDTH * pageWidthCount + (pageWidthCount - 1) * PADDING
- val overviewWidth = innerScrollPanelWidth + 3 * PADDING + SCROLL_BAR_WIDTH
- val x = width / 2 - overviewWidth / 2
- val overviewHeight = minOf(3 * 18 * 6, height - PLAYER_HEIGHT - minOf(80, height / 10))
- val innerScrollPanelHeight = overviewHeight - PADDING * 2
- val y = height / 2 - (overviewHeight + PLAYER_HEIGHT) / 2
- val playerX = width / 2 - PLAYER_WIDTH / 2
- val playerY = y + overviewHeight - PLAYER_Y_INSET
- val totalWidth = overviewWidth
- val totalHeight = overviewHeight - PLAYER_Y_INSET + PLAYER_HEIGHT
- }
+ override fun mouseScrolled(
+ mouseX: Double,
+ mouseY: Double,
+ horizontalAmount: Double,
+ verticalAmount: Double
+ ): Boolean {
+ scroll = (scroll + StorageOverlay.adjustScrollSpeed(verticalAmount)).toFloat()
+ .coerceAtMost(getMaxScroll())
+ .coerceAtLeast(0F)
+ return true
+ }
- var measurements = Measurements()
+ fun getMaxScroll() = lastRenderedInnerHeight.toFloat() - getScrollPanelInner().height
- var lastRenderedInnerHeight = 0
- public override fun init() {
- super.init()
- pageWidthCount = StorageOverlay.TConfig.columns
- .coerceAtMost((width - PADDING) / (PAGE_WIDTH + PADDING))
- .coerceAtLeast(1)
- measurements = Measurements()
- }
+ val playerInventorySprite = Identifier.of("firmament:storageoverlay/player_inventory")
+ val upperBackgroundSprite = Identifier.of("firmament:storageoverlay/upper_background")
+ val slotRowSprite = Identifier.of("firmament:storageoverlay/storage_row")
+ val scrollbarBackground = Identifier.of("firmament:storageoverlay/scroll_bar_background")
+ val scrollbarKnob = Identifier.of("firmament:storageoverlay/scroll_bar_knob")
- override fun mouseScrolled(
- mouseX: Double,
- mouseY: Double,
- horizontalAmount: Double,
- verticalAmount: Double
- ): Boolean {
- scroll = (scroll + StorageOverlay.adjustScrollSpeed(verticalAmount)).toFloat()
- .coerceAtMost(getMaxScroll())
- .coerceAtLeast(0F)
- return true
- }
+ override fun close() {
+ isExiting = true
+ super.close()
+ }
- fun getMaxScroll() = lastRenderedInnerHeight.toFloat() - getScrollPanelInner().height
+ override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
+ super.render(context, mouseX, mouseY, delta)
+ drawBackgrounds(context)
+ drawPages(context, mouseX, mouseY, delta, null, null, Point())
+ drawScrollBar(context)
+ drawPlayerInventory(context, mouseX, mouseY, delta)
+ }
- val playerInventorySprite = Identifier.of("firmament:storageoverlay/player_inventory")
- val upperBackgroundSprite = Identifier.of("firmament:storageoverlay/upper_background")
- val slotRowSprite = Identifier.of("firmament:storageoverlay/storage_row")
- val scrollbarBackground = Identifier.of("firmament:storageoverlay/scroll_bar_background")
- val scrollbarKnob = Identifier.of("firmament:storageoverlay/scroll_bar_knob")
+ fun getScrollbarPercentage(): Float {
+ return scroll / getMaxScroll()
+ }
- override fun close() {
- isExiting = true
- super.close()
- }
+ fun drawScrollBar(context: DrawContext) {
+ val sbRect = getScrollBarRect()
+ context.drawGuiTexture(
+ scrollbarBackground,
+ sbRect.minX, sbRect.minY,
+ sbRect.width, sbRect.height,
+ )
+ context.drawGuiTexture(
+ scrollbarKnob,
+ sbRect.minX, sbRect.minY + (getScrollbarPercentage() * (sbRect.height - SCROLL_BAR_HEIGHT)).toInt(),
+ SCROLL_BAR_WIDTH, SCROLL_BAR_HEIGHT
+ )
+ }
- override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
- super.render(context, mouseX, mouseY, delta)
- drawBackgrounds(context)
- drawPages(context, mouseX, mouseY, delta, null, null, Point())
- drawScrollBar(context)
- drawPlayerInventory(context, mouseX, mouseY, delta)
- }
+ fun drawBackgrounds(context: DrawContext) {
+ context.drawGuiTexture(upperBackgroundSprite,
+ measurements.x,
+ measurements.y,
+ 0,
+ measurements.overviewWidth,
+ measurements.overviewHeight)
+ context.drawGuiTexture(playerInventorySprite,
+ measurements.playerX,
+ measurements.playerY,
+ 0,
+ PLAYER_WIDTH,
+ PLAYER_HEIGHT)
+ }
- fun getScrollbarPercentage(): Float {
- return scroll / getMaxScroll()
- }
+ fun getPlayerInventorySlotPosition(int: Int): Pair<Int, Int> {
+ if (int < 9) {
+ return Pair(measurements.playerX + int * SLOT_SIZE + HOTBAR_X, HOTBAR_Y + measurements.playerY)
+ }
+ return Pair(
+ measurements.playerX + (int % 9) * SLOT_SIZE + HOTBAR_X,
+ measurements.playerY + (int / 9 - 1) * SLOT_SIZE + MAIN_INVENTORY_Y
+ )
+ }
- fun drawScrollBar(context: DrawContext) {
- val sbRect = getScrollBarRect()
- context.drawGuiTexture(
- scrollbarBackground,
- sbRect.minX, sbRect.minY,
- sbRect.width, sbRect.height,
- )
- context.drawGuiTexture(
- scrollbarKnob,
- sbRect.minX, sbRect.minY + (getScrollbarPercentage() * (sbRect.height - SCROLL_BAR_HEIGHT)).toInt(),
- SCROLL_BAR_WIDTH, SCROLL_BAR_HEIGHT
- )
- }
+ fun drawPlayerInventory(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
+ val items = MC.player?.inventory?.main ?: return
+ items.withIndex().forEach { (index, item) ->
+ val (x, y) = getPlayerInventorySlotPosition(index)
+ context.drawItem(item, x, y, 0)
+ context.drawItemInSlot(textRenderer, item, x, y)
+ }
+ }
- fun drawBackgrounds(context: DrawContext) {
- context.drawGuiTexture(upperBackgroundSprite,
- measurements.x,
- measurements.y,
- 0,
- measurements.overviewWidth,
- measurements.overviewHeight)
- context.drawGuiTexture(playerInventorySprite,
- measurements.playerX,
- measurements.playerY,
- 0,
- PLAYER_WIDTH,
- PLAYER_HEIGHT)
- }
+ fun getScrollBarRect(): Rectangle {
+ return Rectangle(measurements.x + PADDING + measurements.innerScrollPanelWidth + PADDING,
+ measurements.y + PADDING,
+ SCROLL_BAR_WIDTH,
+ measurements.innerScrollPanelHeight)
+ }
- fun getPlayerInventorySlotPosition(int: Int): Pair<Int, Int> {
- if (int < 9) {
- return Pair(measurements.playerX + int * SLOT_SIZE + HOTBAR_X, HOTBAR_Y + measurements.playerY)
- }
- return Pair(
- measurements.playerX + (int % 9) * SLOT_SIZE + HOTBAR_X,
- measurements.playerY + (int / 9 - 1) * SLOT_SIZE + MAIN_INVENTORY_Y
- )
- }
+ fun getScrollPanelInner(): Rectangle {
+ return Rectangle(measurements.x + PADDING,
+ measurements.y + PADDING,
+ measurements.innerScrollPanelWidth,
+ measurements.innerScrollPanelHeight)
+ }
- fun drawPlayerInventory(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
- val items = MC.player?.inventory?.main ?: return
- items.withIndex().forEach { (index, item) ->
- val (x, y) = getPlayerInventorySlotPosition(index)
- context.drawItem(item, x, y, 0)
- context.drawItemInSlot(textRenderer, item, x, y)
- }
- }
+ fun createScissors(context: DrawContext) {
+ val rect = getScrollPanelInner()
+ context.enableScissor(
+ rect.minX, rect.minY,
+ rect.maxX, rect.maxY
+ )
+ }
- fun getScrollBarRect(): Rectangle {
- return Rectangle(measurements.x + PADDING + measurements.innerScrollPanelWidth + PADDING,
- measurements.y + PADDING,
- SCROLL_BAR_WIDTH,
- measurements.innerScrollPanelHeight)
- }
+ fun drawPages(
+ context: DrawContext, mouseX: Int, mouseY: Int, delta: Float,
+ excluding: StoragePageSlot?,
+ slots: List<Slot>?,
+ slotOffset: Point
+ ) {
+ createScissors(context)
+ val data = StorageOverlay.Data.data ?: StorageData()
+ layoutedForEach(data) { rect, page, inventory ->
+ drawPage(context,
+ rect.x,
+ rect.y,
+ page, inventory,
+ if (excluding == page) slots else null,
+ slotOffset
+ )
+ }
+ context.disableScissor()
+ }
- fun getScrollPanelInner(): Rectangle {
- return Rectangle(measurements.x + PADDING,
- measurements.y + PADDING,
- measurements.innerScrollPanelWidth,
- measurements.innerScrollPanelHeight)
- }
+ var knobGrabbed = false
- fun createScissors(context: DrawContext) {
- val rect = getScrollPanelInner()
- context.enableScissor(
- rect.minX, rect.minY,
- rect.maxX, rect.maxY
- )
- }
+ override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
+ return mouseClicked(mouseX, mouseY, button, null)
+ }
- fun drawPages(
- context: DrawContext, mouseX: Int, mouseY: Int, delta: Float,
- excluding: StoragePageSlot?,
- slots: List<Slot>?,
- slotOffset: Point
- ) {
- createScissors(context)
- val data = StorageOverlay.Data.data ?: StorageData()
- layoutedForEach(data) { rect, page, inventory ->
- drawPage(context,
- rect.x,
- rect.y,
- page, inventory,
- if (excluding == page) slots else null,
- slotOffset
- )
- }
- context.disableScissor()
- }
+ override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
+ if (knobGrabbed) {
+ knobGrabbed = false
+ return true
+ }
+ return super.mouseReleased(mouseX, mouseY, button)
+ }
- override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
- return mouseClicked(mouseX, mouseY, button, null)
- }
+ override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
+ if (knobGrabbed) {
+ val sbRect = getScrollBarRect()
+ val percentage = (mouseY - sbRect.getY()) / sbRect.getHeight()
+ scroll = (getMaxScroll() * percentage).toFloat()
+ mouseScrolled(0.0, 0.0, 0.0, 0.0)
+ return true
+ }
+ return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY)
+ }
- fun mouseClicked(mouseX: Double, mouseY: Double, button: Int, activePage: StoragePageSlot?): Boolean {
- if (getScrollPanelInner().contains(mouseX, mouseY)) {
- val data = StorageOverlay.Data.data ?: StorageData()
- layoutedForEach(data) { rect, page, _ ->
- if (rect.contains(mouseX, mouseY) && activePage != page && button == 0) {
- page.navigateTo()
- return true
- }
- }
- return false
- }
- val sbRect = getScrollBarRect()
- if (sbRect.contains(mouseX, mouseY)) {
- // TODO: support dragging of the mouse and such
- val percentage = (mouseY - sbRect.getY()) / sbRect.getHeight()
- scroll = (getMaxScroll() * percentage).toFloat()
- mouseScrolled(0.0, 0.0, 0.0, 0.0)
- return true
- }
- return false
- }
+ fun mouseClicked(mouseX: Double, mouseY: Double, button: Int, activePage: StoragePageSlot?): Boolean {
+ if (getScrollPanelInner().contains(mouseX, mouseY)) {
+ val data = StorageOverlay.Data.data ?: StorageData()
+ layoutedForEach(data) { rect, page, _ ->
+ if (rect.contains(mouseX, mouseY) && activePage != page && button == 0) {
+ page.navigateTo()
+ return true
+ }
+ }
+ return false
+ }
+ val sbRect = getScrollBarRect()
+ if (sbRect.contains(mouseX, mouseY)) {
+ val percentage = (mouseY - sbRect.getY()) / sbRect.getHeight()
+ scroll = (getMaxScroll() * percentage).toFloat()
+ mouseScrolled(0.0, 0.0, 0.0, 0.0)
+ knobGrabbed = true
+ return true
+ }
+ return false
+ }
- private inline fun layoutedForEach(
- data: StorageData,
- func: (
- rectangle: Rectangle,
- page: StoragePageSlot, inventory: StorageData.StorageInventory,
- ) -> Unit
- ) {
- var yOffset = -scroll.toInt()
- var xOffset = 0
- var maxHeight = 0
- for ((page, inventory) in data.storageInventories.entries) {
- val currentHeight = inventory.inventory?.let { it.rows * SLOT_SIZE + 4 + textRenderer.fontHeight }
- ?: 18
- maxHeight = maxOf(maxHeight, currentHeight)
- val rect = Rectangle(
- measurements.x + PADDING + (PAGE_WIDTH + PADDING) * xOffset,
- yOffset + measurements.y + PADDING,
- PAGE_WIDTH,
- currentHeight
- )
- func(rect, page, inventory)
- xOffset++
- if (xOffset >= pageWidthCount) {
- yOffset += maxHeight
- xOffset = 0
- maxHeight = 0
- }
- }
- lastRenderedInnerHeight = maxHeight + yOffset + scroll.toInt()
- }
+ private inline fun layoutedForEach(
+ data: StorageData,
+ func: (
+ rectangle: Rectangle,
+ page: StoragePageSlot, inventory: StorageData.StorageInventory,
+ ) -> Unit
+ ) {
+ var yOffset = -scroll.toInt()
+ var xOffset = 0
+ var maxHeight = 0
+ for ((page, inventory) in data.storageInventories.entries) {
+ val currentHeight = inventory.inventory?.let { it.rows * SLOT_SIZE + 4 + textRenderer.fontHeight }
+ ?: 18
+ maxHeight = maxOf(maxHeight, currentHeight)
+ val rect = Rectangle(
+ measurements.x + PADDING + (PAGE_WIDTH + PADDING) * xOffset,
+ yOffset + measurements.y + PADDING,
+ PAGE_WIDTH,
+ currentHeight
+ )
+ func(rect, page, inventory)
+ xOffset++
+ if (xOffset >= pageWidthCount) {
+ yOffset += maxHeight
+ xOffset = 0
+ maxHeight = 0
+ }
+ }
+ lastRenderedInnerHeight = maxHeight + yOffset + scroll.toInt()
+ }
- fun drawPage(
- context: DrawContext,
- x: Int,
- y: Int,
- page: StoragePageSlot,
- inventory: StorageData.StorageInventory,
- slots: List<Slot>?,
- slotOffset: Point,
- ): Int {
- val inv = inventory.inventory
- if (inv == null) {
- context.drawGuiTexture(upperBackgroundSprite, x, y, PAGE_WIDTH, 18)
- context.drawText(textRenderer,
- Text.literal("TODO: open this page"),
- x + 4,
- y + 4,
- -1,
- true)
- return 18
- }
- assertTrueOr(slots == null || slots.size == inv.stacks.size) { return 0 }
- val name = page.defaultName()
- context.drawText(textRenderer, Text.literal(name), x + 4, y + 2,
- if (slots == null) 0xFFFFFFFF.toInt() else 0xFFFFFF00.toInt(), true)
- context.drawGuiTexture(slotRowSprite, x, y + 4 + textRenderer.fontHeight, PAGE_WIDTH, inv.rows * SLOT_SIZE)
- inv.stacks.forEachIndexed { index, stack ->
- val slotX = (index % 9) * SLOT_SIZE + x + 1
- val slotY = (index / 9) * SLOT_SIZE + y + 4 + textRenderer.fontHeight + 1
- if (slots == null) {
- context.drawItem(stack, slotX, slotY)
- context.drawItemInSlot(textRenderer, stack, slotX, slotY)
- } else {
- val slot = slots[index]
- slot.x = slotX - slotOffset.x
- slot.y = slotY - slotOffset.y
- }
- }
- return inv.rows * SLOT_SIZE + 4 + textRenderer.fontHeight
- }
+ fun drawPage(
+ context: DrawContext,
+ x: Int,
+ y: Int,
+ page: StoragePageSlot,
+ inventory: StorageData.StorageInventory,
+ slots: List<Slot>?,
+ slotOffset: Point,
+ ): Int {
+ val inv = inventory.inventory
+ if (inv == null) {
+ context.drawGuiTexture(upperBackgroundSprite, x, y, PAGE_WIDTH, 18)
+ context.drawText(textRenderer,
+ Text.literal("TODO: open this page"),
+ x + 4,
+ y + 4,
+ -1,
+ true)
+ return 18
+ }
+ assertTrueOr(slots == null || slots.size == inv.stacks.size) { return 0 }
+ val name = page.defaultName()
+ context.drawText(textRenderer, Text.literal(name), x + 4, y + 2,
+ if (slots == null) 0xFFFFFFFF.toInt() else 0xFFFFFF00.toInt(), true)
+ context.drawGuiTexture(slotRowSprite, x, y + 4 + textRenderer.fontHeight, PAGE_WIDTH, inv.rows * SLOT_SIZE)
+ inv.stacks.forEachIndexed { index, stack ->
+ val slotX = (index % 9) * SLOT_SIZE + x + 1
+ val slotY = (index / 9) * SLOT_SIZE + y + 4 + textRenderer.fontHeight + 1
+ if (slots == null) {
+ context.drawItem(stack, slotX, slotY)
+ context.drawItemInSlot(textRenderer, stack, slotX, slotY)
+ } else {
+ val slot = slots[index]
+ slot.x = slotX - slotOffset.x
+ slot.y = slotY - slotOffset.y
+ }
+ }
+ return inv.rows * SLOT_SIZE + 4 + textRenderer.fontHeight
+ }
- fun getBounds(): List<Rectangle> {
- return listOf(
- Rectangle(measurements.x,
- measurements.y,
- measurements.overviewWidth,
- measurements.overviewHeight),
- Rectangle(measurements.playerX,
- measurements.playerY,
- PLAYER_WIDTH,
- PLAYER_HEIGHT))
- }
+ fun getBounds(): List<Rectangle> {
+ return listOf(
+ Rectangle(measurements.x,
+ measurements.y,
+ measurements.overviewWidth,
+ measurements.overviewHeight),
+ Rectangle(measurements.playerX,
+ measurements.playerY,
+ PLAYER_WIDTH,
+ PLAYER_HEIGHT))
+ }
}
diff --git a/src/main/kotlin/util/customgui/CustomGui.kt b/src/main/kotlin/util/customgui/CustomGui.kt
index f9094b2..5224448 100644
--- a/src/main/kotlin/util/customgui/CustomGui.kt
+++ b/src/main/kotlin/util/customgui/CustomGui.kt
@@ -1,4 +1,3 @@
-
package moe.nea.firmament.util.customgui
import me.shedaniel.math.Rectangle
@@ -9,64 +8,72 @@ import moe.nea.firmament.events.HandledScreenPushREIEvent
abstract class CustomGui {
- abstract fun getBounds(): List<Rectangle>
+ abstract fun getBounds(): List<Rectangle>
+
+ open fun moveSlot(slot: Slot) {
+ // TODO: return a Pair maybe? worth an investigation
+ }
+
+ companion object {
+ @Subscribe
+ fun onExclusionZone(event: HandledScreenPushREIEvent) {
+ val customGui = event.screen.customGui ?: return
+ event.rectangles.addAll(customGui.getBounds())
+ }
+ }
- open fun moveSlot(slot: Slot) {
- // TODO: return a Pair maybe? worth an investigation
- }
+ open fun render(
+ drawContext: DrawContext,
+ delta: Float,
+ mouseX: Int,
+ mouseY: Int
+ ) {
+ }
- companion object {
- @Subscribe
- fun onExclusionZone(event: HandledScreenPushREIEvent) {
- val customGui = event.screen.customGui ?: return
- event.rectangles.addAll(customGui.getBounds())
- }
- }
+ open fun mouseClick(mouseX: Double, mouseY: Double, button: Int): Boolean {
+ return false
+ }
- open fun render(
- drawContext: DrawContext,
- delta: Float,
- mouseX: Int,
- mouseY: Int
- ) {
- }
+ open fun afterSlotRender(context: DrawContext, slot: Slot) {}
+ open fun beforeSlotRender(context: DrawContext, slot: Slot) {}
+ open fun mouseScrolled(mouseX: Double, mouseY: Double, horizontalAmount: Double, verticalAmount: Double): Boolean {
+ return false
+ }
- open fun mouseClick(mouseX: Double, mouseY: Double, button: Int): Boolean {
- return false
- }
+ open fun isClickOutsideBounds(mouseX: Double, mouseY: Double): Boolean {
+ return getBounds().none { it.contains(mouseX, mouseY) }
+ }
- open fun afterSlotRender(context: DrawContext, slot: Slot) {}
- open fun beforeSlotRender(context: DrawContext, slot: Slot) {}
- open fun mouseScrolled(mouseX: Double, mouseY: Double, horizontalAmount: Double, verticalAmount: Double): Boolean {
- return false
- }
+ open fun isPointWithinBounds(
+ x: Int,
+ y: Int,
+ width: Int,
+ height: Int,
+ pointX: Double,
+ pointY: Double,
+ ): Boolean {
+ return getBounds().any { it.contains(pointX, pointY) } &&
+ Rectangle(x, y, width, height).contains(pointX, pointY)
+ }
- open fun isClickOutsideBounds(mouseX: Double, mouseY: Double): Boolean {
- return getBounds().none { it.contains(mouseX, mouseY) }
- }
+ open fun isPointOverSlot(slot: Slot, xOffset: Int, yOffset: Int, pointX: Double, pointY: Double): Boolean {
+ return isPointWithinBounds(slot.x + xOffset, slot.y + yOffset, 16, 16, pointX, pointY)
+ }
- open fun isPointWithinBounds(
- x: Int,
- y: Int,
- width: Int,
- height: Int,
- pointX: Double,
- pointY: Double,
- ): Boolean {
- return getBounds().any { it.contains(pointX, pointY) } &&
- Rectangle(x, y, width, height).contains(pointX, pointY)
- }
+ open fun onInit() {}
+ open fun shouldDrawForeground(): Boolean {
+ return true
+ }
- open fun isPointOverSlot(slot: Slot, xOffset: Int, yOffset: Int, pointX: Double, pointY: Double): Boolean {
- return isPointWithinBounds(slot.x + xOffset, slot.y + yOffset, 16, 16, pointX, pointY)
- }
+ open fun onVoluntaryExit(): Boolean {
+ return true
+ }
- open fun onInit() {}
- open fun shouldDrawForeground(): Boolean {
- return true
- }
+ open fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean {
+ return false
+ }
- open fun onVoluntaryExit(): Boolean {
- return true
- }
+ open fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean {
+ return false
+ }
}