diff options
author | Robert Jaros <rjaros@finn.pl> | 2018-02-22 12:43:43 +0100 |
---|---|---|
committer | Robert Jaros <rjaros@finn.pl> | 2018-02-22 12:43:43 +0100 |
commit | e40c13c62de806169368adc7c2c4212f7df6413b (patch) | |
tree | 250e39d407cd2c6ef19c9a8ea0176a3215a4a818 /src | |
parent | 1aefed336f9ef305f59d3668abc8a39c550e921d (diff) | |
download | kvision-e40c13c62de806169368adc7c2c4212f7df6413b.tar.gz kvision-e40c13c62de806169368adc7c2c4212f7df6413b.tar.bz2 kvision-e40c13c62de806169368adc7c2c4212f7df6413b.zip |
Property values delegated to a map (idea by tieskedh)
Closes #2
Diffstat (limited to 'src')
27 files changed, 202 insertions, 805 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt b/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt index f0ceb587..d130ec0b 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt @@ -22,187 +22,102 @@ package pl.treksoft.kvision.core import pl.treksoft.kvision.utils.asString +import kotlin.reflect.KProperty /** * Base class for components supporting CSS styling. */ abstract class StyledComponent : Component { + private val propertyValues: MutableMap<String, Any?> = mutableMapOf() + /** * Width of the current component. */ - open var width: CssSize? = null - set(value) { - field = value - refresh() - } + open var width: CssSize? by refreshOnUpdate() /** * Minimal width of the current component. */ - var minWidth: CssSize? = null - set(value) { - field = value - refresh() - } + var minWidth: CssSize? by refreshOnUpdate() /** * Maximal width of the current component. */ - var maxWidth: CssSize? = null - set(value) { - field = value - refresh() - } + var maxWidth: CssSize? by refreshOnUpdate() /** * Height of the current component. */ - var height: CssSize? = null - set(value) { - field = value - refresh() - } + var height: CssSize? by refreshOnUpdate() /** * Minimal height of the current component. */ - var minHeight: CssSize? = null - set(value) { - field = value - refresh() - } + var minHeight: CssSize? by refreshOnUpdate() /** * Maximal height of the current component. */ - var maxHeight: CssSize? = null - set(value) { - field = value - refresh() - } + var maxHeight: CssSize? by refreshOnUpdate() /** * Border of the current component. */ - var border: Border? = null - set(value) { - field = value - refresh() - } + var border: Border? by refreshOnUpdate() /** * Top border of the current component. */ - var borderTop: Border? = null - set(value) { - field = value - refresh() - } + var borderTop: Border? by refreshOnUpdate() /** * Right border of the current component. */ - var borderRight: Border? = null - set(value) { - field = value - refresh() - } + var borderRight: Border? by refreshOnUpdate() /** * Bottom border of the current component. */ - var borderBottom: Border? = null - set(value) { - field = value - refresh() - } + var borderBottom: Border? by refreshOnUpdate() /** * Left border of the current component. */ - var borderLeft: Border? = null - set(value) { - field = value - refresh() - } + var borderLeft: Border? by refreshOnUpdate() /** * Margin of the current component. */ - var margin: CssSize? = null - set(value) { - field = value - refresh() - } + var margin: CssSize? by refreshOnUpdate() /** * Top margin of the current component. */ - var marginTop: CssSize? = null - set(value) { - field = value - refresh() - } + var marginTop: CssSize? by refreshOnUpdate() /** * Right margin of the current component. */ - var marginRight: CssSize? = null - set(value) { - field = value - refresh() - } + var marginRight: CssSize? by refreshOnUpdate() /** * Bottom margin of the current component. */ - var marginBottom: CssSize? = null - set(value) { - field = value - refresh() - } + var marginBottom: CssSize? by refreshOnUpdate() /** * Left margin of the current component. */ - var marginLeft: CssSize? = null - set(value) { - field = value - refresh() - } + var marginLeft: CssSize? by refreshOnUpdate() /** * Padding of the current component. */ - var padding: CssSize? = null - set(value) { - field = value - refresh() - } + var padding: CssSize? by refreshOnUpdate() /** * Top padding of the current component. */ - var paddingTop: CssSize? = null - set(value) { - field = value - refresh() - } + var paddingTop: CssSize? by refreshOnUpdate() /** * Right padding of the current component. */ - var paddingRight: CssSize? = null - set(value) { - field = value - refresh() - } + var paddingRight: CssSize? by refreshOnUpdate() /** * Bottom padding of the current component. */ - var paddingBottom: CssSize? = null - set(value) { - field = value - refresh() - } + var paddingBottom: CssSize? by refreshOnUpdate() /** * Left padding of the current component. */ - var paddingLeft: CssSize? = null - set(value) { - field = value - refresh() - } + var paddingLeft: CssSize? by refreshOnUpdate() /** * Text color for the current component. */ - var color: Color? = null - set(value) { - field = value - refresh() - } + var color: Color? by refreshOnUpdate() /** * Text color for the current component given in hex format (write only). * @@ -234,19 +149,11 @@ abstract class StyledComponent : Component { /** * Opacity of the current component. */ - var opacity: Double? = null - set(value) { - field = value - refresh() - } + var opacity: Double? by refreshOnUpdate() /** * Background of the current component. */ - var background: Background? = null - set(value) { - field = value - refresh() - } + var background: Background? by refreshOnUpdate() private var snStyleCache: List<StringPair>? = null @@ -351,4 +258,36 @@ abstract class StyledComponent : Component { } return snstyle } + + internal fun <T> refreshOnUpdate(refreshFunction: ((T) -> Unit) = { this.refresh() }) = + RefreshDelegateProvider<T>(null, refreshFunction) + + internal fun <T> refreshOnUpdate(initialValue: T, refreshFunction: ((T) -> Unit) = { this.refresh() }) = + RefreshDelegateProvider(initialValue, refreshFunction) + + internal inner class RefreshDelegateProvider<T>( + private val initialValue: T?, private val refreshFunction: (T) -> Unit + ) { + operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): RefreshDelegate<T> { + if (initialValue != null) propertyValues[prop.name] = initialValue + return RefreshDelegate(refreshFunction) + } + } + + internal inner class RefreshDelegate<T>(private val refreshFunction: ((T) -> Unit)) { + @Suppress("UNCHECKED_CAST") + operator fun getValue(thisRef: StyledComponent, property: KProperty<*>): T { + val value = propertyValues[property.name] + return if (value != null) { + value as T + } else { + null as T + } + } + + operator fun setValue(thisRef: StyledComponent, property: KProperty<*>, value: T) { + propertyValues[property.name] = value + refreshFunction(value) + } + } } diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index f50b1679..a746ffa4 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -65,32 +65,18 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() { /** * A title attribute of generated HTML element. */ - var title: String? = null - set(value) { - field = value - refresh() - } + var title: String? by refreshOnUpdate() /** * An ID attribute of generated HTML element. */ - var id: String? = null - set(value) { - field = value - refresh() - } + var id: String? by refreshOnUpdate() /** * A role attribute of generated HTML element. */ - var role: String? = null - set(value) { - field = value - refresh() - } - internal var surroundingSpan: Boolean = false - set(value) { - field = value - refresh() - } + var role: String? by refreshOnUpdate() + + internal var surroundingSpan by refreshOnUpdate(false) + internal var eventTarget: Widget? = null private var vnode: VNode? = null diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt index 0f653d30..1370f25a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt +++ b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt @@ -70,11 +70,7 @@ open class DropDown( set(value) { button.text = value } - private var elements = elements - set(value) { - field = value - setChildrenFromElements() - } + private var elements by refreshOnUpdate(elements, { setChildrenFromElements() }) /** * The icon of the dropdown button. */ @@ -126,11 +122,7 @@ open class DropDown( /** * Determines if the dropdown is showing upwards. */ - var dropup = false - set(value) { - field = value - refresh() - } + var dropup by refreshOnUpdate(false) /** * Width of the dropdown button. */ diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt index 7a8b5905..e76a1c7a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckBox.kt @@ -107,27 +107,15 @@ open class CheckBox( /** * The style (one of Bootstrap standard colors) of the input. */ - var style: CHECKBOXSTYLE? = null - set(value) { - field = value - refresh() - } + var style: CHECKBOXSTYLE? by refreshOnUpdate() /** * Determines if the checkbox is rendered as a circle. */ - var circled: Boolean = false - set(value) { - field = value - refresh() - } + var circled by refreshOnUpdate(false) /** * Determines if the checkbox is rendered inline. */ - var inline: Boolean = false - set(value) { - field = value - refresh() - } + var inline by refreshOnUpdate(false) /** * The size of the input. */ diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt index 46e5395c..7c67c957 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/CheckInput.kt @@ -66,63 +66,34 @@ open class CheckInput( /** * The selection state of the input. */ - var value: Boolean = value - set(value) { - field = value - refreshState() - } + var value by refreshOnUpdate(value, { refreshState() }) /** * The value attribute of the generated HTML input element. * * This value is placed directly in generated HTML code, while the [value] property is dynamically * bound to the input selection state. */ - var startValue: Boolean = value - set(value) { - field = value - this.value = value - refresh() - } + var startValue by refreshOnUpdate(value, { this.value = it; refresh() }) /** * The type of the generated HTML input element. */ - var type: CHECKINPUTTYPE = type - set(value) { - field = value - refresh() - } + var type by refreshOnUpdate(type) /** * The name attribute of the generated HTML input element. */ - var name: String? = null - set(value) { - field = value - refresh() - } + var name: String? by refreshOnUpdate() /** * Determines if the field is disabled. */ - var disabled: Boolean = false - set(value) { - field = value - refresh() - } + var disabled by refreshOnUpdate(false) /** * The additional String value used for the radio button group. */ - var extraValue: String? = null - set(value) { - field = value - refresh() - } + var extraValue: String? by refreshOnUpdate() /** * The size of the input. */ - var size: INPUTSIZE? = null - set(value) { - field = value - refresh() - } + var size: INPUTSIZE? by refreshOnUpdate() override fun render(): VNode { return render("input") diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt index ef5d6eb9..0cf85fc5 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/Radio.kt @@ -117,27 +117,15 @@ open class Radio( /** * The style (one of Bootstrap standard colors) of the input. */ - var style: RADIOSTYLE? = null - set(value) { - field = value - refresh() - } + var style: RADIOSTYLE? by refreshOnUpdate() /** * Determines if the radio button is rendered as a square. */ - var squared: Boolean = false - set(value) { - field = value - refresh() - } + var squared by refreshOnUpdate(false) /** * Determines if the radio button is rendered inline. */ - var inline: Boolean = false - set(value) { - field = value - refresh() - } + var inline by refreshOnUpdate(false) /** * The size of the input. */ diff --git a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt index aa29de34..e5b04a47 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/check/RadioGroup.kt @@ -54,29 +54,17 @@ open class RadioGroup( /** * A list of options (label to value pairs) for the group. */ - var options = options - set(value) { - field = value - setChildrenFromOptions() - } + var options by refreshOnUpdate(options, { setChildrenFromOptions() }) /** * A value of the selected option. */ - override var value = value - set(value) { - field = value - setValueToChildren(value) - } + override var value by refreshOnUpdate(value, { setValueToChildren(it) }) /** * Determines if the options are rendered inline. */ - var inline: Boolean = inline - set(value) { - field = value - refresh() - } + var inline by refreshOnUpdate(inline) override var disabled get() = getDisabledFromChildren() diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt index f90401ce..b0b7f4b3 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SelectInput.kt @@ -65,124 +65,68 @@ open class SelectInput( /** * A list of options (label to value pairs) for the select control. */ - internal var options = options - set(value) { - field = value - setChildrenFromOptions() - } + internal var options by refreshOnUpdate(options, { setChildrenFromOptions() }) /** * A value of the selected option. */ - var value: String? = value - set(value) { - field = value - refreshState() - } + var value by refreshOnUpdate(value, { refreshState() }) /** * The name attribute of the generated HTML select element. */ - var name: String? = null - set(value) { - field = value - refresh() - } + var name: String? by refreshOnUpdate() /** * Determines if multiple value selection is allowed. */ - var multiple: Boolean = multiple - set(value) { - field = value - refresh() - } + var multiple by refreshOnUpdate(multiple) /** * Additional options for remote (AJAX) data source. */ - var ajaxOptions: AjaxOptions? = ajaxOptions - set(value) { - field = value - if (value != null) liveSearch = true - refresh() + var ajaxOptions by refreshOnUpdate(ajaxOptions, { + if (it != null) { + liveSearch = true } + refresh() + }) /** * Maximal number of selected options. */ - var maxOptions: Int? = null - set(value) { - field = value - refresh() - } + var maxOptions: Int? by refreshOnUpdate() /** * Determines if live search is available. */ - var liveSearch: Boolean = false - set(value) { - field = value - refresh() - } + var liveSearch by refreshOnUpdate(false) /** * The placeholder for the select control. */ - var placeholder: String? = null - set(value) { - field = value - refresh() - } + var placeholder: String? by refreshOnUpdate() /** * The style of the select control. */ - var style: BUTTONSTYLE? = null - set(value) { - field = value - refresh() - } + var style: BUTTONSTYLE? by refreshOnUpdate() /** * The width of the select control. */ - var selectWidth: CssSize? = null - set(value) { - field = value - refresh() - } + var selectWidth: CssSize? by refreshOnUpdate() /** * The width type of the select control. */ - var selectWidthType: SELECTWIDTHTYPE? = null - set(value) { - field = value - refresh() - } + var selectWidthType: SELECTWIDTHTYPE? by refreshOnUpdate() /** * Determines if an empty option is automatically generated. */ - var emptyOption: Boolean = false - set(value) { - field = value - setChildrenFromOptions() - } + var emptyOption by refreshOnUpdate(false, { setChildrenFromOptions() }) /** * Determines if the field is disabled. */ - var disabled: Boolean = false - set(value) { - field = value - refresh() - } + var disabled by refreshOnUpdate(false) /** * Determines if the select is automatically focused. */ - var autofocus: Boolean? = null - set(value) { - field = value - refresh() - } + var autofocus: Boolean? by refreshOnUpdate() /** * The size of the input. */ - var size: INPUTSIZE? = null - set(value) { - field = value - refresh() - } + var size: INPUTSIZE? by refreshOnUpdate() init { setChildrenFromOptions() diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt index 6819961f..95d8f178 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOptGroup.kt @@ -45,35 +45,19 @@ open class SelectOptGroup( /** * A label for the group. */ - var label: String = label - set(value) { - field = value - refresh() - } + var label by refreshOnUpdate(label) /** * A list of options (label to value pairs) for the group. */ - var options = options - set(value) { - field = value - setChildrenFromOptions() - } + var options by refreshOnUpdate(options, { setChildrenFromOptions() }) /** * Maximal number of selected options in the group. */ - var maxOptions: Int? = maxOptions - set(value) { - field = value - refresh() - } + var maxOptions by refreshOnUpdate(maxOptions) /** * Determines if the group is disabled. */ - var disabled: Boolean = disabled - set(value) { - field = value - refresh() - } + var disabled by refreshOnUpdate(disabled) init { setChildrenFromOptions() diff --git a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt b/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt index e7a49120..141eff28 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/select/SelectOption.kt @@ -46,51 +46,27 @@ open class SelectOption( /** * The value of the option. */ - var value: String? = value - set(value) { - field = value - refresh() - } + var value by refreshOnUpdate(value) /** * The label of the option. */ - var label: String? = label - set(value) { - field = value - refresh() - } + var label by refreshOnUpdate(label) /** * The subtext after the label of the option. */ - var subtext: String? = subtext - set(value) { - field = value - refresh() - } + var subtext by refreshOnUpdate(subtext) /** * The icon before the label of the option. */ - var icon: String? = icon - set(value) { - field = value - refresh() - } + var icon by refreshOnUpdate(icon) /** * Determines if the option should be rendered as divider. */ - var divider: Boolean = divider - set(value) { - field = value - refresh() - } + var divider by refreshOnUpdate(divider) /** * Determines if the option should be disabled. */ - var disabled: Boolean = disabled - set(value) { - field = value - refresh() - } + var disabled by refreshOnUpdate(disabled) override fun render(): VNode { return if (!divider) { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt index a3f72b75..a5565d2a 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/spinner/SpinnerInput.kt @@ -97,119 +97,62 @@ open class SpinnerInput( /** * Spinner value. */ - var value: Number? = value - set(value) { - field = value - refreshState() - } + var value by refreshOnUpdate(value, { refreshState() }) /** * The value attribute of the generated HTML input element. * * This value is placed directly in generated HTML code, while the [value] property is dynamically * bound to the spinner input value. */ - var startValue: Number? = value - set(value) { - field = value - this.value = value - refresh() - } + var startValue by refreshOnUpdate(value, { this.value = it; refresh() }) /** * Minimal value. */ - var min: Int = min - set(value) { - field = value - refreshSpinner() - } + var min by refreshOnUpdate(min, { refreshSpinner() }) /** * Maximal value. */ - var max: Int = max - set(value) { - field = value - refreshSpinner() - } + var max by refreshOnUpdate(max, { refreshSpinner() }) /** * Step value. */ - var step: Double = step - set(value) { - field = value - refreshSpinner() - } + var step by refreshOnUpdate(step, { refreshSpinner() }) /** * Number of decimal digits value. */ - var decimals: Int = decimals - set(value) { - field = value - refreshSpinner() - } + var decimals by refreshOnUpdate(decimals, { refreshSpinner() }) /** * Spinner buttons type. */ - var buttonsType: BUTTONSTYPE = buttonsType - set(value) { - field = value - refreshSpinner() - } + var buttonsType by refreshOnUpdate(buttonsType, { refreshSpinner() }) /** * Spinner force rounding type. */ - var forceType: FORCETYPE = forceType - set(value) { - field = value - refreshSpinner() - } + var forceType by refreshOnUpdate(forceType, { refreshSpinner() }) /** * The placeholder for the spinner input. */ - var placeholder: String? = null - set(value) { - field = value - refresh() - } + var placeholder: String? by refreshOnUpdate() /** * The name attribute of the generated HTML input element. */ - var name: String? = null - set(value) { - field = value - refresh() - } + var name: String? by refreshOnUpdate() /** * Determines if the field is disabled. */ - var disabled: Boolean = false - set(value) { - field = value - refresh() - } + var disabled by refreshOnUpdate(false) /** * Determines if the spinner is automatically focused. */ - var autofocus: Boolean? = null - set(value) { - field = value - refresh() - } + var autofocus: Boolean? by refreshOnUpdate() /** * Determines if the spinner is read-only. */ - var readonly: Boolean? = null - set(value) { - field = value - refresh() - } + var readonly: Boolean? by refreshOnUpdate() /** * The size of the input. */ - var size: INPUTSIZE? = null - set(value) { - field = value - refresh() - } + var size: INPUTSIZE? by refreshOnUpdate() private var siblings: JQuery? = null diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt index 17a6689b..8467dab8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/AbstractTextInput.kt @@ -50,79 +50,42 @@ abstract class AbstractTextInput( /** * Text input value. */ - var value: String? = value - set(value) { - field = value - refreshState() - } + var value by refreshOnUpdate(value, { refreshState() }) /** * The value attribute of the generated HTML input element. * * This value is placed directly in generated HTML code, while the [value] property is dynamically * bound to the text input value. */ - var startValue: String? = value - set(value) { - field = value - this.value = value - refresh() - } + var startValue by refreshOnUpdate(value, { this.value = it; refresh() }) /** * The placeholder for the text input. */ - var placeholder: String? = null - set(value) { - field = value - refresh() - } + var placeholder: String? by refreshOnUpdate() /** * The name attribute of the generated HTML input element. */ - var name: String? = null - set(value) { - field = value - refresh() - } + var name: String? by refreshOnUpdate() /** * Maximal length of the text input value. */ - var maxlength: Int? = null - set(value) { - field = value - refresh() - } + var maxlength: Int? by refreshOnUpdate() /** * Determines if the field is disabled. */ - var disabled: Boolean = false - set(value) { - field = value - refresh() - } + var disabled by refreshOnUpdate(false) /** * Determines if the text input is automatically focused. */ - var autofocus: Boolean? = null - set(value) { - field = value - refresh() - } + var autofocus: Boolean? by refreshOnUpdate() /** * Determines if the text input is read-only. */ - var readonly: Boolean? = null - set(value) { - field = value - refresh() - } + var readonly: Boolean? by refreshOnUpdate() /** * The size of the input. */ - var size: INPUTSIZE? = null - set(value) { - field = value - refresh() - } + var size: INPUTSIZE? by refreshOnUpdate() override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt index 8ee150e1..9fc89544 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/TextAreaInput.kt @@ -40,27 +40,15 @@ open class TextAreaInput(cols: Int? = null, rows: Int? = null, value: String? = /** * Number of columns. */ - var cols: Int? = cols - set(value) { - field = value - refresh() - } + var cols by refreshOnUpdate(cols) /** * Number of rows. */ - var rows: Int? = rows - set(value) { - field = value - refresh() - } + var rows by refreshOnUpdate(rows) /** * Determines if hard wrapping is enabled for the textarea element. */ - var wrapHard: Boolean = false - set(value) { - field = value - refresh() - } + var wrapHard by refreshOnUpdate(false) override fun render(): VNode { return startValue?.let { diff --git a/src/main/kotlin/pl/treksoft/kvision/form/text/TextInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/text/TextInput.kt index a2bfcd0b..998bfb2c 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/text/TextInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/text/TextInput.kt @@ -52,19 +52,11 @@ open class TextInput(type: TEXTINPUTTYPE = TEXTINPUTTYPE.TEXT, value: String? = /** * Text input type. */ - var type: TEXTINPUTTYPE = type - set(value) { - field = value - refresh() - } + var type by refreshOnUpdate(type) /** * Determines if autocomplete is enabled for the input element. */ - var autocomplete: Boolean? = null - set(value) { - field = value - refresh() - } + var autocomplete: Boolean? by refreshOnUpdate() override fun render(): VNode { return render("input") diff --git a/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt b/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt index c198ec77..3eeec789 100644 --- a/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt +++ b/src/main/kotlin/pl/treksoft/kvision/form/time/DateTimeInput.kt @@ -60,123 +60,63 @@ open class DateTimeInput( /** * Date/time input value. */ - var value: Date? = value - set(value) { - field = value - refreshState() - } + var value by refreshOnUpdate(value, { refreshState() }) /** * Date/time format. */ - var format: String = format - set(value) { - field = value - refreshDatePicker() - } + var format by refreshOnUpdate(format, { refreshDatePicker() }) /** * The placeholder for the date/time input. */ - var placeholder: String? = null - set(value) { - field = value - refresh() - } + var placeholder: String? by refreshOnUpdate() /** * The name attribute of the generated HTML input element. */ - var name: String? = null - set(value) { - field = value - refresh() - } + var name: String? by refreshOnUpdate() /** * Determines if the field is disabled. */ - var disabled: Boolean = false - set(value) { - field = value - refresh() - } + var disabled by refreshOnUpdate(false) /** * Determines if the text input is automatically focused. */ - var autofocus: Boolean? = null - set(value) { - field = value - refresh() - } + var autofocus: Boolean? by refreshOnUpdate() /** * Determines if the date/time input is read-only. */ - var readonly: Boolean? = null - set(value) { - field = value - refresh() - } + var readonly: Boolean? by refreshOnUpdate() /** * The size of the input. */ - var size: INPUTSIZE? = null - set(value) { - field = value - refresh() - } + var size: INPUTSIZE? by refreshOnUpdate() /** * Day of the week start. 0 (Sunday) to 6 (Saturday). */ - var weekStart: Int = 0 - set(value) { - field = value - refreshDatePicker() - } + var weekStart by refreshOnUpdate(0, { refreshDatePicker() }) /** * Days of the week that should be disabled. Multiple values should be comma separated. */ - var daysOfWeekDisabled: Array<Int> = arrayOf() - set(value) { - field = value - refreshDatePicker() - } + var daysOfWeekDisabled by refreshOnUpdate(arrayOf<Int>(), { refreshDatePicker() }) /** * Determines if *Clear* button should be visible. */ - var clearBtn: Boolean = true - set(value) { - field = value - refreshDatePicker() - } + var clearBtn by refreshOnUpdate(true, { refreshDatePicker() }) /** * Determines if *Today* button should be visible. */ - var todayBtn: Boolean = false - set(value) { - field = value - refreshDatePicker() - } + var todayBtn by refreshOnUpdate(false, { refreshDatePicker() }) /** * Determines if the current day should be highlighted. */ - var todayHighlight: Boolean = false - set(value) { - field = value - refreshDatePicker() - } + var todayHighlight by refreshOnUpdate(false, { refreshDatePicker() }) /** * The increment used to build the hour view. */ - var minuteStep: Int = DEFAULT_MINUTE_STEP - set(value) { - field = value - refreshDatePicker() - } + var minuteStep by refreshOnUpdate(DEFAULT_MINUTE_STEP, { refreshDatePicker() }) /** * Determines if meridian views are visible in day and hour views. */ - var showMeridian: Boolean = false - set(value) { - field = value - refreshDatePicker() - } + var showMeridian by refreshOnUpdate(false, { refreshDatePicker() }) override fun render(): VNode { return render("input") diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt index 79155395..e6f53737 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Button.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Button.kt @@ -69,59 +69,31 @@ open class Button( /** * Button label. */ - var text = text - set(value) { - field = value - refresh() - } + var text by refreshOnUpdate(text) /** * Button icon. */ - var icon = icon - set(value) { - field = value - refresh() - } + var icon by refreshOnUpdate(icon) /** * Button style. */ - var style = style - set(value) { - field = value - refresh() - } + var style by refreshOnUpdate(style) /** * Determines if button is disabled. */ - var disabled = disabled - set(value) { - field = value - refresh() - } + var disabled by refreshOnUpdate(disabled) /** * Button image. */ - var image: ResString? = null - set(value) { - field = value - refresh() - } + var image: ResString? by refreshOnUpdate() /** * Button size. */ - var size: BUTTONSIZE? = null - set(value) { - field = value - refresh() - } + var size: BUTTONSIZE? by refreshOnUpdate() /** * Determines if the button takes all the space horizontally. */ - var block = false - set(value) { - field = value - refresh() - } + var block by refreshOnUpdate(false) override fun render(): VNode { val t = createLabelWithIcon(text, icon, image) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt index bd469afe..ac7829e8 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Image.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Image.kt @@ -55,43 +55,23 @@ open class Image( /** * URL of the image. */ - var src = src - set(value) { - field = value - refresh() - } + var src by refreshOnUpdate(src) /** * The alternative text of the image. */ - var alt = alt - set(value) { - field = value - refresh() - } + var alt by refreshOnUpdate(alt) /** * Determines if the image is rendered as responsive. */ - var responsive = responsive - set(value) { - field = value - refresh() - } + var responsive by refreshOnUpdate(responsive) /** * The shape of the image. */ - var shape = shape - set(value) { - field = value - refresh() - } + var shape by refreshOnUpdate(shape) /** * Determines if the image is rendered as centered. */ - var centered = centered - set(value) { - field = value - refresh() - } + var centered by refreshOnUpdate(centered) override fun render(): VNode { return render("img") diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt index e075d685..94c7c594 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Link.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Link.kt @@ -44,35 +44,19 @@ open class Link( /** * Link label. */ - var label = label - set(value) { - field = value - refresh() - } + var label by refreshOnUpdate(label) /** * Link URL address. */ - var url = url - set(value) { - field = value - refresh() - } + var url by refreshOnUpdate(url) /** * Link icon. */ - var icon = icon - set(value) { - field = value - refresh() - } + var icon by refreshOnUpdate(icon) /** * Link image. */ - var image = image - set(value) { - field = value - refresh() - } + var image by refreshOnUpdate(image) override fun render(): VNode { val t = createLabelWithIcon(label, icon, image) diff --git a/src/main/kotlin/pl/treksoft/kvision/html/List.kt b/src/main/kotlin/pl/treksoft/kvision/html/List.kt index 2dadd546..185d2eea 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/List.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/List.kt @@ -61,27 +61,15 @@ open class ListTag( /** * List type. */ - var type = type - set(value) { - field = value - refresh() - } + var type by refreshOnUpdate(type) /** * List of elements. */ - var elements = elements - set(value) { - field = value - refresh() - } + var elements by refreshOnUpdate(elements) /** * Determines if [elements] can contain HTML code. */ - var rich = rich - set(value) { - field = value - refresh() - } + var rich by refreshOnUpdate(rich) init { @Suppress("LeakingThis") diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt index 62a647bc..a3b7f231 100644 --- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt +++ b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt @@ -98,35 +98,19 @@ open class Tag( /** * Tag type. */ - var type = type - set(value) { - field = value - refresh() - } + var type by refreshOnUpdate(type) /** * Text content of the tag. */ - var text = text - set(value) { - field = value - refresh() - } + var text by refreshOnUpdate(text) /** * Determines if [text] can contain HTML code. */ - var rich = rich - set(value) { - field = value - refresh() - } + var rich by refreshOnUpdate(rich) /** * Text align. */ - var align = align - set(value) { - field = value - refresh() - } + var align by refreshOnUpdate(align) init { @Suppress("LeakingThis") diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt index 33512a7e..a3bb8d77 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt +++ b/src/main/kotlin/pl/treksoft/kvision/modal/Confirm.kt @@ -75,11 +75,7 @@ open class Confirm( /** * Determines if Cancel button is visible. */ - var cancelVisible = cancelVisible - set(value) { - field = value - refreshCancelButton() - } + var cancelVisible by refreshOnUpdate(cancelVisible, { refreshCancelButton() }) private val content = Tag(TAG.DIV, text, rich, align) private val cancelButton = Button("Cancel", "remove") diff --git a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt index f913fac1..d9cd0e8e 100644 --- a/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt +++ b/src/main/kotlin/pl/treksoft/kvision/modal/Modal.kt @@ -89,11 +89,7 @@ open class Modal( /** * Determines if animations are used. */ - var animation = animation - set(value) { - field = value - refresh() - } + var animation by refreshOnUpdate(animation) private val dialog = ModalDialog(size) private val header = SimplePanel(setOf("modal-header")) @@ -260,11 +256,7 @@ internal class ModalDialog(size: MODALSIZE?) : SimplePanel(setOf("modal-dialog") /** * Modal window size. */ - var size = size - set(value) { - field = value - refresh() - } + var size by refreshOnUpdate(size) override fun getSnClass(): List<StringBoolPair> { val cl = super.getSnClass().toMutableList() diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt index e4e5dd47..3bb42d53 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt @@ -104,53 +104,27 @@ open class FlexPanel( /** * CSS flexbox direction. */ - var direction = direction - set(value) { - field = value - refreshSpacing() - refresh() - } + var direction by refreshOnUpdate(direction, { refreshSpacing(); refresh() }) /** * CSS flexbox wrap mode. */ - var wrap = wrap - set(value) { - field = value - refresh() - } + var wrap by refreshOnUpdate(wrap) /** * CSS flexbox content justification. */ - var justify = justify - set(value) { - field = value - refresh() - } + var justify by refreshOnUpdate(justify) /** * CSS flexbox items alignment. */ - var alignItems = alignItems - set(value) { - field = value - refresh() - } + var alignItems by refreshOnUpdate(alignItems) /** * CSS flexbox content alignment. */ - var alignContent = alignContent - set(value) { - field = value - refresh() - } + var alignContent by refreshOnUpdate(alignContent) /** * The spacing between columns/rows. */ - var spacing = spacing - set(value) { - field = value - refreshSpacing() - refresh() - } + var spacing by refreshOnUpdate(spacing, { refreshSpacing(); refresh() }) init { @Suppress("LeakingThis") diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt index 178c1e7f..10e956be 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/GridPanel.kt @@ -112,99 +112,51 @@ open class GridPanel( /** * CSS grid auto columns. */ - var autoColumns = autoColumns - set(value) { - field = value - refresh() - } + var autoColumns by refreshOnUpdate(autoColumns) /** * CSS grid auto rows. */ - var autoRows = autoRows - set(value) { - field = value - refresh() - } + var autoRows by refreshOnUpdate(autoRows) /** * CSS grid auto flow. */ - var autoFlow = autoFlow - set(value) { - field = value - refresh() - } + var autoFlow by refreshOnUpdate(autoFlow) /** * CSS grid columns template. */ - var templateColumns = templateColumns - set(value) { - field = value - refresh() - } + var templateColumns by refreshOnUpdate(templateColumns) /** * CSS grid rows template. */ - var templateRows = templateRows - set(value) { - field = value - refresh() - } + var templateRows by refreshOnUpdate(templateRows) /** * CSS grid areas template. */ - var templateAreas = templateAreas - set(value) { - field = value - refresh() - } + var templateAreas by refreshOnUpdate(templateAreas) /** * CSS grid column gap. */ - var columnGap = columnGap - set(value) { - field = value - refresh() - } + var columnGap by refreshOnUpdate(columnGap) /** * CSS grid row gap. */ - var rowGap = rowGap - set(value) { - field = value - refresh() - } + var rowGap by refreshOnUpdate(rowGap) /** * CSS grid items justification. */ - var justifyItems = justifyItems - set(value) { - field = value - refresh() - } + var justifyItems by refreshOnUpdate(justifyItems) /** * CSS grid items alignment. */ - var alignItems = alignItems - set(value) { - field = value - refresh() - } + var alignItems by refreshOnUpdate(alignItems) /** * CSS grid content justification. */ - var justifyContent = justifyContent - set(value) { - field = value - refresh() - } + var justifyContent by refreshOnUpdate(justifyContent) /** * CSS grid content alignment. */ - var alignContent = alignContent - set(value) { - field = value - refresh() - } + var alignContent by refreshOnUpdate(alignContent) init { @Suppress("LeakingThis") diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt index 4a82ed5b..a5b3d577 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/ResponsiveGridPanel.kt @@ -62,11 +62,7 @@ open class ResponsiveGridPanel( /** * Text align of grid cells. */ - var align = align - set(value) { - field = value - refreshRowContainers() - } + var align by refreshOnUpdate(align, { refreshRowContainers() }) internal val map = mutableMapOf<Int, MutableMap<Int, WidgetParam>>() private var auto: Boolean = true diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt index bac027fe..da41db9f 100644 --- a/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt +++ b/src/main/kotlin/pl/treksoft/kvision/panel/StackPanel.kt @@ -44,11 +44,7 @@ open class StackPanel( /** * The index of active (visible) child. */ - var activeIndex = -1 - set(value) { - field = value - refresh() - } + var activeIndex by refreshOnUpdate(-1) init { @Suppress("LeakingThis") diff --git a/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt index e44d4b44..45ea9eb0 100644 --- a/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt +++ b/src/test/kotlin/test/pl/treksoft/kvision/html/ImageSpec.kt @@ -37,6 +37,7 @@ class ImageSpec : DomSpec { run { val root = Root("test") val res = require("./img/placeholder.png") + @Suppress("UnsafeCastFromDynamic") val image = Image(res, "Image", true, IMAGESHAPE.ROUNDED, true) root.add(image) val element = document.getElementById("test") |