Cells/cells/ui/src/net/okennedy/cells/widgets/DragFrame.scala

117 lines
3.6 KiB
Scala

package net.okennedy.cells.widgets
import com.raquo.laminar.api.L._
import com.raquo.airstream.ownership.OneTimeOwner
object DragFrame
{
def position(x: Int, y: Int, width: Int, height: Int, evt: org.scalajs.dom.MouseEvent)(callback: (Int, Int) => Unit): Unit =
{
val frame = new Position(x, y, width, height, evt.pageX, evt.pageY, callback)
Widgets.register(frame)
}
def width(x: Int, y: Int, width: Int, height: Int, evt: org.scalajs.dom.MouseEvent)(callback: (Int) => Unit) =
{
val frame = new Width(x, y, width, height, evt.pageX, evt.pageY, callback)
Widgets.register(frame)
}
def snapWidth(x: Int, y: Int, width: Int, height: Int, evt: org.scalajs.dom.MouseEvent)(doSnap: Int => Int)(callback: (Int) => Unit) =
{
val frame = new Width(x, y, width, height, evt.pageX, evt.pageY, callback) { override def snap(x: Int) = doSnap(x+width)-width }
Widgets.register(frame)
}
def height(x: Int, y: Int, width: Int, height: Int, evt: org.scalajs.dom.MouseEvent)(callback: (Int) => Unit) =
{
val frame = new Height(x, y, width, height, evt.pageX, evt.pageY, callback)
Widgets.register(frame)
}
def snapHeight(x: Int, y: Int, width: Int, height: Int, evt: org.scalajs.dom.MouseEvent)(doSnap: Int => Int)(callback: (Int) => Unit) =
{
val frame = new Height(x, y, width, height, evt.pageX, evt.pageY, callback) { override def snap(x: Int) = doSnap(x+height)-height }
Widgets.register(frame)
}
class Position(initX: Int, initY: Int, width: Int, height: Int, cursorX: Double, cursorY: Double, callback: (Int, Int) => Unit)
extends Widget
{
val curr = Var[(Int, Int)](initial = (initX, initY))
val root = div(
className("dragFrame"),
styleAttr <--
curr.signal.map { case (x, y) =>
s"left: ${x-2}px; top: ${y-2}px; height: ${height-4}px; width: ${width-4}px"
},
documentEvents.onMouseUp --> {
(evt) =>
val (x, y) = curr.now()
callback( x, y )
Widgets.remove(this)
},
documentEvents.onMouseMove --> {
(evt) =>
curr.set( (
initX + (evt.pageX - cursorX).toInt,
initY + (evt.pageY - cursorY).toInt
) )
}
)
}
class Width(x: Int, y: Int, width: Int, height: Int, cursorX: Double, cursorY: Double, callback: (Int) => Unit)
extends Widget
{
val curr = Var[Int](initial = width)
def snap(v: Int): Int = v
val root = div(
className("dragFrame"),
styleAttr <--
curr.signal.map { case width =>
s"left: ${x-2}px; top: ${y-2}px; height: ${height-4}px; width: ${width-4}px"
},
documentEvents.onMouseUp --> {
(evt) =>
val width = curr.now()
callback( width )
Widgets.remove(this)
},
documentEvents.onMouseMove --> {
(evt) =>
curr.set( (width) + snap( (evt.pageX - cursorX).toInt ) )
}
)
}
class Height(x: Int, y: Int, width: Int, height: Int, cursorX: Double, cursorY: Double, callback: (Int) => Unit)
extends Widget
{
val curr = Var[Int](initial = height)
def snap(v: Int): Int = v
val root = div(
className("dragFrame"),
styleAttr <--
curr.signal.map { case height =>
s"left: ${x-2}px; top: ${y-2}px; height: ${height-4}px; width: ${width-4}px"
},
documentEvents.onMouseUp --> {
(evt) =>
val height = curr.now()
callback( height )
Widgets.remove(this)
},
documentEvents.onMouseMove --> {
(evt) =>
curr.set( (height) + snap( (evt.pageY - cursorY).toInt ) )
}
)
}
}