diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorAnimatedPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorAnimatedPage.java index d0c20d82d..21c8e9699 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorAnimatedPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorAnimatedPage.java @@ -24,11 +24,12 @@ import javafx.scene.control.SkinBase; import javafx.scene.layout.BorderPane; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; +import org.jackhuang.hmcl.ui.FXUtils; public class DecoratorAnimatedPage extends Control { - private final VBox left = new VBox(); - private final StackPane center = new StackPane(); + protected final VBox left = new VBox(); + protected final StackPane center = new StackPane(); protected void setLeft(Node... children) { left.getChildren().setAll(children); @@ -40,19 +41,29 @@ public class DecoratorAnimatedPage extends Control { @Override protected Skin createDefaultSkin() { - return new DecoratorAnimatedPageSkin(this); + return new DecoratorAnimatedPageSkin<>(this); } - private static class DecoratorAnimatedPageSkin extends SkinBase { + public static class DecoratorAnimatedPageSkin extends SkinBase { - protected DecoratorAnimatedPageSkin(DecoratorAnimatedPage control) { + protected DecoratorAnimatedPageSkin(T control) { super(control); BorderPane pane = new BorderPane(); pane.setLeft(control.left); + FXUtils.setLimitWidth(control.left, 200); pane.setCenter(control.center); getChildren().setAll(pane); } + + protected void setLeft(Node... children) { + getSkinnable().setLeft(children); + } + + protected void setCenter(Node... children) { + getSkinnable().setCenter(children); + } + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java index 6bea6d78b..a96d63043 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java @@ -21,7 +21,6 @@ import com.jfoenix.controls.JFXButton; import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.scene.Node; -import javafx.scene.layout.BorderPane; import org.jackhuang.hmcl.download.*; import org.jackhuang.hmcl.download.game.GameRemoteVersion; import org.jackhuang.hmcl.mod.RemoteMod; @@ -43,6 +42,7 @@ import org.jackhuang.hmcl.ui.construct.AdvancedListBox; import org.jackhuang.hmcl.ui.construct.MessageDialogPane; import org.jackhuang.hmcl.ui.construct.TabHeader; import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane; +import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.ui.versions.DownloadListPage; import org.jackhuang.hmcl.ui.versions.ModDownloadListPage; @@ -63,7 +63,7 @@ import static org.jackhuang.hmcl.ui.FXUtils.runInFX; import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -public class DownloadPage extends BorderPane implements DecoratorPage { +public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage { private final ReadOnlyObjectWrapper state = new ReadOnlyObjectWrapper<>(DecoratorPage.State.fromTitle(i18n("download"), -1)); private final TabHeader tab; private final TabHeader.Tab newGameTab = new TabHeader.Tab<>("newGameTab"); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java index 90a3ca90c..489915590 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java @@ -25,7 +25,6 @@ import javafx.application.Platform; import javafx.beans.property.*; import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import javafx.scene.control.Control; import javafx.scene.control.Label; import javafx.scene.control.Skin; import org.jackhuang.hmcl.event.Event; @@ -36,6 +35,7 @@ import org.jackhuang.hmcl.task.TaskExecutor; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.construct.*; +import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.util.StringUtils; @@ -49,7 +49,7 @@ import static org.jackhuang.hmcl.ui.FXUtils.runInFX; import static org.jackhuang.hmcl.util.Logging.LOG; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -public class MultiplayerPage extends Control implements DecoratorPage, PageAware { +public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorPage, PageAware { private final ReadOnlyObjectWrapper state = new ReadOnlyObjectWrapper<>(State.fromTitle(i18n("multiplayer"), -1)); private final ObjectProperty multiplayerState = new SimpleObjectProperty<>(MultiplayerManager.State.DISCONNECTED); @@ -69,7 +69,7 @@ public class MultiplayerPage extends Control implements DecoratorPage, PageAware @Override public void onPageShown() { - checkAgreement(() -> this.downloadCatoIfNecessary()); + checkAgreement(this::downloadCatoIfNecessary); } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java index 6f94fa660..ad5821ce1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java @@ -27,7 +27,6 @@ import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; -import javafx.scene.control.SkinBase; import javafx.scene.layout.*; import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.game.LauncherHelper; @@ -40,6 +39,7 @@ import org.jackhuang.hmcl.ui.SVG; import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.TransitionPane; import org.jackhuang.hmcl.ui.construct.*; +import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage; import org.jackhuang.hmcl.ui.versions.Versions; import org.jackhuang.hmcl.util.javafx.BindingMapping; import org.jackhuang.hmcl.util.javafx.MappedObservableList; @@ -48,7 +48,7 @@ import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig; import static org.jackhuang.hmcl.ui.versions.VersionPage.wrap; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -public class MultiplayerPageSkin extends SkinBase { +public class MultiplayerPageSkin extends DecoratorAnimatedPage.DecoratorAnimatedPageSkin { private ObservableList clients; @@ -60,8 +60,6 @@ public class MultiplayerPageSkin extends SkinBase { protected MultiplayerPageSkin(MultiplayerPage control) { super(control); - BorderPane root = new BorderPane(); - getChildren().setAll(root); { VBox roomPane = new VBox(); { @@ -137,7 +135,7 @@ public class MultiplayerPageSkin extends SkinBase { report.setOnAction(e -> FXUtils.openLink(Metadata.EULA_URL)); }); FXUtils.setLimitWidth(sideBar, 200); - root.setLeft(sideBar); + setLeft(sideBar); } { @@ -147,7 +145,7 @@ public class MultiplayerPageSkin extends SkinBase { ScrollPane scrollPane = new ScrollPane(content); scrollPane.setFitToWidth(true); scrollPane.setFitToHeight(true); - root.setCenter(scrollPane); + setCenter(scrollPane); ComponentList roomPane = new ComponentList(); { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java index 1a85461af..67721360b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java @@ -23,18 +23,16 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Node; import javafx.scene.control.ScrollPane; -import javafx.scene.control.SkinBase; import javafx.scene.control.ToggleGroup; -import javafx.scene.layout.BorderPane; +import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; -import org.jackhuang.hmcl.event.EventBus; -import org.jackhuang.hmcl.event.RefreshingVersionsEvent; import org.jackhuang.hmcl.game.HMCLGameRepository; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Profiles; import org.jackhuang.hmcl.ui.*; import org.jackhuang.hmcl.ui.construct.AdvancedListBox; import org.jackhuang.hmcl.ui.construct.AdvancedListItem; +import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.ui.profile.ProfileListItem; import org.jackhuang.hmcl.ui.profile.ProfilePage; @@ -48,7 +46,7 @@ import static org.jackhuang.hmcl.ui.FXUtils.runInFX; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.createSelectedItemPropertyFor; -public class GameListPage extends ListPageBase implements DecoratorPage { +public class GameListPage extends DecoratorAnimatedPage implements DecoratorPage { private final ReadOnlyObjectWrapper state = new ReadOnlyObjectWrapper<>(State.fromTitle(i18n("version.manage"), -1)); private final ListProperty profiles = new SimpleListProperty<>(FXCollections.observableArrayList()); @SuppressWarnings("FieldCanBeLocal") @@ -58,16 +56,62 @@ public class GameListPage extends ListPageBase implements Decorato private ToggleGroup toggleGroup; public GameListPage() { - EventBus.EVENT_BUS.channel(RefreshingVersionsEvent.class).register(event -> { - if (event.getSource() == Profiles.getSelectedProfile().getRepository()) - runInFX(() -> setLoading(true)); - }); profileListItems = MappedObservableList.create(profilesProperty(), profile -> { ProfileListItem item = new ProfileListItem(profile); FXUtils.setLimitWidth(item, 200); return item; }); selectedProfile = createSelectedItemPropertyFor(profileListItems, Profile.class); + + GameList gameList = new GameList(); + + { + ScrollPane pane = new ScrollPane(); + VBox.setVgrow(pane, Priority.ALWAYS); + { + AdvancedListItem addProfileItem = new AdvancedListItem(); + addProfileItem.getStyleClass().add("navigation-drawer-item"); + addProfileItem.setTitle(i18n("profile.new")); + addProfileItem.setActionButtonVisible(false); + addProfileItem.setLeftGraphic(VersionPage.wrap(SVG::plusCircleOutline)); + addProfileItem.setOnAction(e -> Controllers.navigate(new ProfilePage(null))); + + pane.setFitToWidth(true); + VBox wrapper = new VBox(); + wrapper.getStyleClass().add("advanced-list-box-content"); + VBox box = new VBox(); + box.setFillWidth(true); + Bindings.bindContent(box.getChildren(), profileListItems); + wrapper.getChildren().setAll(box, addProfileItem); + pane.setContent(wrapper); + } + + AdvancedListBox bottomLeftCornerList = new AdvancedListBox() + .addNavigationDrawerItem(installNewGameItem -> { + installNewGameItem.setTitle(i18n("install.new_game")); + installNewGameItem.setLeftGraphic(VersionPage.wrap(SVG::plusCircleOutline)); + installNewGameItem.setOnAction(e -> Versions.addNewGame()); + }) + .addNavigationDrawerItem(installModpackItem -> { + installModpackItem.setTitle(i18n("install.modpack")); + installModpackItem.setLeftGraphic(VersionPage.wrap(SVG::pack)); + installModpackItem.setOnAction(e -> Versions.importModpack()); + }) + .addNavigationDrawerItem(refreshItem -> { + refreshItem.setTitle(i18n("button.refresh")); + refreshItem.setLeftGraphic(VersionPage.wrap(SVG::refresh)); + refreshItem.setOnAction(e -> gameList.refreshList()); + }) + .addNavigationDrawerItem(globalManageItem -> { + globalManageItem.setTitle(i18n("settings.type.global.manage")); + globalManageItem.setLeftGraphic(VersionPage.wrap(SVG::gearOutline)); + globalManageItem.setOnAction(e -> modifyGlobalGameSettings()); + }); + FXUtils.setLimitHeight(bottomLeftCornerList, 40 * 4 + 12 * 2); + setLeft(pane, bottomLeftCornerList); + } + + setCenter(gameList); } public ObjectProperty selectedProfileProperty() { @@ -86,11 +130,6 @@ public class GameListPage extends ListPageBase implements Decorato this.profiles.set(profiles); } - @Override - protected GameListPageSkin createDefaultSkin() { - return new GameListPageSkin(); - } - public void modifyGlobalGameSettings() { Versions.modifyGlobalSettings(Profiles.getSelectedProfile()); } @@ -100,84 +139,6 @@ public class GameListPage extends ListPageBase implements Decorato return state.getReadOnlyProperty(); } - private class GameListPageSkin extends SkinBase { - - protected GameListPageSkin() { - super(GameListPage.this); - - - BorderPane root = new BorderPane(); - GameList gameList = new GameList(); - - { - BorderPane left = new BorderPane(); - FXUtils.setLimitWidth(left, 200); - root.setLeft(left); - - { - AdvancedListItem addProfileItem = new AdvancedListItem(); - addProfileItem.getStyleClass().add("navigation-drawer-item"); - addProfileItem.setTitle(i18n("profile.new")); - addProfileItem.setActionButtonVisible(false); - addProfileItem.setLeftGraphic(VersionPage.wrap(SVG::plusCircleOutline)); - addProfileItem.setOnAction(e -> Controllers.navigate(new ProfilePage(null))); - - ScrollPane pane = new ScrollPane(); - pane.setFitToWidth(true); - VBox wrapper = new VBox(); - wrapper.getStyleClass().add("advanced-list-box-content"); - VBox box = new VBox(); - box.setFillWidth(true); - Bindings.bindContent(box.getChildren(), profileListItems); - wrapper.getChildren().setAll(box, addProfileItem); - pane.setContent(wrapper); - left.setCenter(pane); - } - - { - AdvancedListItem installNewGameItem = new AdvancedListItem(); - installNewGameItem.getStyleClass().add("navigation-drawer-item"); - installNewGameItem.setTitle(i18n("install.new_game")); - installNewGameItem.setActionButtonVisible(false); - installNewGameItem.setLeftGraphic(VersionPage.wrap(SVG::plusCircleOutline)); - installNewGameItem.setOnAction(e -> Versions.addNewGame()); - - AdvancedListItem installModpackItem = new AdvancedListItem(); - installModpackItem.getStyleClass().add("navigation-drawer-item"); - installModpackItem.setTitle(i18n("install.modpack")); - installModpackItem.setActionButtonVisible(false); - installModpackItem.setLeftGraphic(VersionPage.wrap(SVG::pack)); - installModpackItem.setOnAction(e -> Versions.importModpack()); - - AdvancedListItem refreshItem = new AdvancedListItem(); - refreshItem.getStyleClass().add("navigation-drawer-item"); - refreshItem.setTitle(i18n("button.refresh")); - refreshItem.setActionButtonVisible(false); - refreshItem.setLeftGraphic(VersionPage.wrap(SVG::refresh)); - refreshItem.setOnAction(e -> gameList.refreshList()); - - AdvancedListItem globalManageItem = new AdvancedListItem(); - globalManageItem.getStyleClass().add("navigation-drawer-item"); - globalManageItem.setTitle(i18n("settings.type.global.manage")); - globalManageItem.setActionButtonVisible(false); - globalManageItem.setLeftGraphic(VersionPage.wrap(SVG::gearOutline)); - globalManageItem.setOnAction(e -> modifyGlobalGameSettings()); - - AdvancedListBox bottomLeftCornerList = new AdvancedListBox() - .add(installNewGameItem) - .add(installModpackItem) - .add(refreshItem) - .add(globalManageItem); - FXUtils.setLimitHeight(bottomLeftCornerList, 40 * 4 + 12 * 2); - left.setBottom(bottomLeftCornerList); - } - } - - root.setCenter(gameList); - getChildren().setAll(root); - } - } - private class GameList extends ListPageBase { public GameList() { super(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionPage.java index 35959d295..0838bbbce 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/VersionPage.java @@ -24,10 +24,10 @@ import javafx.beans.property.*; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; -import javafx.scene.control.Control; -import javafx.scene.control.SkinBase; import javafx.scene.layout.BorderPane; +import javafx.scene.layout.Priority; import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.ui.FXUtils; @@ -35,6 +35,7 @@ import org.jackhuang.hmcl.ui.SVG; import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.TransitionPane; import org.jackhuang.hmcl.ui.construct.*; +import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.util.io.FileUtils; @@ -43,9 +44,8 @@ import java.util.Optional; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -public class VersionPage extends Control implements DecoratorPage { +public class VersionPage extends DecoratorAnimatedPage implements DecoratorPage { private final ReadOnlyObjectWrapper state = new ReadOnlyObjectWrapper<>(); - private final BooleanProperty loading = new SimpleBooleanProperty(); private final TabHeader tab; private final TabHeader.Tab versionSettingsTab = new TabHeader.Tab<>("versionSettingsTab"); private final TabHeader.Tab modListTab = new TabHeader.Tab<>("modListTab"); @@ -186,7 +186,7 @@ public class VersionPage extends Control implements DecoratorPage { return state.getReadOnlyProperty(); } - public static class Skin extends SkinBase { + public static class Skin extends DecoratorAnimatedPageSkin { /** * Constructor for all SkinBase instances. @@ -196,16 +196,10 @@ public class VersionPage extends Control implements DecoratorPage { protected Skin(VersionPage control) { super(control); - SpinnerPane spinnerPane = new SpinnerPane(); - spinnerPane.getStyleClass().add("large-spinner-pane"); - - // the root page, with the sidebar in left, navigator in center. - BorderPane root = new BorderPane(); - { BorderPane left = new BorderPane(); FXUtils.setLimitWidth(left, 200); - root.setLeft(left); + setLeft(left); AdvancedListItem versionSettingsItem = new AdvancedListItem(); versionSettingsItem.getStyleClass().add("navigation-drawer-item"); @@ -244,8 +238,7 @@ public class VersionPage extends Control implements DecoratorPage { .add(modListItem) .add(installerListItem) .add(worldListItem); - left.setCenter(sideBar); - + VBox.setVgrow(sideBar, Priority.ALWAYS); PopupMenu browseList = new PopupMenu(); JFXPopup browsePopup = new JFXPopup(browseList); @@ -298,7 +291,8 @@ public class VersionPage extends Control implements DecoratorPage { }); toolbar.getStyleClass().add("advanced-list-box-clear-padding"); FXUtils.setLimitHeight(toolbar, 40 * 4 + 12 * 2); - left.setBottom(toolbar); + + setLeft(sideBar, toolbar); } control.state.bind(Bindings.createObjectBinding(() -> @@ -307,11 +301,7 @@ public class VersionPage extends Control implements DecoratorPage { //control.transitionPane.getStyleClass().add("gray-background"); //FXUtils.setOverflowHidden(control.transitionPane, 8); - root.setCenter(control.transitionPane); - - spinnerPane.loadingProperty().bind(control.loading); - spinnerPane.setContent(root); - getChildren().setAll(spinnerPane); + setCenter(control.transitionPane); } }