Inceptum/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt

118 lines
3.8 KiB
Kotlin

package io.gitlab.jfronny.inceptum.gtk
import io.gitlab.jfronny.commons.StringFormatter
import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.util.Log
import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog
import io.gitlab.jfronny.inceptum.gtk.window.dialog.StringInputDialog
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv.EnvBackend
import io.gitlab.jfronny.inceptum.launcher.api.account.MicrosoftAccount
import org.gnome.gio.Cancellable
import org.gnome.gtk.*
import java.util.function.Consumer
object GtkEnvBackend : EnvBackend {
var dialogParent: Window? = null
override fun showError(message: String, title: String) {
Log.error(message)
simpleDialog(message, title, null, null)
}
override fun showError(message: String, t: Throwable) {
simpleDialog(StringFormatter.toString(t), message, null, null)
}
override fun showInfo(message: String, title: String) {
Log.info(message)
simpleDialog(message, title, null, null)
}
override fun showOkCancel(message: String, title: String, ok: Runnable, cancel: Runnable, defaultCancel: Boolean) {
Log.info(message)
simpleDialog(message, title, ok, cancel)
}
override fun getInput(
prompt: String,
details: String,
defaultValue: String,
ok: Consumer<String>,
cancel: Runnable
) = schedule {
var flags = DialogFlags.DESTROY_WITH_PARENT
if (dialogParent != null) flags = flags.or(DialogFlags.MODAL)
val dialog = StringInputDialog(
dialogParent,
flags,
MessageType.QUESTION,
ButtonsType.OK_CANCEL,
details,
defaultValue
)
dialog.title = prompt
dialog.onResponse(processResponses(dialog, { ok.accept(dialog.input) }, cancel))
dialog.visible = true
}
override fun showLoginRefreshPrompt(account: MicrosoftAccount) =
schedule { MicrosoftLoginDialog(dialogParent, account).visible = true }
private fun simpleDialog(
markup: String,
title: String,
ok: Runnable?,
cancel: Runnable?
) = schedule { simpleDialog(dialogParent, markup, title, ok, cancel) }
fun simpleDialog(
parent: Window?,
markup: String,
title: String,
ok: Runnable?,
cancel: Runnable?
) {
val dialog = AlertDialog.builder()
.message(title)
.detail(markup)
.modal(true)
when {
cancel == null -> dialog.buttons(arrayOf(I18n["ok"]))
.defaultButton(0)
.cancelButton(-1)
ok == null -> dialog.buttons(arrayOf("Cancel"))
.defaultButton(-1)
.cancelButton(0)
else -> dialog.buttons(arrayOf("OK", "Cancel"))
.defaultButton(0)
.cancelButton(1)
}
dialog.build().apply {
choose(parent, Cancellable()) { _, res, _ ->
val result = chooseFinish(res)
val cancelIdx = cancelButton
val defaultIdx = defaultButton
if (result == cancelIdx) cancel?.run()
if (result == defaultIdx) ok?.run()
}
}
}
private fun processResponses(dialog: Dialog, ok: Runnable?, cancel: Runnable?): Dialog.Response = Dialog.Response { responseId: Int ->
when (ResponseType.of(responseId)) {
ResponseType.OK -> {
dialog.close()
ok?.run()
}
ResponseType.CLOSE, ResponseType.CANCEL -> {
dialog.close()
cancel?.run()
}
ResponseType.DELETE_EVENT -> dialog.destroy()
else -> Log.error("Unexpected response type: $responseId")
}
}
}