ASMR/src/main/kotlin/net/shadowfacts/cacao/view/StackView.kt

86 lines
2.5 KiB
Kotlin

package net.shadowfacts.cacao.view
import net.shadowfacts.kiwidsl.dsl
import net.shadowfacts.cacao.LayoutVariable
import net.shadowfacts.cacao.geometry.Axis
import net.shadowfacts.cacao.geometry.AxisPosition
import net.shadowfacts.cacao.geometry.AxisPosition.*
import no.birkett.kiwi.Constraint
/**
* @author shadowfacts
*/
class StackView(val axis: Axis, val distribution: Distribution = Distribution.FILL): View() {
val arrangedSubviews = mutableListOf<View>()
private var leadingConnection: Constraint? = null
private var trailingConnection: Constraint? = null
private var arrangedSubviewConnections = mutableListOf<Constraint>()
fun <T: View> addArrangedSubview(view: T, index: Int = arrangedSubviews.size): T {
addSubview(view)
arrangedSubviews.add(index, view)
addConstraintsForArrangedView(view, index)
return view
}
fun addConstraintsForArrangedView(view: View, index: Int) {
if (index == 0) {
if (leadingConnection != null) {
solver.removeConstraint(leadingConnection)
}
solver.dsl {
leadingConnection = anchor(LEADING) equalTo anchor(LEADING, view)
}
}
if (index == arrangedSubviews.size - 1) {
if (trailingConnection != null) {
solver.removeConstraint(trailingConnection)
}
solver.dsl {
trailingConnection = anchor(TRAILING, view) equalTo anchor(TRAILING)
}
}
if (arrangedSubviews.size > 1) {
solver.dsl {
val previous = arrangedSubviews.getOrNull(index - 1)
val next = arrangedSubviews.getOrNull(index + 1)
if (next != null) {
arrangedSubviewConnections.add(index, anchor(TRAILING, view) equalTo anchor(LEADING, next))
}
if (previous != null) {
arrangedSubviewConnections.add(index - 1, anchor(TRAILING, previous) equalTo anchor(LEADING, view))
}
}
}
solver.dsl {
when (distribution) {
Distribution.LEADING ->
perpAnchor(LEADING) equalTo perpAnchor(LEADING, view)
Distribution.TRAILING ->
perpAnchor(TRAILING) equalTo perpAnchor(TRAILING, view)
Distribution.FILL -> {
perpAnchor(LEADING) equalTo perpAnchor(LEADING, view)
perpAnchor(TRAILING) equalTo perpAnchor(TRAILING, view)
}
Distribution.CENTER ->
perpAnchor(CENTER) equalTo perpAnchor(CENTER, view)
}
}
}
private fun anchor(position: AxisPosition, view: View = this): LayoutVariable {
return view.getAnchor(axis, position)
}
private fun perpAnchor(position: AxisPosition, view: View = this): LayoutVariable {
return view.getAnchor(axis.other, position)
}
enum class Distribution {
FILL, LEADING, CENTER, TRAILING
}
}