mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-10 12:26:16 -04:00
Added custom game directory. Closes #199
This commit is contained in:
parent
41337f66a8
commit
5f7f885d99
@ -56,6 +56,7 @@ class HMCLGameRepository(val profile: Profile, baseDirectory: File)
|
|||||||
return when (vs.gameDirType) {
|
return when (vs.gameDirType) {
|
||||||
EnumGameDirectory.VERSION_FOLDER -> getVersionRoot(id)
|
EnumGameDirectory.VERSION_FOLDER -> getVersionRoot(id)
|
||||||
EnumGameDirectory.ROOT_FOLDER -> super.getRunDirectory(id)
|
EnumGameDirectory.ROOT_FOLDER -> super.getRunDirectory(id)
|
||||||
|
EnumGameDirectory.CUSTOM -> File(vs.gameDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,5 +19,6 @@ package org.jackhuang.hmcl.setting
|
|||||||
|
|
||||||
enum class EnumGameDirectory {
|
enum class EnumGameDirectory {
|
||||||
ROOT_FOLDER,
|
ROOT_FOLDER,
|
||||||
VERSION_FOLDER
|
VERSION_FOLDER,
|
||||||
|
CUSTOM
|
||||||
}
|
}
|
@ -166,9 +166,15 @@ class VersionSetting() {
|
|||||||
* 0 - .minecraft<br/>
|
* 0 - .minecraft<br/>
|
||||||
* 1 - .minecraft/versions/<version>/<br/>
|
* 1 - .minecraft/versions/<version>/<br/>
|
||||||
*/
|
*/
|
||||||
val gameDirTypeProperty = ImmediateObjectProperty<EnumGameDirectory>(this, "gameDirTypeProperty", EnumGameDirectory.ROOT_FOLDER)
|
val gameDirTypeProperty = ImmediateObjectProperty<EnumGameDirectory>(this, "gameDirType", EnumGameDirectory.ROOT_FOLDER)
|
||||||
var gameDirType: EnumGameDirectory by gameDirTypeProperty
|
var gameDirType: EnumGameDirectory by gameDirTypeProperty
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Your custom gameDir
|
||||||
|
*/
|
||||||
|
val gameDirProperty = ImmediateStringProperty(this, "gameDir", "")
|
||||||
|
var gameDir: String by gameDirProperty
|
||||||
|
|
||||||
// launcher settings
|
// launcher settings
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,6 +226,7 @@ class VersionSetting() {
|
|||||||
widthProperty.addListener(listener)
|
widthProperty.addListener(listener)
|
||||||
heightProperty.addListener(listener)
|
heightProperty.addListener(listener)
|
||||||
gameDirTypeProperty.addListener(listener)
|
gameDirTypeProperty.addListener(listener)
|
||||||
|
gameDirProperty.addListener(listener)
|
||||||
launcherVisibilityProperty.addListener(listener)
|
launcherVisibilityProperty.addListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +279,7 @@ class VersionSetting() {
|
|||||||
addProperty("notCheckGame", src.notCheckGame)
|
addProperty("notCheckGame", src.notCheckGame)
|
||||||
addProperty("noCommon", src.noCommon)
|
addProperty("noCommon", src.noCommon)
|
||||||
addProperty("showLogs", src.showLogs)
|
addProperty("showLogs", src.showLogs)
|
||||||
|
addProperty("gameDir", src.gameDir)
|
||||||
addProperty("launcherVisibility", src.launcherVisibility.ordinal)
|
addProperty("launcherVisibility", src.launcherVisibility.ordinal)
|
||||||
addProperty("gameDirType", src.gameDirType.ordinal)
|
addProperty("gameDirType", src.gameDirType.ordinal)
|
||||||
}
|
}
|
||||||
@ -299,6 +307,7 @@ class VersionSetting() {
|
|||||||
serverIp = json["serverIp"]?.asString ?: ""
|
serverIp = json["serverIp"]?.asString ?: ""
|
||||||
java = json["java"]?.asString ?: ""
|
java = json["java"]?.asString ?: ""
|
||||||
wrapper = json["wrapper"]?.asString ?: ""
|
wrapper = json["wrapper"]?.asString ?: ""
|
||||||
|
gameDir = json["gameDir"]?.asString ?: ""
|
||||||
fullscreen = json["fullscreen"]?.asBoolean ?: false
|
fullscreen = json["fullscreen"]?.asBoolean ?: false
|
||||||
noJVMArgs = json["noJVMArgs"]?.asBoolean ?: false
|
noJVMArgs = json["noJVMArgs"]?.asBoolean ?: false
|
||||||
notCheckGame = json["notCheckGame"]?.asBoolean ?: false
|
notCheckGame = json["notCheckGame"]?.asBoolean ?: false
|
||||||
|
@ -61,4 +61,5 @@ object SVG {
|
|||||||
fun launch(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M1008 6.286q18.857 13.714 15.429 36.571l-146.286 877.714q-2.857 16.571-18.286 25.714-8 4.571-17.714 4.571-6.286 0-13.714-2.857l-258.857-105.714-138.286 168.571q-10.286 13.143-28 13.143-7.429 0-12.571-2.286-10.857-4-17.429-13.429t-6.571-20.857v-199.429l493.714-605.143-610.857 528.571-225.714-92.571q-21.143-8-22.857-31.429-1.143-22.857 18.286-33.714l950.857-548.571q8.571-5.143 18.286-5.14311.429 0 20.571 6.286z", fill, width, height)
|
fun launch(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M1008 6.286q18.857 13.714 15.429 36.571l-146.286 877.714q-2.857 16.571-18.286 25.714-8 4.571-17.714 4.571-6.286 0-13.714-2.857l-258.857-105.714-138.286 168.571q-10.286 13.143-28 13.143-7.429 0-12.571-2.286-10.857-4-17.429-13.429t-6.571-20.857v-199.429l493.714-605.143-610.857 528.571-225.714-92.571q-21.143-8-22.857-31.429-1.143-22.857 18.286-33.714l950.857-548.571q8.571-5.143 18.286-5.14311.429 0 20.571 6.286z", fill, width, height)
|
||||||
fun pencil(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M20.71,4.04C21.1,3.65 21.1,3 20.71,2.63L18.37,0.29C18,-0.1 17.35,-0.1 16.96,0.29L15,2.25L18.75,6M17.75,7L14,3.25L4,13.25V17H7.75L17.75,7Z", fill, width, height)
|
fun pencil(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M20.71,4.04C21.1,3.65 21.1,3 20.71,2.63L18.37,0.29C18,-0.1 17.35,-0.1 16.96,0.29L15,2.25L18.75,6M17.75,7L14,3.25L4,13.25V17H7.75L17.75,7Z", fill, width, height)
|
||||||
fun refresh(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z", fill, width, height)
|
fun refresh(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z", fill, width, height)
|
||||||
|
fun folderOpen(fill: String = "white", width: Double = 20.0, height: Double = 20.0) = createSVGPath("M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z", fill, width, height)
|
||||||
}
|
}
|
@ -33,11 +33,13 @@ import javafx.scene.layout.VBox
|
|||||||
import javafx.stage.DirectoryChooser
|
import javafx.stage.DirectoryChooser
|
||||||
import javafx.stage.FileChooser
|
import javafx.stage.FileChooser
|
||||||
import org.jackhuang.hmcl.i18n
|
import org.jackhuang.hmcl.i18n
|
||||||
|
import org.jackhuang.hmcl.setting.EnumGameDirectory
|
||||||
import org.jackhuang.hmcl.setting.Profile
|
import org.jackhuang.hmcl.setting.Profile
|
||||||
import org.jackhuang.hmcl.setting.VersionSetting
|
import org.jackhuang.hmcl.setting.VersionSetting
|
||||||
import org.jackhuang.hmcl.task.Scheduler
|
import org.jackhuang.hmcl.task.Scheduler
|
||||||
import org.jackhuang.hmcl.task.task
|
import org.jackhuang.hmcl.task.task
|
||||||
import org.jackhuang.hmcl.ui.construct.ComponentList
|
import org.jackhuang.hmcl.ui.construct.ComponentList
|
||||||
|
import org.jackhuang.hmcl.ui.construct.MultiFileItem
|
||||||
import org.jackhuang.hmcl.ui.construct.NumberValidator
|
import org.jackhuang.hmcl.ui.construct.NumberValidator
|
||||||
import org.jackhuang.hmcl.util.JavaVersion
|
import org.jackhuang.hmcl.util.JavaVersion
|
||||||
import org.jackhuang.hmcl.util.OS
|
import org.jackhuang.hmcl.util.OS
|
||||||
@ -55,20 +57,15 @@ class VersionSettingsController {
|
|||||||
@FXML lateinit var txtWrapper: JFXTextField
|
@FXML lateinit var txtWrapper: JFXTextField
|
||||||
@FXML lateinit var txtPrecallingCommand: JFXTextField
|
@FXML lateinit var txtPrecallingCommand: JFXTextField
|
||||||
@FXML lateinit var txtServerIP: JFXTextField
|
@FXML lateinit var txtServerIP: JFXTextField
|
||||||
@FXML lateinit var txtJavaDir: JFXTextField
|
|
||||||
@FXML lateinit var advancedSettingsPane: ComponentList
|
@FXML lateinit var advancedSettingsPane: ComponentList
|
||||||
@FXML lateinit var cboLauncherVisibility: JFXComboBox<*>
|
@FXML lateinit var cboLauncherVisibility: JFXComboBox<*>
|
||||||
@FXML lateinit var cboRunDirectory: JFXComboBox<*>
|
|
||||||
@FXML lateinit var chkFullscreen: JFXCheckBox
|
@FXML lateinit var chkFullscreen: JFXCheckBox
|
||||||
@FXML lateinit var lblPhysicalMemory: Label
|
@FXML lateinit var lblPhysicalMemory: Label
|
||||||
@FXML lateinit var chkNoJVMArgs: JFXToggleButton
|
@FXML lateinit var chkNoJVMArgs: JFXToggleButton
|
||||||
@FXML lateinit var chkNoCommon: JFXToggleButton
|
@FXML lateinit var chkNoCommon: JFXToggleButton
|
||||||
@FXML lateinit var chkNoGameCheck: JFXToggleButton
|
@FXML lateinit var chkNoGameCheck: JFXToggleButton
|
||||||
@FXML lateinit var componentJava: ComponentList
|
@FXML lateinit var javaItem: MultiFileItem
|
||||||
@FXML lateinit var javaPane: VBox
|
@FXML lateinit var gameDirItem: MultiFileItem
|
||||||
@FXML lateinit var javaPaneCustom: BorderPane
|
|
||||||
@FXML lateinit var radioCustom: JFXRadioButton
|
|
||||||
@FXML lateinit var btnJavaSelect: JFXButton
|
|
||||||
@FXML lateinit var chkShowLogs: JFXToggleButton
|
@FXML lateinit var chkShowLogs: JFXToggleButton
|
||||||
@FXML lateinit var btnIconSelection: JFXButton
|
@FXML lateinit var btnIconSelection: JFXButton
|
||||||
@FXML lateinit var iconView: ImageView
|
@FXML lateinit var iconView: ImageView
|
||||||
@ -76,9 +73,6 @@ class VersionSettingsController {
|
|||||||
lateinit var profile: Profile
|
lateinit var profile: Profile
|
||||||
lateinit var versionId: String
|
lateinit var versionId: String
|
||||||
|
|
||||||
val javaGroup = ToggleGroup()
|
|
||||||
|
|
||||||
|
|
||||||
fun initialize() {
|
fun initialize() {
|
||||||
lblPhysicalMemory.text = i18n("settings.physical_memory") + ": ${OS.TOTAL_MEMORY}MB"
|
lblPhysicalMemory.text = i18n("settings.physical_memory") + ": ${OS.TOTAL_MEMORY}MB"
|
||||||
|
|
||||||
@ -88,7 +82,6 @@ class VersionSettingsController {
|
|||||||
//txtJavaDir.limitWidth(limit)
|
//txtJavaDir.limitWidth(limit)
|
||||||
txtMaxMemory.limitWidth(limit)
|
txtMaxMemory.limitWidth(limit)
|
||||||
cboLauncherVisibility.limitWidth(limit)
|
cboLauncherVisibility.limitWidth(limit)
|
||||||
cboRunDirectory.limitWidth(limit)
|
|
||||||
|
|
||||||
val limitHeight = 10.0
|
val limitHeight = 10.0
|
||||||
chkNoJVMArgs.limitHeight(limitHeight)
|
chkNoJVMArgs.limitHeight(limitHeight)
|
||||||
@ -107,37 +100,18 @@ class VersionSettingsController {
|
|||||||
txtMetaspace.setValidators(validator(true))
|
txtMetaspace.setValidators(validator(true))
|
||||||
txtMetaspace.setValidateWhileTextChanged()
|
txtMetaspace.setValidateWhileTextChanged()
|
||||||
|
|
||||||
javaPaneCustom.limitHeight(20.0)
|
|
||||||
radioCustom.toggleGroup = javaGroup
|
|
||||||
txtJavaDir.disableProperty().bind(radioCustom.selectedProperty().not())
|
|
||||||
btnJavaSelect.disableProperty().bind(radioCustom.selectedProperty().not())
|
|
||||||
|
|
||||||
task {
|
task {
|
||||||
val list = mutableListOf<Node>()
|
it["list"] = JavaVersion.getJREs().values.map { javaVersion ->
|
||||||
list += createJavaPane(JavaVersion.fromCurrentEnvironment(), javaGroup)
|
javaItem.createChildren(javaVersion.longVersion, javaVersion.binary.absolutePath, javaVersion)
|
||||||
JavaVersion.getJREs().values.forEach { javaVersion ->
|
|
||||||
list += createJavaPane(javaVersion, javaGroup)
|
|
||||||
}
|
}
|
||||||
list += javaPaneCustom
|
|
||||||
it["list"] = list
|
|
||||||
}.subscribe(Scheduler.JAVAFX) {
|
}.subscribe(Scheduler.JAVAFX) {
|
||||||
javaPane.children.setAll(it.get<List<Node>>("list"))
|
javaItem.loadChildren(it.get<Collection<Node>>("list"))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun createJavaPane(java: JavaVersion, group: ToggleGroup): Pane {
|
gameDirItem.loadChildren(listOf(
|
||||||
return BorderPane().apply {
|
gameDirItem.createChildren(i18n("advancedsettings.game_dir.default"), userData = EnumGameDirectory.ROOT_FOLDER),
|
||||||
style = "-fx-padding: 3;"
|
gameDirItem.createChildren(i18n("advancedsettings.game_dir.independent"), userData = EnumGameDirectory.VERSION_FOLDER)
|
||||||
limitHeight(20.0)
|
))
|
||||||
left = JFXRadioButton(java.longVersion).apply {
|
|
||||||
toggleGroup = group
|
|
||||||
userData = java
|
|
||||||
}
|
|
||||||
right = Label(java.binary.absolutePath).apply {
|
|
||||||
styleClass += "subtitle-label"
|
|
||||||
style += "-fx-font-size: 10;"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadVersionSetting(profile: Profile, versionId: String, version: VersionSetting) {
|
fun loadVersionSetting(profile: Profile, versionId: String, version: VersionSetting) {
|
||||||
@ -162,13 +136,13 @@ class VersionSettingsController {
|
|||||||
javaDirProperty.unbind()
|
javaDirProperty.unbind()
|
||||||
showLogsProperty.unbind()
|
showLogsProperty.unbind()
|
||||||
unbindEnum(cboLauncherVisibility)
|
unbindEnum(cboLauncherVisibility)
|
||||||
unbindEnum(cboRunDirectory)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bindInt(txtWidth, version.widthProperty)
|
bindInt(txtWidth, version.widthProperty)
|
||||||
bindInt(txtHeight, version.heightProperty)
|
bindInt(txtHeight, version.heightProperty)
|
||||||
bindInt(txtMaxMemory, version.maxMemoryProperty)
|
bindInt(txtMaxMemory, version.maxMemoryProperty)
|
||||||
bindString(txtJavaDir, version.javaDirProperty)
|
bindString(javaItem.txtCustom, version.javaDirProperty)
|
||||||
|
bindString(gameDirItem.txtCustom, version.gameDirProperty)
|
||||||
bindString(txtJVMArgs, version.javaArgsProperty)
|
bindString(txtJVMArgs, version.javaArgsProperty)
|
||||||
bindString(txtGameArgs, version.minecraftArgsProperty)
|
bindString(txtGameArgs, version.minecraftArgsProperty)
|
||||||
bindString(txtMetaspace, version.permSizeProperty)
|
bindString(txtMetaspace, version.permSizeProperty)
|
||||||
@ -176,7 +150,6 @@ class VersionSettingsController {
|
|||||||
bindString(txtPrecallingCommand, version.precalledCommandProperty)
|
bindString(txtPrecallingCommand, version.precalledCommandProperty)
|
||||||
bindString(txtServerIP, version.serverIpProperty)
|
bindString(txtServerIP, version.serverIpProperty)
|
||||||
bindEnum(cboLauncherVisibility, version.launcherVisibilityProperty)
|
bindEnum(cboLauncherVisibility, version.launcherVisibilityProperty)
|
||||||
bindEnum(cboRunDirectory, version.gameDirTypeProperty)
|
|
||||||
bindBoolean(chkFullscreen, version.fullscreenProperty)
|
bindBoolean(chkFullscreen, version.fullscreenProperty)
|
||||||
bindBoolean(chkNoGameCheck, version.notCheckGameProperty)
|
bindBoolean(chkNoGameCheck, version.notCheckGameProperty)
|
||||||
bindBoolean(chkNoCommon, version.noCommonProperty)
|
bindBoolean(chkNoCommon, version.noCommonProperty)
|
||||||
@ -184,29 +157,30 @@ class VersionSettingsController {
|
|||||||
|
|
||||||
val javaGroupKey = "java_group.listener"
|
val javaGroupKey = "java_group.listener"
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
if (javaGroup.properties.containsKey(javaGroupKey))
|
(javaItem.group.properties[javaGroupKey] as? ChangeListener<in Toggle>?)
|
||||||
javaGroup.selectedToggleProperty().removeListener(javaGroup.properties[javaGroupKey] as ChangeListener<in Toggle>)
|
?.run(javaItem.group.selectedToggleProperty()::removeListener)
|
||||||
|
|
||||||
var flag = false
|
var flag = false
|
||||||
var defaultToggle: JFXRadioButton? = null
|
var defaultToggle: JFXRadioButton? = null
|
||||||
for (toggle in javaGroup.toggles)
|
var customToggle = javaItem.radioCustom
|
||||||
if (toggle is JFXRadioButton)
|
javaItem.group.toggles.filter { it is JFXRadioButton }.forEach { toggle ->
|
||||||
if (toggle.userData == version.javaVersion) {
|
if (toggle.userData == version.javaVersion) {
|
||||||
toggle.isSelected = true
|
toggle.isSelected = true
|
||||||
flag = true
|
flag = true
|
||||||
} else if (toggle.userData == JavaVersion.fromCurrentEnvironment()) {
|
} else if (toggle.userData == JavaVersion.fromCurrentEnvironment()) {
|
||||||
defaultToggle = toggle
|
defaultToggle = toggle as JFXRadioButton
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val listener = ChangeListener<Toggle> { _, _, newValue ->
|
val listener = ChangeListener<Toggle> { _, _, newValue ->
|
||||||
if (newValue == radioCustom) { // Custom
|
if (newValue == javaItem.radioCustom) { // Custom
|
||||||
version.java = "Custom"
|
version.java = "Custom"
|
||||||
} else {
|
} else {
|
||||||
version.java = ((newValue as JFXRadioButton).userData as JavaVersion).longVersion
|
version.java = ((newValue as JFXRadioButton).userData as JavaVersion).longVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
javaGroup.properties[javaGroupKey] = listener
|
javaItem.group.properties[javaGroupKey] = listener
|
||||||
javaGroup.selectedToggleProperty().addListener(listener)
|
javaItem.group.selectedToggleProperty().addListener(listener)
|
||||||
|
|
||||||
if (!flag) {
|
if (!flag) {
|
||||||
defaultToggle?.isSelected = true
|
defaultToggle?.isSelected = true
|
||||||
@ -216,6 +190,30 @@ class VersionSettingsController {
|
|||||||
version.javaProperty.setChangedListener { initJavaSubtitle(version) }
|
version.javaProperty.setChangedListener { initJavaSubtitle(version) }
|
||||||
initJavaSubtitle(version)
|
initJavaSubtitle(version)
|
||||||
|
|
||||||
|
val gameDirKey = "game_dir.listener"
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
(gameDirItem.group.properties[gameDirKey] as? ChangeListener<in Toggle>?)
|
||||||
|
?.run(gameDirItem.group.selectedToggleProperty()::removeListener)
|
||||||
|
|
||||||
|
gameDirItem.group.toggles.filter { it is JFXRadioButton }.forEach { toggle ->
|
||||||
|
if (toggle.userData == version.gameDirType) {
|
||||||
|
toggle.isSelected = true
|
||||||
|
flag = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gameDirItem.radioCustom.userData = EnumGameDirectory.CUSTOM
|
||||||
|
|
||||||
|
val gameDirListener = ChangeListener<Toggle> { _, _, newValue ->
|
||||||
|
version.gameDirType = (newValue as JFXRadioButton).userData as EnumGameDirectory
|
||||||
|
}
|
||||||
|
gameDirItem.group.properties[gameDirKey] = gameDirListener
|
||||||
|
gameDirItem.group.selectedToggleProperty().addListener(gameDirListener)
|
||||||
|
|
||||||
|
version.gameDirProperty.setChangedListener { initGameDirSubtitle(version) }
|
||||||
|
version.gameDirTypeProperty.setChangedListener { initGameDirSubtitle(version) }
|
||||||
|
initGameDirSubtitle(version)
|
||||||
|
|
||||||
lastVersionSetting = version
|
lastVersionSetting = version
|
||||||
|
|
||||||
loadIcon()
|
loadIcon()
|
||||||
@ -223,7 +221,11 @@ class VersionSettingsController {
|
|||||||
|
|
||||||
private fun initJavaSubtitle(version: VersionSetting) {
|
private fun initJavaSubtitle(version: VersionSetting) {
|
||||||
task { it["java"] = version.javaVersion }
|
task { it["java"] = version.javaVersion }
|
||||||
.subscribe(task(Scheduler.JAVAFX) { componentJava.subtitle = it.get<JavaVersion?>("java")?.binary?.absolutePath ?: "Invalid Java Directory" })
|
.subscribe(task(Scheduler.JAVAFX) { javaItem.subtitle = it.get<JavaVersion?>("java")?.binary?.absolutePath ?: "Invalid Java Directory" })
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initGameDirSubtitle(version: VersionSetting) {
|
||||||
|
gameDirItem.subtitle = profile.repository.getRunDirectory(versionId).absolutePath
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onShowAdvanced() {
|
fun onShowAdvanced() {
|
||||||
@ -233,14 +235,6 @@ class VersionSettingsController {
|
|||||||
rootPane.children.remove(advancedSettingsPane)
|
rootPane.children.remove(advancedSettingsPane)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onExploreJavaDir() {
|
|
||||||
val chooser = DirectoryChooser()
|
|
||||||
chooser.title = i18n("settings.choose_javapath")
|
|
||||||
val selectedDir = chooser.showDialog(Controllers.stage)
|
|
||||||
if (selectedDir != null)
|
|
||||||
txtJavaDir.text = selectedDir.absolutePath
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onExploreIcon() {
|
fun onExploreIcon() {
|
||||||
val chooser = FileChooser()
|
val chooser = FileChooser()
|
||||||
chooser.extensionFilters += FileChooser.ExtensionFilter("Image", "*.png")
|
chooser.extensionFilters += FileChooser.ExtensionFilter("Image", "*.png")
|
||||||
|
@ -32,9 +32,9 @@ import kotlin.collections.plusAssign
|
|||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
@DefaultProperty("content")
|
@DefaultProperty("content")
|
||||||
class ComponentList: StackPane() {
|
open class ComponentList: StackPane() {
|
||||||
|
|
||||||
val vbox: VBox
|
val vbox = VBox()
|
||||||
|
|
||||||
val content: ObservableList<Node> = FXCollections.observableArrayList<Node>().apply {
|
val content: ObservableList<Node> = FXCollections.observableArrayList<Node>().apply {
|
||||||
addListener { change: ListChangeListener.Change<out Node> ->
|
addListener { change: ListChangeListener.Change<out Node> ->
|
||||||
@ -47,8 +47,6 @@ class ComponentList: StackPane() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
vbox = VBox().apply {
|
|
||||||
}
|
|
||||||
children.setAll(vbox)
|
children.setAll(vbox)
|
||||||
|
|
||||||
styleClass += "options-list"
|
styleClass += "options-list"
|
||||||
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.ui.construct
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXButton
|
||||||
|
import com.jfoenix.controls.JFXRadioButton
|
||||||
|
import com.jfoenix.controls.JFXTextField
|
||||||
|
import javafx.beans.property.SimpleStringProperty
|
||||||
|
import javafx.geometry.Pos
|
||||||
|
import javafx.scene.Node
|
||||||
|
import javafx.scene.control.Label
|
||||||
|
import javafx.scene.control.ToggleGroup
|
||||||
|
import javafx.scene.layout.BorderPane
|
||||||
|
import javafx.scene.layout.HBox
|
||||||
|
import javafx.scene.layout.VBox
|
||||||
|
import javafx.stage.DirectoryChooser
|
||||||
|
import org.jackhuang.hmcl.i18n
|
||||||
|
import org.jackhuang.hmcl.ui.Controllers
|
||||||
|
import org.jackhuang.hmcl.ui.SVG
|
||||||
|
import org.jackhuang.hmcl.ui.limitHeight
|
||||||
|
import org.jackhuang.hmcl.util.*
|
||||||
|
|
||||||
|
class MultiFileItem : ComponentList() {
|
||||||
|
val customTextProperty = SimpleStringProperty(this, "customText", "Custom")
|
||||||
|
var customText by customTextProperty
|
||||||
|
|
||||||
|
val chooserTitleProperty = SimpleStringProperty(this, "chooserTitle", "Select a file")
|
||||||
|
var chooserTitle by chooserTitleProperty
|
||||||
|
|
||||||
|
val group = ToggleGroup()
|
||||||
|
val txtCustom = JFXTextField().apply {
|
||||||
|
BorderPane.setAlignment(this, Pos.CENTER_RIGHT)
|
||||||
|
}
|
||||||
|
val btnSelect = JFXButton().apply {
|
||||||
|
graphic = SVG.folderOpen("black", 15.0, 15.0)
|
||||||
|
setOnMouseClicked {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val radioCustom = JFXRadioButton().apply {
|
||||||
|
textProperty().bind(customTextProperty)
|
||||||
|
toggleGroup = group
|
||||||
|
}
|
||||||
|
val custom = BorderPane().apply {
|
||||||
|
left = radioCustom
|
||||||
|
style = "-fx-padding: 3;"
|
||||||
|
right = HBox().apply {
|
||||||
|
spacing = 3.0
|
||||||
|
children += txtCustom
|
||||||
|
children += btnSelect
|
||||||
|
}
|
||||||
|
limitHeight(20.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
val pane = VBox().apply {
|
||||||
|
style = "-fx-padding: 0 0 10 0;"
|
||||||
|
spacing = 8.0
|
||||||
|
children += custom
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
addChildren(pane)
|
||||||
|
|
||||||
|
txtCustom.disableProperty().bind(radioCustom.selectedProperty().not())
|
||||||
|
btnSelect.disableProperty().bind(radioCustom.selectedProperty().not())
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmOverloads
|
||||||
|
fun createChildren(title: String, subtitle: String = "", userData: Any? = null): Node {
|
||||||
|
return BorderPane().apply {
|
||||||
|
style = "-fx-padding: 3;"
|
||||||
|
limitHeight(20.0)
|
||||||
|
left = JFXRadioButton(title).apply {
|
||||||
|
toggleGroup = group
|
||||||
|
this.userData = userData
|
||||||
|
}
|
||||||
|
right = Label(subtitle).apply {
|
||||||
|
styleClass += "subtitle-label"
|
||||||
|
style += "-fx-font-size: 10;"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadChildren(list: Collection<Node>) {
|
||||||
|
pane.children.setAll(list)
|
||||||
|
pane.children += custom
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onExploreJavaDir() {
|
||||||
|
val chooser = DirectoryChooser()
|
||||||
|
chooser.title = i18n(chooserTitle)
|
||||||
|
val selectedDir = chooser.showDialog(Controllers.stage)
|
||||||
|
if (selectedDir != null)
|
||||||
|
txtCustom.text = selectedDir.absolutePath
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,7 @@
|
|||||||
<?import javafx.scene.image.ImageView?>
|
<?import javafx.scene.image.ImageView?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<?import org.jackhuang.hmcl.ui.construct.ComponentList?>
|
<?import org.jackhuang.hmcl.ui.construct.ComponentList?>
|
||||||
|
<?import org.jackhuang.hmcl.ui.construct.MultiFileItem?>
|
||||||
<StackPane xmlns="http://javafx.com/javafx"
|
<StackPane xmlns="http://javafx.com/javafx"
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
xmlns:fx="http://javafx.com/fxml"
|
||||||
fx:controller="org.jackhuang.hmcl.ui.VersionSettingsController">
|
fx:controller="org.jackhuang.hmcl.ui.VersionSettingsController">
|
||||||
@ -37,26 +38,11 @@
|
|||||||
</right>
|
</right>
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
|
|
||||||
<ComponentList fx:id="componentJava" title="%settings.java_dir"
|
<MultiFileItem fx:id="javaItem" title="%settings.java_dir" chooserTitle="%settings.choose_javapath"
|
||||||
hasSubtitle="true"> <!-- Java Directory -->
|
hasSubtitle="true" customText="%settings.custom" />
|
||||||
<VBox fx:id="javaPane" spacing="8" style="-fx-padding: 0 0 10 0;">
|
|
||||||
<BorderPane fx:id="javaPaneCustom" style="-fx-padding: 3;">
|
<MultiFileItem fx:id="gameDirItem" title="%settings.game_directory" chooserTitle="%settings.choose_gamedir"
|
||||||
<left>
|
hasSubtitle="true" customText="%settings.custom" />
|
||||||
<JFXRadioButton fx:id="radioCustom" text="%settings.custom"/>
|
|
||||||
</left>
|
|
||||||
<right>
|
|
||||||
<HBox spacing="3">
|
|
||||||
<JFXTextField fx:id="txtJavaDir" BorderPane.alignment="CENTER_RIGHT"/>
|
|
||||||
<JFXButton fx:id="btnJavaSelect" onMouseClicked="#onExploreJavaDir">
|
|
||||||
<graphic>
|
|
||||||
<fx:include source="/assets/svg/folder-open.fxml"/>
|
|
||||||
</graphic>
|
|
||||||
</JFXButton>
|
|
||||||
</HBox>
|
|
||||||
</right>
|
|
||||||
</BorderPane>
|
|
||||||
</VBox>
|
|
||||||
</ComponentList>
|
|
||||||
|
|
||||||
<BorderPane> <!-- Max Memory -->
|
<BorderPane> <!-- Max Memory -->
|
||||||
<left>
|
<left>
|
||||||
@ -88,22 +74,6 @@
|
|||||||
</right>
|
</right>
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
|
|
||||||
<BorderPane> <!-- Run Directory -->
|
|
||||||
<left>
|
|
||||||
<Label text="%settings.run_directory" BorderPane.alignment="CENTER_LEFT"/>
|
|
||||||
</left>
|
|
||||||
<right>
|
|
||||||
<JFXComboBox fx:id="cboRunDirectory" BorderPane.alignment="CENTER_RIGHT">
|
|
||||||
<items>
|
|
||||||
<FXCollections fx:factory="observableArrayList">
|
|
||||||
<Label text="%advancedsettings.game_dir.default"/>
|
|
||||||
<Label text="%advancedsettings.game_dir.independent"/>
|
|
||||||
</FXCollections>
|
|
||||||
</items>
|
|
||||||
</JFXComboBox>
|
|
||||||
</right>
|
|
||||||
</BorderPane>
|
|
||||||
|
|
||||||
<BorderPane> <!-- Dimension -->
|
<BorderPane> <!-- Dimension -->
|
||||||
<left>
|
<left>
|
||||||
<Label text="%settings.dimension" BorderPane.alignment="CENTER_LEFT"/>
|
<Label text="%settings.dimension" BorderPane.alignment="CENTER_LEFT"/>
|
||||||
|
@ -163,7 +163,7 @@ open class DefaultLauncher(repository: GameRepository, versionId: String, accoun
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Optional Minecraft arguments
|
// Optional Minecraft arguments
|
||||||
if (options.height != null && options.width != null) {
|
if (options.height != null && options.height != 0 && options.width != null && options.width != 0) {
|
||||||
res.add("--height")
|
res.add("--height")
|
||||||
res.add(options.height.toString())
|
res.add(options.height.toString())
|
||||||
res.add("--width")
|
res.add("--width")
|
||||||
|
@ -149,6 +149,7 @@ data class JavaVersion internal constructor(
|
|||||||
if (javas != null)
|
if (javas != null)
|
||||||
throw IllegalStateException("JavaVersions have already been initialized.")
|
throw IllegalStateException("JavaVersions have already been initialized.")
|
||||||
val temp = mutableMapOf<String, JavaVersion>()
|
val temp = mutableMapOf<String, JavaVersion>()
|
||||||
|
temp += currentJava.longVersion to currentJava
|
||||||
(when (OS.CURRENT_OS) {
|
(when (OS.CURRENT_OS) {
|
||||||
OS.WINDOWS -> queryWindows()
|
OS.WINDOWS -> queryWindows()
|
||||||
OS.OSX -> queryMacintosh()
|
OS.OSX -> queryMacintosh()
|
||||||
|
@ -34,3 +34,11 @@ fun <T> ObservableList<T>.onChange(op: (ListChangeListener.Change<out T>) -> Uni
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T> ObservableValue<*>.onInvalidated(op: () -> T) = apply { addListener { _ -> op() } }
|
fun <T> ObservableValue<*>.onInvalidated(op: () -> T) = apply { addListener { _ -> op() } }
|
||||||
|
|
||||||
|
fun <T> ObservableValue<T>.setOnChangeListener(properties: MutableMap<Any, Any>, key: String = "changeListener", changeListener: ChangeListener<in T>) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
if (properties.containsKey(key))
|
||||||
|
removeListener(properties[key] as ChangeListener<in T>)
|
||||||
|
properties[key] = changeListener
|
||||||
|
addListener(changeListener)
|
||||||
|
}
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,5 @@
|
|||||||
#Wed Jul 19 17:02:19 CST 2017
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
|
||||||
|
8
gradlew
vendored
8
gradlew
vendored
@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
|
|||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD="maximum"
|
||||||
|
|
||||||
warn ( ) {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
}
|
||||||
|
|
||||||
die ( ) {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
@ -155,7 +155,7 @@ if $cygwin ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Escape application args
|
||||||
save ( ) {
|
save () {
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
echo " "
|
echo " "
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ APP_ARGS=$(save "$@")
|
|||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
# by default we should be in the correct project dir, but when execute from Finder on Mac, the cwd is wrong
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
fi
|
fi
|
||||||
|
4
gradlew.bat
vendored
4
gradlew.bat
vendored
@ -5,7 +5,7 @@
|
|||||||
@rem
|
@rem
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
|
|
||||||
@rem Set local scope for the variables then windows NT shell
|
@rem Set local scope for the variables with windows NT shell
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
@ -69,7 +69,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables then windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
|
Loading…
x
Reference in New Issue
Block a user