use string list with IDs, fixes crash on remove, scaffold mods tab

This commit is contained in:
Johannes Frohnmeyer 2023-07-14 14:29:23 +02:00
parent 7cefa88dcb
commit 55b9e5986f
Signed by: Johannes
GPG Key ID: E76429612C2929F4
16 changed files with 221 additions and 167 deletions

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.inceptum.gtk.control
import io.github.jwharm.javagi.util.ListIndexModel.ListIndex
import io.gitlab.jfronny.inceptum.gtk.util.get
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance
import org.gnome.gtk.*
import org.pango.EllipsizeMode
@ -64,8 +64,8 @@ class InstanceGridEntryFactory(instanceList: List<Instance>) : SignalListItemFac
val thumbnail = InstanceThumbnail.castFrom(box.firstChild as Stack)
val label = thumbnail.nextSibling as Label
val instance = instanceList[(li.item as ListIndex).index]
thumbnail.bind(instance)
val instance = instanceList[(li.item as StringObject).string]
thumbnail.bind(instance!!)
label.text = instance.toString()
}
}

View File

@ -1,7 +1,6 @@
package io.gitlab.jfronny.inceptum.gtk.control
import io.github.jwharm.javagi.base.Signal
import io.github.jwharm.javagi.util.ListIndexModel.ListIndex
import io.gitlab.jfronny.commons.io.JFiles
import io.gitlab.jfronny.commons.ref.R
import io.gitlab.jfronny.inceptum.common.MetaHolder
@ -10,6 +9,7 @@ import io.gitlab.jfronny.inceptum.gtk.GtkMenubar
import io.gitlab.jfronny.inceptum.gtk.menu.MenuBuilder
import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.util.fixSubtitle
import io.gitlab.jfronny.inceptum.gtk.util.get
import io.gitlab.jfronny.inceptum.gtk.util.margin
import io.gitlab.jfronny.inceptum.gtk.window.settings.instance.InstanceSettingsWindow
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv
@ -61,19 +61,17 @@ class InstanceListEntryFactory(app: Application?, instanceList: List<Instance>)
onBind {
val li = Decomposed.of(it as ListItem, instanceList)
if (li.instance.isLocked) {
if (li.instance?.isLocked ?: true) {
li.item.activatable = false
li.row.setSubtitle(
if (li.instance.isRunningLocked) I18n["instance.launch.locked.running"]
else I18n["instance.launch.locked.setup"]
)
li.row.subtitle = if (li.instance?.isRunningLocked ?: false) I18n["instance.launch.locked.running"]
else I18n["instance.launch.locked.setup"]
}
li.row.title = li.instance.toString()
li.thumbnail.bind(li.instance)
li.thumbnail.bind(li.instance!!)
val menuBuilder = MenuBuilder(li.popoverMenu, li.instance.id)
val menuBuilder = MenuBuilder(li.popoverMenu, li.instanceId)
val launchSection = menuBuilder.literalSection("launch", null)
val kill = launchSection.literalButton("kill", I18n["instance.kill"]) {
//TODO test
@ -92,7 +90,7 @@ class InstanceListEntryFactory(app: Application?, instanceList: List<Instance>)
val settingsSection = menuBuilder.literalSection("settings", null)
settingsSection.literalButton("settings", I18n["instance.settings"]) {
//TODO keep track of properties windows and don't allow opening two
InstanceSettingsWindow(app, li.instance).show()
InstanceSettingsWindow(app, li.instance).visible = true
}.iconName = "document-edit-symbolic"
settingsSection.literalButton(
"directory", I18n["instance.directory"]
@ -127,7 +125,7 @@ class InstanceListEntryFactory(app: Application?, instanceList: List<Instance>)
}.iconName = "edit-delete-symbolic"
val dc = Consumer { s: Signal<*> ->
toDisconnect.computeIfAbsent(li.instance.id) { _ -> HashSet() }
toDisconnect.computeIfAbsent(li.instanceId) { _ -> HashSet() }
.add(s)
}
@ -135,39 +133,24 @@ class InstanceListEntryFactory(app: Application?, instanceList: List<Instance>)
}
onUnbind {
val li = Decomposed.of(it as ListItem, instanceList)
li.popoverMenu.insertActionGroup(li.instance.id, null)
toDisconnect[li.instance.id]!!
.forEach(Consumer { obj: Signal<*> -> obj.disconnect() })
li.popoverMenu.insertActionGroup(li.instanceId, null)
toDisconnect[li.instanceId]?.forEach(Consumer { obj: Signal<*> -> obj.disconnect() })
}
}
private class Decomposed(
item: ListItem,
instance: Instance,
row: ActionRow,
thumbnail: InstanceThumbnail,
launch: Button,
popoverMenu: PopoverMenu
) {
val item: ListItem
val instance: Instance
val row: ActionRow
val thumbnail: InstanceThumbnail
val launch: Button
val item: ListItem,
val instanceId: String,
val instance: Instance?,
val row: ActionRow,
val thumbnail: InstanceThumbnail,
val launch: Button,
val popoverMenu: PopoverMenu
init {
this.item = item
this.instance = instance
this.row = row
this.thumbnail = thumbnail
this.launch = launch
this.popoverMenu = popoverMenu
}
) {
companion object {
fun of(item: ListItem, instanceList: List<Instance>): Decomposed {
val instance = instanceList[(item.item as ListIndex?)!!.index]
val instanceId = (item.item as StringObject).string
val instance = instanceList[instanceId]
val row = item.child as ActionRow
val prefixes = row.firstChild!!.firstChild as Box
val suffixes = row.firstChild!!.lastChild as Box
@ -175,7 +158,7 @@ class InstanceListEntryFactory(app: Application?, instanceList: List<Instance>)
val launch = suffixes.firstChild as Button
val menuButton = launch.nextSibling as MenuButton
val popoverMenu = menuButton.popover as PopoverMenu
return Decomposed(item, instance, row, thumbnail, launch, popoverMenu)
return Decomposed(item, instanceId, instance, row, thumbnail, launch, popoverMenu)
}
}
}

View File

@ -1,9 +1,11 @@
package io.gitlab.jfronny.inceptum.gtk.control
import io.gitlab.jfronny.inceptum.gtk.util.I18n
import org.gnome.gtk.DropDown
import org.gnome.gtk.PropertyExpression
import org.gnome.gtk.StringList
import org.gnome.gtk.StringObject
import org.jetbrains.annotations.PropertyKey
import java.util.ArrayList
import java.util.function.IntConsumer
@ -29,4 +31,7 @@ class KDropDown<T>(options: Array<T>, private val stringify: (T) -> String, sele
companion object {
private fun <T> Array<T>.toModel(stringify: (T) -> String) = StringList(map(stringify).toTypedArray())
}
}
}
fun KDropDown(vararg options: @PropertyKey(resourceBundle = I18n.BUNDLE) String, selected: Int = 0): KDropDown<String> =
KDropDown(options.map { it }.toTypedArray(), { I18n[it] }, selected)

