fixed a bug where uiitemspinner would accumulate floating point precision errors over use

This commit is contained in:
minjaesong
2022-08-02 03:41:24 +09:00
parent bb3511b1db
commit 026a90c0aa
2 changed files with 26 additions and 7 deletions

View File

@@ -31,7 +31,7 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
arrayOf("fx_backgroundblur", { Lang["MENU_OPTIONS_BLUR"] }, "toggle"),
arrayOf("fx_streamerslayout", { Lang["MENU_OPTION_STREAMERS_LAYOUT"] }, "toggle"),
arrayOf("usevsync", { Lang["MENU_OPTIONS_VSYNC"]+"*" }, "toggle"),
arrayOf("screenmagnifying", { Lang["MENU_OPTIONS_RESOLUTION"]+"*" }, "spinnerd,1.0,2.0,0.25"),
arrayOf("screenmagnifying", { Lang["GAME_ACTION_ZOOM"]+"*" }, "spinnerd,1.0,2.0,0.05"),
arrayOf("maxparticles", { Lang["MENU_OPTIONS_PARTICLES"] }, "spinner,256,1024,256"),
)
@@ -45,7 +45,7 @@ class UIGraphicsControlPanel(remoCon: UIRemoCon?) : UICanvas() {
}
else if (args.startsWith("spinnerd,")) {
val arg = args.split(',')
UIItemSpinner(this, x - spinnerWidth, y, App.getConfigDouble(optionName), arg[1].toDouble(), arg[2].toDouble(), arg[3].toDouble(), spinnerWidth, numberToTextFunction = { "${it}x" })
UIItemSpinner(this, x - spinnerWidth, y, App.getConfigDouble(optionName), arg[1].toDouble(), arg[2].toDouble(), arg[3].toDouble(), spinnerWidth, numberToTextFunction = { "${((it as Double)*100).toInt()}%" })
}
else throw IllegalArgumentException(args)
}

View File

@@ -5,8 +5,11 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.ceilInt
/**
* Internal properties, namely initialValue, min, max, step; have the type of [Double] regardless of their input type.
*
* Created by minjaesong on 2021-10-23.
*/
@@ -22,8 +25,7 @@ class UIItemSpinner(
private val numberToTextFunction: (Number) -> String = { "$it" }
) : UIItem(parentUI, initialX, initialY) {
init {
}
private val valueType = initialValue.javaClass // should be java.lang.Double or java.lang.Integer
private val labels = CommonResourcePool.getAsTextureRegionPack("inventory_category")
@@ -41,6 +43,22 @@ class UIItemSpinner(
var selectionChangeListener: (Number) -> Unit = {}
// to alleviate floating point errors adding up as the spinner is being used
private val values = DoubleArray(1 + ((max.toDouble() - min.toDouble()).div(step.toDouble())).ceilInt()) { min.toDouble() + (step.toDouble() * it) }
private var currentIndex = values.indexOfFirst { it == initialValue.toDouble() }
init {
// println("valueType=${valueType.canonicalName} for UI ${parentUI.javaClass.canonicalName}")
if (currentIndex < 0)
throw IllegalArgumentException("Initial value $initialValue cannot be derived from given ($min..$max step $step) settings")
}
private fun changeValueBy(diff: Int) {
currentIndex = (currentIndex + diff).coerceIn(values.indices)
value = values[currentIndex]
}
override fun update(delta: Float) {
super.update(delta)
@@ -56,7 +74,8 @@ class UIItemSpinner(
if (!mouseLatched && Terrarum.mouseDown && mouseOnButton in 1..2) {
mouseLatched = true
value = (value.toDouble() + step.toDouble() * ((mouseOnButton * 2) - 3)).coerceIn(min.toDouble(), max.toDouble())
changeValueBy((mouseOnButton * 2) - 3)
fboUpdateLatch = true
selectionChangeListener(value)
}
@@ -140,9 +159,9 @@ class UIItemSpinner(
override fun scrolled(amountX: Float, amountY: Float): Boolean {
if (mouseUp) {
if (amountX <= -1 || amountY <= -1)
value = (value.toDouble() - step.toDouble()).coerceIn(min.toDouble(), max.toDouble())
changeValueBy(-1)
else if (amountX >= 1 || amountY >= 1)
value = (value.toDouble() + step.toDouble()).coerceIn(min.toDouble(), max.toDouble())
changeValueBy(1)
selectionChangeListener(value)
fboUpdateLatch = true