Update the NinePatchView computed regions on layout changes

Otherwise, updating the size of a button (e.g. by changing it's content)
would result in the button having an incorrectly displayed background
This commit is contained in:
Shadowfacts 2019-06-25 18:06:17 -04:00
parent 3902b75a27
commit 27bad18931
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
3 changed files with 59 additions and 9 deletions

View File

@ -9,6 +9,9 @@ class ObservableLateInitProperty<T: Any>(val observer: (T) -> Unit) {
lateinit var storage: T lateinit var storage: T
val isInitialized: Boolean
get() = this::storage.isInitialized
operator fun getValue(thisRef: Any, property: KProperty<*>): T { operator fun getValue(thisRef: Any, property: KProperty<*>): T {
return storage return storage
} }

View File

@ -0,0 +1,21 @@
package net.shadowfacts.cacao.util
import kotlin.reflect.KProperty
/**
* @author shadowfacts
*/
class ResettableLazyProperty<Value>(val initializer: () -> Value) {
var value: Value? = null
operator fun getValue(thisRef: Any, property: KProperty<*>): Value {
if (value == null) {
value = initializer()
}
return value!!
}
fun reset() {
value = null
}
}

View File

@ -4,6 +4,7 @@ import net.shadowfacts.cacao.geometry.Point
import net.shadowfacts.cacao.geometry.Rect import net.shadowfacts.cacao.geometry.Rect
import net.shadowfacts.cacao.util.NinePatchTexture import net.shadowfacts.cacao.util.NinePatchTexture
import net.shadowfacts.cacao.util.RenderHelper import net.shadowfacts.cacao.util.RenderHelper
import net.shadowfacts.cacao.util.ResettableLazyProperty
/** /**
* A helper class for drawing a [NinePatchTexture] in a view. * A helper class for drawing a [NinePatchTexture] in a view.
@ -15,37 +16,62 @@ import net.shadowfacts.cacao.util.RenderHelper
class NinePatchView(val ninePatch: NinePatchTexture): View() { class NinePatchView(val ninePatch: NinePatchTexture): View() {
// Corners // Corners
private val topLeft: Rect by lazy { protected val `$topLeft` = ResettableLazyProperty {
Rect(0.0, 0.0, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble()) Rect(0.0, 0.0, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble())
} }
private val topRight by lazy { protected val topLeft by `$topLeft`
protected val `$topRight` = ResettableLazyProperty {
Rect(bounds.width - ninePatch.cornerWidth, 0.0, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble()) Rect(bounds.width - ninePatch.cornerWidth, 0.0, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble())
} }
private val bottomLeft by lazy { protected val topRight by `$topRight`
protected val `$bottomLeft` = ResettableLazyProperty {
Rect(0.0, bounds.height - ninePatch.cornerHeight, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble()) Rect(0.0, bounds.height - ninePatch.cornerHeight, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble())
} }
private val bottomRight by lazy { protected val bottomLeft by `$bottomLeft`
protected val `$bottomRight` = ResettableLazyProperty {
Rect(bounds.width - ninePatch.cornerWidth, bounds.height - ninePatch.cornerHeight, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble()) Rect(bounds.width - ninePatch.cornerWidth, bounds.height - ninePatch.cornerHeight, ninePatch.cornerWidth.toDouble(), ninePatch.cornerHeight.toDouble())
} }
protected val bottomRight by `$bottomRight`
// Edges // Edges
private val topMiddle by lazy { protected val `$topMiddle` = ResettableLazyProperty {
Rect(ninePatch.cornerWidth.toDouble(), topLeft.top, bounds.width - 2 * ninePatch.cornerWidth, ninePatch.cornerHeight.toDouble()) Rect(ninePatch.cornerWidth.toDouble(), topLeft.top, bounds.width - 2 * ninePatch.cornerWidth, ninePatch.cornerHeight.toDouble())
} }
private val bottomMiddle by lazy { protected val topMiddle by `$topMiddle`
protected val `$bottomMiddle` = ResettableLazyProperty {
Rect(topMiddle.left, bottomLeft.top, topMiddle.width, topMiddle.height) Rect(topMiddle.left, bottomLeft.top, topMiddle.width, topMiddle.height)
} }
private val leftMiddle by lazy { protected val bottomMiddle by `$bottomMiddle`
protected val `$leftMiddle` = ResettableLazyProperty {
Rect(topLeft.left, ninePatch.cornerHeight.toDouble(), ninePatch.cornerWidth.toDouble(), bounds.height - 2 * ninePatch.cornerHeight) Rect(topLeft.left, ninePatch.cornerHeight.toDouble(), ninePatch.cornerWidth.toDouble(), bounds.height - 2 * ninePatch.cornerHeight)
} }
private val rightMiddle by lazy { protected val leftMiddle by `$leftMiddle`
protected val `$rightMiddle` = ResettableLazyProperty {
Rect(topRight.left, leftMiddle.top, leftMiddle.width, leftMiddle.height) Rect(topRight.left, leftMiddle.top, leftMiddle.width, leftMiddle.height)
} }
protected val rightMiddle by `$rightMiddle`
// Center // Center
private val center by lazy { protected val `$center` = ResettableLazyProperty {
Rect(topLeft.right, topLeft.bottom, topMiddle.width, leftMiddle.height) Rect(topLeft.right, topLeft.bottom, topMiddle.width, leftMiddle.height)
} }
protected val center by `$center`
protected val delegates = listOf(`$topLeft`, `$topRight`, `$bottomLeft`, `$bottomRight`, `$topMiddle`, `$bottomMiddle`, `$leftMiddle`, `$rightMiddle`, `$center`)
override fun didLayout() {
super.didLayout()
delegates.forEach(ResettableLazyProperty<Rect>::reset)
}
override fun drawContent(mouse: Point, delta: Float) { override fun drawContent(mouse: Point, delta: Float) {
drawCorners() drawCorners()