View File

@ -0,0 +1,74 @@
package io.gitlab.jfronny.inceptum.gtk.control.settings
import io.gitlab.jfronny.inceptum.gtk.control.ILabel
import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.util.marginHorizontal
import org.gnome.gtk.*
import org.jetbrains.annotations.PropertyKey
import java.util.concurrent.atomic.AtomicInteger
open class SectionedSettingsTab(window: Window?): SettingsTab<Box>(window, Box(Orientation.VERTICAL, 8)) {
init {
content.marginHorizontal = 24
content.marginTop = 12
}
fun append(child: Widget) = content.append(child)
protected fun section(title: @PropertyKey(resourceBundle = I18n.BUNDLE) String?, builder: Section.() -> Unit) {
if (title != null) append(ILabel(title, ILabel.Mode.HEADING))
val frame = Frame(null as String?)
val listBox = ListBox()
listBox.selectionMode = SelectionMode.NONE
listBox.showSeparators = true
frame.child = listBox
val count = AtomicInteger(0)
builder(object : Section {
override fun row(title: String, subtitle: String?, vararg args: Any?, build: IRow.() -> Unit): IRow {
val row = IRow(title, subtitle, *args)
row(row)
build(row)
return row
}
override fun row(row: Widget): ListBoxRow {
listBox.append(row)
return listBox.getRowAtIndex(count.getAndIncrement())!!
}
override fun remove(row: Widget) {
listBox.remove(row)
count.decrementAndGet()
}
override fun clear() {
var i = 0
val len = count.getAndSet(0)
while (i < len) {
listBox.remove(listBox.getRowAtIndex(0))
i++
}
}
})
append(frame)
}
interface Section {
fun row(
title: @PropertyKey(resourceBundle = I18n.BUNDLE) String,
subtitle: @PropertyKey(resourceBundle = I18n.BUNDLE) String?,
vararg args: Any?
): IRow = row(title, subtitle, *args, build = {})
fun row(
title: @PropertyKey(resourceBundle = I18n.BUNDLE) String,
subtitle: @PropertyKey(resourceBundle = I18n.BUNDLE) String?,
vararg args: Any?,
build: IRow.() -> Unit
): IRow
fun row(row: Widget): ListBoxRow?
fun remove(row: Widget)
fun clear()
}
}

