Merge branch 'gtk_mod_browsing'
ci/woodpecker/push/docs Pipeline is pending Details
ci/woodpecker/push/woodpecker Pipeline failed Details

# Conflicts:
#	build.gradle.kts
#	launcher-gtk/build.gradle.kts
#	launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt
#	launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/assistant/KAssistant.kt
#	launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt
#	launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt
#	launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java
This commit is contained in:
Johannes Frohnmeyer 2023-10-21 17:41:20 +02:00
commit e61df73dd3
Signed by: Johannes
GPG Key ID: E76429612C2929F4
25 changed files with 111 additions and 122 deletions

View File

@ -3,7 +3,7 @@
pipeline: pipeline:
export_metadata: export_metadata:
image: gradle:jdk19-jammy image: gradle:jdk20-jammy
pull: true pull: true
commands: commands:
- mkdir public - mkdir public
@ -15,20 +15,20 @@ pipeline:
commands: commands:
- ./platform_jars.sh - ./platform_jars.sh
build_wrapper: build_wrapper:
image: gradle:jdk19-jammy image: gradle:jdk20-jammy
commands: commands:
- gradle --build-cache :wrapper:build -Pflavor=windows -Ppublic -Ptimestamp=${CI_PIPELINE_STARTED} - gradle --build-cache :wrapper:build -Pflavor=windows -Ppublic -Ptimestamp=${CI_PIPELINE_STARTED}
- cp wrapper/build/libs/*.exe public/wrapper.exe - cp wrapper/build/libs/*.exe public/wrapper.exe
- cp wrapper/build/libs/*-all.jar public/wrapper.jar - cp wrapper/build/libs/*-all.jar public/wrapper.jar
publish_debug: publish_debug:
image: gradle:jdk19-jammy image: gradle:jdk20-jammy
commands: commands:
- gradle --build-cache build publish -Pflavor=maven -Ppublic -Ptimestamp=${CI_PIPELINE_STARTED} - gradle --build-cache build publish -Pflavor=maven -Ppublic -Ptimestamp=${CI_PIPELINE_STARTED}
secrets: [ maven_token, maven_name ] secrets: [ maven_token, maven_name ]
when: when:
- branch: master - branch: master
publish_release: publish_release:
image: gradle:jdk19-jammy image: gradle:jdk20-jammy
commands: commands:
- gradle --build-cache build publish -Pflavor=maven -Ppublic -Prelease - gradle --build-cache build publish -Pflavor=maven -Ppublic -Prelease
secrets: [ maven_token, maven_name ] secrets: [ maven_token, maven_name ]

View File

@ -17,7 +17,7 @@ val jbAnnotationsVersion by extra("24.0.1")
val lwjglVersion by extra("3.3.2") val lwjglVersion by extra("3.3.2")
val imguiVersion by extra("1.86.10") val imguiVersion by extra("1.86.10")
// launcher-gtk // launcher-gtk
val javagiVersion by extra("0.6.1") val javagiVersion by extra("0.7.2")
val flavorProp: String by extra(prop("flavor", "custom")) val flavorProp: String by extra(prop("flavor", "custom"))
if (!setOf("custom", "maven", "fat", "windows", "linux", "macos").contains(flavorProp)) throw IllegalStateException("Unsupported flavor: $flavorProp") if (!setOf("custom", "maven", "fat", "windows", "linux", "macos").contains(flavorProp)) throw IllegalStateException("Unsupported flavor: $flavorProp")

View File

@ -3,12 +3,6 @@ plugins {
`maven-publish` `maven-publish`
} }
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(20))
}
}
repositories { repositories {
mavenCentral() mavenCentral()
maven("https://maven.frohnmeyer-wds.de/artifacts") maven("https://maven.frohnmeyer-wds.de/artifacts")
@ -42,7 +36,6 @@ afterEvaluate {
if (hasProperty("offline")) { if (hasProperty("offline")) {
tasks.withType(JavaExec::class) { tasks.withType(JavaExec::class) {
environment("G_ORIGINAL_EXECUTABLE", executable ?: "java") environment("G_ORIGINAL_EXECUTABLE", executable ?: "java")
//TODO once we are not using a toolchain, just do executable(rootDir.resolve("buildSrc/java-offline"))
val originalMetadata = javaLauncher.get().metadata val originalMetadata = javaLauncher.get().metadata
val field = org.gradle.api.internal.provider.AbstractProperty::class.java.getDeclaredField("value") val field = org.gradle.api.internal.provider.AbstractProperty::class.java.getDeclaredField("value")
field.isAccessible = true field.isAccessible = true

View File

@ -17,20 +17,14 @@ samWithReceiver {
repositories { repositories {
mavenLocal() mavenLocal()
maven("https://jitpack.io") {
content {
includeGroup("com.github.jwharm.java-gi")
includeGroup("com.github.jwharm")
}
}
} }
dependencies { dependencies {
val javagiVersion: String by rootProject.extra val javagiVersion: String by rootProject.extra
implementation("com.github.jwharm.java-gi:glib:$javagiVersion") //implementation("io.github.jwharm.javagi:glib:$javagiVersion")
implementation("com.github.jwharm.java-gi:gtk:$javagiVersion") //implementation("io.github.jwharm.javagi:gtk:$javagiVersion")
implementation("com.github.jwharm.java-gi:adwaita:$javagiVersion") implementation("io.github.jwharm.javagi:adw:$javagiVersion")
implementation(project(":launcher")) implementation(project(":launcher"))
} }

View File

@ -1,7 +1,6 @@
package io.gitlab.jfronny.inceptum.gtk package io.gitlab.jfronny.inceptum.gtk
import io.gitlab.jfronny.commons.StringFormatter 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.util.I18n
import io.gitlab.jfronny.inceptum.gtk.util.Log 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.MicrosoftLoginDialog
@ -75,33 +74,29 @@ object GtkEnvBackend : EnvBackend {
ok: Runnable?, ok: Runnable?,
cancel: Runnable? cancel: Runnable?
) { ) {
val dialog = AlertDialog("") val dialog = AlertDialog.builder()
dialog.message = title .message(title)
dialog.detail = markup .detail(markup)
dialog.modal = true .modal(true)
when { when {
cancel == null -> { cancel == null -> dialog.buttons(arrayOf(I18n["ok"]))
dialog.setButtons(arrayOf(I18n["ok"])) .defaultButton(0)
dialog.defaultButton = 0 .cancelButton(-1)
dialog.cancelButton = -1 ok == null -> dialog.buttons(arrayOf("Cancel"))
} .defaultButton(-1)
ok == null -> { .cancelButton(0)
dialog.setButtons(arrayOf("Cancel")) else -> dialog.buttons(arrayOf("OK", "Cancel"))
dialog.defaultButton = -1 .defaultButton(0)
dialog.cancelButton = 0 .cancelButton(1)
}
else -> {
dialog.setButtons(arrayOf("OK", "Cancel"))
dialog.defaultButton = 0
dialog.cancelButton = 1
}
} }
dialog.choose(parent, Cancellable()) { _, res, _ -> dialog.build().apply {
val result = dialog.chooseFinish(res) choose(parent, Cancellable()) { _, res, _ ->
val cancelIdx = dialog.cancelButton val result = chooseFinish(res)
val defaultIdx = dialog.defaultButton val cancelIdx = cancelButton
if (result == cancelIdx) cancel?.run() val defaultIdx = defaultButton
if (result == defaultIdx) ok?.run() if (result == cancelIdx) cancel?.run()
if (result == defaultIdx) ok?.run()
}
} }
} }

View File

@ -2,7 +2,6 @@ package io.gitlab.jfronny.inceptum.gtk
import io.gitlab.jfronny.inceptum.common.BuildMetadata import io.gitlab.jfronny.inceptum.common.BuildMetadata
import io.gitlab.jfronny.inceptum.common.MetaHolder import io.gitlab.jfronny.inceptum.common.MetaHolder
import io.gitlab.jfronny.inceptum.common.Utils
import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.util.Log
import io.gitlab.jfronny.inceptum.gtk.window.MainWindow import io.gitlab.jfronny.inceptum.gtk.window.MainWindow
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv import io.gitlab.jfronny.inceptum.launcher.LauncherEnv

View File

@ -3,7 +3,6 @@ package io.gitlab.jfronny.inceptum.gtk
import io.gitlab.jfronny.commons.OSUtils import io.gitlab.jfronny.commons.OSUtils
import io.gitlab.jfronny.commons.io.JFiles import io.gitlab.jfronny.commons.io.JFiles
import io.gitlab.jfronny.inceptum.common.MetaHolder 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.menu.MenuBuilder
import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.util.Log
@ -22,8 +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.launch.LaunchType
import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState import io.gitlab.jfronny.inceptum.launcher.util.ProcessState
import org.gnome.gdk.Clipboard
import org.gnome.gio.Cancellable import org.gnome.gio.Cancellable
import org.gnome.gio.Menu
import org.gnome.gtk.* import org.gnome.gtk.*
import java.awt.Toolkit import java.awt.Toolkit
import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.DataFlavor
@ -69,7 +68,7 @@ object GtkMenubar {
file.button("exit") { app.quit() } file.button("exit") { app.quit() }
launchMenu = menu.submenu("launch") launchMenu = menu.submenu("launch")
generateLaunchMenu(app) generateLaunchMenu(app)
accountsMenu = menu.submenu("account") accountsMenu = MenuBuilder(app, Menu(), "account") // this should ideally be menu.submenu("account"), but that causes a segfault
generateAccountsMenu(app) generateAccountsMenu(app)
val help = menu.submenu("help") val help = menu.submenu("help")
help.button("about") { AboutWindow.createAndShow() } help.button("about") { AboutWindow.createAndShow() }
@ -81,7 +80,7 @@ object GtkMenubar {
@JvmStatic @JvmStatic
fun generateNewMenu(app: Application) { fun generateNewMenu(app: Application) {
newMenu!!.clear() newMenu!!.clear()
newMenu!!.button("new") { NewInstanceWindow(app).show() } newMenu!!.button("new") { NewInstanceWindow(app).visible = true }
newMenu!!.button("file") { newMenu!!.button("file") {
val dialog = FileChooserNative( val dialog = FileChooserNative(
I18n["menu.file.new.file"], I18n["menu.file.new.file"],
@ -204,11 +203,11 @@ object GtkMenubar {
@JvmStatic @JvmStatic
fun generateAccountsMenu(app: Application) { fun generateAccountsMenu(app: Application) {
accountsMenu!!.clear() accountsMenu!!.clear()
accountsMenu!!.button("new") { MicrosoftLoginDialog(GtkEnvBackend.dialogParent).show() } accountsMenu!!.button("new") { MicrosoftLoginDialog(GtkEnvBackend.dialogParent).visible = true }
accountsMenu!!.button("manage") { accountsMenu!!.button("manage") {
val window = LauncherSettingsWindow(app) val window = LauncherSettingsWindow(app)
window.activePage = "settings.accounts" window.activePage = "settings.accounts"
window.show() window.visible = true
} }
val accounts: MutableList<MicrosoftAccount?> = ArrayList(AccountManager.getAccounts()) val accounts: MutableList<MicrosoftAccount?> = ArrayList(AccountManager.getAccounts())
accounts.add(null) accounts.add(null)

View File

@ -6,7 +6,6 @@ import org.gnome.gtk.PropertyExpression
import org.gnome.gtk.StringList import org.gnome.gtk.StringList
import org.gnome.gtk.StringObject import org.gnome.gtk.StringObject
import org.jetbrains.annotations.PropertyKey import org.jetbrains.annotations.PropertyKey
import java.util.ArrayList
import java.util.function.IntConsumer import java.util.function.IntConsumer
class KDropDown<T>(options: Array<T>, private val stringify: (T) -> String, selected: Int): DropDown(options.toModel(stringify), null) { class KDropDown<T>(options: Array<T>, private val stringify: (T) -> String, selected: Int): DropDown(options.toModel(stringify), null) {

View File

@ -1,13 +1,13 @@
package io.gitlab.jfronny.inceptum.gtk.control package io.gitlab.jfronny.inceptum.gtk.control
import io.github.jwharm.javagi.base.Signal import io.github.jwharm.javagi.gobject.SignalConnection
import org.gnome.gtk.ListItem import org.gnome.gtk.ListItem
import org.gnome.gtk.SignalListItemFactory import org.gnome.gtk.SignalListItemFactory
import org.gnome.gtk.StringObject import org.gnome.gtk.StringObject
import org.gnome.gtk.Widget import org.gnome.gtk.Widget
abstract class KSignalListItemFactory<TData, TWidget : Widget> : SignalListItemFactory() { abstract class KSignalListItemFactory<TData, TWidget : Widget> : SignalListItemFactory() {
private val toDisconnect: MutableMap<String, MutableSet<Signal<*>>> = HashMap() private val toDisconnect: MutableMap<String, MutableSet<SignalConnection<*>>> = HashMap()
init { init {
onSetup { onSetup {
val li = it as ListItem val li = it as ListItem
@ -41,14 +41,14 @@ abstract class KSignalListItemFactory<TData, TWidget : Widget> : SignalListItemF
} }
interface BindContext: ActionContext { interface BindContext: ActionContext {
fun registerForUnbind(signal: Signal<*>) fun registerForUnbind(signal: SignalConnection<*>)
} }
interface UnbindContext: ActionContext { interface UnbindContext: ActionContext {
} }
private inner class BindContextImpl(private val id: String, override val listItem: ListItem) : BindContext { private inner class BindContextImpl(private val id: String, override val listItem: ListItem) : BindContext {
override fun registerForUnbind(signal: Signal<*>) { override fun registerForUnbind(signal: SignalConnection<*>) {
toDisconnect.computeIfAbsent(id) { _ -> HashSet() } toDisconnect.computeIfAbsent(id) { _ -> HashSet() }
.add(signal) .add(signal)
} }

View File

@ -1,6 +1,5 @@
package io.gitlab.jfronny.inceptum.gtk.control.assistant package io.gitlab.jfronny.inceptum.gtk.control.assistant
import io.gitlab.jfronny.inceptum.common.Utils
import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.util.Log
import org.gnome.gtk.Application import org.gnome.gtk.Application
import org.gnome.gtk.Assistant import org.gnome.gtk.Assistant

View File

@ -1,12 +1,11 @@
package io.gitlab.jfronny.inceptum.gtk.menu package io.gitlab.jfronny.inceptum.gtk.menu
import io.github.jwharm.javagi.glib.types.VariantTypes
import io.gitlab.jfronny.commons.throwable.ThrowingRunnable import io.gitlab.jfronny.commons.throwable.ThrowingRunnable
import io.gitlab.jfronny.inceptum.common.Utils
import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.util.Log
import org.gnome.gio.* import org.gnome.gio.*
import org.gnome.glib.Variant import org.gnome.glib.Variant
import org.gnome.glib.VariantType
import org.gnome.gtk.Application import org.gnome.gtk.Application
import org.gnome.gtk.MenuButton import org.gnome.gtk.MenuButton
import org.gnome.gtk.PopoverMenu import org.gnome.gtk.PopoverMenu
@ -89,7 +88,7 @@ class MenuBuilder private constructor(map: ActionMap, menu: Menu, prefix: String
): BuiltRadioItem<T> { ): BuiltRadioItem<T> {
var name = name var name = name
name = prefix + name name = prefix + name
val action = SimpleAction.newStateful(name, VariantType("i"), Variant.newInt32(options.indexOf(initial))) val action = SimpleAction.newStateful(name, VariantTypes.INT32, Variant.newInt32(options.indexOf(initial)))
addAction(name, action) addAction(name, action)
action.onActivate { variant: Variant? -> action.onActivate { variant: Variant? ->
action.state = variant action.state = variant

View File

@ -1,7 +1,6 @@
package io.gitlab.jfronny.inceptum.gtk.util package io.gitlab.jfronny.inceptum.gtk.util
import io.gitlab.jfronny.commons.OSUtils import io.gitlab.jfronny.commons.OSUtils
import io.gitlab.jfronny.inceptum.common.Utils
import java.io.IOException import java.io.IOException
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path

View File

@ -2,11 +2,7 @@ package io.gitlab.jfronny.inceptum.gtk.util
import io.gitlab.jfronny.inceptum.gtk.control.ILabel import io.gitlab.jfronny.inceptum.gtk.control.ILabel
import org.gnome.adw.ActionRow import org.gnome.adw.ActionRow
import org.gnome.gtk.Entry import org.gnome.gtk.*
import org.gnome.gtk.EntryBuffer
import org.gnome.gtk.Label
import org.gnome.gtk.MessageDialog
import org.gnome.gtk.Widget
var Widget.margin: Int var Widget.margin: Int
set(value) { set(value) {
@ -35,12 +31,4 @@ var MessageDialog.markup: String
fun ActionRow.fixSubtitle() = ILabel.theme(firstChild!!.lastChild!!.prevSibling!!.lastChild as Label, ILabel.Mode.SUBTITLE) fun ActionRow.fixSubtitle() = ILabel.theme(firstChild!!.lastChild!!.prevSibling!!.lastChild as Label, ILabel.Mode.SUBTITLE)
// Work around a segfault with empty entries
var Entry.kText: String?
get() = text
set(value) {
if (value == "") buffer.clear()
else text = value
}
fun EntryBuffer.clear() = deleteText(0, length) fun EntryBuffer.clear() = deleteText(0, length)

View File

@ -25,7 +25,7 @@ class AboutWindow : AboutDialog() {
companion object { companion object {
@JvmStatic @JvmStatic
fun createAndShow() { fun createAndShow() {
AboutWindow().show() AboutWindow().visible = true
} }
} }
} }

View File

@ -54,7 +54,7 @@ class MainWindow(app: Application) : ApplicationWindow(app) {
val uiMenu = MenuBuilder(app, Menu(), "hamburger") val uiMenu = MenuBuilder(app, Menu(), "hamburger")
uiMenu.button("support") { Utils.openWebBrowser(URI("https://git.frohnmeyer-wds.de/JfMods/Inceptum/issues")) } uiMenu.button("support") { Utils.openWebBrowser(URI("https://git.frohnmeyer-wds.de/JfMods/Inceptum/issues")) }
uiMenu.button("preferences") { LauncherSettingsWindow(app).show() } uiMenu.button("preferences") { LauncherSettingsWindow(app).visible = true }
uiMenu.button("about") { AboutWindow.createAndShow() } uiMenu.button("about") { AboutWindow.createAndShow() }
val menuButton = MenuButton() val menuButton = MenuButton()
menuButton.iconName = "open-menu-symbolic" menuButton.iconName = "open-menu-symbolic"

View File

@ -1,17 +1,13 @@
package io.gitlab.jfronny.inceptum.gtk.window.create package io.gitlab.jfronny.inceptum.gtk.window.create
import io.gitlab.jfronny.commons.StringFormatter 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.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.KDropDown
import io.gitlab.jfronny.inceptum.gtk.control.KEntry import io.gitlab.jfronny.inceptum.gtk.control.KEntry
import io.gitlab.jfronny.inceptum.gtk.control.assistant.KAssistant import io.gitlab.jfronny.inceptum.gtk.control.assistant.KAssistant
import io.gitlab.jfronny.inceptum.gtk.schedule import io.gitlab.jfronny.inceptum.gtk.schedule
import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.util.Log
import io.gitlab.jfronny.inceptum.gtk.util.kText
import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray
import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi
@ -24,7 +20,6 @@ import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo
import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps
import org.gnome.glib.GLib import org.gnome.glib.GLib
import org.gnome.gtk.* import org.gnome.gtk.*
import java.io.IOException
class NewInstanceWindow(app: Application) : KAssistant(app) { class NewInstanceWindow(app: Application) : KAssistant(app) {
@ -105,7 +100,7 @@ class NewInstanceWindow(app: Application) : KAssistant(app) {
append(entry) append(entry)
onOpen { onOpen {
name = InstanceNameTool.getDefaultName(gameVersion!!.id, useFabric) name = InstanceNameTool.getDefaultName(gameVersion!!.id, useFabric)
entry.kText = name entry.text = name
} }
setComplete(true) setComplete(true)
@ -145,21 +140,19 @@ class NewInstanceWindow(app: Application) : KAssistant(app) {
try { try {
for (step in Steps.STEPS) { for (step in Steps.STEPS) {
if (state.isCancelled) { if (state.isCancelled) {
try { state.tryRemoveInstance()
JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name))
} catch (e: IOException) {
Log.error("Could not delete instance dir", e)
}
return@Thread return@Thread
} }
pState.incrementStep(step.name) pState.incrementStep(step.name)
step.execute(state) step.execute(state)
} }
state.clearSetupLock()
} catch (e: Throwable) { } catch (e: Throwable) {
pState.cancel() pState.cancel()
Log.error("Could not create instance") Log.error("Could not create instance")
failureMessage = StringFormatter.toString(e) failureMessage = StringFormatter.toString(e)
isFailure = true isFailure = true
state.tryRemoveInstance()
} finally { } finally {
finished = true finished = true
schedule { setComplete(true) } schedule { setComplete(true) }

View File

@ -2,7 +2,6 @@ package io.gitlab.jfronny.inceptum.gtk.window.dialog
import io.gitlab.jfronny.commons.StringFormatter import io.gitlab.jfronny.commons.StringFormatter
import io.gitlab.jfronny.commons.throwable.ThrowingRunnable import io.gitlab.jfronny.commons.throwable.ThrowingRunnable
import io.gitlab.jfronny.inceptum.common.Utils
import io.gitlab.jfronny.inceptum.gtk.GtkEnvBackend import io.gitlab.jfronny.inceptum.gtk.GtkEnvBackend
import io.gitlab.jfronny.inceptum.gtk.schedule import io.gitlab.jfronny.inceptum.gtk.schedule
import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.I18n
@ -96,7 +95,7 @@ class ProcessStateWatcherDialog(
executor: ThrowingRunnable<*> executor: ThrowingRunnable<*>
): ProcessStateWatcherDialog { ): ProcessStateWatcherDialog {
val dialog = ProcessStateWatcherDialog(parent, title, errorMessage, state, executor) val dialog = ProcessStateWatcherDialog(parent, title, errorMessage, state, executor)
dialog.show() dialog.visible = true
return dialog return dialog
} }
} }

View File

@ -40,7 +40,7 @@ class GeneralTab(window: InstanceSettingsWindow) : SectionedSettingsTab<Instance
val newPath = MetaHolder.INSTANCE_DIR.resolve(InstanceNameTool.getNextValid(entry.text)) val newPath = MetaHolder.INSTANCE_DIR.resolve(InstanceNameTool.getNextValid(entry.text))
Files.move(instance.path, newPath) Files.move(instance.path, newPath)
window.close() window.close()
InstanceSettingsWindow(window.application, InstanceList.read(newPath)).show() InstanceSettingsWindow(window.application, InstanceList.read(newPath)).visible = true
} catch (e: IOException) { } catch (e: IOException) {
showError("Could not rename", e) showError("Could not rename", e)
} }
@ -230,7 +230,7 @@ class GeneralTab(window: InstanceSettingsWindow) : SectionedSettingsTab<Instance
else -> {} else -> {}
} }
} }
dialog.show() dialog.visible = true
} }
} }
row("instance.directory", "instance.directory.subtitle") { row("instance.directory", "instance.directory.subtitle") {

View File

@ -4,7 +4,8 @@ module io.gitlab.jfronny.inceptum.launcher.gtk {
requires kotlin.stdlib; requires kotlin.stdlib;
requires org.gnome.glib; requires org.gnome.glib;
requires org.gnome.gtk; requires org.gnome.gtk;
requires org.gnome.adwaita; requires org.gnome.adw;
requires org.gnome.pango;
// Should theoretically already be included transitively through inceptum.launcher and inceptum.common // Should theoretically already be included transitively through inceptum.launcher and inceptum.common
requires io.gitlab.jfronny.commons; requires io.gitlab.jfronny.commons;

View File

@ -93,7 +93,7 @@ public class AddModWindow extends Window {
ImGui.text("Installed"); ImGui.text("Installed");
} else { } else {
if (ImGui.button("Add##" + projectId)) { if (ImGui.button("Add##" + projectId)) {
ModrinthVersion latest = ModrinthApi.getLatestVersion(projectId, instance.getGameVersion()); ModrinthVersion latest = ModrinthApi.getLatestVersions(projectId, instance.getGameVersion()).latest();
if (latest == null) { if (latest == null) {
LauncherEnv.showError("No valid version could be identified for this mod", "No version found"); LauncherEnv.showError("No valid version could be identified for this mod", "No version found");
} else { } else {

View File

@ -2,7 +2,6 @@ package io.gitlab.jfronny.inceptum.imgui.window;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.imgui.GuiMain; import io.gitlab.jfronny.inceptum.imgui.GuiMain;
import io.gitlab.jfronny.inceptum.imgui.window.dialog.ProcessStateWatcherWindow; import io.gitlab.jfronny.inceptum.imgui.window.dialog.ProcessStateWatcherWindow;
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
@ -44,17 +43,14 @@ public class GuiUtil {
GuiMain.open(new ProcessStateWatcherWindow("Creating Instance", "Could not create instance", pState, () -> { GuiMain.open(new ProcessStateWatcherWindow("Creating Instance", "Could not create instance", pState, () -> {
for (Step step : Steps.STEPS) { for (Step step : Steps.STEPS) {
if (state.isCancelled()) { if (state.isCancelled()) {
try { state.tryRemoveInstance();
JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name()));
} catch (IOException e) {
Utils.LOGGER.error("Could not delete instance dir", e);
}
return; return;
} }
pState.incrementStep(step.getName()); pState.incrementStep(step.getName());
step.execute(state); step.execute(state);
} }
state.clearSetupLock();
LauncherEnv.showInfo("The instance was successfully created. You can now launch it using the main menu", "Successfully installed"); LauncherEnv.showInfo("The instance was successfully created. You can now launch it using the main menu", "Successfully installed");
})); }, t -> state.tryRemoveInstance()));
} }
} }

View File

@ -1,16 +1,22 @@
package io.gitlab.jfronny.inceptum.imgui.window.dialog; package io.gitlab.jfronny.inceptum.imgui.window.dialog;
import imgui.ImGui; import imgui.ImGui;
import io.gitlab.jfronny.commons.ref.R;
import io.gitlab.jfronny.commons.throwable.ThrowingRunnable; import io.gitlab.jfronny.commons.throwable.ThrowingRunnable;
import io.gitlab.jfronny.inceptum.imgui.window.Window; import io.gitlab.jfronny.inceptum.imgui.window.Window;
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;
import java.util.function.Consumer;
public class ProcessStateWatcherWindow extends Window { public class ProcessStateWatcherWindow extends Window {
private final ProcessState state; private final ProcessState state;
private boolean finished; private boolean finished;
public ProcessStateWatcherWindow(String title, String errorMessage, ProcessState state, ThrowingRunnable<?> executor) { public ProcessStateWatcherWindow(String title, String errorMessage, ProcessState state, ThrowingRunnable<?> executor) {
this(title, errorMessage, state, executor, R::nop);
}
public ProcessStateWatcherWindow(String title, String errorMessage, ProcessState state, ThrowingRunnable<?> executor, Consumer<Throwable> onFail) {
super(title); super(title);
this.state = state; this.state = state;
new Thread(() -> { new Thread(() -> {
@ -18,6 +24,7 @@ public class ProcessStateWatcherWindow extends Window {
executor.run(); executor.run();
} catch (Throwable e) { } catch (Throwable e) {
state.cancel(); state.cancel();
onFail.accept(e);
LauncherEnv.showError(errorMessage, e); LauncherEnv.showError(errorMessage, e);
} finally { } finally {
finished = true; finished = true;

View File

@ -1,9 +1,16 @@
package io.gitlab.jfronny.inceptum.launcher.system.setup; package io.gitlab.jfronny.inceptum.launcher.system.setup;
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.launcher.model.mojang.VersionInfo; import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo;
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.system.instance.LoaderInfo; import io.gitlab.jfronny.inceptum.launcher.system.instance.LoaderInfo;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;
import java.io.IOException;
import java.nio.file.Files;
public record SetupStepInfo(VersionInfo version, public record SetupStepInfo(VersionInfo version,
LoaderInfo loader, LoaderInfo loader,
String name, String name,
@ -15,4 +22,23 @@ public record SetupStepInfo(VersionInfo version,
public boolean isCancelled() { public boolean isCancelled() {
return currentState.isCancelled(); return currentState.isCancelled();
} }
public void tryRemoveInstance() {
try {
removeInstance();
} catch (IOException e) {
Utils.LOGGER.error("Could not delete instance dir", e);
}
}
public void removeInstance() throws IOException {
JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(name));
}
public void clearSetupLock() {
try {
Files.deleteIfExists(MetaHolder.INSTANCE_DIR.resolve(name).resolve(Instance.SETUP_LOCK_NAME));
} catch (IOException ignored) {
}
}
} }

View File

@ -15,11 +15,11 @@ import java.util.*;
public class Steps { public class Steps {
public static Set<Step> STEPS = new LinkedHashSet<>(List.of( public static Set<Step> STEPS = new LinkedHashSet<>(List.of(
new SetupDirsStep(), new SetupDirsStep(),
new WriteMetadataStep(),
new DownloadJavaStep(), new DownloadJavaStep(),
new DownloadClientStep(), new DownloadClientStep(),
new DownloadLibrariesStep(), new DownloadLibrariesStep(),
new DownloadAssetsStep(), new DownloadAssetsStep(),
new WriteMetadataStep(),
new RunMdsStep() new RunMdsStep()
)); ));
@ -29,24 +29,28 @@ public class Steps {
public static void reDownload(Instance instance, ProcessState state) throws IOException { public static void reDownload(Instance instance, ProcessState state) throws IOException {
if (instance.isLocked()) return; if (instance.isLocked()) return;
boolean found = false; try {
for (VersionsListInfo version : McApi.getVersions().versions()) { boolean found = false;
if (version.id.equals(instance.getGameVersion())) { for (VersionsListInfo version : McApi.getVersions().versions()) {
found = true; if (version.id.equals(instance.getGameVersion())) {
VersionInfo vi = McApi.getVersionInfo(version); found = true;
if (instance.isFabric()) VersionInfo vi = McApi.getVersionInfo(version);
vi = FabricMetaApi.addFabric(vi, instance.getLoaderVersion(), FabricMetaApi.FabricVersionInfoType.Both); if (instance.isFabric())
LoaderInfo li = instance.isFabric() vi = FabricMetaApi.addFabric(vi, instance.getLoaderVersion(), FabricMetaApi.FabricVersionInfoType.Both);
? new LoaderInfo(LoaderInfo.Type.Fabric, instance.getLoaderVersion()) LoaderInfo li = instance.isFabric()
: LoaderInfo.NONE; ? new LoaderInfo(LoaderInfo.Type.Fabric, instance.getLoaderVersion())
SetupStepInfo info = new SetupStepInfo(vi, li, instance.getName(), state); : LoaderInfo.NONE;
for (Step step : Steps.STEPS) { SetupStepInfo info = new SetupStepInfo(vi, li, instance.getName(), state);
state.incrementStep(step.getName()); for (Step step : Steps.STEPS) {
step.execute(info); state.incrementStep(step.getName());
if (state.isCancelled()) return; step.execute(info);
if (state.isCancelled()) return;
}
} }
} }
if (!found) throw new IOException("Could not identify minecraft version " + instance.getGameVersion());
} finally {
instance.setSetupLock(false);
} }
if (!found) throw new IOException("Could not identify minecraft version " + instance.getGameVersion());
} }
} }

View File

@ -22,7 +22,6 @@ public class WriteMetadataStep implements Step {
meta.gameVersion = info.version().id; meta.gameVersion = info.version().id;
GC_InstanceMeta.write(meta, metaPath); GC_InstanceMeta.write(meta, metaPath);
} }
Instance.setSetupLock(instance, false);
if (!Files.exists(instance.resolve(".gitignore"))) { if (!Files.exists(instance.resolve(".gitignore"))) {
Files.writeString(instance.resolve(".gitignore"), """ Files.writeString(instance.resolve(".gitignore"), """
realms_persistence.json realms_persistence.json