edvin / tornadofx

Lightweight JavaFX Framework for Kotlin
Apache License 2.0
3.67k stars 271 forks source link

`fold` in `Squeze Box` does not resize stage #750

Open arslancharyev31 opened 6 years ago

arslancharyev31 commented 6 years ago

Good day. I've noticed that folding and unfolding does not cause the stage to be resized according to expanded/collapsed height. Is there any way to enable this dynamic resizing?

edvin commented 6 years ago

It’s not s component’s resposibility to resize the stage. I don’t think any of the stock components does this either. You’d have to attach a listener to the prefHeightProperty and resize when it changes :)

arslancharyev31 commented 6 years ago

OK, so based on my research I've been able to come with the following solution: I declare requestWindowAutoResize function in the root form block of a View subclass as following:

override val root = form {
    fun Region.requestWindowAutoResize(){
        this.heightProperty().addListener { _ ->
            currentWindow?.let {
                val rootPrefHeight = this@form.prefHeight(-1.0)
                val decorationHeight = it.height - scene.height// window decorations
                it.height = rootPrefHeight + decorationHeight
            }
        }
    }
    // build ui
}

And then call this function on required component:

squeezebox {
    requestWindowAutoResize()
    fold("Foldable") {
        // build ui
    }
}

There are 2 issues asociated with this approach:

  1. The resulting animation is a bit laggy and if a user expands/collapses view with high frequency, then the resulting height might be slightly off by 5-10 pixels. Any ideas on how to ensure that window's final height is what it's supposed to be?
  2. I cannot seem to be able to generalize requestWindowAutoResize() function and make it global, because if I make it an extension of Region then I can access component's heightProperty(), but not View's currentWindow and scene. And vica-versa if I make it an extension of View. Any ideas on this front?