edvin / tornadofx

Lightweight JavaFX Framework for Kotlin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TornadoFx stackpane overlapping with menubar

Harrisonust opened this issue · comments

Recently I am having trouble with my application with TornadoFx. The stackpane I created for drawing shape was overlapping the menubar and toolbar when I moved it by mouse. How can I solve this program? Thanks a lot. Below is my code:

overlap

class MainView : View("TornadoFX Zoom Test") {
    var canvas:  PannableCanvas by singleAssign()
    var stackPane: StackPane by singleAssign()
    var topCell = Group()
    override val root = vbox {
      menubar{
            menu("File") {
                menu("Connect") {
                    item("Facebook")
                    item("Twitter")
                }
                item("Save")
                item("Quit")
            }
            menu("Edit") {
                item("Copy")
                item("Paste")
            }
        }
```

        toolbar{
            region  { // Only needed if you want content on the left side
                //hgrow = Priority.SOMETIMES
            }
            button("Test") {
                action{
                }
            }
            button("Test2") {
                action{

                }
            }
        }
        stackPane = stackpane {
            prefWidth = 600.0
            prefHeight =508.0
        }
        createCanvas()
    }



    fun createCanvas(){
        canvas = PannableCanvas().apply {
            children.add(topCell)
            stackPane.children.add(this)
            setTranslateX(0.0)
            setTranslateY(0.0)
        }

        val sceneGestures = SceneGestures(canvas)
        stackPane.addEventFilter(MouseEvent.MOUSE_PRESSED, sceneGestures.onMousePressedEventHandler)
        stackPane.addEventFilter(MouseEvent.MOUSE_DRAGGED, sceneGestures.onMouseDraggedEventHandler)
        stackPane.addEventFilter(ScrollEvent.ANY, sceneGestures.onScrollEventHandler)

        canvas.addGrid()
    }
}
`

`class PannableCanvas : Pane() {
    var myScale: DoubleProperty = SimpleDoubleProperty(1.0)
    init {
        prefWidth = 600.0
        prefHeight = 500.0
        // add scale transform
        scaleXProperty().bind(myScale)
        scaleYProperty().bind(myScale)
    }
    /**
     * Add a grid to the canvas, send it to back
     */
    fun addGrid() {
        val w = 600.0 //boundsInLocal.width
        val h = 500.0 //boundsInLocal.height

        // add grid
        val grid = Canvas(w, h)

        // don't catch mouse events
        grid.isMouseTransparent = true
        val gc = grid.graphicsContext2D
        gc.stroke = Color.GRAY
        gc.lineWidth = 1.0

        // draw grid lines
        val offset = 50.0
        var i = offset
        while (i < w) {
            gc.strokeLine(i, 0.0, i, h)
            gc.strokeLine(0.0, i, w, i)
            i += offset
        }
        children.add(grid)
        grid.toBack()
    }

    var scale: Double
        get() = myScale.get()
        set(scale) {
            myScale.set(scale)
        }

    fun setPivot(x: Double, y: Double) {
        translateX = translateX - x
        translateY = translateY - y
    }
}`

`class DragContext {
    var mouseAnchorX = 0.0
    var mouseAnchorY = 0.0
    var translateAnchorX = 0.0
    var translateAnchorY = 0.0
}


/**
 * Listeners for making the scene's canvas draggable and zoomable
 */
class SceneGestures(var canvas: PannableCanvas) {
    private val sceneDragContext = DragContext()
    val onMousePressedEventHandler = EventHandler<MouseEvent> { event -> // right mouse button => panning
            if (!event.isSecondaryButtonDown) return@EventHandler
            sceneDragContext.mouseAnchorX = event.sceneX
            sceneDragContext.mouseAnchorY = event.sceneY
            sceneDragContext.translateAnchorX = canvas.translateX
            sceneDragContext.translateAnchorY = canvas.translateY
        }
    val onMouseDraggedEventHandler = EventHandler<MouseEvent> { event -> // right mouse button => panning
            if (!event.isSecondaryButtonDown) return@EventHandler
            canvas.translateX = sceneDragContext.translateAnchorX + event.sceneX - sceneDragContext.mouseAnchorX
            canvas.translateY = sceneDragContext.translateAnchorY + event.sceneY - sceneDragContext.mouseAnchorY
            event.consume()
        }

    /**
     * Mouse wheel handler: zoom to pivot point
     */
    val onScrollEventHandler = EventHandler<ScrollEvent> { event ->
            val delta = 1.1
            //var scale: Double = canvas.getScale() // currently we only use Y, same value is used for X
            var scale: Double = canvas.scale // currently we only use Y, same value is used for X
            val oldScale = scale
            if (event.deltaY < 0) scale /= delta else scale *= delta
            scale = clamp(scale, MIN_SCALE, MAX_SCALE)
            val f = scale / oldScale - 1
            val dx = event.sceneX - (canvas.boundsInParent.width / 2 + canvas.boundsInParent.minX)
            val dy = event.sceneY - (canvas.boundsInParent.height / 2 + canvas.boundsInParent.minY)
            //canvas.setScale(scale)
            canvas.scale = scale

            // note: pivot value must be untransformed, i. e. without scaling
            canvas.setPivot(f * dx, f * dy)
            event.consume()
        }

    companion object {
        private const val MAX_SCALE = 10.0
        private const val MIN_SCALE = .1
        fun clamp(value: Double, min: Double, max: Double): Double {
            if (java.lang.Double.compare(value, min) < 0) return min
            return if (java.lang.Double.compare(value, max) > 0) max else value
        }
    }
}`