aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/pl/treksoft/kvision/panel
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/pl/treksoft/kvision/panel')
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt149
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt31
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt55
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt27
4 files changed, 262 insertions, 0 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt
new file mode 100644
index 00000000..243d1442
--- /dev/null
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt
@@ -0,0 +1,149 @@
+package pl.treksoft.kvision.panel
+
+import com.github.snabbdom.VNode
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.core.Widget
+import pl.treksoft.kvision.html.ALIGN
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+enum class GRIDTYPE {
+ BOOTSTRAP,
+ DSG
+}
+
+enum class GRIDSIZE(val size: String) {
+ XS("xs"),
+ SM("sm"),
+ MD("md"),
+ LG("lg")
+}
+
+const val FULLPERCENT = 100
+const val MAX_COLUMNS = 12
+
+internal data class WidgetParam(val widget: Widget, val size: Int, val offset: Int)
+
+open class GridPanel(private val gridtype: GRIDTYPE = GRIDTYPE.BOOTSTRAP, private val gridsize: GRIDSIZE = GRIDSIZE.MD,
+ protected var rows: Int = 0, protected var cols: Int = 0, align: ALIGN = ALIGN.NONE,
+ classes: Set<String> = setOf()) : Container(classes) {
+ var align = align
+ set(value) {
+ field = value
+ refresh()
+ }
+
+ internal val map = mutableMapOf<Int, MutableMap<Int, WidgetParam>>()
+ private var auto: Boolean = true
+
+ open fun add(child: Widget, row: Int, col: Int, size: Int = 0, offset: Int = 0): Container {
+ val cRow = if (row < 0) 0 else row
+ val cCol = if (col < 0) 0 else col
+ if (row > rows - 1) rows = cRow + 1
+ if (col > cols - 1) cols = cCol + 1
+ map.getOrPut(cRow, { mutableMapOf() }).put(cCol, WidgetParam(child, size, offset))
+ if (size > 0 || offset > 0) auto = false
+ return this
+ }
+
+ override fun add(child: Widget): Container {
+ return this.add(child, 0, this.cols)
+ }
+
+ override fun addAll(children: List<Widget>): Container {
+ children.forEach { this.add(it) }
+ return this
+ }
+
+ override fun remove(child: Widget): Container {
+ for (i in 0 until rows) {
+ val row = map[i]
+ if (row != null) {
+ for (j in 0 until cols) {
+ val wp = row[j]
+ if (wp != null) {
+ if (wp.widget == child) row.remove(j)
+ }
+ }
+ }
+ }
+ return this
+ }
+
+ open fun removeAt(row: Int, col: Int): Container {
+ map[row]?.remove(col)
+ return this
+ }
+
+ override fun removeAt(index: Int): Container {
+ return this.removeAt(0, index)
+ }
+
+ override fun childrenVNodes(): Array<VNode> {
+ return if (gridtype == GRIDTYPE.BOOTSTRAP) {
+ childrenVNodesBts()
+ } else {
+ childrenVNodesDsg()
+ }
+ }
+
+ @Suppress("NestedBlockDepth", "LoopToCallChain")
+ protected open fun childrenVNodesDsg(): Array<VNode> {
+ val ret = mutableListOf<VNode>()
+ val num = FULLPERCENT / cols
+ for (i in 0 until rows) {
+ val rowContainer = Container(setOf("dsgrow"))
+ val row = map[i]
+ if (row != null) {
+ for (j in 0 until cols) {
+ val wp = row[j]
+ val widget = wp?.widget?.addCssClass("dsgcol") ?: Tag(TAG.DIV, classes = setOf("dsgcol"))
+ widget.widthPercent = num
+ if (align != ALIGN.NONE) {
+ widget.addCssClass(align.className)
+ }
+ rowContainer.add(widget)
+ }
+ }
+ ret.add(rowContainer.render())
+ }
+ return ret.toTypedArray()
+ }
+
+ @Suppress("NestedBlockDepth", "LoopToCallChain")
+ private fun childrenVNodesBts(): Array<VNode> {
+ val ret = mutableListOf<VNode>()
+ val num = MAX_COLUMNS / cols
+ for (i in 0 until rows) {
+ val rowContainer = Container(setOf("row"))
+ val row = map[i]
+ if (row != null) {
+ for (j in 0 until cols) {
+ val wp = row[j]
+ if (auto) {
+ val widget = wp?.widget?.addCssClass("col-" + gridsize.size + "-" + num) ?:
+ Tag(TAG.DIV, classes = setOf("col-" + gridsize.size + "-" + num))
+ if (align != ALIGN.NONE) {
+ widget.addCssClass(align.className)
+ }
+ rowContainer.add(widget)
+ } else {
+ if (wp != null) {
+ val s = if (wp.size > 0) wp.size else num
+ wp.widget.addCssClass("col-" + gridsize.size + "-" + s)
+ if (wp.offset > 0) {
+ wp.widget.addCssClass("col-" + gridsize.size + "-offset-" + wp.offset)
+ }
+ if (align != ALIGN.NONE) {
+ wp.widget.addCssClass(align.className)
+ }
+ rowContainer.add(wp.widget)
+ }
+ }
+ }
+ }
+ ret.add(rowContainer.render())
+ }
+ return ret.toTypedArray()
+ }
+}
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt
new file mode 100644
index 00000000..685cfc87
--- /dev/null
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt
@@ -0,0 +1,31 @@
+package pl.treksoft.kvision.panel
+
+import com.github.snabbdom.VNode
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.core.Widget
+import pl.treksoft.kvision.html.ALIGN
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+open class HPanel(align: ALIGN = ALIGN.NONE, classes: Set<String> = setOf()) : GridPanel(GRIDTYPE.DSG, align = align,
+ classes = classes) {
+
+ override fun add(child: Widget, row: Int, col: Int, size: Int, offset: Int): Container {
+ return super.add(child, 0, col, size, offset)
+ }
+
+ override fun childrenVNodesDsg(): Array<VNode> {
+ val ret = mutableListOf<VNode>()
+ val rowContainer = Container(setOf("dsgrow"))
+ val row = map[0]
+ if (row != null) {
+ for (j in 0 until cols) {
+ val wp = row[j]
+ val widget = wp?.widget?.addCssClass("dsgcolf") ?: Tag(TAG.DIV, classes = setOf("dsgcolf"))
+ rowContainer.add(widget)
+ }
+ }
+ ret.add(rowContainer.render())
+ return ret.toTypedArray()
+ }
+}
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt
new file mode 100644
index 00000000..0022023b
--- /dev/null
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt
@@ -0,0 +1,55 @@
+package pl.treksoft.kvision.panel
+
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.core.ResString
+import pl.treksoft.kvision.core.Widget
+import pl.treksoft.kvision.html.Link
+import pl.treksoft.kvision.html.TAG
+import pl.treksoft.kvision.html.Tag
+
+open class TabPanel : Container(setOf()) {
+ private var nav = Tag(TAG.UL, classes = setOf("nav", "nav-tabs"))
+ private var content = StackPanel(false)
+ var activeIndex
+ get() = content.activeIndex
+ set(value) {
+ content.activeIndex = value
+ nav.children.forEach { it.removeCssClass("active") }
+ if (content.activeIndex >= 0 && content.activeIndex <= nav.children.size) {
+ nav.children[content.activeIndex].addCssClass("active")
+ }
+ }
+
+ init {
+ this.add(nav)
+ this.add(content)
+ }
+
+ open fun addTab(title: String, panel: Widget, icon: String? = null,
+ image: ResString? = null): TabPanel {
+ val tag = Tag(TAG.LI)
+ tag.role = "presentation"
+ tag.add(Link(title, "#", icon, image))
+ val index = nav.children.size
+ tag.setEventListener {
+ click = { e ->
+ activeIndex = index
+ e.preventDefault()
+ }
+ }
+ nav.add(tag)
+ if (nav.children.size == 1) {
+ tag.addCssClass("active")
+ activeIndex = 0
+ }
+ content.add(panel)
+ return this
+ }
+
+ open fun removeTab(index: Int): TabPanel {
+ nav.removeAt(index)
+ content.removeAt(index)
+ activeIndex = content.activeIndex
+ return this
+ }
+}
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt
new file mode 100644
index 00000000..f81c4a7e
--- /dev/null
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt
@@ -0,0 +1,27 @@
+package pl.treksoft.kvision.panel
+
+import pl.treksoft.kvision.core.Container
+import pl.treksoft.kvision.core.Widget
+import pl.treksoft.kvision.html.ALIGN
+
+open class VPanel(align: ALIGN = ALIGN.NONE, classes: Set<String> = setOf()) : GridPanel(GRIDTYPE.BOOTSTRAP,
+ align = align, classes = classes) {
+
+ override fun add(child: Widget, row: Int, col: Int, size: Int, offset: Int): Container {
+ return super.add(child, row, 0, size, offset)
+ }
+
+ override fun add(child: Widget): Container {
+ return this.add(child, this.rows, 0)
+ }
+
+ override fun addAll(children: List<Widget>): Container {
+ children.forEach { this.add(it) }
+ return this
+ }
+
+ override fun removeAt(index: Int): Container {
+ return this.removeAt(index, 0)
+ }
+
+}