/* * Skytils - Hypixel Skyblock Quality of Life Mod * Copyright (C) 2021 Skytils * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package skytils.skytilsmod.gui import gg.essential.universal.UResolution import net.minecraft.client.gui.GuiButton import net.minecraft.client.gui.GuiScreen import net.minecraft.client.renderer.GlStateManager import org.lwjgl.input.Mouse import org.lwjgl.opengl.Display import skytils.skytilsmod.Skytils import skytils.skytilsmod.core.GuiManager import skytils.skytilsmod.core.PersistentSave import skytils.skytilsmod.core.structure.FloatPair import skytils.skytilsmod.core.structure.GuiElement import skytils.skytilsmod.core.structure.LocationButton import skytils.skytilsmod.core.structure.ResizeButton import skytils.skytilsmod.core.structure.ResizeButton.Corner import java.awt.Color open class LocationEditGui : GuiScreen(), ReopenableGUI { private var xOffset = 0f private var yOffset = 0f private var resizing = false private var resizingCorner: Corner? = null private var dragging: GuiElement? = null private val locationButtons: MutableMap = HashMap() private var scaleCache = 0f override fun doesGuiPauseGame() = false override fun initGui() { for ((_, value) in Skytils.guiManager.elements) { val lb = LocationButton(value) buttonList.add(lb) locationButtons[value] = lb } } override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) { onMouseMove(mouseX, mouseY) recalculateResizeButtons() drawGradientRect(0, 0, width, height, Color(0, 0, 0, 50).rgb, Color(0, 0, 0, 200).rgb) for (button in buttonList) { if (button is LocationButton) { if (button.element.toggled) { GlStateManager.pushMatrix() val scale = button.element.scale GlStateManager.translate(button.x, button.y, 0f) GlStateManager.scale(scale.toDouble(), scale.toDouble(), 1.0) button.drawButton(mc, mouseX, mouseY) GlStateManager.popMatrix() } } else if (button is ResizeButton) { val element = button.element GlStateManager.pushMatrix() val scale = element.scale GlStateManager.translate(button.x, button.y, 0f) GlStateManager.scale(scale.toDouble(), scale.toDouble(), 1.0) button.drawButton(mc, mouseX, mouseY) GlStateManager.popMatrix() } else { button.drawButton(mc, mouseX, mouseY) } } } public override fun actionPerformed(button: GuiButton) { val sr = UResolution val minecraftScale = sr.scaleFactor.toFloat() val floatMouseX = Mouse.getX() / minecraftScale val floatMouseY = (mc.displayHeight - Mouse.getY()) / minecraftScale if (button is LocationButton) { dragging = button.element xOffset = floatMouseX - dragging!!.actualX yOffset = floatMouseY - dragging!!.actualY } else if (button is ResizeButton) { dragging = button.element resizing = true scaleCache = button.element.scale xOffset = floatMouseX - button.x yOffset = floatMouseY - button.y resizingCorner = button.corner } } override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) { if (mouseButton == 1) { buttonList.filterIsInstance().filter { it.mousePressed(mc, mouseX, mouseY) }.forEach { it.element.pos = FloatPair(10, 10) it.element.scale = 1f } } super.mouseClicked(mouseX, mouseY, mouseButton) } /** * Set the coordinates when the mouse moves. */ private fun onMouseMove(mouseX: Int, mouseY: Int) { val sr = UResolution val minecraftScale = sr.scaleFactor.toFloat() val floatMouseX = Mouse.getX() / minecraftScale val floatMouseY = (Display.getHeight() - Mouse.getY()) / minecraftScale if (resizing) { //TODO Fix rescaling for top right, top left, and bottom right corners val locationButton = locationButtons[dragging] ?: return when (resizingCorner) { Corner.BOTTOM_RIGHT -> { val scaledX1 = locationButton.x val scaledY1 = locationButton.y val width = locationButton.x2 - locationButton.x val height = locationButton.y2 - locationButton.y val newWidth = floatMouseX - scaledX1 val newHeight = floatMouseY - scaledY1 val scaleX = newWidth / width val scaleY = newHeight / height val newScale = scaleX.coerceAtLeast(scaleY / 2).coerceAtLeast(0.01f) locationButton.element.scale *= newScale } Corner.TOP_LEFT -> { } Corner.TOP_RIGHT -> { val scaledX = locationButton.x val scaledY = locationButton.y2 val width = locationButton.x2 - locationButton.x val height = locationButton.y2 - locationButton.y val newWidth = floatMouseX - scaledX val newHeight = scaledY - floatMouseY val scaleX = newWidth / width val scaleY = newHeight / height val newScale = scaleX.coerceAtLeast(scaleY).coerceAtLeast(0.01f) locationButton.element.scale *= newScale locationButton.element.pos.setY((scaledY - newHeight) / sr.scaledHeight) } Corner.BOTTOM_LEFT -> { } } locationButton.drawButton(mc, mouseX, mouseY) recalculateResizeButtons() } else if (dragging != null) { val x = (floatMouseX - xOffset) / sr.scaledWidth.toFloat() val y = (floatMouseY - yOffset) / sr.scaledHeight.toFloat() dragging!!.setPos(x, y) addResizeCorners(dragging!!) } } private fun addResizeCorners(element: GuiElement) { buttonList.removeIf { button: GuiButton? -> button is ResizeButton && button.element === element } buttonList.removeIf { button: GuiButton? -> button is ResizeButton && button.element !== element } val locationButton = locationButtons[element] ?: return val boxXOne = locationButton.x - ResizeButton.SIZE * element.scale val boxXTwo = locationButton.x + element.actualWidth + ResizeButton.SIZE * 2 * element.scale val boxYOne = locationButton.y - ResizeButton.SIZE * element.scale val boxYTwo = locationButton.y + element.actualHeight + ResizeButton.SIZE * 2 * element.scale buttonList.add(ResizeButton(boxXOne, boxYOne, element, Corner.TOP_LEFT)) buttonList.add(ResizeButton(boxXTwo, boxYOne, element, Corner.TOP_RIGHT)) buttonList.add(ResizeButton(boxXOne, boxYTwo, element, Corner.BOTTOM_LEFT)) buttonList.add(ResizeButton(boxXTwo, boxYTwo, element, Corner.BOTTOM_RIGHT)) } private fun recalculateResizeButtons() { for (button in buttonList) { if (button is ResizeButton) { val corner = button.corner val element = button.element val locationButton = locationButtons[element] ?: continue val boxXOne = locationButton.x - ResizeButton.SIZE * element.scale val boxXTwo = locationButton.x + element.actualWidth + ResizeButton.SIZE * element.scale val boxYOne = locationButton.y - ResizeButton.SIZE * element.scale val boxYTwo = locationButton.y + element.actualHeight + ResizeButton.SIZE * element.scale when (corner) { Corner.TOP_LEFT -> { button.x = boxXOne button.y = boxYOne } Corner.TOP_RIGHT -> { button.x = boxXTwo button.y = boxYOne } Corner.BOTTOM_LEFT -> { button.x = boxXOne button.y = boxYTwo } Corner.BOTTOM_RIGHT -> { button.x = boxXTwo button.y = boxYTwo } } } } } override fun handleMouseInput() { super.handleMouseInput() val hovered = LocationButton.lastHoveredElement if (hovered != null) { hovered.scale = (hovered.scale + Mouse.getEventDWheel() / 1000f).coerceAtLeast(0.01f) } } /** * Reset the dragged feature when the mouse is released. */ override fun mouseReleased(mouseX: Int, mouseY: Int, state: Int) { super.mouseReleased(mouseX, mouseY, state) dragging = null resizing = false scaleCache = 0f } /** * Saves the positions when the gui is closed */ override fun onGuiClosed() { PersistentSave.markDirty() } }