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 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 io.gitlab.jfronny.inceptum.launcher.system.instance.Instance
import org.gnome.gtk.* import org.gnome.gtk.*
import org.pango.EllipsizeMode import org.pango.EllipsizeMode
@ -64,8 +64,8 @@ class InstanceGridEntryFactory(instanceList: List<Instance>) : SignalListItemFac
val thumbnail = InstanceThumbnail.castFrom(box.firstChild as Stack) val thumbnail = InstanceThumbnail.castFrom(box.firstChild as Stack)
val label = thumbnail.nextSibling as Label val label = thumbnail.nextSibling as Label
val instance = instanceList[(li.item as ListIndex).index] val instance = instanceList[(li.item as StringObject).string]
thumbnail.bind(instance) thumbnail.bind(instance!!)
label.text = instance.toString() label.text = instance.toString()
} }
} }

View File

@ -1,7 +1,6 @@
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.base.Signal
import io.github.jwharm.javagi.util.ListIndexModel.ListIndex
import io.gitlab.jfronny.commons.io.JFiles import io.gitlab.jfronny.commons.io.JFiles
import io.gitlab.jfronny.commons.ref.R import io.gitlab.jfronny.commons.ref.R
import io.gitlab.jfronny.inceptum.common.MetaHolder 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.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.fixSubtitle 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.util.margin
import io.gitlab.jfronny.inceptum.gtk.window.settings.instance.InstanceSettingsWindow import io.gitlab.jfronny.inceptum.gtk.window.settings.instance.InstanceSettingsWindow
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv import io.gitlab.jfronny.inceptum.launcher.LauncherEnv
@ -61,19 +61,17 @@ class InstanceListEntryFactory(app: Application?, instanceList: List<Instance>)
onBind { onBind {
val li = Decomposed.of(it as ListItem, instanceList) val li = Decomposed.of(it as ListItem, instanceList)
if (li.instance.isLocked) { if (li.instance?.isLocked ?: true) {
li.item.activatable = false li.item.activatable = false
li.row.setSubtitle( li.row.subtitle = if (li.instance?.isRunningLocked ?: false) I18n["instance.launch.locked.running"]
if (li.instance.isRunningLocked) I18n["instance.launch.locked.running"] else I18n["instance.launch.locked.setup"]
else I18n["instance.launch.locked.setup"]
)
} }
li.row.title = li.instance.toString() 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 launchSection = menuBuilder.literalSection("launch", null)
val kill = launchSection.literalButton("kill", I18n["instance.kill"]) { val kill = launchSection.literalButton("kill", I18n["instance.kill"]) {
//TODO test //TODO test
@ -92,7 +90,7 @@ class InstanceListEntryFactory(app: Application?, instanceList: List<Instance>)
val settingsSection = menuBuilder.literalSection("settings", null) val settingsSection = menuBuilder.literalSection("settings", null)
settingsSection.literalButton("settings", I18n["instance.settings"]) { settingsSection.literalButton("settings", I18n["instance.settings"]) {
//TODO keep track of properties windows and don't allow opening two //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" }.iconName = "document-edit-symbolic"
settingsSection.literalButton( settingsSection.literalButton(
"directory", I18n["instance.directory"] "directory", I18n["instance.directory"]
@ -127,7 +125,7 @@ class InstanceListEntryFactory(app: Application?, instanceList: List<Instance>)
}.iconName = "edit-delete-symbolic" }.iconName = "edit-delete-symbolic"
val dc = Consumer { s: Signal<*> -> val dc = Consumer { s: Signal<*> ->
toDisconnect.computeIfAbsent(li.instance.id) { _ -> HashSet() } toDisconnect.computeIfAbsent(li.instanceId) { _ -> HashSet() }
.add(s) .add(s)
} }
@ -135,39 +133,24 @@ class InstanceListEntryFactory(app: Application?, instanceList: List<Instance>)
} }
onUnbind { onUnbind {
val li = Decomposed.of(it as ListItem, instanceList) val li = Decomposed.of(it as ListItem, instanceList)
li.popoverMenu.insertActionGroup(li.instance.id, null) li.popoverMenu.insertActionGroup(li.instanceId, null)
toDisconnect[li.instance.id]!! toDisconnect[li.instanceId]?.forEach(Consumer { obj: Signal<*> -> obj.disconnect() })
.forEach(Consumer { obj: Signal<*> -> obj.disconnect() })
} }
} }
private class Decomposed( private class Decomposed(
item: ListItem, val item: ListItem,
instance: Instance, val instanceId: String,
row: ActionRow, val instance: Instance?,
thumbnail: InstanceThumbnail, val row: ActionRow,
launch: Button, val thumbnail: InstanceThumbnail,
popoverMenu: PopoverMenu val launch: Button,
) {
val item: ListItem
val instance: Instance
val row: ActionRow
val thumbnail: InstanceThumbnail
val launch: Button
val popoverMenu: PopoverMenu val popoverMenu: PopoverMenu
) {
init {
this.item = item
this.instance = instance
this.row = row
this.thumbnail = thumbnail
this.launch = launch
this.popoverMenu = popoverMenu
}
companion object { companion object {
fun of(item: ListItem, instanceList: List<Instance>): Decomposed { 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 row = item.child as ActionRow
val prefixes = row.firstChild!!.firstChild as Box val prefixes = row.firstChild!!.firstChild as Box
val suffixes = row.firstChild!!.lastChild 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 launch = suffixes.firstChild as Button
val menuButton = launch.nextSibling as MenuButton val menuButton = launch.nextSibling as MenuButton
val popoverMenu = menuButton.popover as PopoverMenu 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 package io.gitlab.jfronny.inceptum.gtk.control
import io.gitlab.jfronny.inceptum.gtk.util.I18n
import org.gnome.gtk.DropDown import org.gnome.gtk.DropDown
import org.gnome.gtk.PropertyExpression 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 java.util.ArrayList import java.util.ArrayList
import java.util.function.IntConsumer import java.util.function.IntConsumer
@ -29,4 +31,7 @@ class KDropDown<T>(options: Array<T>, private val stringify: (T) -> String, sele
companion object { companion object {
private fun <T> Array<T>.toModel(stringify: (T) -> String) = StringList(map(stringify).toTypedArray()) 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.commons.StringFormatter
import io.gitlab.jfronny.inceptum.gtk.GtkEnvBackend import io.gitlab.jfronny.inceptum.gtk.GtkEnvBackend
import io.gitlab.jfronny.inceptum.gtk.control.ILabel import org.gnome.gtk.Widget
import io.gitlab.jfronny.inceptum.gtk.util.I18n import org.gnome.gtk.Window
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()
}
open class SettingsTab<T : Widget>(
protected val window: Window?,
val content: T
) {
protected fun showError(message: String, t: Throwable) { protected fun showError(message: String, t: Throwable) {
GtkEnvBackend.simpleDialog( GtkEnvBackend.simpleDialog(
window, window,

View File

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

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.inceptum.gtk.window.settings.instance package io.gitlab.jfronny.inceptum.gtk.window.settings.instance
import io.gitlab.jfronny.inceptum.common.Utils 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.schedule
import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.I18n
import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog
@ -13,7 +13,7 @@ import org.gnome.gio.Cancellable
import org.gnome.gtk.* import org.gnome.gtk.*
import java.nio.file.Path 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 { init {
section(null) { section(null) {
row("instance.settings.export.version", "instance.settings.export.version.subtitle") { 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.MetaHolder
import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.common.Utils
import io.gitlab.jfronny.inceptum.gtk.control.ILabel 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.I18n
import io.gitlab.jfronny.inceptum.gtk.util.Memory import io.gitlab.jfronny.inceptum.gtk.util.Memory
import io.gitlab.jfronny.inceptum.gtk.util.markup import io.gitlab.jfronny.inceptum.gtk.util.markup
import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray 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.FabricMetaApi
import io.gitlab.jfronny.inceptum.launcher.api.McApi 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.Instance
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList
import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceNameTool 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.nio.file.Path
import java.util.* import java.util.*
class GeneralTab(instance: Instance, window: InstanceSettingsWindow) : SettingsTab(window) { class GeneralTab(instance: Instance, window: InstanceSettingsWindow) : SectionedSettingsTab(window) {
companion object { companion object {
private val VERSIONS = McApi.getVersions() private val VERSIONS = McApi.getVersions()
} }

View File

@ -1,12 +1,55 @@
package io.gitlab.jfronny.inceptum.gtk.window.settings.instance package io.gitlab.jfronny.inceptum.gtk.window.settings.instance
import io.gitlab.jfronny.inceptum.gtk.control.ILabel 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.gtk.control.settings.SettingsTab
import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance 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 { init {
append(ILabel("instance.settings.mods.unsupported")) content.apply {
//TODO implement this, somehow 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.GtkMenubar
import io.gitlab.jfronny.inceptum.gtk.control.ILabel 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.util.margin
import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog
import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager
import org.gnome.gtk.* import org.gnome.gtk.*
class AccountsTab(window: Window?) : SettingsTab(window) { class AccountsTab(window: Window?) : SectionedSettingsTab(window) {
init { init {
section(null) { section(null) {
build() build()
@ -51,7 +51,7 @@ class AccountsTab(window: Window?) : SettingsTab(window) {
remove.halign = Align.END remove.halign = Align.END
remove.onClicked { remove.onClicked {
AccountManager.removeAccount(account) AccountManager.removeAccount(account)
remove(ref) remove(ref!!)
GtkMenubar.generateAccountsMenu(window!!.application!!) GtkMenubar.generateAccountsMenu(window!!.application!!)
} }
row.append(remove) 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.InceptumConfig
import io.gitlab.jfronny.inceptum.common.model.inceptum.UpdateChannel 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 import org.gnome.gtk.Window
class GeneralTab(window: Window?) : SettingsTab(window) { class GeneralTab(window: Window?) : SectionedSettingsTab(window) {
init { init {
section(null) { section(null) {
row("settings.general.snapshots", "settings.general.snapshots.subtitle") { 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.url.error=Could not import Instance
menu.file.new.file=From File menu.file.new.file=From File
menu.file.new.file.error=Could not import Instance 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.url.error=Konnte Instanz nicht importieren
menu.file.new.file=Aus einer Datei menu.file.new.file=Aus einer Datei
menu.file.new.file.error=Konnte Instanz nicht importieren 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