Implement new instance window, bump java and GTK
This commit is contained in:
parent
e9f8af5617
commit
1be0d68a56
|
@ -17,10 +17,7 @@ val jbAnnotationsVersion by extra("24.0.1")
|
|||
val lwjglVersion by extra("3.3.2")
|
||||
val imguiVersion by extra("1.86.10")
|
||||
// launcher-gtk
|
||||
val javagiVersion by extra("0.4")
|
||||
val glibVersion by extra("1.2.10")
|
||||
val gtkVersion by extra("4.8.3")
|
||||
val adwaitaVersion by extra("1.2.0")
|
||||
val javagiVersion by extra("v0.5.1")
|
||||
|
||||
val flavorProp: String by extra(prop("flavor", "custom"))
|
||||
if (!setOf("custom", "maven", "fat", "windows", "linux", "macos").contains(flavorProp)) throw IllegalStateException("Unsupported flavor: $flavorProp")
|
||||
|
|
|
@ -10,5 +10,5 @@ repositories {
|
|||
dependencies {
|
||||
implementation("gradle.plugin.com.github.johnrengelman:shadow:7.1.2")
|
||||
implementation("de.undercouch:gradle-download-task:5.1.2")
|
||||
implementation("io.gitlab.jfronny:convention:1.3-SNAPSHOT")
|
||||
implementation("io.gitlab.jfronny:convention:1.4-SNAPSHOT")
|
||||
}
|
|
@ -3,6 +3,12 @@ plugins {
|
|||
`maven-publish`
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(20))
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://maven.frohnmeyer-wds.de/artifacts")
|
||||
|
|
|
@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||
plugins {
|
||||
id("inceptum.application")
|
||||
id("com.github.johnrengelman.shadow")
|
||||
kotlin("jvm") version "1.8.21"
|
||||
kotlin("jvm") version "1.9.0-RC"
|
||||
}
|
||||
|
||||
application {
|
||||
|
@ -12,18 +12,19 @@ application {
|
|||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url = uri("https://maven.frohnmeyer-wds.de/java-gi") }
|
||||
maven("https://jitpack.io") {
|
||||
content {
|
||||
includeGroup("com.github.jwharm.java-gi")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val javagiVersion: String by rootProject.extra
|
||||
val glibVersion: String by rootProject.extra
|
||||
val gtkVersion: String by rootProject.extra
|
||||
val adwaitaVersion: String by rootProject.extra
|
||||
|
||||
implementation("io.github.jwharm.javagi:glib:$glibVersion-$javagiVersion")
|
||||
implementation("io.github.jwharm.javagi:gtk:$gtkVersion-$javagiVersion")
|
||||
implementation("io.github.jwharm.javagi:adwaita:$adwaitaVersion-$javagiVersion")
|
||||
implementation("com.github.jwharm.java-gi:glib:$javagiVersion")
|
||||
implementation("com.github.jwharm.java-gi:gtk:$javagiVersion")
|
||||
implementation("com.github.jwharm.java-gi:adwaita:$javagiVersion")
|
||||
implementation(project(":launcher"))
|
||||
}
|
||||
|
||||
|
@ -51,13 +52,4 @@ tasks.runShadow {
|
|||
jvmArgs("--enable-preview", "--enable-native-access=ALL-UNNAMED")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets.all {
|
||||
languageSettings {
|
||||
languageVersion = "2.0"
|
||||
progressiveMode = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(KotlinCompile::class) { compilerOptions.freeCompilerArgs.addAll("-Xlambdas=indy") }
|
|
@ -2,11 +2,11 @@ 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.markup
|
||||
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
|
||||
|
||||
|
@ -16,21 +16,21 @@ object GtkEnvBackend : EnvBackend {
|
|||
|
||||
override fun showError(message: String, title: String) {
|
||||
Utils.LOGGER.error(message)
|
||||
simpleDialog(message, title, MessageType.ERROR, ButtonsType.CLOSE, null, null)
|
||||
simpleDialog(message, title, null, null)
|
||||
}
|
||||
|
||||
override fun showError(message: String, t: Throwable) {
|
||||
simpleDialog(StringFormatter.toString(t), message, MessageType.ERROR, ButtonsType.CLOSE, null, null)
|
||||
simpleDialog(StringFormatter.toString(t), message, null, null)
|
||||
}
|
||||
|
||||
override fun showInfo(message: String, title: String) {
|
||||
Utils.LOGGER.info(message)
|
||||
simpleDialog(message, title, MessageType.INFO, ButtonsType.CLOSE, null, null)
|
||||
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, MessageType.QUESTION, ButtonsType.OK_CANCEL, ok, cancel)
|
||||
simpleDialog(message, title, ok, cancel)
|
||||
}
|
||||
|
||||
override fun getInput(
|
||||
|
@ -52,37 +52,40 @@ object GtkEnvBackend : EnvBackend {
|
|||
)
|
||||
dialog.title = prompt
|
||||
dialog.onResponse(processResponses(dialog, { ok.accept(dialog.input) }, cancel))
|
||||
dialog.show()
|
||||
dialog.visible = true
|
||||
}
|
||||
|
||||
override fun showLoginRefreshPrompt(account: MicrosoftAccount) =
|
||||
schedule { MicrosoftLoginDialog(dialogParent, account).show() }
|
||||
schedule { MicrosoftLoginDialog(dialogParent, account).visible = true }
|
||||
|
||||
private fun simpleDialog(
|
||||
markup: String,
|
||||
title: String,
|
||||
type: MessageType,
|
||||
buttons: ButtonsType,
|
||||
ok: Runnable?,
|
||||
cancel: Runnable?
|
||||
) = schedule { simpleDialog(dialogParent, markup, title, type, buttons, ok, cancel) }
|
||||
) = schedule { simpleDialog(dialogParent, markup, title, ok, cancel) }
|
||||
|
||||
@JvmStatic
|
||||
fun simpleDialog(
|
||||
parent: Window?,
|
||||
markup: String,
|
||||
title: String,
|
||||
type: MessageType?,
|
||||
buttons: ButtonsType?,
|
||||
ok: Runnable?,
|
||||
cancel: Runnable?
|
||||
) {
|
||||
val dialog =
|
||||
MessageDialog(parent, DialogFlags.MODAL.or(DialogFlags.DESTROY_WITH_PARENT), type, buttons, null)
|
||||
dialog.title = title
|
||||
dialog.markup = markup
|
||||
dialog.onResponse(processResponses(dialog, ok, cancel))
|
||||
dialog.show()
|
||||
run {
|
||||
val dialog = AlertDialog("")
|
||||
dialog.message = title
|
||||
dialog.detail = markup
|
||||
dialog.modal = true
|
||||
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 {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package io.gitlab.jfronny.inceptum.gtk
|
||||
|
||||
import io.gitlab.jfronny.commons.OSUtils
|
||||
import io.gitlab.jfronny.commons.io.JFiles
|
||||
import io.gitlab.jfronny.inceptum.common.MetaHolder
|
||||
import io.gitlab.jfronny.inceptum.common.Utils
|
||||
import io.gitlab.jfronny.inceptum.gtk.menu.MenuBuilder
|
||||
import io.gitlab.jfronny.inceptum.gtk.util.I18n
|
||||
import io.gitlab.jfronny.inceptum.gtk.window.AboutWindow
|
||||
import io.gitlab.jfronny.inceptum.gtk.window.NewInstanceWindow
|
||||
import io.gitlab.jfronny.inceptum.gtk.window.create.NewInstanceWindow
|
||||
import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog
|
||||
import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog
|
||||
import io.gitlab.jfronny.inceptum.gtk.window.settings.launcher.LauncherSettingsWindow
|
||||
|
@ -20,6 +21,8 @@ import io.gitlab.jfronny.inceptum.launcher.system.launch.InstanceLauncher
|
|||
import io.gitlab.jfronny.inceptum.launcher.system.launch.LaunchType
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps
|
||||
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState
|
||||
import org.gnome.gdk.Clipboard
|
||||
import org.gnome.gio.Cancellable
|
||||
import org.gnome.gtk.*
|
||||
import java.awt.Toolkit
|
||||
import java.awt.datatransfer.DataFlavor
|
||||
|
@ -111,21 +114,34 @@ object GtkMenubar {
|
|||
dialog.show()
|
||||
}
|
||||
newMenu!!.button("url") {
|
||||
LauncherEnv.getInput(
|
||||
I18n["menu.file.new.url"],
|
||||
I18n["menu.file.new.url.details"],
|
||||
Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor) as String,
|
||||
{ s: String? ->
|
||||
val state = ProcessState(Importers.MAX_STEPS, "Initializing")
|
||||
ProcessStateWatcherDialog.show(
|
||||
GtkEnvBackend.dialogParent,
|
||||
I18n["menu.file.new.url"],
|
||||
I18n["menu.file.new.url.error"],
|
||||
state
|
||||
) {
|
||||
Importers.importPack(s, state)
|
||||
}
|
||||
}, {})
|
||||
readClipboard { clipboard ->
|
||||
LauncherEnv.getInput(
|
||||
I18n["menu.file.new.url"],
|
||||
I18n["menu.file.new.url.details"],
|
||||
clipboard ?: "",
|
||||
{ s: String? ->
|
||||
val state = ProcessState(Importers.MAX_STEPS, "Initializing")
|
||||
ProcessStateWatcherDialog.show(
|
||||
GtkEnvBackend.dialogParent,
|
||||
I18n["menu.file.new.url"],
|
||||
I18n["menu.file.new.url.error"],
|
||||
state
|
||||
) {
|
||||
Importers.importPack(s, state)
|
||||
}
|
||||
}, {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun readClipboard(continuation: (String?) -> Unit) {
|
||||
if (OSUtils.TYPE == OSUtils.Type.LINUX) {
|
||||
val clipboard = GtkEnvBackend.dialogParent!!.display.clipboard
|
||||
clipboard.readTextAsync(Cancellable()) { _, res, _ ->
|
||||
continuation(clipboard.readTextFinish(res))
|
||||
}
|
||||
} else {
|
||||
continuation(Toolkit.getDefaultToolkit().systemClipboard.getData(DataFlavor.stringFlavor) as String?)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,10 @@ class ILabel(str: @PropertyKey(resourceBundle = I18n.BUNDLE) String, mode: Mode,
|
|||
val provider = CssProvider()
|
||||
try {
|
||||
GtkMain::class.java.classLoader.getResourceAsStream("inceptum.css")!!
|
||||
.use { provider.loadFromData(it.readAllBytes()) }
|
||||
.use {
|
||||
val bytes = it.readAllBytes()
|
||||
provider.loadFromData(String(bytes), bytes.size.toLong())
|
||||
}
|
||||
} catch (t: Throwable) {
|
||||
throw RuntimeException(t)
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@ import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance
|
|||
import org.gnome.gtk.Image
|
||||
import org.gnome.gtk.Spinner
|
||||
import org.gnome.gtk.Stack
|
||||
import java.lang.foreign.Addressable
|
||||
import java.lang.foreign.MemorySegment
|
||||
|
||||
class InstanceThumbnail : Stack {
|
||||
private constructor(address: Addressable) : super(address)
|
||||
private constructor(address: MemorySegment) : super(address)
|
||||
|
||||
constructor() : super() {
|
||||
val spinner = Spinner()
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package io.gitlab.jfronny.inceptum.gtk.control
|
||||
|
||||
import org.gnome.gtk.DropDown
|
||||
import org.gnome.gtk.PropertyExpression
|
||||
import org.gnome.gtk.StringList
|
||||
import org.gnome.gtk.StringObject
|
||||
import java.util.ArrayList
|
||||
import java.util.function.IntConsumer
|
||||
|
||||
class KDropDown<T>(options: Array<T>, private val stringify: (T) -> String, selected: Int): DropDown(options.toModel(stringify), null) {
|
||||
private val onChange = ArrayList<IntConsumer>()
|
||||
|
||||
init {
|
||||
this.selected = selected
|
||||
onNotify("selected") { _ -> onChange.forEach { it.accept(this.selected) } }
|
||||
expression = PropertyExpression(StringObject.getType(), null, "string")
|
||||
}
|
||||
|
||||
fun onChange(changed: IntConsumer) {
|
||||
onChange.add(changed)
|
||||
}
|
||||
|
||||
fun updateOptions(newOptions: Array<T>, newSelected: Int) {
|
||||
selected = 0
|
||||
model = newOptions.toModel(stringify)
|
||||
selected = newSelected
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun <T> Array<T>.toModel(stringify: (T) -> String) = StringList(map(stringify).toTypedArray())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package io.gitlab.jfronny.inceptum.gtk.control
|
||||
|
||||
import org.gnome.gtk.Entry
|
||||
import java.util.function.Consumer
|
||||
|
||||
class KEntry(value: String? = ""): Entry() {
|
||||
private val onChange = ArrayList<Consumer<String>>()
|
||||
|
||||
init {
|
||||
text = value ?: ""
|
||||
onChanged { onChange.forEach { it.accept(text) } }
|
||||
}
|
||||
|
||||
fun onChange(changed: Consumer<String>) {
|
||||
onChange.add(changed)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package io.gitlab.jfronny.inceptum.gtk.control.assistant
|
||||
|
||||
import org.gnome.gtk.AssistantPageType
|
||||
import org.gnome.gtk.Box
|
||||
import org.gnome.gtk.Orientation
|
||||
|
||||
class AssistantPage(val title: String, val type: AssistantPageType): Box(Orientation.VERTICAL, 8) {
|
||||
lateinit var setComplete: (Boolean) -> Unit
|
||||
private val onOpen = ArrayList<Runnable>()
|
||||
fun onOpen(action: Runnable) {
|
||||
onOpen.add(action)
|
||||
}
|
||||
|
||||
fun emitOpen() = onOpen.forEach { it.run() }
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package io.gitlab.jfronny.inceptum.gtk.control.assistant
|
||||
|
||||
import io.gitlab.jfronny.inceptum.common.Utils
|
||||
import org.gnome.gtk.Application
|
||||
import org.gnome.gtk.Assistant
|
||||
import org.gnome.gtk.AssistantPageType
|
||||
|
||||
open class KAssistant(app: Application) : Assistant() {
|
||||
private val pages = ArrayList<AssistantPage>()
|
||||
|
||||
init {
|
||||
application = app
|
||||
onPrepare { next ->
|
||||
val page = pages.firstOrNull { it.handle() == next.handle() }
|
||||
if (page == null) {
|
||||
Utils.LOGGER.error("Unknown page opened in assistant")
|
||||
} else {
|
||||
page.emitOpen()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun page(title: String, type: AssistantPageType, setup: AssistantPage.() -> Unit): Int {
|
||||
val page = AssistantPage(title, type)
|
||||
val idx = appendPage(page)
|
||||
pages.add(page)
|
||||
page.setComplete = { setPageComplete(page, it) }
|
||||
page.setup()
|
||||
setPageType(page, page.type)
|
||||
setPageTitle(page, page.title)
|
||||
return idx
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.gtk.control.settings
|
||||
|
||||
import io.gitlab.jfronny.inceptum.gtk.control.ILabel
|
||||
import io.gitlab.jfronny.inceptum.gtk.control.KDropDown
|
||||
import io.gitlab.jfronny.inceptum.gtk.control.KEntry
|
||||
import io.gitlab.jfronny.inceptum.gtk.util.I18n
|
||||
import io.gitlab.jfronny.inceptum.gtk.util.margin
|
||||
import org.gnome.gtk.*
|
||||
|
@ -41,12 +43,10 @@ class IRow(
|
|||
}
|
||||
}
|
||||
|
||||
fun setDropdown(options: Array<String>, defaultIndex: Int, changed: IntConsumer): DropDown {
|
||||
return DropDown(StringList(options), null).apply {
|
||||
fun setDropdown(options: Array<String>, defaultIndex: Int, changed: IntConsumer): KDropDown<String> {
|
||||
return KDropDown(options, { it } , defaultIndex).apply {
|
||||
onChange(changed)
|
||||
packSmallEnd()
|
||||
selected = defaultIndex
|
||||
onNotify("selected") { _ -> changed.accept(selected) }
|
||||
expression = PropertyExpression(StringObject.getType(), null, "string")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,13 +69,12 @@ class IRow(
|
|||
}
|
||||
}
|
||||
|
||||
fun setEntry(value: String?, changed: Consumer<String>): Entry {
|
||||
return Entry().apply {
|
||||
text = value ?: ""
|
||||
fun setEntry(value: String?, changed: Consumer<String>): KEntry {
|
||||
return KEntry(value).apply {
|
||||
hexpand = true
|
||||
valign = Align.CENTER
|
||||
halign = Align.FILL
|
||||
onChanged { changed.accept(text) }
|
||||
onChange(changed)
|
||||
append(this)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,8 +81,6 @@ open class SettingsTab(window: Window?) : Box(Orientation.VERTICAL, 8) {
|
|||
window,
|
||||
StringFormatter.toString(t),
|
||||
message,
|
||||
MessageType.ERROR,
|
||||
ButtonsType.CLOSE,
|
||||
null,
|
||||
null
|
||||
)
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.gtk.window
|
||||
|
||||
import org.gnome.gtk.*
|
||||
|
||||
class NewInstanceWindow(app: Application) : Assistant() {
|
||||
init {
|
||||
application = app
|
||||
run {
|
||||
val initialPage = Box(Orientation.VERTICAL, 8)
|
||||
initialPage.append(Label("Importing instances via this assistant is not yet supported, use the ImGUI"))
|
||||
appendPage(initialPage)
|
||||
setPageType(initialPage, AssistantPageType.INTRO)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
package io.gitlab.jfronny.inceptum.gtk.window.create
|
||||
|
||||
import io.gitlab.jfronny.commons.StringFormatter
|
||||
import io.gitlab.jfronny.commons.io.JFiles
|
||||
import io.gitlab.jfronny.inceptum.common.InceptumConfig
|
||||
import io.gitlab.jfronny.inceptum.common.MetaHolder
|
||||
import io.gitlab.jfronny.inceptum.common.Utils
|
||||
import io.gitlab.jfronny.inceptum.gtk.control.KDropDown
|
||||
import io.gitlab.jfronny.inceptum.gtk.control.KEntry
|
||||
import io.gitlab.jfronny.inceptum.gtk.control.assistant.KAssistant
|
||||
import io.gitlab.jfronny.inceptum.gtk.schedule
|
||||
import io.gitlab.jfronny.inceptum.gtk.util.I18n
|
||||
import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray
|
||||
import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog
|
||||
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi
|
||||
import io.gitlab.jfronny.inceptum.launcher.api.McApi
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionsListInfo
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceNameTool
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.instance.LoaderInfo
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps
|
||||
import org.gnome.glib.GLib
|
||||
import org.gnome.gtk.*
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
class NewInstanceWindow(app: Application) : KAssistant(app) {
|
||||
companion object {
|
||||
private val VERSIONS = McApi.getVersions()
|
||||
}
|
||||
|
||||
init {
|
||||
var gameVersion: VersionsListInfo? = null
|
||||
var useFabric = false
|
||||
var fabricVersion: FabricVersionLoaderInfo? = null
|
||||
var name = "New Instance"
|
||||
|
||||
var failureMessage = "Unknown error, please look at the log!"
|
||||
var isFailure = false
|
||||
|
||||
page("Welcome", AssistantPageType.INTRO) {
|
||||
append(Label("This assistant will guide you through the process of setting up a Minecraft instance.\nTo begin, please choose the game version you want to use"))
|
||||
|
||||
val versions = VERSIONS.versions.stream()
|
||||
.filter { InceptumConfig.snapshots || it.type == "release" }
|
||||
.toTypedArray()
|
||||
val def = versions.withIndex().firstOrNull { it.value.id == VERSIONS.latest.release }?.index ?: 0
|
||||
gameVersion = versions[def]
|
||||
|
||||
append(KDropDown(versions, { it.id }, def).apply {
|
||||
onChange { gameVersion = versions[it] }
|
||||
})
|
||||
|
||||
setComplete(true)
|
||||
}
|
||||
page("Loader", AssistantPageType.CONTENT) {
|
||||
append(Label("Select a mod loader if you want to use mods in this instance. This can be changed later."))
|
||||
var lastGameVersion: VersionsListInfo? = null
|
||||
var versions = arrayOf<FabricVersionLoaderInfo>()
|
||||
var def = 0
|
||||
|
||||
val none = CheckButton.newWithLabel("None")
|
||||
val fabric = CheckButton.newWithLabel("Fabric")
|
||||
none.onActivate { useFabric = false }
|
||||
none.onActivate { useFabric = true }
|
||||
append(none)
|
||||
val fabricVersionDropdown = KDropDown(versions, { it.loader.version }, def)
|
||||
fabricVersionDropdown.onChange { fabricVersion = versions[it] }
|
||||
append(Box(Orientation.HORIZONTAL, 8).apply {
|
||||
append(fabric)
|
||||
append(fabricVersionDropdown)
|
||||
})
|
||||
|
||||
onOpen {
|
||||
if (lastGameVersion == null || lastGameVersion != gameVersion) {
|
||||
versions = FabricMetaApi.getLoaderVersions(gameVersion!!).toTypedArray()
|
||||
def = versions.withIndex().firstOrNull { it.value.loader.stable }?.index ?: 0
|
||||
fabricVersionDropdown.updateOptions(versions, def)
|
||||
lastGameVersion = gameVersion
|
||||
none.active = true
|
||||
fabric.active = false
|
||||
useFabric = false
|
||||
}
|
||||
|
||||
if (versions.isEmpty()) {
|
||||
none.active = true
|
||||
fabric.active = false
|
||||
useFabric = false
|
||||
fabric.sensitive = false
|
||||
}
|
||||
}
|
||||
|
||||
setComplete(true)
|
||||
}
|
||||
page("Name", AssistantPageType.CONTENT) {
|
||||
append(Label(I18n["instance.settings.general.name.placeholder"]))
|
||||
val entry = KEntry(name)
|
||||
entry.placeholderText = I18n["instance.settings.general.name.placeholder"]
|
||||
entry.valign
|
||||
entry.onChange { name = InstanceNameTool.getNextValid(it) }
|
||||
append(entry)
|
||||
onOpen {
|
||||
name = InstanceNameTool.getDefaultName(gameVersion!!.id, useFabric)
|
||||
entry.text = name
|
||||
}
|
||||
|
||||
setComplete(true)
|
||||
}
|
||||
page("Creating", AssistantPageType.PROGRESS) {
|
||||
append(Label("Creating Instance"))
|
||||
val progress = ProgressBar()
|
||||
append(progress)
|
||||
val stage = Label("")
|
||||
append(stage)
|
||||
onOpen {
|
||||
commit()
|
||||
val pState = Steps.createProcessState()
|
||||
val state = SetupStepInfo(
|
||||
McApi.getVersionInfo(gameVersion),
|
||||
if (useFabric) LoaderInfo(fabricVersion!!.loader) else LoaderInfo.NONE,
|
||||
name,
|
||||
pState
|
||||
)
|
||||
var finished = false
|
||||
var cachedState: ProcessStateWatcherDialog.State? = null
|
||||
addTickCallback { widget, _ ->
|
||||
if (finished) return@addTickCallback GLib.SOURCE_REMOVE
|
||||
val nc = ProcessStateWatcherDialog.State(pState)
|
||||
if (nc != cachedState) {
|
||||
cachedState = nc
|
||||
stage.setMarkup(cachedState!!.msg)
|
||||
progress.fraction = cachedState!!.progress.coerceAtMost(1f).toDouble()
|
||||
widget.queueDraw()
|
||||
}
|
||||
GLib.SOURCE_CONTINUE
|
||||
}
|
||||
onClose { pState.cancel() }
|
||||
onCancel { pState.cancel() }
|
||||
pState.updateStep("Starting install process")
|
||||
Thread {
|
||||
try {
|
||||
for (step in Steps.STEPS) {
|
||||
if (state.isCancelled) {
|
||||
try {
|
||||
JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name))
|
||||
} catch (e: IOException) {
|
||||
Utils.LOGGER.error("Could not delete instance dir", e)
|
||||
}
|
||||
return@Thread
|
||||
}
|
||||
pState.incrementStep(step.name)
|
||||
step.execute(state)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
pState.cancel()
|
||||
Utils.LOGGER.error("Could not create instance")
|
||||
failureMessage = StringFormatter.toString(e)
|
||||
isFailure = true
|
||||
} finally {
|
||||
finished = true
|
||||
schedule { setComplete(true) }
|
||||
schedule { nextPage() }
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
page("Done", AssistantPageType.SUMMARY) {
|
||||
val status = Label("")
|
||||
onOpen {
|
||||
if (isFailure) {
|
||||
status.setMarkup("Something went wrong while creating the instance.\n\n$failureMessage")
|
||||
} else {
|
||||
status.setMarkup("The instance was successfully created. You can now launch it using the main menu")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -51,9 +51,7 @@ class ProcessStateWatcherDialog(
|
|||
(messageArea as Box).append(progress)
|
||||
addTickCallback { widget, _ ->
|
||||
if (finished) return@addTickCallback GLib.SOURCE_REMOVE
|
||||
val nc = State(
|
||||
state
|
||||
)
|
||||
val nc = State(state)
|
||||
if (nc != cachedState) {
|
||||
cachedState = nc
|
||||
setMarkup(cachedState!!.msg)
|
||||
|
@ -72,8 +70,6 @@ class ProcessStateWatcherDialog(
|
|||
parent,
|
||||
StringFormatter.toString(e),
|
||||
errorMessage,
|
||||
MessageType.ERROR,
|
||||
ButtonsType.CLOSE,
|
||||
null,
|
||||
null
|
||||
)
|
||||
|
@ -85,7 +81,7 @@ class ProcessStateWatcherDialog(
|
|||
}
|
||||
|
||||
@JvmRecord
|
||||
internal data class State(val msg: String, val progress: Float) {
|
||||
data class State(val msg: String, val progress: Float) {
|
||||
constructor(source: ProcessState) : this(source.currentStep, source.progress)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package io.gitlab.jfronny.inceptum.gtk.window.settings.instance
|
||||
|
||||
import io.gitlab.jfronny.inceptum.common.Utils
|
||||
import io.gitlab.jfronny.inceptum.gtk.GtkEnvBackend
|
||||
import io.gitlab.jfronny.inceptum.gtk.control.settings.SettingsTab
|
||||
import io.gitlab.jfronny.inceptum.gtk.schedule
|
||||
import io.gitlab.jfronny.inceptum.gtk.util.I18n
|
||||
|
@ -10,6 +9,7 @@ import io.gitlab.jfronny.inceptum.launcher.system.exporter.Exporter
|
|||
import io.gitlab.jfronny.inceptum.launcher.system.exporter.Exporters
|
||||
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance
|
||||
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState
|
||||
import org.gnome.gio.Cancellable
|
||||
import org.gnome.gtk.*
|
||||
import java.nio.file.Path
|
||||
|
||||
|
@ -25,37 +25,20 @@ class ExportTab(private val instance: Instance, window: InstanceSettingsWindow?)
|
|||
for (exporter in Exporters.EXPORTERS) {
|
||||
row("instance.settings.export.title", "instance.settings.export.subtitle", exporter.name, exporter.fileExtension) {
|
||||
setButton("instance.settings.export") {
|
||||
val dialog = FileChooserNative(
|
||||
I18n["instance.settings.export.dialog.title", exporter.name],
|
||||
window,
|
||||
FileChooserAction.SAVE,
|
||||
"_" + I18n["save"],
|
||||
"_" + I18n["cancel"]
|
||||
)
|
||||
val filter = FileFilter()
|
||||
filter.name = exporter.name + " Pack"
|
||||
filter.addPattern("*." + exporter.fileExtension)
|
||||
dialog.addFilter(filter)
|
||||
dialog.currentName = exporter.getDefaultFileName(instance)
|
||||
dialog.onResponse { responseId: Int ->
|
||||
if (responseId == ResponseType.ACCEPT.value) {
|
||||
val file = dialog.file!!.path
|
||||
if (file == null) {
|
||||
GtkEnvBackend.simpleDialog(
|
||||
window,
|
||||
"The path returned by the file dialog is null",
|
||||
"Could not export",
|
||||
MessageType.ERROR,
|
||||
ButtonsType.CLOSE,
|
||||
null,
|
||||
null
|
||||
)
|
||||
return@onResponse
|
||||
}
|
||||
export(exporter, Path.of(file))
|
||||
run {
|
||||
val dialog = FileDialog()
|
||||
dialog.title = I18n["instance.settings.export.dialog.title", exporter.name]
|
||||
val filters = AnyFilter()
|
||||
val filter = FileFilter()
|
||||
filter.name = exporter.name + " Pack"
|
||||
filter.addPattern("*." + exporter.fileExtension)
|
||||
filters.append(filter)
|
||||
dialog.filters = filters
|
||||
dialog.initialName = exporter.getDefaultFileName(instance)
|
||||
dialog.save(window, Cancellable()) { _, res, _ ->
|
||||
export(exporter, Path.of(dialog.saveFinish(res)?.path ?: return@save))
|
||||
}
|
||||
}
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,7 +77,7 @@ class ExportTab(private val instance: Instance, window: InstanceSettingsWindow?)
|
|||
else -> {}
|
||||
}
|
||||
}
|
||||
success.show()
|
||||
success.visible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.gitlab.jfronny.inceptum.gtk.util.I18n
|
|||
import io.gitlab.jfronny.inceptum.gtk.util.Memory
|
||||
import io.gitlab.jfronny.inceptum.gtk.util.markup
|
||||
import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray
|
||||
import io.gitlab.jfronny.inceptum.gtk.window.create.NewInstanceWindow
|
||||
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi
|
||||
import io.gitlab.jfronny.inceptum.launcher.api.McApi
|
||||
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta
|
||||
|
@ -65,8 +66,7 @@ class GeneralTab(instance: Instance, window: InstanceSettingsWindow) : SettingsT
|
|||
.filter { InceptumConfig.snapshots || it.type == "release" }
|
||||
.map { it.id }
|
||||
.toTypedArray()
|
||||
var def = 0
|
||||
for (i in versions.indices) if (versions[i] == instance.gameVersion) def = i
|
||||
val def = versions.withIndex().firstOrNull { it.value == instance.gameVersion }?.index ?: 0
|
||||
|
||||
row("instance.settings.general.game.version", "instance.settings.general.game.version.subtitle") {
|
||||
setDropdown(versions, def) { i ->
|
||||
|
@ -111,7 +111,7 @@ class GeneralTab(instance: Instance, window: InstanceSettingsWindow) : SettingsT
|
|||
.map { it.loader.version }
|
||||
.orElse(null)
|
||||
fabricVersions = ver.map { Arrays.stream(it) }
|
||||
.map{ it.map { l -> l.loader.version }.toTypedArray() }
|
||||
.map { it.map { l -> l.loader.version }.toTypedArray() }
|
||||
.orElse(null)
|
||||
if (fabricVersions == null || fabricVersions!!.isEmpty()) {
|
||||
fabricEnabled.active = false
|
||||
|
|
|
@ -24,7 +24,7 @@ class AccountsTab(window: Window?) : SettingsTab(window) {
|
|||
clear()
|
||||
build()
|
||||
GtkMenubar.generateAccountsMenu(window!!.application!!)
|
||||
}.show()
|
||||
}.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
|
|||
import io.gitlab.jfronny.inceptum.common.GsonPreset;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
|
||||
@GSerializable(configure = GsonPreset.Api.class)
|
||||
public class VersionsListInfo {
|
||||
|
@ -24,4 +25,9 @@ public class VersionsListInfo {
|
|||
this.sha1 = vli.sha1;
|
||||
this.complianceLevel = vli.complianceLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof VersionsListInfo li && Objects.equals(id, li.id);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue