mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-08 19:35:36 -04:00
Load mod list asynchronously
This commit is contained in:
parent
833247d133
commit
cc2c186e7f
@ -17,7 +17,7 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui
|
||||
|
||||
import com.jfoenix.effects.JFXDepthManager
|
||||
import com.jfoenix.controls.JFXTabPane
|
||||
import javafx.fxml.FXML
|
||||
import javafx.scene.control.ScrollPane
|
||||
import javafx.scene.input.TransferMode
|
||||
@ -29,11 +29,15 @@ import org.jackhuang.hmcl.mod.ModManager
|
||||
import org.jackhuang.hmcl.task.Scheduler
|
||||
import org.jackhuang.hmcl.task.task
|
||||
import org.jackhuang.hmcl.util.onChange
|
||||
import org.jackhuang.hmcl.util.onChangeAndOperateWeakly
|
||||
import java.util.*
|
||||
|
||||
class ModController {
|
||||
@FXML lateinit var scrollPane: ScrollPane
|
||||
@FXML lateinit var rootPane: StackPane
|
||||
@FXML lateinit var contentPane: VBox
|
||||
@FXML lateinit var modPane: VBox
|
||||
@FXML lateinit var contentPane: StackPane
|
||||
lateinit var parentTab: JFXTabPane
|
||||
private lateinit var modManager: ModManager
|
||||
private lateinit var versionId: String
|
||||
|
||||
@ -61,23 +65,36 @@ class ModController {
|
||||
this.modManager = modManager
|
||||
this.versionId = versionId
|
||||
task {
|
||||
modManager.refreshMods(versionId)
|
||||
}.subscribe(Scheduler.JAVAFX) {
|
||||
contentPane.children.clear()
|
||||
for (modInfo in modManager.getMods(versionId)) {
|
||||
contentPane.children += ModItem(modInfo) {
|
||||
modManager.removeMods(versionId, modInfo)
|
||||
loadMods(modManager, versionId)
|
||||
}.apply {
|
||||
modInfo.activeProperty.onChange {
|
||||
if (it)
|
||||
styleClass -= "disabled"
|
||||
else
|
||||
synchronized(contentPane) {
|
||||
runOnUiThread { rootPane.children -= contentPane }
|
||||
modManager.refreshMods(versionId)
|
||||
|
||||
// Surprisingly, if there are a great number of mods, this processing will cause a UI pause.
|
||||
// We must do this asynchronously.
|
||||
val list = LinkedList<ModItem>()
|
||||
for (modInfo in modManager.getMods(versionId)) {
|
||||
list += ModItem(modInfo) {
|
||||
modManager.removeMods(versionId, modInfo)
|
||||
loadMods(modManager, versionId)
|
||||
}.apply {
|
||||
modInfo.activeProperty.onChange {
|
||||
if (it)
|
||||
styleClass -= "disabled"
|
||||
else
|
||||
styleClass += "disabled"
|
||||
}
|
||||
|
||||
if (!modInfo.isActive)
|
||||
styleClass += "disabled"
|
||||
}
|
||||
|
||||
if (!modInfo.isActive)
|
||||
styleClass += "disabled"
|
||||
}
|
||||
runOnUiThread { rootPane.children += contentPane }
|
||||
it["list"] = list
|
||||
}
|
||||
}.subscribe(Scheduler.JAVAFX) { variables ->
|
||||
parentTab.selectionModel.selectedItemProperty().onChangeAndOperateWeakly {
|
||||
if (it?.userData == this) {
|
||||
modPane.children.setAll(variables.get<List<ModItem>>("list"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,11 +105,7 @@ class ModController {
|
||||
chooser.title = i18n("mods.choose_mod")
|
||||
chooser.extensionFilters.setAll(FileChooser.ExtensionFilter("Mod", "*.jar", "*.zip", "*.litemod"))
|
||||
val res = chooser.showOpenDialog(Controllers.stage) ?: return
|
||||
try {
|
||||
modManager.addMod(versionId, res)
|
||||
loadMods(modManager, versionId)
|
||||
} catch (e: Exception) {
|
||||
Controllers.dialog(i18n("mods.failed"))
|
||||
}
|
||||
task { modManager.addMod(versionId, res) }
|
||||
.subscribe(task(Scheduler.JAVAFX) { loadMods(modManager, versionId) })
|
||||
}
|
||||
}
|
@ -20,10 +20,12 @@ package org.jackhuang.hmcl.ui
|
||||
import com.jfoenix.controls.JFXButton
|
||||
import com.jfoenix.controls.JFXListView
|
||||
import com.jfoenix.controls.JFXPopup
|
||||
import com.jfoenix.controls.JFXTabPane
|
||||
import javafx.beans.property.SimpleStringProperty
|
||||
import javafx.beans.property.StringProperty
|
||||
import javafx.fxml.FXML
|
||||
import javafx.scene.control.Alert
|
||||
import javafx.scene.control.Tab
|
||||
import javafx.scene.control.Tooltip
|
||||
import javafx.scene.layout.StackPane
|
||||
import org.jackhuang.hmcl.download.game.GameAssetIndexDownloadTask
|
||||
@ -36,6 +38,7 @@ class VersionPage : StackPane(), DecoratorPage {
|
||||
override val titleProperty: StringProperty = SimpleStringProperty(this, "title", null)
|
||||
|
||||
@FXML lateinit var versionSettingsController: VersionSettingsController
|
||||
@FXML lateinit var modTab: Tab
|
||||
@FXML lateinit var modController: ModController
|
||||
@FXML lateinit var installerController: InstallerController
|
||||
|
||||
@ -46,6 +49,7 @@ class VersionPage : StackPane(), DecoratorPage {
|
||||
@FXML lateinit var btnExport: JFXButton
|
||||
@FXML lateinit var rootPane: StackPane
|
||||
@FXML lateinit var contentPane: StackPane
|
||||
@FXML lateinit var tabPane: JFXTabPane
|
||||
val browsePopup: JFXPopup
|
||||
val managementPopup: JFXPopup
|
||||
lateinit var profile: Profile
|
||||
@ -71,6 +75,8 @@ class VersionPage : StackPane(), DecoratorPage {
|
||||
titleProperty.set(i18n("launcher.title.game") + " - " + id)
|
||||
|
||||
versionSettingsController.loadVersionSetting(profile, id, profile.getVersionSetting(id))
|
||||
modController.parentTab = tabPane
|
||||
modTab.userData = modController
|
||||
modController.loadMods(profile.modManager, id)
|
||||
installerController.loadVersion(profile, id)
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ class VersionSettingsController {
|
||||
|
||||
private fun initJavaSubtitle(version: VersionSetting) {
|
||||
task { it["java"] = version.javaVersion }
|
||||
.then(task(Scheduler.JAVAFX) { componentJava.subtitle = it.get<JavaVersion?>("java")?.binary?.absolutePath ?: "Invalid Java Directory" })
|
||||
.subscribe(task(Scheduler.JAVAFX) { componentJava.subtitle = it.get<JavaVersion?>("java")?.binary?.absolutePath ?: "Invalid Java Directory" })
|
||||
}
|
||||
|
||||
fun onShowAdvanced() {
|
||||
|
@ -1,24 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import com.jfoenix.controls.JFXSpinner?>
|
||||
<StackPane xmlns="http://javafx.com/javafx"
|
||||
xmlns:fx="http://javafx.com/fxml"
|
||||
fx:id="rootPane"
|
||||
fx:controller="org.jackhuang.hmcl.ui.ModController">
|
||||
<ScrollPane fx:id="scrollPane" fitToWidth="true" fitToHeight="true">
|
||||
<VBox fx:id="contentPane" spacing="10" style="-fx-padding: 20;">
|
||||
<JFXSpinner style="-fx-radius:16" styleClass="materialDesign-purple, first-spinner" />
|
||||
<StackPane fx:id="contentPane">
|
||||
<ScrollPane fx:id="scrollPane" fitToWidth="true" fitToHeight="true">
|
||||
<VBox fx:id="modPane" spacing="10" style="-fx-padding: 20;">
|
||||
|
||||
</VBox>
|
||||
</ScrollPane>
|
||||
<VBox style="-fx-padding: 15;" spacing="15" pickOnBounds="false" alignment="BOTTOM_RIGHT">
|
||||
<JFXButton prefWidth="40" prefHeight="40" buttonType="RAISED" onMouseClicked="#onAdd"
|
||||
style="-fx-background-color:#5264AE;-fx-background-radius: 50px;">
|
||||
<graphic>
|
||||
<fx:include source="/assets/svg/plus.fxml"/>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
</VBox>
|
||||
</ScrollPane>
|
||||
<VBox style="-fx-padding: 15;" spacing="15" pickOnBounds="false" alignment="BOTTOM_RIGHT">
|
||||
<JFXButton prefWidth="40" prefHeight="40" buttonType="RAISED" onMouseClicked="#onAdd"
|
||||
style="-fx-background-color:#5264AE;-fx-background-radius: 50px;">
|
||||
<graphic>
|
||||
<fx:include source="/assets/svg/plus.fxml" />
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
</VBox>
|
||||
</StackPane>
|
||||
</StackPane>
|
||||
|
@ -10,11 +10,11 @@
|
||||
type="StackPane">
|
||||
<JFXRippler />
|
||||
<StackPane fx:id="contentPane">
|
||||
<JFXTabPane>
|
||||
<JFXTabPane fx:id="tabPane">
|
||||
<Tab text="%settings">
|
||||
<fx:include source="version-settings.fxml" fx:id="versionSettings"/>
|
||||
</Tab>
|
||||
<Tab text="%mods">
|
||||
<Tab fx:id="modTab" text="%mods">
|
||||
<fx:include source="mod.fxml" fx:id="mod"/>
|
||||
</Tab>
|
||||
<Tab text="%settings.tabs.installers">
|
||||
|
@ -23,6 +23,7 @@ import javafx.collections.ObservableList
|
||||
|
||||
fun <T> ObservableValue<T>.onChange(op: (T?) -> Unit) = apply { addListener { _, _, new -> op(new) } }
|
||||
fun <T> ObservableValue<T>.onChangeAndOperate(op: (T?) -> Unit) = apply { addListener { _, _, new -> op(new) }; op(value) }
|
||||
fun <T> ObservableValue<T>.onChangeAndOperateWeakly(op: (T?) -> Unit) = apply { addListener(WeakChangeListener { _, _, new -> op(new) }); op(value) }
|
||||
fun ObservableBooleanValue.onChange(op: (Boolean) -> Unit) = apply { addListener { _, _, new -> op(new ?: false) } }
|
||||
fun ObservableIntegerValue.onChange(op: (Int) -> Unit) = apply { addListener { _, _, new -> op((new ?: 0).toInt()) } }
|
||||
fun ObservableLongValue.onChange(op: (Long) -> Unit) = apply { addListener { _, _, new -> op((new ?: 0L).toLong()) } }
|
||||
|
Loading…
x
Reference in New Issue
Block a user