Icon selection

This commit is contained in:
huangyuhui 2017-08-25 08:54:33 +08:00
parent f532df20e6
commit 833247d133
16 changed files with 276 additions and 109 deletions

View File

@ -17,6 +17,7 @@
*/
package org.jackhuang.hmcl.game
import javafx.geometry.Rectangle2D
import javafx.scene.image.Image
import org.jackhuang.hmcl.Main
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount
@ -24,6 +25,7 @@ import org.jackhuang.hmcl.setting.Settings
import org.jackhuang.hmcl.task.FileDownloadTask
import org.jackhuang.hmcl.task.Scheduler
import org.jackhuang.hmcl.task.Task
import org.jackhuang.hmcl.ui.DEFAULT_ICON
import org.jackhuang.hmcl.ui.DialogController
import org.jackhuang.hmcl.util.toURL
import java.net.Proxy
@ -63,16 +65,20 @@ object AccountHelper {
}
private fun getSkinFile(name: String) = SKIN_DIR.resolve("$name.png")
private val DEFAULT_IMAGE = Image("/assets/img/icon.png")
fun getSkin(account: YggdrasilAccount, scaleRatio: Double = 1.0): Image {
if (account.selectedProfile == null) return DEFAULT_IMAGE
val name = account.selectedProfile?.name ?: return DEFAULT_IMAGE
if (account.selectedProfile == null) return DEFAULT_ICON
val name = account.selectedProfile?.name ?: return DEFAULT_ICON
val file = getSkinFile(name)
if (file.exists()) {
val original = Image("file:" + file.absolutePath)
return Image("file:" + file.absolutePath, original.width * scaleRatio, original.height * scaleRatio, false, false)
}
else return DEFAULT_IMAGE
else return DEFAULT_ICON
}
fun getViewport(scaleRatio: Double): Rectangle2D {
val size = 8.0 * scaleRatio
return Rectangle2D(size, size, size, size)
}
}

View File

@ -127,6 +127,9 @@ class HMCLGameRepository(val profile: Profile, baseDirectory: File)
return versionSettings[id]
}
fun getVersionIcon(id: String): File =
getVersionRoot(id).resolve("icon.png")
fun markVersionAsModpack(id: String) {
beingModpackVersions += id
}

View File

