diff --git a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/component/SliderComponent.kt b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/component/SliderComponent.kt index 927c43fe7..be6ae249b 100644 --- a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/component/SliderComponent.kt +++ b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/component/SliderComponent.kt @@ -30,7 +30,7 @@ open class SliderComponent( } val value: Float = value.get() context.renderContext.drawTexturedRect(GuiTextures.SLIDER_ON_CAP, 0F, 0F, 4F, context.height.toFloat()) - context.renderContext.drawTexturedRect(GuiTextures.SLIDER_OFF_CAP, (width - 4).toFloat(), 0F, 4F, context.height.toFloat()) + context.renderContext.drawTexturedRect(GuiTextures.SLIDER_OFF_CAP, (context.width - 4).toFloat(), 0F, 4F, context.height.toFloat()) val sliderPosition = ((value.coerceIn(minValue..maxValue) - minValue) / (maxValue - minValue) * context.width).toInt() if (sliderPosition > 5) { context.renderContext.drawTexturedRect(GuiTextures.SLIDER_ON_SEGMENT, 4F, 0F, (sliderPosition - 4).toFloat(), context.height.toFloat()) diff --git a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/component/SliderWithTextComponent.kt b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/component/SliderWithTextComponent.kt index 5fc8991c3..7361442a6 100644 --- a/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/component/SliderWithTextComponent.kt +++ b/common/src/main/java/io/github/notenoughupdates/moulconfig/gui/component/SliderWithTextComponent.kt @@ -8,7 +8,6 @@ import io.github.notenoughupdates.moulconfig.gui.MouseEvent import io.github.notenoughupdates.moulconfig.observer.GetSetter import java.util.function.BiFunction import kotlin.math.max -import kotlin.math.min open class SliderWithTextComponent( value: GetSetter, @@ -17,46 +16,57 @@ open class SliderWithTextComponent( minStep: Float, width: Int, ) : SliderComponent(value, minValue, maxValue, minStep, width) { + private val sliderWidth = width + override fun getWidth(): Int = SLIDER_INSET + sliderWidth + INPUT_GAP + componentNumberInput.width - override fun render(context: GuiImmediateContext) { - context.renderContext.translate(-(width/3).toFloat(), 0f) - super.render(context) - context.renderContext.translate(60f, -5f) - componentNumberInput.width - componentNumberInput.render(context.translated(60, -5, componentNumberInput.width, 18)) - } + override fun getHeight(): Int = max(super.getHeight(), INPUT_HEIGHT) - // I made this because I couldn't get isHovered to work with the translation - private fun GuiImmediateContext.isHovered(): Boolean { - return mouseX in 0 - width/3 until width - 13 && mouseY in 0 until height + override fun render(context: GuiImmediateContext) { + renderSlider(context) + renderInput(context) } override fun mouseEvent(mouseEvent: MouseEvent, context: GuiImmediateContext): Boolean { - if (!context.renderContext.isMouseButtonDown(0)) clicked = false - if (context.isHovered() && mouseEvent is MouseEvent.Click && mouseEvent.mouseState && mouseEvent.mouseButton == 0) { - clicked = true - } - if (clicked) { - setValueFromContext(context) - return true - } - return componentNumberInput.mouseEvent(mouseEvent, context.translated(45, -5, componentNumberInput.width, 18)) + val sliderHandled = super.mouseEvent(mouseEvent, sliderContext(context)) + val inputHandled = componentNumberInput.mouseEvent(mouseEvent, inputContext(context)) + return sliderHandled || inputHandled } override fun keyboardEvent(event: KeyboardEvent, context: GuiImmediateContext): Boolean { componentNumberInput.setShouldExpandToFit(true) - return componentNumberInput.keyboardEvent(event, context) + return componentNumberInput.keyboardEvent(event, inputContext(context)) } - override fun setValueFromContext(context: GuiImmediateContext) { - var v: Float = (context.mouseX + width/3) * (maxValue - minValue) / context.width + minValue - v = min(v.toDouble(), maxValue.toDouble()).toFloat() - v = max(v.toDouble(), minValue.toDouble()).toFloat() - v = Math.round(v / minStep) * minStep - value.set(v) + private fun renderSlider(context: GuiImmediateContext) { + context.renderContext.pushMatrix() + context.renderContext.translate(SLIDER_INSET.toFloat(), sliderY().toFloat()) + super.render(sliderContext(context)) + context.renderContext.popMatrix() } + private fun renderInput(context: GuiImmediateContext) { + context.renderContext.pushMatrix() + context.renderContext.translate(inputX(context).toFloat(), inputY().toFloat()) + componentNumberInput.render(inputContext(context)) + context.renderContext.popMatrix() + } + + private fun sliderContext(context: GuiImmediateContext): GuiImmediateContext = + context.translated(SLIDER_INSET, sliderY(), effectiveSliderWidth(context), super.getHeight()) + + private fun inputContext(context: GuiImmediateContext): GuiImmediateContext = + context.translated(inputX(context), inputY(), componentNumberInput.width, INPUT_HEIGHT) + + private fun effectiveSliderWidth(context: GuiImmediateContext): Int = + (context.width - SLIDER_INSET - INPUT_GAP - componentNumberInput.width).coerceIn(MIN_SLIDER_WIDTH, sliderWidth) + + private fun sliderY(): Int = (getHeight() - super.getHeight()) / 2 + + private fun inputX(context: GuiImmediateContext): Int = SLIDER_INSET + effectiveSliderWidth(context) + INPUT_GAP + + private fun inputY(): Int = (getHeight() - INPUT_HEIGHT) / 2 + private val componentNumberInput by lazy { TextFieldComponent( object : GetSetter { @@ -96,4 +106,11 @@ open class SliderWithTextComponent( override fun foldChildren(initial: T, visitor: BiFunction): T { return visitor.apply(componentNumberInput, initial) } + + private companion object { + private const val SLIDER_INSET = 10 + private const val INPUT_GAP = 10 + private const val INPUT_HEIGHT = 18 + private const val MIN_SLIDER_WIDTH = 35 + } } diff --git a/modern/templates/java/io/github/notenoughupdates/moulconfig/test/TestCategoryA.kt b/modern/templates/java/io/github/notenoughupdates/moulconfig/test/TestCategoryA.kt index 3941ae208..76e17f592 100644 --- a/modern/templates/java/io/github/notenoughupdates/moulconfig/test/TestCategoryA.kt +++ b/modern/templates/java/io/github/notenoughupdates/moulconfig/test/TestCategoryA.kt @@ -60,6 +60,10 @@ class TestCategoryA { @ConfigOption(name = "Enum Dropdown", desc = "1, 2, 3, 4") @ConfigEditorDropdown var enumDropdown: Property = Property.of(DropdownEnum.FOUR) + + @ConfigOption(name = "Nested Slider", desc = "A deeply suspicious slider living in an accordion.") + @ConfigEditorSlider(minValue = 1F, maxValue = 5F, minStep = 1F) + var nestedSlider: Int = 1 } enum class DropdownEnum(private val label: String) {