Start adding ViewControllers
This commit is contained in:
parent
2044daec40
commit
e4fc677dc1
|
@ -1,17 +1,9 @@
|
||||||
package net.shadowfacts.asmr
|
package net.shadowfacts.asmr
|
||||||
|
|
||||||
import net.minecraft.util.Identifier
|
|
||||||
import net.shadowfacts.asmr.util.RedstoneMode
|
|
||||||
import net.shadowfacts.kiwidsl.dsl
|
|
||||||
import net.shadowfacts.cacao.CacaoScreen
|
import net.shadowfacts.cacao.CacaoScreen
|
||||||
import net.shadowfacts.cacao.Window
|
import net.shadowfacts.cacao.Window
|
||||||
import net.shadowfacts.cacao.geometry.Axis
|
|
||||||
import net.shadowfacts.cacao.geometry.Size
|
|
||||||
import net.shadowfacts.cacao.util.Color
|
|
||||||
import net.shadowfacts.cacao.util.texture.NinePatchTexture
|
|
||||||
import net.shadowfacts.cacao.util.texture.Texture
|
|
||||||
import net.shadowfacts.cacao.view.*
|
import net.shadowfacts.cacao.view.*
|
||||||
import net.shadowfacts.cacao.view.button.DropdownButton
|
import net.shadowfacts.cacao.viewcontroller.ViewController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -19,103 +11,125 @@ import net.shadowfacts.cacao.view.button.DropdownButton
|
||||||
class TestCacaoScreen: CacaoScreen() {
|
class TestCacaoScreen: CacaoScreen() {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
addWindow(Window().apply {
|
val viewController = object: ViewController() {
|
||||||
val stack = addView(StackView(Axis.VERTICAL, StackView.Distribution.CENTER, spacing = 4.0).apply {
|
override fun loadView() {
|
||||||
backgroundColor = Color.WHITE
|
this.view = View()
|
||||||
})
|
|
||||||
val red = stack.addArrangedSubview(TextureView(Texture(Identifier("textures/block/birch_log_top.png"), 0, 0, 16, 16)).apply {
|
|
||||||
intrinsicContentSize = Size(50.0, 50.0)
|
|
||||||
})
|
|
||||||
val green = stack.addArrangedSubview(NinePatchView(NinePatchTexture.PANEL_BG).apply {
|
|
||||||
intrinsicContentSize = Size(75.0, 100.0)
|
|
||||||
})
|
|
||||||
val blue = stack.addArrangedSubview(View().apply {
|
|
||||||
intrinsicContentSize = Size(50.0, 50.0)
|
|
||||||
backgroundColor = Color(0x0000ff)
|
|
||||||
})
|
|
||||||
val purple = blue.addSubview(DropdownButton(
|
|
||||||
initialValue = RedstoneMode.HIGH,
|
|
||||||
allValues = RedstoneMode.values().asIterable(),
|
|
||||||
createView = { Label(it.name) },
|
|
||||||
updateView = { newValue, label -> label.text = newValue.name }
|
|
||||||
).apply {
|
|
||||||
handler = {
|
|
||||||
println("dropdown value: ${it.value}")
|
|
||||||
val dialog = DialogView(
|
|
||||||
"New redstone mode",
|
|
||||||
it.value.name,
|
|
||||||
arrayOf(DialogView.DefaultButtonType.OK),
|
|
||||||
Texture(Identifier("textures/block/birch_log_top.png"), 0, 0, 16, 16),
|
|
||||||
buttonCallback = { _, window ->
|
|
||||||
window.removeFromScreen()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
val dialogWindow = Window()
|
|
||||||
dialogWindow.addView(dialog)
|
|
||||||
this@TestCacaoScreen.addWindow(dialogWindow)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
val label = addView(Label("test ".repeat(100), maxLines = 5))
|
|
||||||
|
|
||||||
solver.dsl {
|
|
||||||
stack.topAnchor equalTo 0
|
|
||||||
stack.centerXAnchor equalTo this@apply.centerXAnchor
|
|
||||||
stack.widthAnchor equalTo 100
|
|
||||||
purple.centerXAnchor equalTo blue.centerXAnchor
|
|
||||||
purple.centerYAnchor equalTo blue.centerYAnchor
|
|
||||||
// purple.widthAnchor equalTo 50
|
|
||||||
|
|
||||||
label.topAnchor equalTo 0
|
|
||||||
label.leftAnchor equalTo 0
|
|
||||||
label.widthAnchor equalTo 100
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun viewDidLoad() {
|
||||||
|
val labelContainer = view.addSubview(View())
|
||||||
|
createConstraints {
|
||||||
|
labelContainer.centerXAnchor equalTo view.centerXAnchor
|
||||||
|
labelContainer.centerYAnchor equalTo view.centerYAnchor
|
||||||
|
}
|
||||||
|
embedChild(object: ViewController() {
|
||||||
|
override fun loadView() {
|
||||||
|
this.view = Label("test child")
|
||||||
|
}
|
||||||
|
}, container = labelContainer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addWindow(Window(viewController))
|
||||||
|
}
|
||||||
|
|
||||||
// val red = addView(View().apply {
|
// init {
|
||||||
// backgroundColor = Color(0xff0000)
|
// addWindow(Window().apply {
|
||||||
|
// val stack = addView(StackView(Axis.VERTICAL, StackView.Distribution.CENTER, spacing = 4.0).apply {
|
||||||
|
// backgroundColor = Color.WHITE
|
||||||
// })
|
// })
|
||||||
// val green = addView(View().apply {
|
// val red = stack.addArrangedSubview(TextureView(Texture(Identifier("textures/block/birch_log_top.png"), 0, 0, 16, 16)).apply {
|
||||||
// backgroundColor = Color(0x00ff00)
|
// intrinsicContentSize = Size(50.0, 50.0)
|
||||||
// })
|
// })
|
||||||
// val blue = addView(View().apply {
|
// val green = stack.addArrangedSubview(NinePatchView(NinePatchTexture.PANEL_BG).apply {
|
||||||
|
// intrinsicContentSize = Size(75.0, 100.0)
|
||||||
|
// })
|
||||||
|
// val blue = stack.addArrangedSubview(View().apply {
|
||||||
|
// intrinsicContentSize = Size(50.0, 50.0)
|
||||||
// backgroundColor = Color(0x0000ff)
|
// backgroundColor = Color(0x0000ff)
|
||||||
// })
|
// })
|
||||||
// val purple = green.addSubview(View().apply {
|
// val purple = blue.addSubview(DropdownButton(
|
||||||
// backgroundColor = Color(0x800080)
|
// initialValue = RedstoneMode.HIGH,
|
||||||
// })
|
// allValues = RedstoneMode.values().asIterable(),
|
||||||
// purple.intrinsicContentSize = Size(width = 150.0, height = 150.0)
|
// createView = { Label(it.name) },
|
||||||
// val label = purple.addSubview(Label("Hello, world!").apply {
|
// updateView = { newValue, label -> label.text = newValue.name }
|
||||||
// textColor = Color.WHITE
|
// ).apply {
|
||||||
|
// handler = {
|
||||||
|
// println("dropdown value: ${it.value}")
|
||||||
|
// val dialog = DialogView(
|
||||||
|
// "New redstone mode",
|
||||||
|
// it.value.name,
|
||||||
|
// arrayOf(DialogView.DefaultButtonType.OK),
|
||||||
|
// Texture(Identifier("textures/block/birch_log_top.png"), 0, 0, 16, 16),
|
||||||
|
// buttonCallback = { _, window ->
|
||||||
|
// window.removeFromScreen()
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// val dialogWindow = Window()
|
||||||
|
// dialogWindow.addView(dialog)
|
||||||
|
// this@TestCacaoScreen.addWindow(dialogWindow)
|
||||||
|
// }
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
|
// val label = addView(Label("test ".repeat(100), maxLines = 5))
|
||||||
|
//
|
||||||
// solver.dsl {
|
// solver.dsl {
|
||||||
// red.leftAnchor equalTo 0
|
// stack.topAnchor equalTo 0
|
||||||
// red.widthAnchor equalTo 200
|
// stack.centerXAnchor equalTo this@apply.centerXAnchor
|
||||||
// red.topAnchor equalTo 0
|
// stack.widthAnchor equalTo 100
|
||||||
// red.heightAnchor equalTo 100
|
// purple.centerXAnchor equalTo blue.centerXAnchor
|
||||||
|
// purple.centerYAnchor equalTo blue.centerYAnchor
|
||||||
|
//// purple.widthAnchor equalTo 50
|
||||||
//
|
//
|
||||||
// green.leftAnchor equalTo (red.leftAnchor + red.widthAnchor + 20)
|
// label.topAnchor equalTo 0
|
||||||
// green.widthAnchor equalTo red.widthAnchor
|
// label.leftAnchor equalTo 0
|
||||||
// green.topAnchor equalTo 0
|
// label.widthAnchor equalTo 100
|
||||||
// green.heightAnchor equalTo (red.heightAnchor + 100)
|
|
||||||
//
|
|
||||||
// blue.leftAnchor equalTo green.leftAnchor
|
|
||||||
// blue.widthAnchor equalTo green.widthAnchor
|
|
||||||
// blue.topAnchor equalTo (green.topAnchor + green.heightAnchor)
|
|
||||||
// blue.heightAnchor equalTo 50
|
|
||||||
//
|
|
||||||
//// purple.widthAnchor equalTo 100
|
|
||||||
//// purple.heightAnchor equalTo 100
|
|
||||||
// purple.centerXAnchor equalTo green.centerXAnchor
|
|
||||||
// purple.centerYAnchor equalTo green.centerYAnchor
|
|
||||||
//
|
|
||||||
// label.centerXAnchor equalTo purple.centerXAnchor
|
|
||||||
// label.centerYAnchor equalTo purple.centerYAnchor
|
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// layout()
|
//
|
||||||
})
|
//// val red = addView(View().apply {
|
||||||
}
|
//// backgroundColor = Color(0xff0000)
|
||||||
|
//// })
|
||||||
|
//// val green = addView(View().apply {
|
||||||
|
//// backgroundColor = Color(0x00ff00)
|
||||||
|
//// })
|
||||||
|
//// val blue = addView(View().apply {
|
||||||
|
//// backgroundColor = Color(0x0000ff)
|
||||||
|
//// })
|
||||||
|
//// val purple = green.addSubview(View().apply {
|
||||||
|
//// backgroundColor = Color(0x800080)
|
||||||
|
//// })
|
||||||
|
//// purple.intrinsicContentSize = Size(width = 150.0, height = 150.0)
|
||||||
|
//// val label = purple.addSubview(Label("Hello, world!").apply {
|
||||||
|
//// textColor = Color.WHITE
|
||||||
|
//// })
|
||||||
|
////
|
||||||
|
//// solver.dsl {
|
||||||
|
//// red.leftAnchor equalTo 0
|
||||||
|
//// red.widthAnchor equalTo 200
|
||||||
|
//// red.topAnchor equalTo 0
|
||||||
|
//// red.heightAnchor equalTo 100
|
||||||
|
////
|
||||||
|
//// green.leftAnchor equalTo (red.leftAnchor + red.widthAnchor + 20)
|
||||||
|
//// green.widthAnchor equalTo red.widthAnchor
|
||||||
|
//// green.topAnchor equalTo 0
|
||||||
|
//// green.heightAnchor equalTo (red.heightAnchor + 100)
|
||||||
|
////
|
||||||
|
//// blue.leftAnchor equalTo green.leftAnchor
|
||||||
|
//// blue.widthAnchor equalTo green.widthAnchor
|
||||||
|
//// blue.topAnchor equalTo (green.topAnchor + green.heightAnchor)
|
||||||
|
//// blue.heightAnchor equalTo 50
|
||||||
|
////
|
||||||
|
////// purple.widthAnchor equalTo 100
|
||||||
|
////// purple.heightAnchor equalTo 100
|
||||||
|
//// purple.centerXAnchor equalTo green.centerXAnchor
|
||||||
|
//// purple.centerYAnchor equalTo green.centerYAnchor
|
||||||
|
////
|
||||||
|
//// label.centerXAnchor equalTo purple.centerXAnchor
|
||||||
|
//// label.centerYAnchor equalTo purple.centerYAnchor
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// layout()
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@ package net.shadowfacts.cacao
|
||||||
import net.shadowfacts.cacao.geometry.Point
|
import net.shadowfacts.cacao.geometry.Point
|
||||||
import net.shadowfacts.cacao.util.MouseButton
|
import net.shadowfacts.cacao.util.MouseButton
|
||||||
import net.shadowfacts.cacao.view.View
|
import net.shadowfacts.cacao.view.View
|
||||||
|
import net.shadowfacts.cacao.viewcontroller.ViewController
|
||||||
import net.shadowfacts.kiwidsl.dsl
|
import net.shadowfacts.kiwidsl.dsl
|
||||||
import no.birkett.kiwi.Constraint
|
import no.birkett.kiwi.Constraint
|
||||||
import no.birkett.kiwi.Solver
|
import no.birkett.kiwi.Solver
|
||||||
|
@ -17,7 +18,7 @@ import java.util.*
|
||||||
*
|
*
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
class Window {
|
class Window(val viewController: ViewController) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The screen that this window belongs to.
|
* The screen that this window belongs to.
|
||||||
|
@ -68,18 +69,25 @@ class Window {
|
||||||
private var widthConstraint: Constraint? = null
|
private var widthConstraint: Constraint? = null
|
||||||
private var heightConstraint: Constraint? = null
|
private var heightConstraint: Constraint? = null
|
||||||
|
|
||||||
// _views is the internal, mutable object, since we only want it to be mutated by the add/removeView methods
|
|
||||||
private val _views = LinkedList<View>()
|
|
||||||
/**
|
|
||||||
* The list of top-level views in this window.
|
|
||||||
* This list should never be modified directly, only by calling the [addView]/[removeView] methods.
|
|
||||||
*/
|
|
||||||
val views: List<View> = _views
|
|
||||||
|
|
||||||
private var viewsSortedByZIndex: List<View> = listOf()
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
createInternalConstraints()
|
createInternalConstraints()
|
||||||
|
|
||||||
|
viewController.window = this
|
||||||
|
viewController.loadView()
|
||||||
|
|
||||||
|
viewController.view.window = this
|
||||||
|
viewController.view.solver = solver
|
||||||
|
viewController.view.wasAdded()
|
||||||
|
viewController.createConstraints {
|
||||||
|
viewController.view.leftAnchor equalTo leftAnchor
|
||||||
|
viewController.view.rightAnchor equalTo rightAnchor
|
||||||
|
viewController.view.topAnchor equalTo topAnchor
|
||||||
|
viewController.view.bottomAnchor equalTo bottomAnchor
|
||||||
|
}
|
||||||
|
|
||||||
|
viewController.viewDidLoad()
|
||||||
|
|
||||||
|
layout()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,47 +124,9 @@ class Window {
|
||||||
* Convenience method that removes this window from its [screen].
|
* Convenience method that removes this window from its [screen].
|
||||||
*/
|
*/
|
||||||
fun removeFromScreen() {
|
fun removeFromScreen() {
|
||||||
|
viewController.viewWillDisappear()
|
||||||
screen.removeWindow(this)
|
screen.removeWindow(this)
|
||||||
}
|
viewController.viewDidDisappear()
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the given view as a top-level view in this window.
|
|
||||||
*
|
|
||||||
* @param view The view to add.
|
|
||||||
* @return The same view, as a convenience.
|
|
||||||
*/
|
|
||||||
fun <T: View> addView(view: T): T {
|
|
||||||
_views.add(view)
|
|
||||||
viewsSortedByZIndex = views.sortedBy(View::zIndex)
|
|
||||||
|
|
||||||
view.window = this
|
|
||||||
view.solver = solver
|
|
||||||
|
|
||||||
view.wasAdded()
|
|
||||||
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds all views in this window at the given point.
|
|
||||||
*
|
|
||||||
* @param point The point to find views at, in the coordinate system of the window.
|
|
||||||
* @return All views that contain the point.
|
|
||||||
*/
|
|
||||||
fun viewsAtPoint(point: Point): List<View> {
|
|
||||||
return views.filter { point in it.frame }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to find a top level view of this window that contains the given point.
|
|
||||||
* If there are multiple overlapping views, which one this method returns is undefined.
|
|
||||||
* [viewsAtPoint] may be used, and the resulting List sorted by [View.zIndex].
|
|
||||||
*
|
|
||||||
* @param point The point to find views at, in the coordinate system of the window.
|
|
||||||
* @return the Veiw, if any, that contain the given point.
|
|
||||||
*/
|
|
||||||
fun viewAtPoint(point: Point): View? {
|
|
||||||
return views.firstOrNull { point in it.frame }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,7 +135,9 @@ class Window {
|
||||||
*/
|
*/
|
||||||
fun layout() {
|
fun layout() {
|
||||||
solver.updateVariables()
|
solver.updateVariables()
|
||||||
views.forEach(View::didLayout)
|
viewController.viewWillLayoutSubviews()
|
||||||
|
viewController.view.didLayout()
|
||||||
|
viewController.viewDidLayoutSubviews()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,10 +148,8 @@ class Window {
|
||||||
* @param delta The time elapsed since the last frame.
|
* @param delta The time elapsed since the last frame.
|
||||||
*/
|
*/
|
||||||
fun draw(mouse: Point, delta: Float) {
|
fun draw(mouse: Point, delta: Float) {
|
||||||
viewsSortedByZIndex.forEach {
|
val mouseInView = Point(mouse.x - viewController.view.frame.left, mouse.y - viewController.view.frame.top)
|
||||||
val mouseInView = Point(mouse.x - it.frame.left, mouse.y - it.frame.top)
|
viewController.view.draw(mouseInView, delta)
|
||||||
it.draw(mouseInView, delta)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -191,10 +161,9 @@ class Window {
|
||||||
* @return Whether the mouse click was handled by a view.
|
* @return Whether the mouse click was handled by a view.
|
||||||
*/
|
*/
|
||||||
fun mouseClicked(point: Point, mouseButton: MouseButton): Boolean {
|
fun mouseClicked(point: Point, mouseButton: MouseButton): Boolean {
|
||||||
val view = viewsAtPoint(point).maxBy(View::zIndex)
|
if (point in viewController.view.frame) {
|
||||||
if (view != null) {
|
val mouseInView = Point(point.x - viewController.view.frame.left, point.y - viewController.view.frame.top)
|
||||||
val pointInView = Point(point.x - view.frame.left, point.y - view.frame.top)
|
return viewController.view.mouseClicked(mouseInView, mouseButton)
|
||||||
return view.mouseClicked(pointInView, mouseButton)
|
|
||||||
} else {
|
} else {
|
||||||
// remove the window from the screen when the mouse clicks outside the window and this is not the primary window
|
// remove the window from the screen when the mouse clicks outside the window and this is not the primary window
|
||||||
if (screen.windows.size > 1) {
|
if (screen.windows.size > 1) {
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package net.shadowfacts.cacao.util.properties
|
||||||
|
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class ObservableLazyProperty<Value>(val create: () -> Value, val onCreate: () -> Unit) {
|
||||||
|
|
||||||
|
var storage: Value? = null
|
||||||
|
|
||||||
|
operator fun getValue(thisRef: Any, property: KProperty<*>): Value {
|
||||||
|
if (storage == null) {
|
||||||
|
storage = create()
|
||||||
|
onCreate()
|
||||||
|
}
|
||||||
|
return storage!!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -88,48 +88,48 @@ class DropdownButton<Value, ContentView: View>(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showDropdown() {
|
private fun showDropdown() {
|
||||||
val dropdownWindow = window.screen.addWindow(Window())
|
// val dropdownWindow = window.screen.addWindow(Window())
|
||||||
val dropdownBackground = dropdownWindow.addView(NinePatchView(NinePatchTexture.BUTTON_BG).apply {
|
// val dropdownBackground = dropdownWindow.addView(NinePatchView(NinePatchTexture.BUTTON_BG).apply {
|
||||||
zIndex = -1.0
|
// zIndex = -1.0
|
||||||
})
|
// })
|
||||||
val stack = dropdownWindow.addView(StackView(Axis.VERTICAL, StackView.Distribution.FILL))
|
// val stack = dropdownWindow.addView(StackView(Axis.VERTICAL, StackView.Distribution.FILL))
|
||||||
lateinit var selectedButton: View
|
// lateinit var selectedButton: View
|
||||||
val buttons = mutableListOf<Button>()
|
// val buttons = mutableListOf<Button>()
|
||||||
val last = allValues.count() - 1
|
// val last = allValues.count() - 1
|
||||||
for ((index, value) in allValues.withIndex()) {
|
// for ((index, value) in allValues.withIndex()) {
|
||||||
val contentView = createView(value)
|
// val contentView = createView(value)
|
||||||
val button = stack.addArrangedSubview(Button(contentView, padding).apply {
|
// val button = stack.addArrangedSubview(Button(contentView, padding).apply {
|
||||||
background = null
|
// background = null
|
||||||
hoveredBackground = DropdownItemBackgroundView(index == 0, index == last, NinePatchTexture.BUTTON_HOVERED_BG)
|
// hoveredBackground = DropdownItemBackgroundView(index == 0, index == last, NinePatchTexture.BUTTON_HOVERED_BG)
|
||||||
disabledBackground = DropdownItemBackgroundView(index == 0, index == last, NinePatchTexture.BUTTON_DISABLED_BG)
|
// disabledBackground = DropdownItemBackgroundView(index == 0, index == last, NinePatchTexture.BUTTON_DISABLED_BG)
|
||||||
disabled = value == this@DropdownButton.value
|
// disabled = value == this@DropdownButton.value
|
||||||
handler = {
|
// handler = {
|
||||||
dropdownWindow.removeFromScreen()
|
// dropdownWindow.removeFromScreen()
|
||||||
valueSelected(value)
|
// valueSelected(value)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
if (value == this@DropdownButton.value) {
|
// if (value == this@DropdownButton.value) {
|
||||||
selectedButton = button
|
// selectedButton = button
|
||||||
}
|
// }
|
||||||
buttons.add(button)
|
// buttons.add(button)
|
||||||
dropdownWindow.solver.dsl {
|
// dropdownWindow.solver.dsl {
|
||||||
if (button.content.intrinsicContentSize != null) {
|
// if (button.content.intrinsicContentSize != null) {
|
||||||
button.widthAnchor greaterThanOrEqualTo button.content.intrinsicContentSize!!.width + 2 * button.padding
|
// button.widthAnchor greaterThanOrEqualTo button.content.intrinsicContentSize!!.width + 2 * button.padding
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
dropdownWindow.solver.dsl {
|
// dropdownWindow.solver.dsl {
|
||||||
// constrain to the DropdownButton anchor's value constant, because we're crossing windows and
|
// // constrain to the DropdownButton anchor's value constant, because we're crossing windows and
|
||||||
// therefore solvers, which isn't allowed
|
// // therefore solvers, which isn't allowed
|
||||||
stack.leftAnchor equalTo this@DropdownButton.rightAnchor.value
|
// stack.leftAnchor equalTo this@DropdownButton.rightAnchor.value
|
||||||
selectedButton.centerYAnchor equalTo this@DropdownButton.centerYAnchor.value
|
// selectedButton.centerYAnchor equalTo this@DropdownButton.centerYAnchor.value
|
||||||
|
//
|
||||||
dropdownBackground.leftAnchor equalTo stack.leftAnchor
|
// dropdownBackground.leftAnchor equalTo stack.leftAnchor
|
||||||
dropdownBackground.rightAnchor equalTo stack.rightAnchor
|
// dropdownBackground.rightAnchor equalTo stack.rightAnchor
|
||||||
dropdownBackground.topAnchor equalTo stack.topAnchor
|
// dropdownBackground.topAnchor equalTo stack.topAnchor
|
||||||
dropdownBackground.bottomAnchor equalTo stack.bottomAnchor
|
// dropdownBackground.bottomAnchor equalTo stack.bottomAnchor
|
||||||
}
|
// }
|
||||||
dropdownWindow.layout()
|
// dropdownWindow.layout()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun valueSelected(value: Value) {
|
private fun valueSelected(value: Value) {
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
package net.shadowfacts.cacao.viewcontroller
|
||||||
|
|
||||||
|
import net.shadowfacts.cacao.Window
|
||||||
|
import net.shadowfacts.cacao.util.properties.ObservableLazyProperty
|
||||||
|
import net.shadowfacts.cacao.view.View
|
||||||
|
import net.shadowfacts.kiwidsl.dsl
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
abstract class ViewController {
|
||||||
|
|
||||||
|
lateinit var window: Window
|
||||||
|
|
||||||
|
val createConstraints
|
||||||
|
get() = window.solver::dsl
|
||||||
|
|
||||||
|
lateinit var view: View
|
||||||
|
protected set
|
||||||
|
|
||||||
|
var parent: ViewController? = null
|
||||||
|
set(value) {
|
||||||
|
willMoveTo(value)
|
||||||
|
field = value
|
||||||
|
didMoveTo(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var _children = LinkedList<ViewController>()
|
||||||
|
val children: List<ViewController> = _children
|
||||||
|
|
||||||
|
abstract fun loadView()
|
||||||
|
|
||||||
|
open fun viewDidLoad() {}
|
||||||
|
|
||||||
|
open fun viewWillLayoutSubviews() {
|
||||||
|
children.forEach(ViewController::viewWillLayoutSubviews)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun viewDidLayoutSubviews() {
|
||||||
|
children.forEach(ViewController::viewDidLayoutSubviews)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun viewWillAppear() {
|
||||||
|
children.forEach(ViewController::viewWillAppear)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun viewDidAppear() {
|
||||||
|
children.forEach(ViewController::viewDidAppear)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun viewWillDisappear() {
|
||||||
|
children.forEach(ViewController::viewWillDisappear)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun viewDidDisappear() {
|
||||||
|
children.forEach(ViewController::viewDidDisappear)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun willMoveTo(parent: ViewController?) {}
|
||||||
|
|
||||||
|
open fun didMoveTo(parent: ViewController?) {}
|
||||||
|
|
||||||
|
fun embedChild(viewController: ViewController, container: View = this.view) {
|
||||||
|
viewController.parent = this
|
||||||
|
viewController.window = window
|
||||||
|
_children.add(viewController)
|
||||||
|
viewController.loadView()
|
||||||
|
|
||||||
|
container.addSubview(viewController.view)
|
||||||
|
createConstraints {
|
||||||
|
viewController.view.leftAnchor equalTo container.leftAnchor
|
||||||
|
viewController.view.rightAnchor equalTo container.rightAnchor
|
||||||
|
viewController.view.topAnchor equalTo container.topAnchor
|
||||||
|
viewController.view.bottomAnchor equalTo container.bottomAnchor
|
||||||
|
}
|
||||||
|
|
||||||
|
viewController.viewDidLoad()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeChild(viewController: ViewController) {
|
||||||
|
viewController.parent = null
|
||||||
|
_children.remove(viewController)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeFromParent() {
|
||||||
|
parent?.removeChild(this)
|
||||||
|
// todo: remove view from superview
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue