feat(ui): DecoratorAnimatedPage for future animation implementation.

This commit is contained in:
huanghongxun 2021-10-06 16:08:08 +08:00
parent 1cd4470187
commit 135f15dd9f
6 changed files with 88 additions and 128 deletions

View File

@ -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<DecoratorAnimatedPage> {
public static class DecoratorAnimatedPageSkin<T extends DecoratorAnimatedPage> extends SkinBase<T> {
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);
}
}
}

View File

@ -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<DecoratorPage.State> state = new ReadOnlyObjectWrapper<>(DecoratorPage.State.fromTitle(i18n("download"), -1));
private final TabHeader tab;
private final TabHeader.Tab<VersionsPage> newGameTab = new TabHeader.Tab<>("newGameTab");

View File

@ -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> state = new ReadOnlyObjectWrapper<>(State.fromTitle(i18n("multiplayer"), -1));
private final ObjectProperty<MultiplayerManager.State> 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

View File

@ -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<MultiplayerPage> {
public class MultiplayerPageSkin extends DecoratorAnimatedPage.DecoratorAnimatedPageSkin<MultiplayerPage> {
private ObservableList<Node> clients;
@ -60,8 +60,6 @@ public class MultiplayerPageSkin extends SkinBase<MultiplayerPage> {
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<MultiplayerPage> {
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<MultiplayerPage> {
ScrollPane scrollPane = new ScrollPane(content);
scrollPane.setFitToWidth(true);
scrollPane.setFitToHeight(true);
root.setCenter(scrollPane);
setCenter(scrollPane);
ComponentList roomPane = new ComponentList();
{

View File

@ -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<GameListItem> implements DecoratorPage {
public class GameListPage extends DecoratorAnimatedPage implements DecoratorPage {
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(State.fromTitle(i18n("version.manage"), -1));
private final ListProperty<Profile> profiles = new SimpleListProperty<>(FXCollections.observableArrayList());
@SuppressWarnings("FieldCanBeLocal")
@ -58,16 +56,62 @@ public class GameListPage extends ListPageBase<GameListItem> 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<Profile> selectedProfileProperty() {
@ -86,11 +130,6 @@ public class GameListPage extends ListPageBase<GameListItem> 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<GameListItem> implements Decorato
return state.getReadOnlyProperty();
}
private class GameListPageSkin extends SkinBase<GameListPage> {
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<GameListItem> {
public GameList() {
super();

View File

@ -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> state = new ReadOnlyObjectWrapper<>();
private final BooleanProperty loading = new SimpleBooleanProperty();
private final TabHeader tab;
private final TabHeader.Tab<VersionSettingsPage> versionSettingsTab = new TabHeader.Tab<>("versionSettingsTab");
private final TabHeader.Tab<ModListPage> 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<VersionPage> {
public static class Skin extends DecoratorAnimatedPageSkin<VersionPage> {
/**
* 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);
}
}