aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/pl/treksoft/kvision
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/pl/treksoft/kvision')
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/core/Css.kt11
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt43
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/core/Widget.kt74
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt60
4 files changed, 157 insertions, 31 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Css.kt b/src/main/kotlin/pl/treksoft/kvision/core/Css.kt
index 8aeee71a..096cb26a 100644
--- a/src/main/kotlin/pl/treksoft/kvision/core/Css.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/core/Css.kt
@@ -257,6 +257,17 @@ enum class BGCLIP(internal val clip: String) {
}
/**
+ * Definitions of CSS position options.
+ */
+enum class POSITION(internal val position: String) {
+ STATIC("static"),
+ RELATIVE("relative"),
+ FIXED("fixed"),
+ ABSOLUTE("absolute"),
+ STICKY("sticky")
+}
+
+/**
* Type-safe definition of CSS border.
*/
class Border private constructor(
diff --git a/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt b/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt
index d130ec0b..0215d967 100644
--- a/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt
@@ -55,6 +55,30 @@ abstract class StyledComponent : Component {
*/
var maxHeight: CssSize? by refreshOnUpdate()
/**
+ * CSS position of the current component.
+ */
+ var position: POSITION? by refreshOnUpdate()
+ /**
+ * Top edge of the current component.
+ */
+ var top: CssSize? by refreshOnUpdate()
+ /**
+ * Left edge of the current component.
+ */
+ var left: CssSize? by refreshOnUpdate()
+ /**
+ * Right edge of the current component.
+ */
+ var right: CssSize? by refreshOnUpdate()
+ /**
+ * Bottom edge of the current component.
+ */
+ var bottom: CssSize? by refreshOnUpdate()
+ /**
+ * Z-index of the current component.
+ */
+ var zIndex: Int? by refreshOnUpdate()
+ /**
* Border of the current component.
*/
var border: Border? by refreshOnUpdate()
@@ -155,7 +179,6 @@ abstract class StyledComponent : Component {
*/
var background: Background? by refreshOnUpdate()
-
private var snStyleCache: List<StringPair>? = null
/**
@@ -202,6 +225,24 @@ abstract class StyledComponent : Component {
maxHeight?.let {
snstyle.add("max-height" to it.asString())
}
+ position?.let {
+ snstyle.add("position" to it.position)
+ }
+ top?.let {
+ snstyle.add("top" to it.asString())
+ }
+ left?.let {
+ snstyle.add("left" to it.asString())
+ }
+ right?.let {
+ snstyle.add("right" to it.asString())
+ }
+ bottom?.let {
+ snstyle.add("bottom" to it.asString())
+ }
+ zIndex?.let {
+ snstyle.add("z-index" to it.toString())
+ }
border?.let {
snstyle.add("border" to it.asString())
}
diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt
index 8e66d130..bfa1fc40 100644
--- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt
@@ -25,6 +25,7 @@ import com.github.snabbdom.VNode
import com.github.snabbdom.VNodeData
import com.github.snabbdom.h
import org.w3c.dom.CustomEventInit
+import org.w3c.dom.DragEvent
import org.w3c.dom.Node
import pl.treksoft.jquery.JQuery
import pl.treksoft.jquery.jQuery
@@ -74,6 +75,10 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() {
* A role attribute of generated HTML element.
*/
var role: String? by refreshOnUpdate()
+ /**
+ * Determines if the current widget is draggable.
+ */
+ var draggable: Boolean? by refreshOnUpdate()
internal var surroundingSpan by refreshOnUpdate(false)
@@ -210,6 +215,9 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() {
role?.let {
snattrs.add("role" to it)
}
+ if (draggable == true) {
+ snattrs.add("draggable" to "true")
+ }
return snattrs
}
@@ -476,6 +484,72 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() {
}
/**
+ * Sets D&D data for the current widget. It also makes it draggable.
+ * @param format D&D data format
+ * @param data D&D data transferred to a drop target
+ */
+ open fun setDragDropData(format: String, data: String) {
+ draggable = true
+ setEventListener<Widget> {
+ dragstart = { e ->
+ e.dataTransfer?.setData(format, data)
+ }
+ }
+ }
+
+ /**
+ * Clears D&D data for the current widget. It also makes it not draggable.
+ */
+ open fun clearDragDropData() {
+ draggable = false
+ setEventListener<Widget> {
+ dragstart = {
+ }
+ }
+ }
+
+ /**
+ * Sets the current widget as a D&D drop target with helper callback accepting String data.
+ * @param format accepted D&D data format
+ * @param callback a callback function accepting String data called after any drop event
+ */
+ open fun setDropTargetData(format: String, callback: (String?) -> Unit) {
+ setDropTarget(format) { e ->
+ callback(e.dataTransfer?.getData(format))
+ }
+ }
+
+ /**
+ * Sets the current widget as a D&D drop target.
+ * @param format accepted D&D data format
+ * @param callback a callback function accepting event object called after any drop event
+ */
+ open fun setDropTarget(format: String, callback: (DragEvent) -> Unit) {
+ setDropTarget(setOf(format), callback)
+ }
+
+ /**
+ * Sets the current widget as a D&D drop target.
+ * @param formats a set of accepted D&D data formats
+ * @param callback a callback function accepting event object called after any drop event
+ */
+ open fun setDropTarget(formats: Set<String>? = null, callback: (DragEvent) -> Unit) {
+ setEventListener<Widget> {
+ dragover = { e ->
+ val types = e.dataTransfer?.types?.toSet() ?: setOf()
+ if (formats == null || formats.intersect(types).isNotEmpty()) {
+ e.preventDefault()
+ }
+ }
+ drop = { e ->
+ e.preventDefault()
+ e.stopPropagation()
+ callback(e)
+ }
+ }
+ }
+
+ /**
* @suppress
* Internal function
*/
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt
index 4573b6a4..b605cf56 100644
--- a/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt
@@ -48,27 +48,27 @@ open class DockPanel(classes: Set<String> = setOf(), init: (DockPanel.() -> Unit
* @suppress
* Internal property.
*/
- protected var left: Component? = null
+ protected var leftComponent: Component? = null
/**
* @suppress
* Internal property.
*/
- protected var center: Component? = null
+ protected var centerComponent: Component? = null
/**
* @suppress
* Internal property.
*/
- protected var right: Component? = null
+ protected var rightComponent: Component? = null
/**
* @suppress
* Internal property.
*/
- protected var up: Component? = null
+ protected var upComponent: Component? = null
/**
* @suppress
* Internal property.
*/
- protected var down: Component? = null
+ protected var downComponent: Component? = null
/**
* @suppress
@@ -101,28 +101,28 @@ open class DockPanel(classes: Set<String> = setOf(), init: (DockPanel.() -> Unit
open fun add(child: Component, position: SIDE): DockPanel {
when (position) {
SIDE.UP -> {
- up?.let { mainContainer.remove(it) }
- up = child
+ upComponent?.let { mainContainer.remove(it) }
+ upComponent = child
mainContainer.add(child, 1, alignSelf = FLEXALIGNITEMS.CENTER)
}
SIDE.CENTER -> {
- center?.let { subContainer.remove(it) }
- center = child
+ centerComponent?.let { subContainer.remove(it) }
+ centerComponent = child
subContainer.add(child, 2)
}
SIDE.LEFT -> {
- left?.let { subContainer.remove(it) }
- left = child
+ leftComponent?.let { subContainer.remove(it) }
+ leftComponent = child
subContainer.add(child, 1)
}
SIDE.RIGHT -> {
- right?.let { subContainer.remove(it) }
- right = child
+ rightComponent?.let { subContainer.remove(it) }
+ rightComponent = child
subContainer.add(child, 3)
}
SIDE.DOWN -> {
- down?.let { mainContainer.remove(it) }
- down = child
+ downComponent?.let { mainContainer.remove(it) }
+ downComponent = child
mainContainer.add(child, 3, alignSelf = FLEXALIGNITEMS.CENTER)
}
}
@@ -139,11 +139,11 @@ open class DockPanel(classes: Set<String> = setOf(), init: (DockPanel.() -> Unit
}
override fun remove(child: Component): DockPanel {
- if (child == left) removeAt(SIDE.LEFT)
- if (child == center) removeAt(SIDE.CENTER)
- if (child == right) removeAt(SIDE.RIGHT)
- if (child == up) removeAt(SIDE.UP)
- if (child == down) removeAt(SIDE.DOWN)
+ if (child == leftComponent) removeAt(SIDE.LEFT)
+ if (child == centerComponent) removeAt(SIDE.CENTER)
+ if (child == rightComponent) removeAt(SIDE.RIGHT)
+ if (child == upComponent) removeAt(SIDE.UP)
+ if (child == downComponent) removeAt(SIDE.DOWN)
return this
}
@@ -155,24 +155,24 @@ open class DockPanel(classes: Set<String> = setOf(), init: (DockPanel.() -> Unit
open fun removeAt(position: SIDE): DockPanel {
when (position) {
SIDE.UP -> {
- up?.let { mainContainer.remove(it) }
- up = null
+ upComponent?.let { mainContainer.remove(it) }
+ upComponent = null
}
SIDE.CENTER -> {
- center?.let { subContainer.remove(it) }
- center = null
+ centerComponent?.let { subContainer.remove(it) }
+ centerComponent = null
}
SIDE.LEFT -> {
- left?.let { subContainer.remove(it) }
- left = null
+ leftComponent?.let { subContainer.remove(it) }
+ leftComponent = null
}
SIDE.RIGHT -> {
- right?.let { subContainer.remove(it) }
- right = null
+ rightComponent?.let { subContainer.remove(it) }
+ rightComponent = null
}
SIDE.DOWN -> {
- down?.let { mainContainer.remove(it) }
- down = null
+ downComponent?.let { mainContainer.remove(it) }
+ downComponent = null
}
}
return this