This repository has been archived by the owner on Apr 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.kt
150 lines (125 loc) · 4.72 KB
/
Main.kt
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
import bindings.gtk.*
import bindings.gtk.usertypes.WidgetClass
import bindings.gtk.usertypes.WidgetCompanion
import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDate
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import native.gobject.G_BINDING_SYNC_CREATE
import native.gobject.G_PARAM_READWRITE
import native.gtk.GTK_DIALOG_MODAL
import native.gtk.GtkButtonsType
import native.gtk.GtkMessageType
import native.gtk.GtkOrientation.GTK_ORIENTATION_VERTICAL
import usertypes.intProperty
fun main() {
val app = Application("io.quantus.gtkkn.sevenguis.flight-booker")
app.onActivate {
val window = ApplicationWindow(app).apply {
title = "7GUIs Flight Booker"
}
window.child = FlightBookerWidget()
window.show()
}
app.run()
app.unref()
}
enum class BookingOption(val label: String) {
OneWay("one-way flight"),
Return("return-flight")
}
class FlightBookerWidget : Box(newInstancePointer()) {
// FIXME This is a first implementation with the limited property binding we already have
private var selectedOptionIndex: Int = BookingOption.OneWay.ordinal
set(value) {
field = value
configureBookingOption(BookingOption.values()[value])
}
private lateinit var selectedOption: BookingOption
private val dropDown = DropDown(BookingOption.values().map { it.label })
private val startEntry = Entry()
private val returnEntry = Entry()
private val bookButton = Button("Book").apply { actionName = "book" }
init {
// setup box
orientation = GTK_ORIENTATION_VERTICAL
spacing = 10
marginStart = 10
marginEnd = 10
marginTop = 10
marginBottom = 10
// add controls
appendAll(
dropDown,
startEntry,
returnEntry,
bookButton
)
dropDown.bindProperty("selected", this, "selected-item", G_BINDING_SYNC_CREATE)
val startDate = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date.toString()
startEntry.text = startDate
returnEntry.text = startDate
startEntry.onChanged(::evaluate)
returnEntry.onChanged(::evaluate)
}
private fun configureBookingOption(option: BookingOption) {
selectedOption = option
returnEntry.sensitive = when (option) {
BookingOption.OneWay -> false
BookingOption.Return -> true
}
}
private val dateRegex = Regex("^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\$")
private fun evaluate() {
val startDate = parseDate(startEntry.text)
val endDate = parseDate(returnEntry.text)
if (startDate == null) startEntry.addCssClass("error")
else startEntry.removeCssClass("error")
if (endDate == null) returnEntry.addCssClass("error")
else returnEntry.removeCssClass("error")
bookButton.sensitive = when (selectedOption) {
BookingOption.OneWay -> startDate != null
BookingOption.Return -> startDate != null
&& endDate != null
&& startDate.toEpochDays() <= endDate.toEpochDays()
}
}
private fun parseDate(string: String): LocalDate? {
return dateRegex.find(string)?.let { matchResult ->
println("Match result: ${matchResult.groupValues}")
LocalDate(
matchResult.groupValues[1].toInt(),
matchResult.groupValues[2].toInt(),
matchResult.groupValues[3].toInt()
)
}
}
private fun book() {
val bookingText = when (selectedOption) {
BookingOption.OneWay -> "You have booked a one-way flight on ${startEntry.text}"
BookingOption.Return -> "You have booked a one-way flight on ${startEntry.text} with return on ${returnEntry.text}"
}
MessageDialog(
null,
GTK_DIALOG_MODAL,
GtkMessageType.GTK_MESSAGE_INFO,
GtkButtonsType.GTK_BUTTONS_OK,
bookingText
).apply {
title = "Confirmation"
onResponse { close() }
}.show()
}
companion object : WidgetCompanion<FlightBookerWidget>() {
override val typeName = "FlightBookerWidget"
override val parentType = Box.Type
val SelectedItemProperty = intProperty(
FlightBookerWidget::selectedOptionIndex,
"selected-item", null, null, 0, BookingOption.values().size - 1, 0, G_PARAM_READWRITE
)
override fun classInit(klass: WidgetClass<FlightBookerWidget>) {
klass.installProperty(SelectedItemProperty)
klass.installAction("book", FlightBookerWidget::book)
}
}
}