use string list with IDs, fixes crash on remove, scaffold mods tab
This commit is contained in:
parent
7cefa88dcb
commit
55b9e5986f
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 }
|
|
@ -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
|
|
@ -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()
|
||||||
|
|
|
@ -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") {
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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") {
|
||||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue