diff options
author | Robert Jaros <rjaros@finn.pl> | 2018-02-12 08:04:05 +0100 |
---|---|---|
committer | Robert Jaros <rjaros@finn.pl> | 2018-02-12 08:04:05 +0100 |
commit | 2feea5e7cf8d492663e826ebcfb0a58e61820352 (patch) | |
tree | 2586cefdd5bf15193158d92b53442608632cd9d9 | |
parent | 4f1a7d4331ec802789009937cda5a1e0e2213cb4 (diff) | |
download | kvision-2feea5e7cf8d492663e826ebcfb0a58e61820352.tar.gz kvision-2feea5e7cf8d492663e826ebcfb0a58e61820352.tar.bz2 kvision-2feea5e7cf8d492663e826ebcfb0a58e61820352.zip |
DSL syntax for containers
17 files changed, 107 insertions, 18 deletions
diff --git a/build.gradle b/build.gradle index be3fdef6..42465be0 100644 --- a/build.gradle +++ b/build.gradle @@ -34,7 +34,7 @@ apply plugin: "io.gitlab.arturbosch.detekt" apply plugin: 'org.jetbrains.dokka' group = 'pl.treksoft' -version = '0.0.2' +version = '0.0.3' repositories { jcenter() diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt b/src/main/kotlin/pl/treksoft/kvision/core/Container.kt index a428ad14..d2650f7e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Container.kt @@ -40,6 +40,15 @@ interface Container : Component { fun addAll(children: List<Component>): Container /** + * Operator function for adding children in a DSL style. + * @param child children components + * @return current container + */ + operator fun invoke(vararg children: Component): Container { + return addAll(children.asList()) + } + + /** * Removes given component from the current container. * @param child child component * @return current container diff --git a/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt b/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt index 209c9ae6..13b5ce00 100644 --- a/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt +++ b/src/main/kotlin/pl/treksoft/kvision/data/DataContainer.kt @@ -37,11 +37,13 @@ import pl.treksoft.kvision.panel.VPanel * @param model data model of type *ObservableList<M>* * @param binding a function which creates component C from data model at given index * @param child internal container (defaults to [VPanel]) + * @param init an initializer extension function */ class DataContainer<M : DataComponent, C : Component>( private val model: ObservableList<M>, private val binding: (Int) -> C, - private val child: Container = VPanel() + private val child: Container = VPanel(), + init: (DataContainer<M, C>.() -> Unit)? = null ) : Widget(setOf()), Container, DataUpdatable { @@ -59,6 +61,8 @@ class DataContainer<M : DataComponent, C : Component>( update() } update() + @Suppress("LeakingThis") + init?.invoke(this) } override fun add(child: Component): Container { diff --git a/src/main/kotlin/pl/treksoft/kvision/html/List.kt b/src/main/kotlin/pl/treksoft/kvision/html/List.kt index c8252080..261555c9 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/List.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/List.kt @@ -51,10 +51,11 @@ enum class LISTTYPE(internal val tagName: String) { * @param elements optional list of elements * @param rich determines if [elements] can contain HTML code * @param classes a set of CSS class names + * @param init an initializer extension function */ open class ListTag( type: LISTTYPE, elements: List<String>? = null, rich: Boolean = false, - classes: Set<String> = setOf() + classes: Set<String> = setOf(), init: (ListTag.() -> Unit)? = null ) : SimplePanel(classes) { /** * List type. @@ -81,6 +82,11 @@ open class ListTag( refresh() } + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + override fun render(): VNode { val childrenElements = when (type) { LISTTYPE.UL, LISTTYPE.OL, LISTTYPE.UNSTYLED, LISTTYPE.INLINE -> elements?.map { el -> diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt index 557784b0..91fa2587 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt @@ -87,10 +87,11 @@ enum class ALIGN(val className: String) { * @param rich determines if [text] can contain HTML code * @param align text align * @param classes a set of CSS class names + * @param init an initializer extension function */ open class Tag( type: TAG, text: String? = null, rich: Boolean = false, align: ALIGN? = null, - classes: Set<String> = setOf() + classes: Set<String> = setOf(), init: (Tag.() -> Unit)? = null ) : SimplePanel(classes) { /** @@ -126,6 +127,11 @@ open class Tag( refresh() } + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + override fun render(): VNode { return if (text != null) { if (rich) { diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt index 874b4370..f913fac1 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt +++ b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt @@ -51,12 +51,13 @@ enum class MODALSIZE(val className: String) { * @param animation determines if animations are used * @param escape determines if dialog can be closed with Esc key * @param classes a set of CSS class names + * @param init an initializer extension function */ @Suppress("TooManyFunctions") open class Modal( caption: String? = null, closeButton: Boolean = true, size: MODALSIZE? = null, animation: Boolean = true, private val escape: Boolean = true, - classes: Set<String> = setOf() + classes: Set<String> = setOf(), init: (Modal.() -> Unit)? = null ) : SimplePanel(classes) { /** @@ -135,6 +136,8 @@ open class Modal( } else { println("At least one Root object is required to create a modal!") } + @Suppress("LeakingThis") + init?.invoke(this) } private fun checkHeaderVisibility() { diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt index 7f32a61c..82d1c117 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/DockPanel.kt @@ -39,8 +39,10 @@ enum class SIDE { * * @constructor * @param classes a set of CSS class names + * @param init an initializer extension function */ -open class DockPanel(classes: Set<String> = setOf()) : SimplePanel(classes = classes) { +open class DockPanel(classes: Set<String> = setOf(), init: (DockPanel.() -> Unit)? = null) : + SimplePanel(classes = classes) { /** * @suppress * Internal property. @@ -84,6 +86,8 @@ open class DockPanel(classes: Set<String> = setOf()) : SimplePanel(classes = cla init { this.addInternal(mainContainer) mainContainer.add(subContainer, 2) + @Suppress("LeakingThis") + init?.invoke(this) } /** diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt index 266612fe..5aebe1c6 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt @@ -92,11 +92,12 @@ enum class FLEXALIGNCONTENT(internal val alignContent: String) { * @param alignContent flexbox content alignment * @param spacing spacing between columns/rows * @param classes a set of CSS class names + * @param init an initializer extension function */ open class FlexPanel( direction: FLEXDIR? = null, wrap: FLEXWRAP? = null, justify: FLEXJUSTIFY? = null, alignItems: FLEXALIGNITEMS? = null, alignContent: FLEXALIGNCONTENT? = null, - spacing: Int? = null, classes: Set<String> = setOf() + spacing: Int? = null, classes: Set<String> = setOf(), init: (FlexPanel.() -> Unit)? = null ) : SimplePanel(classes) { /** @@ -150,6 +151,11 @@ open class FlexPanel( refresh() } + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + /** * Adds a component to the flexbox container. * @param child child component diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt index b6f1d3a5..ba72535a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt @@ -98,13 +98,14 @@ enum class GRIDFLOW(internal val flow: String) { * @param justifyContent flexbox content justification * @param alignContent flexbox content alignment * @param classes a set of CSS class names + * @param init an initializer extension function */ open class GridPanel( autoColumns: String? = null, autoRows: String? = null, autoFlow: GRIDFLOW? = null, templateColumns: String? = null, templateRows: String? = null, templateAreas: List<String>? = null, columnGap: Int? = null, rowGap: Int? = null, justifyItems: GRIDJUSTIFY? = null, alignItems: GRIDALIGN? = null, justifyContent: GRIDJUSTIFYCONTENT? = null, - alignContent: GRIDALIGNCONTENT? = null, classes: Set<String> = setOf() + alignContent: GRIDALIGNCONTENT? = null, classes: Set<String> = setOf(), init: (GridPanel.() -> Unit)? = null ) : SimplePanel(classes) { /** @@ -204,6 +205,11 @@ open class GridPanel( refresh() } + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + /** * Adds a component to the grid container. * @param child child component diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt index 7639ca3b..755c675b 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/HPanel.kt @@ -32,11 +32,17 @@ package pl.treksoft.kvision.panel * @param alignItems flexbox items alignment * @param spacing spacing between columns/rows * @param classes a set of CSS class names + * @param init an initializer extension function */ open class HPanel( wrap: FLEXWRAP? = null, justify: FLEXJUSTIFY? = null, alignItems: FLEXALIGNITEMS? = null, spacing: Int? = null, - classes: Set<String> = setOf() + classes: Set<String> = setOf(), init: (HPanel.() -> Unit)? = null ) : FlexPanel( null, wrap, justify, alignItems, null, spacing, classes -) +) { + init { + @Suppress("LeakingThis") + init?.invoke(this) + } +} diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt index 93588617..8831e905 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt @@ -50,11 +50,12 @@ internal data class WidgetParam(val widget: Component, val size: Int, val offset * @param cols number of columns * @param align text align of grid cells * @param classes a set of CSS class names + * @param init an initializer extension function */ open class ResponsiveGridPanel( private val gridsize: GRIDSIZE = GRIDSIZE.MD, private var rows: Int = 0, private var cols: Int = 0, align: ALIGN? = null, - classes: Set<String> = setOf() + classes: Set<String> = setOf(), init: (ResponsiveGridPanel.() -> Unit)? = null ) : SimplePanel(classes) { /** @@ -69,6 +70,11 @@ open class ResponsiveGridPanel( internal val map = mutableMapOf<Int, MutableMap<Int, WidgetParam>>() private var auto: Boolean = true + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + /** * Adds child component to the grid. * @param child child component diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt index e10fdc86..d81b103d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt @@ -37,8 +37,9 @@ import pl.treksoft.kvision.modal.Modal * @param id ID attribute of element in the main HTML file * @param fixed if false, the container is rendered with Bootstrap "container-fluid" class, * otherwise it's rendered with "container" class (default is false) + * @param init an initializer extension function */ -class Root(id: String, private val fixed: Boolean = false) : SimplePanel() { +class Root(id: String, private val fixed: Boolean = false, init: (Root.() -> Unit)? = null) : SimplePanel() { private val modals: MutableList<Modal> = mutableListOf() private var rootVnode: VNode = renderVNode() @@ -48,6 +49,8 @@ class Root(id: String, private val fixed: Boolean = false) : SimplePanel() { rootVnode = KVManager.patch(id, this.renderVNode()) this.id = id roots.add(this) + @Suppress("LeakingThis") + init?.invoke(this) } override fun render(): VNode { diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt index b210f2cb..aad57023 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/SimplePanel.kt @@ -31,10 +31,17 @@ import pl.treksoft.kvision.core.Widget * * @constructor * @param classes a set of CSS class names + * @param init an initializer extension function */ -open class SimplePanel(classes: Set<String> = setOf()) : Widget(classes), Container { +open class SimplePanel(classes: Set<String> = setOf(), init: (SimplePanel.() -> Unit)? = null) : Widget(classes), + Container { internal val children: MutableList<Component> = mutableListOf() + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + override fun render(): VNode { return render("div", childrenVNodes()) } diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/SplitPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/SplitPanel.kt index cfeadd58..677d0704 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/SplitPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/SplitPanel.kt @@ -47,15 +47,21 @@ enum class DIRECTION(internal val dir: String) { * @constructor * @param direction direction of the splitter * @param classes a set of CSS class names + * @param init an initializer extension function */ open class SplitPanel( private val direction: DIRECTION = DIRECTION.VERTICAL, - classes: Set<String> = setOf() + classes: Set<String> = setOf(), init: (SplitPanel.() -> Unit)? = null ) : SimplePanel(classes + ("splitpanel-" + direction.dir)) { @Suppress("LeakingThis") internal val splitter = Splitter(this, direction) + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + @Suppress("UnsafeCastFromDynamic") internal fun afterInsertSplitter() { if (children.size == 2) { diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt index 672c8690..cf765928 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt @@ -33,10 +33,11 @@ import pl.treksoft.kvision.routing.routing * @constructor * @param activateLast determines if added component is automatically activated (default true) * @param classes a set of CSS class names + * @param init an initializer extension function */ open class StackPanel( private val activateLast: Boolean = true, - classes: Set<String> = setOf() + classes: Set<String> = setOf(), init: (StackPanel.() -> Unit)? = null ) : SimplePanel(classes) { /** @@ -48,6 +49,11 @@ open class StackPanel( refresh() } + init { + @Suppress("LeakingThis") + init?.invoke(this) + } + override fun childrenVNodes(): Array<VNode> { return if (activeIndex >= 0 && activeIndex < children.size) { arrayOf(children[activeIndex].renderVNode()) diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt index 9072d261..067a8146 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/TabPanel.kt @@ -35,8 +35,9 @@ import pl.treksoft.kvision.routing.routing * * @constructor * @param classes a set of CSS class names + * @param init an initializer extension function */ -open class TabPanel(classes: Set<String> = setOf()) : SimplePanel(classes) { +open class TabPanel(classes: Set<String> = setOf(), init: (TabPanel.() -> Unit)? = null) : SimplePanel(classes) { /** * The index of active (visible) tab. @@ -61,6 +62,9 @@ open class TabPanel(classes: Set<String> = setOf()) : SimplePanel(classes) { init { this.addInternal(nav) this.addInternal(content) + + @Suppress("LeakingThis") + init?.invoke(this) } /** diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt index 91ee4a6a..823ab66f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/VPanel.kt @@ -31,11 +31,18 @@ package pl.treksoft.kvision.panel * @param alignItems flexbox items alignment * @param spacing spacing between columns/rows * @param classes a set of CSS class names + * @param init an initializer extension function */ open class VPanel( justify: FLEXJUSTIFY? = null, alignItems: FLEXALIGNITEMS? = null, spacing: Int? = null, - classes: Set<String> = setOf() + classes: Set<String> = setOf(), init: (VPanel.() -> Unit)? = null ) : FlexPanel( FLEXDIR.COLUMN, null, justify, alignItems, null, spacing, classes -) +) { + init { + @Suppress("LeakingThis") + init?.invoke(this) + } +} + |