Skip to content

Commit

Permalink
First version of a model for the combobox
Browse files Browse the repository at this point in the history
* Provide a list of values and a ModelEntry for the selected element
* When a different item is selected, the model is updated accordingly
* Values can be list of a user-defined type, the text displayed is the toString()
* Changes to the values are not reflected yet (WIP)

Refer to issue: msink#8

Co-authored-by: Mervyn McCreight <[email protected]>
  • Loading branch information
andreas-mausch and mervyn-mccreight committed Nov 16, 2018
1 parent 276b92c commit aa28b4b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 13 deletions.
39 changes: 29 additions & 10 deletions libui/src/nativeMain/kotlin/widgets.kt
Original file line number Diff line number Diff line change
Expand Up @@ -218,31 +218,50 @@ class Checkbox(label: String, private val modelEntry: ModelEntry<Boolean>) : Con
///////////////////////////////////////////////////////////////////////////////

/** DSL builder for a drop down combo box that allow list selection only. */
inline fun <T> Container.combobox(
values: List<T>,
selected: ModelEntry<T>? = null,
init: Combobox<T>.() -> Unit = {}
): Combobox<T> = add(Combobox(values, selected).apply(init))

inline fun Container.combobox(
init: Combobox.() -> Unit = {}
): Combobox = add(Combobox().apply(init))
init: Combobox<String>.() -> Unit = {}
) = combobox(emptyList(), null, init)

/** Wrapper class for [uiCombobox] - a drop down combo box that allow list selection only. */
class Combobox : Control<uiCombobox>(uiNewCombobox()) {

/** Adds the named entry to the end of the combobox.
* If it is the first entry, it is automatically selected. */
fun item(text: String) = uiComboboxAppend(ptr, text)
// TODO: ObservableList
class Combobox<T>(private val values: List<T>, private val selected: ModelEntry<T>?) : Control<uiCombobox>(uiNewCombobox()) {

/** Return or set the current selected option by index. */
var value: Int
get() = uiComboboxSelected(ptr)
set(value) = uiComboboxSetSelected(ptr, value)

init {
values.forEach { item(it.toString()) }
selected?.let {
value = values.indexOf(it.get())
it.addListener { newValue -> this.value = values.indexOf(newValue) }

uiComboboxOnSelected(ptr, staticCFunction { _, ref -> with(ref.to<Combobox<T>>()) {
selected?.update(values[this.value])
}}, ref.asCPointer())
}
}

/** Adds the named entry to the end of the combobox.
* If it is the first entry, it is automatically selected. */
fun item(text: String) = uiComboboxAppend(ptr, text)

/** Function to be run when the user makes a change to the Combobox.
* Only one function can be registered at a time. */
fun action(block: Combobox.() -> Unit) {
fun action(block: Combobox<T>.() -> Unit) {
action = block
uiComboboxOnSelected(ptr, staticCFunction { _, ref -> with(ref.to<Combobox>()) {
uiComboboxOnSelected(ptr, staticCFunction { _, ref -> with(ref.to<Combobox<T>>()) {
action?.invoke(this)
}}, ref.asCPointer())
}
internal var action: (Combobox.() -> Unit)? = null
internal var action: (Combobox<T>.() -> Unit)? = null
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
6 changes: 5 additions & 1 deletion samples/data-binding-2/src/nativeMain/kotlin/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ fun main(args: Array<String>) {
val searchFieldModel = ModelEntry("SearchField")
val textAreaModel = ModelEntry("TextArea")
val checkboxModel = ModelEntry(false)
val comboboxModel = ModelEntry("Item 1")
}

val model = Model()
Expand All @@ -18,14 +19,16 @@ fun main(args: Array<String>) {
"${model.passwordFieldModel.value}\n" +
"${model.searchFieldModel.value}\n" +
"${model.textAreaModel.value}\n" +
"${model.checkboxModel.value}"
"${model.checkboxModel.value}\n" +
"${model.comboboxModel.value}"
}

model.textFieldModel.addListener { updateValues() }
model.passwordFieldModel.addListener { updateValues() }
model.searchFieldModel.addListener { updateValues() }
model.textAreaModel.addListener { updateValues() }
model.checkboxModel.addListener { updateValues() }
model.comboboxModel.addListener { updateValues() }

appWindow(
title = "Data-binding Example #2",
Expand All @@ -51,6 +54,7 @@ fun main(args: Array<String>) {
checkbox("Toggle me", modelEntry = model.checkboxModel) {
this@form.label = "Checkbox"
}
combobox(listOf("Item 1", "Item 2", "Item 3"), model.comboboxModel)
}
separator()
group("Values") { stretchy = true }.form {
Expand Down
4 changes: 2 additions & 2 deletions samples/drawtext/src/nativeMain/kotlin/main.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import kotlinx.cinterop.convert
import libui.*
import libui.ktx.*
import libui.ktx.draw.*
import kotlinx.cinterop.convert

fun AttributedString.append(what: String, attr: Attribute, attr2: Attribute? = null) {
val start = length
Expand Down Expand Up @@ -62,7 +62,7 @@ fun main(args: Array<String>) = appWindow(
) {
hbox {
lateinit var font: FontButton
lateinit var align: Combobox
lateinit var align: Combobox<String>
lateinit var area: DrawArea

vbox {
Expand Down

0 comments on commit aa28b4b

Please sign in to comment.