Skip to content

Commit

Permalink
Enable data binding for textfield and label ui components
Browse files Browse the repository at this point in the history
Add possibility to do data binding to label and textfield and introduce a
simple example in the samples, to showcase a shared string value between an
input and a label.

Refer to issue: msink#8


Co-authored-by: Andreas Mausch <[email protected]>
  • Loading branch information
mervyn-mccreight and andreas-mausch committed Nov 4, 2018
1 parent d58a4e1 commit 10db0cb
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 6 deletions.
30 changes: 24 additions & 6 deletions libui-ktx/src/main/kotlin/widgets.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package libui.ktx

import kotlinx.cinterop.*
import libui.*
import libui.ktx.databinding.*
import libui.ktx.draw.Color
import libui.ktx.draw.Font
import platform.posix.*
Expand Down Expand Up @@ -38,8 +39,9 @@ import platform.posix.*
/** DSL builder for a simple single line text entry widget. */
inline fun Container.textfield(
readonly: Boolean = false,
modelEntry: ModelEntry<String>? = null,
init: TextField.() -> Unit = {}
): TextField = add(TextField()
): TextField = add(modelEntry?.let { TextField(it) } ?: TextField()
.apply { if (readonly) this.readonly = readonly }
.apply(init))

Expand All @@ -61,8 +63,20 @@ inline fun Container.searchfield(
.apply(init))

/** Wrapper class for [uiEntry] - a simple single line text entry widget */
open class TextField internal constructor(alloc: CPointer<uiEntry>?) : Control<uiEntry>(alloc) {
constructor(): this(uiNewEntry())
open class TextField internal constructor(alloc: CPointer<uiEntry>?, val modelEntry: ModelEntry<String>) : Control<uiEntry>(alloc) {
constructor(): this(ModelEntry(""))
constructor(alloc: CPointer<uiEntry>?): this(alloc, ModelEntry(""))
constructor(modelEntry: ModelEntry<String>): this(uiNewEntry(), modelEntry) {
this.value = modelEntry.get()
modelEntry.addListener({newValue -> this.value = newValue})
addOnChangeListener()
}

private fun addOnChangeListener() {
uiEntryOnChanged(ptr, staticCFunction { _, ref -> with(ref.to<TextField>()) {
modelEntry.update(this.value)
}}, ref.asCPointer())
}

/** The current text of the TextField. */
var value: String
Expand Down Expand Up @@ -386,12 +400,16 @@ class TimePicker : DateTimePicker(uiNewTimePicker()) {

/** DSL builder for a static text label. */
inline fun Container.label(
text: String,
text: String = "",
modelEntry: ModelEntry<String>? = null,
init: Label.() -> Unit = {}
): Label = add(Label(text).apply(init))
): Label = add(Label(modelEntry ?: ModelEntry<String>(text)).apply(init))

/** Wrapper class for [uiLabel] - a static text label. */
class Label(text: String) : Control<uiLabel>(uiNewLabel(text)) {
class Label(modelEntry: ModelEntry<String>) : Control<uiLabel>(uiNewLabel(modelEntry.get())) {
init {
modelEntry.addListener({newText -> this.text = newText})
}

/** The static text of the label. */
var text: String
Expand Down
25 changes: 25 additions & 0 deletions samples/data-binding-1/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apply plugin: 'konan'

def konanUserDir = System.getenv("KONAN_DATA_DIR") ?: "${System.getProperty("user.home")}/.konan"
def windresDir = "$konanUserDir/dependencies/msys2-mingw-w64-x86_64-gcc-7.3.0-clang-llvm-lld-6.0.1/bin"
def rcFile = file('src/main/resources/samples.rc')
def resFile = file("$buildDir/konan/resources/samples.res")
task windowsResources(type: Exec) {
inputs.file rcFile
outputs.file resFile
commandLine "$windresDir/windres", rcFile, '-O', 'coff', '-o', resFile
environment 'PATH', "$windresDir;${System.getenv('PATH')}"
}

konanArtifacts {
program('data-binding-1') {
libraries {
artifact project(':libui-ktx'), 'libui-ktx'
}
target('mingw') {
dependsOn 'windowsResources'
inputs.file resFile
linkerOpts "$resFile -mwindows"
}
}
}
20 changes: 20 additions & 0 deletions samples/data-binding-1/src/main/kotlin/data-binding-1.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import libui.ktx.*
import libui.ktx.databinding.*

fun main(args: Array<String>) {
class Model {
val myString = ModelEntry<String>("Hello kotlin-libui!")
}
val model = Model()

appWindow(
title = "Data-binding Example #1",
width = 320,
height = 100
) {
vbox {
label(modelEntry = model.myString)
textfield(modelEntry = model.myString)
}
}
}
43 changes: 43 additions & 0 deletions samples/data-binding-1/src/main/resources/samples.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="CompanyName.ProductName.YourApplication"
type="win32"
/>
<description>Your application description here.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker"/>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--The ID below indicates application support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates application support for Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!--The ID below indicates application support for Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!--The ID below indicates application support for Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>
6 changes: 6 additions & 0 deletions samples/data-binding-1/src/main/resources/samples.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// this is a UTF-8 file
#pragma code_page(65001)

// this is the Common Controls 6 manifest
// 1 is the value of CREATEPROCESS_MANIFEST_RESOURCE_ID and 24 is the value of RT_MANIFEST
1 24 "samples.manifest"
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ include ':libui'
include ':libui-ktx'

include ':samples:controlgallery'
include ':samples:data-binding-1'
include ':samples:datetime'
include ':samples:drawtext'
include ':samples:form'
Expand Down

0 comments on commit 10db0cb

Please sign in to comment.