View File

@ -2,80 +2,13 @@ package io.gitlab.jfronny.inceptum.gtk.control.settings
import io.gitlab.jfronny.commons.StringFormatter
import io.gitlab.jfronny.inceptum.gtk.GtkEnvBackend
import io.gitlab.jfronny.inceptum.gtk.control.ILabel
import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.util.marginHorizontal
import org.gnome.gtk.*
import org.jetbrains.annotations.PropertyKey
import java.util.concurrent.atomic.AtomicInteger
open class SettingsTab(window: Window?) : Box(Orientation.VERTICAL, 8) {
@JvmField
protected val window: Window?
init {
marginHorizontal = 24
marginTop = 12
this.window = window
}
protected fun section(title: @PropertyKey(resourceBundle = I18n.BUNDLE) String?, builder: Section.() -> Unit) {
if (title != null) append(ILabel(title, ILabel.Mode.HEADING))
val frame = Frame(null as String?)
val listBox = ListBox()
listBox.selectionMode = SelectionMode.NONE
listBox.showSeparators = true
frame.child = listBox
val count = AtomicInteger(0)
builder(object : Section {
override fun row(title: String, subtitle: String?, vararg args: Any?, build: IRow.() -> Unit): IRow {
val row = IRow(title, subtitle, *args)
row(row)
build(row)
return row
}
override fun row(row: Widget): ListBoxRow {
listBox.append(row)
return listBox.getRowAtIndex(count.getAndIncrement())!!
}
override fun remove(row: Widget) {
listBox.remove(row)
count.decrementAndGet()
}
override fun clear() {
var i = 0
val len = count.getAndSet(0)
while (i < len) {
listBox.remove(listBox.getRowAtIndex(0))
i++
}
}
})
append(frame)
}
interface Section {
fun row(
title: @PropertyKey(resourceBundle = I18n.BUNDLE) String,
subtitle: @PropertyKey(resourceBundle = I18n.BUNDLE) String?,
vararg args: Any?
): IRow = row(title, subtitle, *args, build = {})
fun row(
title: @PropertyKey(resourceBundle = I18n.BUNDLE) String,
subtitle: @PropertyKey(resourceBundle = I18n.BUNDLE) String?,
vararg args: Any?,
build: IRow.() -> Unit
): IRow
fun row(row: Widget): ListBoxRow?
fun remove(row: Widget)
fun clear()
}
import org.gnome.gtk.Widget
import org.gnome.gtk.Window
open class SettingsTab<T : Widget>(
protected val window: Window?,
val content: T
) {
protected fun showError(message: String, t: Throwable) {
GtkEnvBackend.simpleDialog(
window,

View File

@ -41,8 +41,8 @@ open class SettingsWindow(app: Application?) : Window() {
setDefaultSize(720, 360)
}
fun addTab(tab: SettingsTab?, title: @PropertyKey(resourceBundle = I18n.BUNDLE) String, iconName: String) {
stack.addTitledWithIcon(tab, title, I18n[title], iconName)
fun addTab(tab: SettingsTab<*>, title: @PropertyKey(resourceBundle = I18n.BUNDLE) String, iconName: String) {
stack.addTitledWithIcon(tab.content, title, I18n[title], iconName)
}
var activePage: String

View File

@ -0,0 +1,5 @@
package io.gitlab.jfronny.inceptum.gtk.util
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance
operator fun List<Instance>.get(id: String) = firstOrNull { it.id == id }

View File

@ -0,0 +1,9 @@
package io.gitlab.jfronny.inceptum.gtk.util
import org.gnome.gio.ListModel
import org.gnome.gtk.StringList
fun StringList.clear() = splice(0, size, null)
fun StringList.addAll(values: Array<String>) = splice(size, 0, values)
val ListModel.size get() = nItems

View File

@ -1,15 +1,10 @@
package io.gitlab.jfronny.inceptum.gtk.window
import io.github.jwharm.javagi.util.ListIndexModel
import io.gitlab.jfronny.inceptum.common.InceptumConfig
import io.gitlab.jfronny.inceptum.common.Utils
import io.gitlab.jfronny.inceptum.gtk.GtkMenubar
import io.gitlab.jfronny.inceptum.gtk.control.InstanceGridEntryFactory
import io.gitlab.jfronny.inceptum.gtk.control.InstanceListEntryFactory
import io.gitlab.jfronny.inceptum.gtk.menu.MenuBuilder
import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.util.marginHorizontal
import io.gitlab.jfronny.inceptum.gtk.util.marginVertical
import io.gitlab.jfronny.inceptum.gtk.util.*
import io.gitlab.jfronny.inceptum.gtk.window.settings.launcher.LauncherSettingsWindow
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList
@ -25,14 +20,14 @@ import java.io.IOException
import java.net.URI
class MainWindow(app: Application) : ApplicationWindow(app) {
private val listButton: Button
private val gridButton: Button
// private val listButton: Button
// private val gridButton: Button
private val stack: Stack
private val empty: StatusPage
private val listContainer: Clamp
private val gridView: GridView
// private val gridView: GridView
private val instanceList: MutableList<Instance>
private val instanceListIndex: ListIndexModel
private val instanceListModel: StringList
init {
val header = HeaderBar()
@ -42,18 +37,18 @@ class MainWindow(app: Application) : ApplicationWindow(app) {
val accountsButton = MenuButton()
accountsButton.iconName = "avatar-default-symbolic"
accountsButton.menuModel = GtkMenubar.accountsMenu!!.menu
listButton = Button.newFromIconName("view-list-symbolic")
listButton.onClicked {
InceptumConfig.listView = true
InceptumConfig.saveConfig()
generateWindowBody()
}
gridButton = Button.newFromIconName("view-grid-symbolic")
gridButton.onClicked {
InceptumConfig.listView = false
InceptumConfig.saveConfig()
generateWindowBody()
}
// listButton = Button.newFromIconName("view-list-symbolic")
// listButton.onClicked {
// InceptumConfig.listView = true
// InceptumConfig.saveConfig()
// generateWindowBody()
// }
// gridButton = Button.newFromIconName("view-grid-symbolic")
// gridButton.onClicked {
// InceptumConfig.listView = false
// InceptumConfig.saveConfig()
// generateWindowBody()
// }
//TODO search button like boxes
@ -68,13 +63,13 @@ class MainWindow(app: Application) : ApplicationWindow(app) {
header.packStart(newButton)
header.packEnd(menuButton)
header.packEnd(gridButton)
header.packEnd(listButton)
// header.packEnd(gridButton)
// header.packEnd(listButton)
header.packEnd(accountsButton)
instanceList = ArrayList()
instanceListIndex = ListIndexModel.newInstance(instanceList.size)
val selection = NoSelection(instanceListIndex)
instanceListModel = StringList(arrayOf())
val selection = NoSelection(instanceListModel)
val listView = ListView(selection, InstanceListEntryFactory(app, instanceList))
listView.addCssClass("rich-list")
@ -91,14 +86,14 @@ class MainWindow(app: Application) : ApplicationWindow(app) {
listContainer = Clamp()
listContainer.maximumSize = 900
listContainer.child = frame
gridView = GridView(selection, InstanceGridEntryFactory(instanceList))
// gridView = GridView(selection, InstanceGridEntryFactory(instanceList))
empty = StatusPage()
empty.title = I18n["main.empty.title"]
empty.description = I18n["main.empty.description"]
//TODO empty.setIconName(new Str());
stack = Stack()
stack.addChild(listContainer)
stack.addChild(gridView)
// stack.addChild(gridView)
stack.addChild(empty)
val scroll = ScrolledWindow()
@ -107,7 +102,8 @@ class MainWindow(app: Application) : ApplicationWindow(app) {
setDefaultSize(720, 360)
title = "Inceptum"
titlebar = header
//TODO figure out why this segfaults
// titlebar = header
showMenubar = false
child = scroll
@ -144,20 +140,22 @@ class MainWindow(app: Application) : ApplicationWindow(app) {
}
private fun generateWindowBody() {
listButton.visible = !InceptumConfig.listView
gridButton.visible = InceptumConfig.listView
// listButton.visible = !InceptumConfig.listView
// gridButton.visible = InceptumConfig.listView
try {
// Unbind then clear
instanceListIndex.setSize(0)
instanceListModel.clear()
instanceList.clear()
// Add new entries
instanceList.addAll(InstanceList.ordered())
instanceListIndex.setSize(instanceList.size)
instanceListModel.addAll(instanceList.map { it.id }.toTypedArray())
// Choose view for this amount of entries
if (InstanceList.isEmpty()) stack.visibleChild = empty else if (InceptumConfig.listView) stack.visibleChild =
listContainer else stack.visibleChild = gridView
// stack.visibleChild = if (InstanceList.isEmpty()) empty
// else if (InceptumConfig.listView) listContainer
// else gridView
stack.visibleChild = if (InstanceList.isEmpty()) empty else listContainer
// This is called from a tick callback, so re-render
stack.queueResize()

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.inceptum.gtk.window.settings.instance
import io.gitlab.jfronny.inceptum.common.Utils
import io.gitlab.jfronny.inceptum.gtk.control.settings.SettingsTab
import io.gitlab.jfronny.inceptum.gtk.control.settings.SectionedSettingsTab
import io.gitlab.jfronny.inceptum.gtk.schedule
import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog
@ -13,7 +13,7 @@ import org.gnome.gio.Cancellable
import org.gnome.gtk.*
import java.nio.file.Path
class ExportTab(private val instance: Instance, window: InstanceSettingsWindow?) : SettingsTab(window) {
class ExportTab(private val instance: Instance, window: InstanceSettingsWindow?) : SectionedSettingsTab(window) {
init {
section(null) {
row("instance.settings.export.version", "instance.settings.export.version.subtitle") {

View File

@ -7,15 +7,13 @@ 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.ILabel
import io.gitlab.jfronny.inceptum.gtk.control.settings.SettingsTab
import io.gitlab.jfronny.inceptum.gtk.control.settings.SectionedSettingsTab
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
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceNameTool
@ -28,7 +26,7 @@ import java.nio.file.Files
import java.nio.file.Path
import java.util.*
class GeneralTab(instance: Instance, window: InstanceSettingsWindow) : SettingsTab(window) {
class GeneralTab(instance: Instance, window: InstanceSettingsWindow) : SectionedSettingsTab(window) {
companion object {
private val VERSIONS = McApi.getVersions()
}

View File

@ -1,12 +1,55 @@
package io.gitlab.jfronny.inceptum.gtk.window.settings.instance
import io.gitlab.jfronny.inceptum.gtk.control.ILabel
import io.gitlab.jfronny.inceptum.gtk.control.KDropDown
import io.gitlab.jfronny.inceptum.gtk.control.settings.SettingsTab
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance
import org.gnome.adw.Leaflet
import org.gnome.adw.LeafletTransitionType
import org.gnome.gtk.Box
import org.gnome.gtk.Orientation
import org.gnome.gtk.SearchBar
import org.gnome.gtk.SearchEntry
import org.gnome.gtk.Separator
class ModsTab(instance: Instance?, window: InstanceSettingsWindow?) : SettingsTab(window) {
class ModsTab(instance: Instance?, window: InstanceSettingsWindow?) : SettingsTab<Leaflet>(window, Leaflet()) {
init {
append(ILabel("instance.settings.mods.unsupported"))
//TODO implement this, somehow
content.apply {
homogeneous = false
canNavigateBack = true
transitionType = LeafletTransitionType.OVER
append(Box(Orientation.VERTICAL, 6).apply {
content.visibleChild = this
append(KDropDown("instance.settings.mods.local", "instance.settings.mods.modrinth", "instance.settings.mods.curseforge").apply {
onChange { newFilter ->
when (newFilter) {
0 -> switchToLocalMods()
1 -> switchToModrinthMods()
2 -> switchToCurseforgeMods()
}
}
})
append(SearchBar().apply {
hexpand = false
showCloseButton = false
searchMode = false
val entry = SearchEntry().apply {
onSearchChanged { updateSearch(text) }
}
child = entry
keyCaptureWidget = entry
})
})
append(Separator(Orientation.VERTICAL)).navigatable = false
append(Box(Orientation.VERTICAL, 6).apply {
append(ILabel("instance.settings.mods.unsupported"))
//TODO content
})
}
}
fun switchToLocalMods(): Unit = TODO("set up")
fun switchToModrinthMods(): Unit = TODO("set up")
fun switchToCurseforgeMods(): Unit = TODO("set up")
fun updateSearch(search: String): Unit = TODO("set up")
}

View File

@ -2,13 +2,13 @@ package io.gitlab.jfronny.inceptum.gtk.window.settings.launcher
import io.gitlab.jfronny.inceptum.gtk.GtkMenubar
import io.gitlab.jfronny.inceptum.gtk.control.ILabel
import io.gitlab.jfronny.inceptum.gtk.control.settings.SettingsTab
import io.gitlab.jfronny.inceptum.gtk.control.settings.SectionedSettingsTab
import io.gitlab.jfronny.inceptum.gtk.util.margin
import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog
import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager
import org.gnome.gtk.*
class AccountsTab(window: Window?) : SettingsTab(window) {
class AccountsTab(window: Window?) : SectionedSettingsTab(window) {
init {
section(null) {
build()
@ -51,7 +51,7 @@ class AccountsTab(window: Window?) : SettingsTab(window) {
remove.halign = Align.END
remove.onClicked {
AccountManager.removeAccount(account)
remove(ref)
remove(ref!!)
GtkMenubar.generateAccountsMenu(window!!.application!!)
}
row.append(remove)

View File

@ -2,10 +2,10 @@ package io.gitlab.jfronny.inceptum.gtk.window.settings.launcher
import io.gitlab.jfronny.inceptum.common.InceptumConfig
import io.gitlab.jfronny.inceptum.common.model.inceptum.UpdateChannel
import io.gitlab.jfronny.inceptum.gtk.control.settings.SettingsTab
import io.gitlab.jfronny.inceptum.gtk.control.settings.SectionedSettingsTab
import org.gnome.gtk.Window
class GeneralTab(window: Window?) : SettingsTab(window) {
class GeneralTab(window: Window?) : SectionedSettingsTab(window) {
init {
section(null) {
row("settings.general.snapshots", "settings.general.snapshots.subtitle") {

View File

@ -109,4 +109,7 @@ menu.file.new.url.details=Select the URL to import from
menu.file.new.url.error=Could not import Instance
menu.file.new.file=From File
menu.file.new.file.error=Could not import Instance
menu.file.new.new=Create
menu.file.new.new=Create
instance.settings.mods.local=Local
instance.settings.mods.modrinth=Modrinth
instance.settings.mods.curseforge=CurseForge

View File

@ -109,4 +109,7 @@ menu.file.new.url.details=W
menu.file.new.url.error=Konnte Instanz nicht importieren
menu.file.new.file=Aus einer Datei
menu.file.new.file.error=Konnte Instanz nicht importieren
menu.file.new.new=Erstellen
menu.file.new.new=Erstellen
instance.settings.mods.local=Lokal
instance.settings.mods.modrinth=Modrinth
instance.settings.mods.curseforge=CurseForge