diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java index 5aa66fc8e..4c1c1c979 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java @@ -55,7 +55,8 @@ public final class Launcher extends Application { Main.showErrorAndExit(i18n("fatal.config_loading_failure", Paths.get("").toAbsolutePath().normalize())); } - try { + // runLater to ensure ConfigHolder.init() finished initialization + Platform.runLater(() -> { // When launcher visibility is set to "hide and reopen" without Platform.implicitExit = false, // Stage.show() cannot work again because JavaFX Toolkit have already shut down. Platform.setImplicitExit(false); @@ -66,9 +67,8 @@ public final class Launcher extends Application { UpdateChecker.init(); primaryStage.show(); - } catch (Throwable e) { - CRASH_REPORTER.uncaughtException(Thread.currentThread(), e); - } + }); + } public static void main(String[] args) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index 8c08326de..f1341c17e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -17,33 +17,46 @@ */ package org.jackhuang.hmcl.ui; +import com.jfoenix.concurrency.JFXUtilities; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.image.Image; +import javafx.scene.input.TransferMode; import javafx.scene.layout.Region; import javafx.stage.Stage; import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.Metadata; +import org.jackhuang.hmcl.game.HMCLGameRepository; +import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.setting.Accounts; import org.jackhuang.hmcl.setting.Profiles; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.TaskExecutor; import org.jackhuang.hmcl.ui.account.AccountList; import org.jackhuang.hmcl.ui.account.AuthlibInjectorServersPage; -import org.jackhuang.hmcl.ui.construct.InputDialogPane; -import org.jackhuang.hmcl.ui.construct.MessageBox; -import org.jackhuang.hmcl.ui.construct.MessageDialogPane; -import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane; +import org.jackhuang.hmcl.ui.construct.*; import org.jackhuang.hmcl.ui.decorator.DecoratorController; +import org.jackhuang.hmcl.ui.download.ModpackInstallWizardProvider; import org.jackhuang.hmcl.ui.profile.ProfileList; +import org.jackhuang.hmcl.ui.versions.GameItem; import org.jackhuang.hmcl.ui.versions.GameList; import org.jackhuang.hmcl.ui.versions.VersionPage; +import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.util.FutureCallback; +import org.jackhuang.hmcl.util.Logging; +import org.jackhuang.hmcl.util.io.FileUtils; +import org.jackhuang.hmcl.util.javafx.MultiStepBinding; import org.jackhuang.hmcl.util.platform.JavaVersion; +import org.jackhuang.hmcl.util.versioning.VersionNumber; +import java.io.File; +import java.util.Comparator; +import java.util.List; import java.util.function.Consumer; +import java.util.stream.Collectors; import static org.jackhuang.hmcl.setting.ConfigHolder.config; +import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public final class Controllers { @@ -121,8 +134,60 @@ public final class Controllers { } public static MainPage getMainPage() { - if (mainPage == null) + if (mainPage == null) { mainPage = new MainPage(); + mainPage.setOnDragOver(event -> { + if (event.getGestureSource() != mainPage && event.getDragboard().hasFiles()) { + if (event.getDragboard().getFiles().stream().anyMatch(it -> "zip".equals(FileUtils.getExtension(it)))) + event.acceptTransferModes(TransferMode.COPY_OR_MOVE); + } + event.consume(); + }); + + mainPage.setOnDragDropped(event -> { + List files = event.getDragboard().getFiles(); + if (files != null) { + List modpacks = files.stream() + .filter(it -> "zip".equals(FileUtils.getExtension(it))) + .collect(Collectors.toList()); + if (!modpacks.isEmpty()) { + File modpack = modpacks.get(0); + Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(modpack), i18n("install.modpack")); + event.setDropCompleted(true); + } + } + event.consume(); + }); + + FXUtils.onChangeAndOperate(Profiles.selectedVersionProperty(), version -> { + if (version != null) { + mainPage.setCurrentGame(version); + } else { + mainPage.setCurrentGame(i18n("version.empty")); + } + }); + mainPage.showUpdateProperty().bind(UpdateChecker.outdatedProperty()); + mainPage.latestVersionProperty().bind( + MultiStepBinding.of(UpdateChecker.latestVersionProperty()) + .map(version -> version == null ? "" : i18n("update.bubble.title", version.getVersion()))); + + Profiles.registerVersionsListener(profile -> { + HMCLGameRepository repository = profile.getRepository(); + List children = repository.getVersions().parallelStream() + .filter(version -> !version.isHidden()) + .sorted(Comparator.comparing(Version::getReleaseTime).thenComparing(a -> VersionNumber.asVersion(a.getId()))) + .map(version -> { + Node node = PopupMenu.wrapPopupMenuItem(new GameItem(profile, version.getId())); + node.setOnMouseClicked(e -> profile.setSelectedVersion(version.getId())); + return node; + }) + .collect(Collectors.toList()); + JFXUtilities.runInFX(() -> { + if (profile == Profiles.getSelectedProfile()) + mainPage.getVersions().setAll(children); + }); + }); + } return mainPage; } @@ -131,6 +196,8 @@ public final class Controllers { } public static void initialize(Stage stage) { + Logging.LOG.info("Start initializing application"); + Controllers.stage = stage; stage.setOnCloseRequest(e -> Launcher.stopApplication()); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/ListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/ListPageSkin.java index cf530fb05..3f5547cdd 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/ListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/ListPageSkin.java @@ -46,14 +46,14 @@ public class ListPageSkin extends SkinBase { { scrollPane.setFitToWidth(true); - VBox accountList = new VBox(); - accountList.maxWidthProperty().bind(scrollPane.widthProperty()); - accountList.setSpacing(10); - accountList.setStyle("-fx-padding: 10 10 10 10;"); + VBox list = new VBox(); + list.maxWidthProperty().bind(scrollPane.widthProperty()); + list.setSpacing(10); + list.setPadding(new Insets(10)); - Bindings.bindContent(accountList.getChildren(), skinnable.itemsProperty()); + Bindings.bindContent(list.getChildren(), skinnable.itemsProperty()); - scrollPane.setContent(accountList); + scrollPane.setContent(list); JFXScrollPane.smoothScrolling(scrollPane); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java index 39e73aa61..2b91bd082 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/MainPage.java @@ -17,52 +17,37 @@ */ package org.jackhuang.hmcl.ui; -import com.jfoenix.concurrency.JFXUtilities; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXPopup; -import javafx.animation.Interpolator; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; -import javafx.beans.property.ReadOnlyStringProperty; -import javafx.beans.property.ReadOnlyStringWrapper; -import javafx.fxml.FXML; +import javafx.beans.binding.Bindings; +import javafx.beans.property.*; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Label; -import javafx.scene.input.TransferMode; +import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.util.Duration; -import org.jackhuang.hmcl.game.HMCLGameRepository; -import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Profiles; import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.ui.construct.PopupMenu; -import org.jackhuang.hmcl.ui.construct.RipplerContainer; import org.jackhuang.hmcl.ui.construct.TwoLineListItem; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; -import org.jackhuang.hmcl.ui.download.ModpackInstallWizardProvider; -import org.jackhuang.hmcl.ui.versions.GameItem; import org.jackhuang.hmcl.ui.versions.Versions; import org.jackhuang.hmcl.upgrade.RemoteVersion; import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.upgrade.UpdateHandler; -import org.jackhuang.hmcl.util.Logging; -import org.jackhuang.hmcl.util.io.FileUtils; -import org.jackhuang.hmcl.util.javafx.MultiStepBinding; -import org.jackhuang.hmcl.util.versioning.VersionNumber; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.List; -import java.util.logging.Level; -import java.util.stream.Collectors; +import static org.jackhuang.hmcl.ui.FXUtils.SINE; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public final class MainPage extends StackPane implements DecoratorPage { @@ -71,133 +56,142 @@ public final class MainPage extends StackPane implements DecoratorPage { private final PopupMenu menu = new PopupMenu(); private final JFXPopup popup = new JFXPopup(menu); - @FXML - private StackPane main; - @FXML + private final StringProperty currentGame = new SimpleStringProperty(this, "currentGame"); + private final BooleanProperty showUpdate = new SimpleBooleanProperty(this, "showUpdate"); + private final StringProperty latestVersion = new SimpleStringProperty(this, "latestVersion"); + private final ObservableList versions = FXCollections.observableArrayList(); + private StackPane updatePane; - @FXML - private JFXButton btnLaunch; - @FXML - private JFXButton btnMenu; - @FXML - private JFXButton closeUpdateButton; - @FXML - private Label lblCurrentGame; - @FXML - private Label lblIcon; - @FXML - private TwoLineListItem lblLatestVersion; - @FXML - private Rectangle separator; + private JFXButton menuButton; { - FXUtils.loadFXML(this, "/assets/fxml/main.fxml"); + setPadding(new Insets(25)); + + updatePane = new StackPane(); + updatePane.setVisible(false); + updatePane.getStyleClass().add("bubble"); + FXUtils.setLimitWidth(updatePane, 230); + FXUtils.setLimitHeight(updatePane, 55); + StackPane.setAlignment(updatePane, Pos.TOP_RIGHT); + updatePane.setOnMouseClicked(e -> onUpgrade()); + FXUtils.onChange(showUpdateProperty(), this::doAnimation); + + { + HBox hBox = new HBox(); + hBox.setSpacing(12); + hBox.setAlignment(Pos.CENTER_LEFT); + StackPane.setAlignment(hBox, Pos.CENTER_LEFT); + StackPane.setMargin(hBox, new Insets(9, 12, 9, 16)); + { + Label lblIcon = new Label(); + lblIcon.setGraphic(SVG.update(Theme.whiteFillBinding(), 20, 20)); + + TwoLineListItem prompt = new TwoLineListItem(); + prompt.setTitleFill(Color.WHITE); + prompt.setSubtitleFill(Color.WHITE); + prompt.setSubtitle(i18n("update.bubble.subtitle")); + prompt.setPickOnBounds(false); + prompt.setStyle("-jfx-title-font-weight: BOLD;"); + prompt.titleProperty().bind(latestVersionProperty()); + + hBox.getChildren().setAll(lblIcon, prompt); + } + + JFXButton closeUpdateButton = new JFXButton(); + closeUpdateButton.setGraphic(SVG.close(Theme.whiteFillBinding(), 10, 10)); + StackPane.setAlignment(closeUpdateButton, Pos.TOP_RIGHT); + closeUpdateButton.getStyleClass().add("toggle-icon-tiny"); + StackPane.setMargin(closeUpdateButton, new Insets(5)); + closeUpdateButton.setOnMouseClicked(e -> closeUpdateBubble()); + + updatePane.getChildren().setAll(hBox, closeUpdateButton); + } + + StackPane launchPane = new StackPane(); + launchPane.setMaxWidth(230); + launchPane.setMaxHeight(55); + StackPane.setAlignment(launchPane, Pos.BOTTOM_RIGHT); + { + JFXButton launchButton = new JFXButton(); + launchButton.setPrefWidth(230); + launchButton.setPrefHeight(55); + launchButton.setButtonType(JFXButton.ButtonType.RAISED); + launchButton.getStyleClass().add("jfx-button-raised"); + launchButton.setOnMouseClicked(e -> launch()); + launchButton.setClip(new Rectangle(-100, -100, 310, 200)); + { + VBox graphic = new VBox(); + graphic.setAlignment(Pos.CENTER); + graphic.setTranslateX(-7); + graphic.setMaxWidth(200); + Label launchLabel = new Label(i18n("version.launch")); + launchLabel.setStyle("-fx-font-size: 16px;"); + Label currentLabel = new Label(); + currentLabel.setStyle("-fx-font-size: 12px;"); + currentLabel.textProperty().bind(currentGameProperty()); + graphic.getChildren().setAll(launchLabel, currentLabel); + + launchButton.setGraphic(graphic); + } + + Rectangle separator = new Rectangle(); + separator.getStyleClass().add("darker-fill"); + separator.setWidth(1); + separator.setHeight(57); + separator.setTranslateX(95); + separator.setMouseTransparent(true); + + menuButton = new JFXButton(); + menuButton.setPrefHeight(55); + menuButton.setPrefWidth(230); + menuButton.setButtonType(JFXButton.ButtonType.RAISED); + menuButton.getStyleClass().add("jfx-button-raised"); + menuButton.setStyle("-fx-font-size: 15px;"); + menuButton.setOnMouseClicked(e -> onMenu()); + menuButton.setClip(new Rectangle(211, -100, 100, 200)); + StackPane graphic = new StackPane(); + Node svg = SVG.triangle(Theme.whiteFillBinding(), 10, 10); + StackPane.setAlignment(svg, Pos.CENTER_RIGHT); + graphic.getChildren().setAll(svg); + graphic.setTranslateX(12); + menuButton.setGraphic(graphic); + + launchPane.getChildren().setAll(launchButton, separator, menuButton); + } + + getChildren().setAll(updatePane, launchPane); - btnLaunch.setClip(new Rectangle(-100, -100, 310, 200)); - btnMenu.setClip(new Rectangle(211, -100, 100, 200)); menu.setMaxHeight(365); menu.setMaxWidth(545); menu.setAlwaysShowingVBar(true); - - updatePane.visibleProperty().bind(UpdateChecker.outdatedProperty()); - closeUpdateButton.setGraphic(SVG.close(Theme.whiteFillBinding(), 10, 10)); - closeUpdateButton.setOnMouseClicked(event -> { - Duration duration = Duration.millis(320); - Timeline nowAnimation = new Timeline(); - nowAnimation.getKeyFrames().addAll( - new KeyFrame(Duration.ZERO, - new KeyValue(updatePane.translateXProperty(), 0, Interpolator.EASE_IN)), - new KeyFrame(duration, - new KeyValue(updatePane.translateXProperty(), 260, Interpolator.EASE_IN)), - new KeyFrame(duration, e -> { - updatePane.visibleProperty().unbind(); - updatePane.setVisible(false); - })); - nowAnimation.play(); - }); - lblIcon.setGraphic(SVG.update(Theme.whiteFillBinding(), 20, 20)); - lblLatestVersion.titleProperty().bind( - MultiStepBinding.of(UpdateChecker.latestVersionProperty()) - .map(version -> version == null ? "" : i18n("update.bubble.title", version.getVersion()))); - - StackPane graphic = new StackPane(); - Node svg = SVG.triangle(Theme.whiteFillBinding(), 10, 10); - StackPane.setAlignment(svg, Pos.CENTER_RIGHT); - graphic.getChildren().setAll(svg); - graphic.setTranslateX(12); - btnMenu.setGraphic(graphic); - - FXUtils.onChangeAndOperate(Profiles.selectedVersionProperty(), version -> { - if (version != null) { - lblCurrentGame.setText(version); - } else { - lblCurrentGame.setText(i18n("version.empty")); - } - }); - - Profiles.registerVersionsListener(this::loadVersions); - - setOnDragOver(event -> { - if (event.getGestureSource() != this && event.getDragboard().hasFiles()) { - if (event.getDragboard().getFiles().stream().anyMatch(it -> "zip".equals(FileUtils.getExtension(it)))) - event.acceptTransferModes(TransferMode.COPY_OR_MOVE); - } - event.consume(); - }); - - setOnDragDropped(event -> { - List files = event.getDragboard().getFiles(); - if (files != null) { - List modpacks = files.stream() - .filter(it -> "zip".equals(FileUtils.getExtension(it))) - .collect(Collectors.toList()); - if (!modpacks.isEmpty()) { - File modpack = modpacks.get(0); - Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(modpack), i18n("install.modpack")); - event.setDropCompleted(true); - } - } - event.consume(); - }); + menu.setOnMouseClicked(e -> popup.hide()); + Bindings.bindContent(menu.getContent(), versions); } - private void loadVersions(Profile profile) { - HMCLGameRepository repository = profile.getRepository(); - List children = repository.getVersions().parallelStream() - .filter(version -> !version.isHidden()) - .sorted(Comparator.comparing(Version::getReleaseTime).thenComparing(a -> VersionNumber.asVersion(a.getId()))) - .map(version -> { - StackPane pane = new StackPane(); - GameItem item = new GameItem(profile, version.getId()); - pane.getChildren().setAll(item); - pane.getStyleClass().setAll("menu-container"); - item.setMouseTransparent(true); - RipplerContainer container = new RipplerContainer(pane); - container.setOnMouseClicked(e -> { - profile.setSelectedVersion(version.getId()); - popup.hide(); - }); - return container; - }) - .collect(Collectors.toList()); - JFXUtilities.runInFX(() -> { - if (profile == Profiles.getSelectedProfile()) - menu.getContent().setAll(children); - }); + private void doAnimation(boolean show) { + Duration duration = Duration.millis(320); + Timeline nowAnimation = new Timeline(); + nowAnimation.getKeyFrames().addAll( + new KeyFrame(Duration.ZERO, + new KeyValue(updatePane.translateXProperty(), show ? 260 : 0, SINE)), + new KeyFrame(duration, + new KeyValue(updatePane.translateXProperty(), show ? 0 : 260, SINE))); + if (show) nowAnimation.getKeyFrames().add( + new KeyFrame(Duration.ZERO, e -> updatePane.setVisible(true))); + else nowAnimation.getKeyFrames().add( + new KeyFrame(duration, e -> updatePane.setVisible(false))); + nowAnimation.play(); } - @FXML private void launch() { Profile profile = Profiles.getSelectedProfile(); Versions.launch(profile, profile.getSelectedVersion()); } - @FXML private void onMenu() { - popup.show(btnMenu, JFXPopup.PopupVPosition.BOTTOM, JFXPopup.PopupHPosition.RIGHT, 0, -btnMenu.getHeight()); + popup.show(menuButton, JFXPopup.PopupVPosition.BOTTOM, JFXPopup.PopupHPosition.RIGHT, 0, -menuButton.getHeight()); } - @FXML private void onUpgrade() { RemoteVersion target = UpdateChecker.getLatestVersion(); if (target == null) { @@ -206,6 +200,11 @@ public final class MainPage extends StackPane implements DecoratorPage { UpdateHandler.updateFrom(target); } + private void closeUpdateBubble() { + showUpdate.unbind(); + showUpdate.set(false); + } + public String getTitle() { return title.get(); } @@ -218,4 +217,44 @@ public final class MainPage extends StackPane implements DecoratorPage { public void setTitle(String title) { this.title.set(title); } + + public String getCurrentGame() { + return currentGame.get(); + } + + public StringProperty currentGameProperty() { + return currentGame; + } + + public void setCurrentGame(String currentGame) { + this.currentGame.set(currentGame); + } + + public boolean isShowUpdate() { + return showUpdate.get(); + } + + public BooleanProperty showUpdateProperty() { + return showUpdate; + } + + public void setShowUpdate(boolean showUpdate) { + this.showUpdate.set(showUpdate); + } + + public String getLatestVersion() { + return latestVersion.get(); + } + + public StringProperty latestVersionProperty() { + return latestVersion; + } + + public void setLatestVersion(String latestVersion) { + this.latestVersion.set(latestVersion); + } + + public ObservableList getVersions() { + return versions; + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/PopupMenu.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/PopupMenu.java index 94846b5db..9ca16d845 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/PopupMenu.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/PopupMenu.java @@ -28,6 +28,7 @@ import javafx.scene.control.Control; import javafx.scene.control.ScrollPane; import javafx.scene.control.Skin; import javafx.scene.control.SkinBase; +import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import org.jackhuang.hmcl.ui.FXUtils; @@ -60,6 +61,14 @@ public class PopupMenu extends Control { return new PopupMenuSkin(); } + public static Node wrapPopupMenuItem(Node node) { + StackPane pane = new StackPane(); + pane.getChildren().setAll(node); + pane.getStyleClass().setAll("menu-container"); + node.setMouseTransparent(true); + return new RipplerContainer(pane); + } + private class PopupMenuSkin extends SkinBase { protected PopupMenuSkin() { diff --git a/HMCL/src/main/resources/assets/fxml/advanced-list-item.fxml b/HMCL/src/main/resources/assets/fxml/advanced-list-item.fxml deleted file mode 100644 index 7f71c65f5..000000000 --- a/HMCL/src/main/resources/assets/fxml/advanced-list-item.fxml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/HMCL/src/main/resources/assets/fxml/main.fxml b/HMCL/src/main/resources/assets/fxml/main.fxml deleted file mode 100644 index f018b098b..000000000 --- a/HMCL/src/main/resources/assets/fxml/main.fxml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index e10c5a001..671955f74 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -165,8 +165,8 @@ launcher=Launcher launcher.background=Background Image launcher.background.choose=Choose background path. launcher.background.default=Default -launcher.common_directory=Cache Directory (Store downloaded files) -launcher.common_directory.choose=Choose cache directory. +launcher.common_directory=Download Cache Directory +launcher.common_directory.choose=Choose download cache directory launcher.common_directory.default=Default launcher.common_directory.disabled=Disabled launcher.contact=Contact Us diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 8f6c63232..650998fea 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -165,8 +165,8 @@ launcher=啟動器 launcher.background=背景位址 launcher.background.choose=選擇背景路徑 launcher.background.default=預設(自動尋找啟動器同目錄下的 background.png/jpg 及 bg 資料夾內的圖片) -launcher.common_directory=緩存目錄(檔案下載緩存) -launcher.common_directory.choose=選擇緩存目錄 +launcher.common_directory=檔案下載緩存目錄 +launcher.common_directory.choose=選擇檔案下載緩存目錄 launcher.common_directory.default=預設 launcher.common_directory.disabled=停用 launcher.contact=聯絡我們 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 9d471fe06..7fe9808fc 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -165,8 +165,8 @@ launcher=启动器 launcher.background=背景地址 launcher.background.choose=选择背景路径 launcher.background.default=默认(自动检索启动器同目录下的 background.png/jpg 及 bg 文件夹内的图片) -launcher.common_directory=缓存目录(文件下载缓存) -launcher.common_directory.choose=选择缓存目录 +launcher.common_directory=文件下载缓存目录 +launcher.common_directory.choose=选择文件下载缓存目录 launcher.common_directory.default=默认(%AppData%/.minecraft 或者 ~/.minecraft) launcher.common_directory.disabled=禁用(总是使用游戏路径) launcher.contact=联系我们 diff --git a/lib/JFoenix.jar b/lib/JFoenix.jar index ddb87c8b8..c6a5de074 100644 Binary files a/lib/JFoenix.jar and b/lib/JFoenix.jar differ