@ -98,11 +98,9 @@ class AccountItem(i: Int, val account: Account, group: ToggleGroup) : StackPane(
if (account !is YggdrasilAccount)
return
pgsSkin.isVisible = false
val size = 8.0 * 4
portraitView.viewport = Rectangle2D(size, size, size, size)
portraitView.viewport = AccountHelper.getViewport(4.0)
portraitView.image = AccountHelper.getSkin(account, 4.0)
portraitView.fitHeight = 32.0
portraitView.fitWidth = 32.0
portraitView.limitSize(32.0, 32.0)
}
private fun getDefaultColor(i: Int): String {

View File

@ -37,6 +37,7 @@ import org.jackhuang.hmcl.task.Scheduler
import org.jackhuang.hmcl.task.taskResult
import org.jackhuang.hmcl.ui.wizard.DecoratorPage
import org.jackhuang.hmcl.util.onChange
import org.jackhuang.hmcl.util.onChangeAndOperate
class AccountsPage() : StackPane(), DecoratorPage {
override val titleProperty: StringProperty = SimpleStringProperty(this, "title", "Accounts")
@ -69,7 +70,7 @@ class AccountsPage() : StackPane(), DecoratorPage {
txtPassword.setOnAction { onCreationAccept() }
txtUsername.setOnAction { onCreationAccept() }
Settings.selectedAccountProperty.setChangedListener { account ->
Settings.selectedAccountProperty.onChangeAndOperate { account ->
masonryPane.children.forEach { node ->
if (node is AccountItem) {
node.chkSelected.isSelected = account?.username == node.lblUser.text

View File

@ -33,6 +33,8 @@ import javafx.scene.Node
import javafx.scene.Parent
import javafx.scene.Scene
import javafx.scene.control.*
import javafx.scene.image.Image
import javafx.scene.image.ImageView
import javafx.scene.image.WritableImage
import javafx.scene.input.MouseEvent
import javafx.scene.input.ScrollEvent
@ -248,4 +250,19 @@ fun JFXTextField.setValidateWhileTextChanged() {
fun JFXPasswordField.setValidateWhileTextChanged() {
textProperty().addListener { _ -> validate() }
validate()
}
}
fun ImageView.limitSize(maxWidth: Double, maxHeight: Double) {
isPreserveRatio = true
imageProperty().onChangeAndOperate {
if (it != null && (it.width > maxWidth || it.height > maxHeight)) {
fitHeight = maxHeight
fitWidth = maxWidth
} else {
fitHeight = -1.0
fitWidth = -1.0
}
}
}
val DEFAULT_ICON = Image("/assets/img/icon.png")

View File

@ -19,10 +19,13 @@ package org.jackhuang.hmcl.ui
import com.jfoenix.controls.JFXComboBox
import javafx.scene.layout.VBox
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount
import org.jackhuang.hmcl.game.AccountHelper
import org.jackhuang.hmcl.i18n
import org.jackhuang.hmcl.setting.Settings
import org.jackhuang.hmcl.ui.construct.IconedItem
import org.jackhuang.hmcl.ui.construct.RipplerContainer
import org.jackhuang.hmcl.util.onChangeAndOperate
class LeftPaneController(private val leftPane: AdvancedListBox) {
val versionsPane = VBox()
@ -63,7 +66,7 @@ class LeftPaneController(private val leftPane: AdvancedListBox) {
}
Controllers.mainPane.buttonLaunch.setOnMouseClicked { LauncherHelper.launch() }*/
Settings.selectedAccountProperty.setChangedListener {
Settings.selectedAccountProperty.onChangeAndOperate {
if (it == null) {
accountItem.lblVersionName.text = "mojang@mojang.com"
accountItem.lblGameVersion.text = "Yggdrasil"
@ -71,6 +74,13 @@ class LeftPaneController(private val leftPane: AdvancedListBox) {
accountItem.lblVersionName.text = it.username
accountItem.lblGameVersion.text = accountType(it)
}
if (it is YggdrasilAccount) {
accountItem.imageView.image = AccountHelper.getSkin(it, 4.0)
accountItem.imageView.viewport = AccountHelper.getViewport(4.0)
} else {
accountItem.imageView.image = DEFAULT_ICON
accountItem.imageView.viewport = null
}
}
if (Settings.getAccounts().isEmpty())

View File

@ -25,6 +25,7 @@ import javafx.beans.property.StringProperty
import javafx.fxml.FXML
import javafx.scene.Node
import javafx.scene.control.ToggleGroup
import javafx.scene.image.Image
import javafx.scene.layout.StackPane
import org.jackhuang.hmcl.ProfileChangedEvent
import org.jackhuang.hmcl.ProfileLoadingEvent
@ -83,6 +84,9 @@ class MainPage : StackPane(), DecoratorPage {
Controllers.decorator.showPage(Controllers.versionPane)
Controllers.versionPane.load(version, profile)
}
val iconFile = profile.repository.getVersionIcon(version)
if (iconFile.exists())
iconView.image = Image("file:" + iconFile.absolutePath)
}
}

View File

@ -25,6 +25,7 @@ import javafx.scene.control.Label
import javafx.scene.control.ToggleGroup
import javafx.scene.effect.BlurType
import javafx.scene.effect.DropShadow
import javafx.scene.image.ImageView
import javafx.scene.layout.Pane
import javafx.scene.layout.StackPane
import javafx.scene.layout.VBox
@ -41,6 +42,7 @@ class VersionItem(i: Int, group: ToggleGroup) : StackPane() {
@FXML lateinit var lblVersionName: Label
@FXML lateinit var chkSelected: JFXRadioButton
@FXML lateinit var lblGameVersion: Label
@FXML lateinit var iconView: ImageView
init {
loadFXML("/assets/fxml/version-item.fxml")
@ -60,6 +62,7 @@ class VersionItem(i: Int, group: ToggleGroup) : StackPane() {
// create image view
icon.translateYProperty().bind(Bindings.createDoubleBinding(Callable { header.boundsInParent.height - icon.height }, header.boundsInParentProperty(), icon.heightProperty()))
iconView.limitSize(32.0, 32.0)
}
private fun getDefaultColor(i: Int): String {

View File

@ -20,13 +20,15 @@ package org.jackhuang.hmcl.ui
import javafx.fxml.FXML
import javafx.scene.control.Button
import javafx.scene.control.Label
import javafx.scene.image.ImageView
import javafx.scene.layout.StackPane
class VersionListItem(val versionName: String, val gameVersion: String) : StackPane() {
class VersionListItem(versionName: String, gameVersion: String) : StackPane() {
@FXML lateinit var lblVersionName: Label
@FXML lateinit var lblGameVersion: Label
@FXML lateinit var btnSettings: Button
@FXML lateinit var imageView: ImageView
@FXML lateinit var imageViewContainer: StackPane
private var handler: () -> Unit = {}
@ -34,6 +36,10 @@ class VersionListItem(val versionName: String, val gameVersion: String) : StackP
loadFXML("/assets/fxml/version-list-item.fxml")
lblVersionName.text = versionName
lblGameVersion.text = gameVersion
imageView.limitSize(32.0, 32.0)
imageViewContainer.limitWidth(32.0)
imageViewContainer.limitHeight(32.0)
}
fun onSettings() {

View File

@ -44,6 +44,8 @@ class VersionPage : StackPane(), DecoratorPage {
@FXML lateinit var btnBrowseMenu: JFXButton
@FXML lateinit var btnManagementMenu: JFXButton
@FXML lateinit var btnExport: JFXButton
@FXML lateinit var rootPane: StackPane
@FXML lateinit var contentPane: StackPane
val browsePopup: JFXPopup
val managementPopup: JFXPopup
lateinit var profile: Profile
@ -68,7 +70,7 @@ class VersionPage : StackPane(), DecoratorPage {
this.profile = profile
titleProperty.set(i18n("launcher.title.game") + " - " + id)
versionSettingsController.loadVersionSetting(profile.getVersionSetting(id))
versionSettingsController.loadVersionSetting(profile, id, profile.getVersionSetting(id))
modController.loadMods(profile.modManager, id)
installerController.loadVersion(profile, id)
}

View File

@ -18,19 +18,24 @@
package org.jackhuang.hmcl.ui
import com.jfoenix.controls.*
import javafx.beans.InvalidationListener
import javafx.beans.value.ChangeListener
import javafx.fxml.FXML
import javafx.scene.control.Label
import javafx.scene.control.ScrollPane
import javafx.scene.control.Toggle
import javafx.scene.control.ToggleGroup
import javafx.scene.image.Image
import javafx.scene.image.ImageView
import javafx.scene.layout.BorderPane
import javafx.scene.layout.Pane
import javafx.scene.layout.VBox
import javafx.stage.DirectoryChooser
import javafx.stage.FileChooser
import org.jackhuang.hmcl.i18n
import org.jackhuang.hmcl.setting.Profile
import org.jackhuang.hmcl.setting.VersionSetting
import org.jackhuang.hmcl.task.Scheduler
import org.jackhuang.hmcl.task.task
import org.jackhuang.hmcl.ui.construct.ComponentList
import org.jackhuang.hmcl.ui.construct.NumberValidator
import org.jackhuang.hmcl.util.JavaVersion
@ -64,9 +69,15 @@ class VersionSettingsController {
@FXML lateinit var radioCustom: JFXRadioButton
@FXML lateinit var btnJavaSelect: JFXButton
@FXML lateinit var chkShowLogs: JFXToggleButton
@FXML lateinit var btnIconSelection: JFXButton
@FXML lateinit var iconView: ImageView
lateinit var profile: Profile
lateinit var versionId: String
val javaGroup = ToggleGroup()
fun initialize() {
lblPhysicalMemory.text = i18n("settings.physical_memory") + ": ${OS.TOTAL_MEMORY}MB"
@ -122,9 +133,12 @@ class VersionSettingsController {
}
}
fun loadVersionSetting(version: VersionSetting) {
fun loadVersionSetting(profile: Profile, versionId: String, version: VersionSetting) {
rootPane.children -= advancedSettingsPane
this.profile = profile
this.versionId = versionId
lastVersionSetting?.apply {
widthProperty.unbind()
heightProperty.unbind()
@ -192,14 +206,17 @@ class VersionSettingsController {
}
version.javaDirProperty.setChangedListener { initJavaSubtitle(version) }
version.javaProperty.setChangedListener { initJavaSubtitle(version)}
version.javaProperty.setChangedListener { initJavaSubtitle(version) }
initJavaSubtitle(version)
lastVersionSetting = version
loadIcon()
}
private fun initJavaSubtitle(version: VersionSetting) {
componentJava.subtitle = version.javaVersion?.binary?.absolutePath ?: "Invalid Java Directory"
task { it["java"] = version.javaVersion }
.then(task(Scheduler.JAVAFX) { componentJava.subtitle = it.get<JavaVersion?>("java")?.binary?.absolutePath ?: "Invalid Java Directory" })
}
fun onShowAdvanced() {
@ -216,4 +233,24 @@ class VersionSettingsController {
if (selectedDir != null)
txtJavaDir.text = selectedDir.absolutePath
}
fun onExploreIcon() {
val chooser = FileChooser()
chooser.extensionFilters += FileChooser.ExtensionFilter("Image", "*.png")
val selectedFile = chooser.showOpenDialog(Controllers.stage)
if (selectedFile != null) {
val iconFile = profile.repository.getVersionIcon(versionId)
selectedFile.copyTo(iconFile, overwrite = true)
loadIcon()
}
}
private fun loadIcon() {
val iconFile = profile.repository.getVersionIcon(versionId)
if (iconFile.exists())
iconView.image = Image("file:" + iconFile.absolutePath)
else
iconView.image = DEFAULT_ICON
iconView.limitSize(32.0, 32.0)
}
}

View File

@ -42,7 +42,7 @@
</StackPane>
</VBox>
<StackPane fx:id="icon" StackPane.alignment="TOP_RIGHT" pickOnBounds="false">
<ImageView StackPane.alignment="CENTER_RIGHT">
<ImageView fx:id="iconView" StackPane.alignment="CENTER_RIGHT">
<StackPane.margin>
<Insets right="12" />
</StackPane.margin>

View File

@ -14,15 +14,17 @@
<BorderPane pickOnBounds="false">
<left>
<HBox alignment="CENTER" mouseTransparent="true">
<ImageView>
<StackPane fx:id="imageViewContainer">
<ImageView preserveRatio="true" fx:id="imageView" smooth="false">
<Image url="/assets/img/icon.png" requestedWidth="25" requestedHeight="25" />
</ImageView>
</StackPane>
<BorderPane style="-fx-padding: 0 0 0 10;">
<top>
<Label fx:id="lblVersionName" maxWidth="100" style="-fx-font-size: 15;" textAlignment="JUSTIFY" />
<Label fx:id="lblVersionName" maxWidth="90" style="-fx-font-size: 15;" textAlignment="JUSTIFY" />
</top>
<bottom>
<Label fx:id="lblGameVersion" maxWidth="100" style="-fx-font-size: 10;" textAlignment="JUSTIFY" />
<Label fx:id="lblGameVersion" maxWidth="90" style="-fx-font-size: 10;" textAlignment="JUSTIFY" />
</bottom>
</BorderPane>
</HBox>

View File

@ -1,36 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import com.jfoenix.controls.JFXTextField?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXCheckBox?>
<?import javafx.geometry.Insets?>
<?import com.jfoenix.controls.JFXComboBox?>
<?import com.jfoenix.controls.*?>
<?import javafx.collections.FXCollections?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.*?>
<?import org.jackhuang.hmcl.ui.construct.ComponentList?>
<?import com.jfoenix.controls.JFXToggleButton?>
<?import com.jfoenix.controls.JFXRadioButton?>
<StackPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.jackhuang.hmcl.ui.VersionSettingsController">
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.jackhuang.hmcl.ui.VersionSettingsController">
<ScrollPane fx:id="scroll" fitToHeight="true" fitToWidth="true">
<VBox fx:id="rootPane" style="-fx-padding: 20;">
<ComponentList depth="1">
<ComponentList fx:id="componentJava" title="%settings.java_dir" hasSubtitle="true"> <!-- Java Directory -->
<BorderPane> <!-- Icon -->
<left>
<Label text="settings.icon" />
</left>
<right>
<HBox alignment="CENTER_RIGHT" spacing="8">
<ImageView fx:id="iconView" smooth="false" preserveRatio="true">
<StackPane.margin>
<Insets right="12"/>
</StackPane.margin>
<Image url="/assets/img/icon.png"/>
</ImageView>
<JFXButton fx:id="btnIconSelection" onMouseClicked="#onExploreIcon" styleClass="toggle-icon4">
<graphic>
<fx:include source="/assets/svg/pencil.fxml" />
</graphic>
</JFXButton>
</HBox>
</right>
</BorderPane>
<ComponentList fx:id="componentJava" title="%settings.java_dir"
hasSubtitle="true"> <!-- Java Directory -->
<VBox fx:id="javaPane" spacing="8" style="-fx-padding: 0 0 10 0;">
<BorderPane fx:id="javaPaneCustom" style="-fx-padding: 3;">
<left>
<JFXRadioButton fx:id="radioCustom" text="%settings.custom" />
<JFXRadioButton fx:id="radioCustom" text="%settings.custom"/>
</left>
<right>
<HBox spacing="3">
<JFXTextField fx:id="txtJavaDir" BorderPane.alignment="CENTER_RIGHT" />
<JFXTextField fx:id="txtJavaDir" BorderPane.alignment="CENTER_RIGHT"/>
<JFXButton fx:id="btnJavaSelect" onMouseClicked="#onExploreJavaDir">
<graphic>
<fx:include source="/assets/svg/folder-open.fxml" />
<fx:include source="/assets/svg/folder-open.fxml"/>
</graphic>
</JFXButton>
</HBox>
@ -40,20 +59,29 @@
</ComponentList>
<BorderPane> <!-- Max Memory -->
<left><VBox><Label text="%settings.max_memory" BorderPane.alignment="CENTER_LEFT" /><Label fx:id="lblPhysicalMemory" styleClass="subtitle-label" /></VBox></left>
<right><JFXTextField fx:id="txtMaxMemory" BorderPane.alignment="CENTER_RIGHT" /></right>
<left>
<VBox>
<Label text="%settings.max_memory" BorderPane.alignment="CENTER_LEFT"/>
<Label fx:id="lblPhysicalMemory" styleClass="subtitle-label"/>
</VBox>
</left>
<right>
<JFXTextField fx:id="txtMaxMemory" BorderPane.alignment="CENTER_RIGHT"/>
</right>
</BorderPane>
<BorderPane> <!-- Launcher Visibility -->
<left><Label text="%advancedsettings.launcher_visible" BorderPane.alignment="CENTER_LEFT" /></left>
<left>
<Label text="%advancedsettings.launcher_visible" BorderPane.alignment="CENTER_LEFT"/>
</left>
<right>
<JFXComboBox fx:id="cboLauncherVisibility" BorderPane.alignment="CENTER_RIGHT">
<items>
<FXCollections fx:factory="observableArrayList">
<Label text="%advancedsettings.launcher_visibility.close" />
<Label text="%advancedsettings.launcher_visibility.hide" />
<Label text="%advancedsettings.launcher_visibility.keep" />
<Label text="%advancedsettings.launcher_visibility.hide_reopen" />
<Label text="%advancedsettings.launcher_visibility.close"/>
<Label text="%advancedsettings.launcher_visibility.hide"/>
<Label text="%advancedsettings.launcher_visibility.keep"/>
<Label text="%advancedsettings.launcher_visibility.hide_reopen"/>
</FXCollections>
</items>
</JFXComboBox>
@ -61,13 +89,15 @@
</BorderPane>
<BorderPane> <!-- Run Directory -->
<left><Label text="%settings.run_directory" BorderPane.alignment="CENTER_LEFT" /></left>
<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" />
<Label text="%advancedsettings.game_dir.default"/>
<Label text="%advancedsettings.game_dir.independent"/>
</FXCollections>
</items>
</JFXComboBox>
@ -75,18 +105,21 @@
</BorderPane>
<BorderPane> <!-- Dimension -->
<left><Label text="%settings.dimension" BorderPane.alignment="CENTER_LEFT" /></left>
<left>
<Label text="%settings.dimension" BorderPane.alignment="CENTER_LEFT"/>
</left>
<right>
<BorderPane>
<left>
<HBox prefWidth="210" spacing="3" alignment="CENTER" BorderPane.alignment="CENTER">
<JFXTextField fx:id="txtWidth" promptText="800" prefWidth="100" />
<JFXTextField fx:id="txtWidth" promptText="800" prefWidth="100"/>
<Label>x</Label>
<JFXTextField fx:id="txtHeight" promptText="480" prefWidth="100" />
<JFXTextField fx:id="txtHeight" promptText="480" prefWidth="100"/>
</HBox>
</left>
<right>
<JFXCheckBox fx:id="chkFullscreen" text="%settings.fullscreen" alignment="CENTER" BorderPane.alignment="CENTER">
<JFXCheckBox fx:id="chkFullscreen" text="%settings.fullscreen" alignment="CENTER"
BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets right="7"/>
</BorderPane.margin>
@ -96,28 +129,62 @@
</right>
</BorderPane>
<BorderPane><left><Label text="%mainwindow.show_log" /></left><right><JFXToggleButton fx:id="chkShowLogs" size="7" /></right></BorderPane>
<BorderPane>
<left>
<Label text="%mainwindow.show_log"/>
</left>
<right>
<JFXToggleButton fx:id="chkShowLogs" size="7"/>
</right>
</BorderPane>
</ComponentList>
<HBox alignment="CENTER" style="-fx-padding: 10 0 10 0;">
<JFXButton text="%advancedsettings" onMouseClicked="#onShowAdvanced" />
<JFXButton text="%advancedsettings" onMouseClicked="#onShowAdvanced"/>
</HBox>
<ComponentList fx:id="advancedSettingsPane" depth="1">
<JFXTextField labelFloat="true" promptText="%advancedsettings.jvm_args" styleClass="fit-width" fx:id="txtJVMArgs">
<JFXTextField labelFloat="true" promptText="%advancedsettings.jvm_args" styleClass="fit-width"
fx:id="txtJVMArgs">
<tooltip>
<Tooltip text="%advancedsettings.java_args_default" />
<Tooltip text="%advancedsettings.java_args_default"/>
</tooltip>
</JFXTextField>
<fx:define>
<Insets fx:id="insets" bottom="8" />
<Insets fx:id="insets" bottom="8"/>
</fx:define>
<JFXTextField labelFloat="true" promptText="%advancedsettings.Minecraft_arguments" styleClass="fit-width" fx:id="txtGameArgs" StackPane.margin="$insets" />
<JFXTextField labelFloat="true" promptText="%advancedsettings.java_permanent_generation_space" styleClass="fit-width" fx:id="txtMetaspace" StackPane.margin="$insets" />
<JFXTextField labelFloat="true" promptText="%advancedsettings.wrapper_launcher" styleClass="fit-width" fx:id="txtWrapper" StackPane.margin="$insets" />
<JFXTextField labelFloat="true" promptText="%advancedsettings.precall_command" styleClass="fit-width" fx:id="txtPrecallingCommand" StackPane.margin="$insets" />
<JFXTextField labelFloat="true" promptText="%advancedsettings.server_ip" styleClass="fit-width" fx:id="txtServerIP" StackPane.margin="$insets" />
<BorderPane><left><Label text="%advancedsettings.no_jvm_args" /></left><right><JFXToggleButton fx:id="chkNoJVMArgs" size="7" /></right></BorderPane>
<BorderPane><left><Label text="%advancedsettings.no_common" /></left><right><JFXToggleButton fx:id="chkNoCommon" size="7" /></right></BorderPane>
<BorderPane><left><Label text="%advancedsettings.dont_check_game_completeness" /></left><right><JFXToggleButton fx:id="chkNoGameCheck" size="7" /></right></BorderPane>
<JFXTextField labelFloat="true" promptText="%advancedsettings.Minecraft_arguments"
styleClass="fit-width" fx:id="txtGameArgs" StackPane.margin="$insets"/>
<JFXTextField labelFloat="true" promptText="%advancedsettings.java_permanent_generation_space"
styleClass="fit-width" fx:id="txtMetaspace" StackPane.margin="$insets"/>
<JFXTextField labelFloat="true" promptText="%advancedsettings.wrapper_launcher" styleClass="fit-width"
fx:id="txtWrapper" StackPane.margin="$insets"/>
<JFXTextField labelFloat="true" promptText="%advancedsettings.precall_command" styleClass="fit-width"
fx:id="txtPrecallingCommand" StackPane.margin="$insets"/>
<JFXTextField labelFloat="true" promptText="%advancedsettings.server_ip" styleClass="fit-width"
fx:id="txtServerIP" StackPane.margin="$insets"/>
<BorderPane>
<left>
<Label text="%advancedsettings.no_jvm_args"/>
</left>
<right>
<JFXToggleButton fx:id="chkNoJVMArgs" size="7"/>
</right>
</BorderPane>
<BorderPane>
<left>
<Label text="%advancedsettings.no_common"/>
</left>
<right>
<JFXToggleButton fx:id="chkNoCommon" size="7"/>
</right>
</BorderPane>
<BorderPane>
<left>
<Label text="%advancedsettings.dont_check_game_completeness"/>
</left>
<right>
<JFXToggleButton fx:id="chkNoGameCheck" size="7"/>
</right>
</BorderPane>
</ComponentList>
</VBox>
</ScrollPane>

View File

@ -2,54 +2,64 @@
<?import com.jfoenix.controls.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane">
<JFXTabPane>
<Tab text="%settings">
<fx:include source="version-settings.fxml" fx:id="versionSettings" />
</Tab>
<Tab text="%mods">
<fx:include source="mod.fxml" fx:id="mod" />
</Tab>
<Tab text="%settings.tabs.installers">
<fx:include source="installer.fxml" fx:id="installer" />
</Tab>
</JFXTabPane>
xmlns:fx="http://javafx.com/fxml"
fx:id="rootPane"
type="StackPane">
<JFXRippler />
<StackPane fx:id="contentPane">
<JFXTabPane>
<Tab text="%settings">
<fx:include source="version-settings.fxml" fx:id="versionSettings"/>
</Tab>
<Tab text="%mods">
<fx:include source="mod.fxml" fx:id="mod"/>
</Tab>
<Tab text="%settings.tabs.installers">
<fx:include source="installer.fxml" fx:id="installer"/>
</Tab>
</JFXTabPane>
<HBox alignment="TOP_RIGHT" style="-fx-padding: 3px;" pickOnBounds="false">
<JFXButton fx:id="btnExport" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onExport" styleClass="toggle-icon3" ripplerFill="white">
<graphic>
<fx:include source="/assets/svg/export.fxml"/>
</graphic>
</JFXButton>
<JFXButton fx:id="btnBrowseMenu" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onBrowseMenu" styleClass="toggle-icon3" ripplerFill="white">
<graphic>
<fx:include source="/assets/svg/folder-open.fxml"/>
</graphic>
</JFXButton>
<JFXButton fx:id="btnManagementMenu" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onManagementMenu" styleClass="toggle-icon3" ripplerFill="white">
<graphic>
<fx:include source="/assets/svg/wrench-black.fxml"/>
</graphic>
</JFXButton>
</HBox>
<HBox alignment="TOP_RIGHT" style="-fx-padding: 3px;" pickOnBounds="false">
<JFXButton fx:id="btnExport" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onExport"
styleClass="toggle-icon3" ripplerFill="white">
<graphic>
<fx:include source="/assets/svg/export.fxml"/>
</graphic>
</JFXButton>
<JFXButton fx:id="btnBrowseMenu" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onBrowseMenu"
styleClass="toggle-icon3" ripplerFill="white">
<graphic>
<fx:include source="/assets/svg/folder-open.fxml"/>
</graphic>
</JFXButton>
<JFXButton fx:id="btnManagementMenu" maxHeight="28.0" minHeight="28.0" onMouseClicked="#onManagementMenu"
styleClass="toggle-icon3" ripplerFill="white">
<graphic>
<fx:include source="/assets/svg/wrench-black.fxml"/>
</graphic>
</JFXButton>
</HBox>
</StackPane>
<JFXListView fx:id="browseList" styleClass="option-list-view" onMouseClicked="#onBrowse" maxWidth="150.0" minWidth="150.0">
<Label text="%folder.game" />
<Label text="%folder.mod" />
<Label text="%folder.coremod" />
<Label text="%folder.config" />
<Label text="%folder.resourcepacks" />
<Label text="%folder.screenshots" />
<Label text="%folder.saves" />
<JFXListView fx:id="browseList" styleClass="option-list-view" onMouseClicked="#onBrowse" maxWidth="150.0"
minWidth="150.0">
<Label text="%folder.game"/>
<Label text="%folder.mod"/>
<Label text="%folder.coremod"/>
<Label text="%folder.config"/>
<Label text="%folder.resourcepacks"/>
<Label text="%folder.screenshots"/>
<Label text="%folder.saves"/>
</JFXListView>
<JFXListView fx:id="managementList" styleClass="option-list-view" onMouseClicked="#onManagement" maxWidth="300.0" minWidth="300.0">
<Label text="%versions.manage.rename" />
<Label text="%versions.manage.remove" />
<Label text="%versions.manage.redownload_assets_index" />
<Label text="%versions.manage.remove_libraries" />
<JFXListView fx:id="managementList" styleClass="option-list-view" onMouseClicked="#onManagement"
maxWidth="300.0" minWidth="300.0">
<Label text="%versions.manage.rename"/>
<Label text="%versions.manage.remove"/>
<Label text="%versions.manage.redownload_assets_index"/>
<Label text="%versions.manage.remove_libraries"/>
</JFXListView>
</fx:root>

View File

@ -22,6 +22,7 @@ import javafx.collections.ListChangeListener
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 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()) } }