package io.gitlab.jfronny.inceptum.gtk import io.gitlab.jfronny.commons.StringFormatter import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.I18n 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 { @JvmField var dialogParent: Window? = null override fun showError(message: String, title: String) { Utils.LOGGER.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) { Utils.LOGGER.info(message) simpleDialog(message, title, null, null) } override fun showOkCancel(message: String, title: String, ok: Runnable, cancel: Runnable, defaultCancel: Boolean) { Utils.LOGGER.info(message) simpleDialog(message, title, ok, cancel) } override fun getInput( prompt: String, details: String, defaultValue: String, ok: Consumer, 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) } @JvmStatic fun simpleDialog( parent: Window?, markup: String, title: String, ok: Runnable?, cancel: Runnable? ) { val dialog = AlertDialog("") dialog.message = title dialog.detail = markup dialog.modal = true when { cancel == null -> { dialog.setButtons(arrayOf(I18n["ok"])) dialog.defaultButton = 0 dialog.cancelButton = -1 } ok == null -> { dialog.setButtons(arrayOf("Cancel")) dialog.defaultButton = -1 dialog.cancelButton = 0 } else -> { dialog.setButtons(arrayOf("OK", "Cancel")) dialog.defaultButton = 0 dialog.cancelButton = 1 } } dialog.choose(parent, Cancellable()) { _, res, _ -> val result = dialog.chooseFinish(res) val cancelIdx = dialog.cancelButton val defaultIdx = dialog.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 -> Utils.LOGGER.error("Unexpected response type: $responseId") } } }