86 lines
2.5 KiB
Kotlin
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
|
|
}
|
|
} |