1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
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.core.WidgetWrapper
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) {
private 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?.let { WidgetWrapper(it, setOf("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?.let {
WidgetWrapper(it, setOf("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
val widget = WidgetWrapper(wp.widget, setOf("col-" + gridsize.size + "-" + s))
if (wp.offset > 0) {
widget.addCssClass("col-" + gridsize.size + "-offset-" + wp.offset)
}
if (align != ALIGN.NONE) {
widget.addCssClass(align.className)
}
rowContainer.add(widget)
}
}
}
}
ret.add(rowContainer.render())
}
return ret.toTypedArray()
}
}
|