fix: ModListPage not loading mods.

This commit is contained in:
huanghongxun
2021-08-04 01:29:07 +08:00
parent 5ddb69077f
commit 53c63db150
11 changed files with 118 additions and 101 deletions

View File

@@ -114,13 +114,14 @@ public final class FXUtils {
return onWeakChange(value, consumer); return onWeakChange(value, consumer);
} }
public static WeakInvalidationListener observeWeak(Runnable runnable, Observable... observables) { public static InvalidationListener observeWeak(Runnable runnable, Observable... observables) {
WeakInvalidationListener listener = new WeakInvalidationListener(observable -> runnable.run()); InvalidationListener originalListener = observable -> runnable.run();
WeakInvalidationListener listener = new WeakInvalidationListener(originalListener);
for (Observable observable : observables) { for (Observable observable : observables) {
observable.addListener(listener); observable.addListener(listener);
} }
runnable.run(); runnable.run();
return listener; return originalListener;
} }
public static void runLaterIf(BooleanSupplier condition, Runnable runnable) { public static void runLaterIf(BooleanSupplier condition, Runnable runnable) {

View File

@@ -19,7 +19,7 @@ package org.jackhuang.hmcl.ui.construct;
import com.jfoenix.controls.JFXSpinner; import com.jfoenix.controls.JFXSpinner;
import javafx.beans.DefaultProperty; import javafx.beans.DefaultProperty;
import javafx.beans.WeakInvalidationListener; import javafx.beans.InvalidationListener;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Control; import javafx.scene.control.Control;
@@ -94,7 +94,7 @@ public class SpinnerPane extends Control {
private final StackPane failedPane = new StackPane(); private final StackPane failedPane = new StackPane();
private final Label failedReasonLabel = new Label(); private final Label failedReasonLabel = new Label();
@SuppressWarnings("FieldCanBeLocal") // prevent from gc. @SuppressWarnings("FieldCanBeLocal") // prevent from gc.
private final WeakInvalidationListener observer; private final InvalidationListener observer;
protected Skin(SpinnerPane control) { protected Skin(SpinnerPane control) {
super(control); super(control);

View File

@@ -27,9 +27,9 @@ import javafx.scene.control.SingleSelectionModel;
import java.util.function.Supplier; import java.util.function.Supplier;
public interface TabControl { public interface TabControl {
ObservableList<Tab> getTabs(); ObservableList<Tab<?>> getTabs();
class TabControlSelectionModel extends SingleSelectionModel<Tab> { class TabControlSelectionModel extends SingleSelectionModel<Tab<?>> {
private final TabControl tabHeader; private final TabControl tabHeader;
public TabControlSelectionModel(final TabControl t) { public TabControlSelectionModel(final TabControl t) {
@@ -39,9 +39,9 @@ public interface TabControl {
this.tabHeader = t; this.tabHeader = t;
// watching for changes to the items list content // watching for changes to the items list content
final ListChangeListener<Tab> itemsContentObserver = c -> { final ListChangeListener<Tab<?>> itemsContentObserver = c -> {
while (c.next()) { while (c.next()) {
for (Tab tab : c.getRemoved()) { for (Tab<?> tab : c.getRemoved()) {
if (tab != null && !tabHeader.getTabs().contains(tab)) { if (tab != null && !tabHeader.getTabs().contains(tab)) {
if (tab.isSelected()) { if (tab.isSelected()) {
tab.setSelected(false); tab.setSelected(false);
@@ -117,29 +117,29 @@ public interface TabControl {
} }
} }
@Override protected Tab getModelItem(int index) { @Override protected Tab<?> getModelItem(int index) {
final ObservableList<Tab> items = tabHeader.getTabs(); final ObservableList<Tab<?>> items = tabHeader.getTabs();
if (items == null) return null; if (items == null) return null;
if (index < 0 || index >= items.size()) return null; if (index < 0 || index >= items.size()) return null;
return items.get(index); return items.get(index);
} }
@Override protected int getItemCount() { @Override protected int getItemCount() {
final ObservableList<Tab> items = tabHeader.getTabs(); final ObservableList<Tab<?>> items = tabHeader.getTabs();
return items == null ? 0 : items.size(); return items == null ? 0 : items.size();
} }
private Tab findNearestAvailableTab(int tabIndex, boolean doSelect) { private Tab<?> findNearestAvailableTab(int tabIndex, boolean doSelect) {
// we always try to select the nearest, non-disabled // we always try to select the nearest, non-disabled
// tab from the position of the closed tab. // tab from the position of the closed tab.
final int tabCount = getItemCount(); final int tabCount = getItemCount();
int i = 1; int i = 1;
Tab bestTab = null; Tab<?> bestTab = null;
while (true) { while (true) {
// look leftwards // look leftwards
int downPos = tabIndex - i; int downPos = tabIndex - i;
if (downPos >= 0) { if (downPos >= 0) {
Tab _tab = getModelItem(downPos); Tab<?> _tab = getModelItem(downPos);
if (_tab != null) { if (_tab != null) {
bestTab = _tab; bestTab = _tab;
break; break;
@@ -153,7 +153,7 @@ public interface TabControl {
// the removed tabs position). // the removed tabs position).
int upPos = tabIndex + i - 1; int upPos = tabIndex + i - 1;
if (upPos < tabCount) { if (upPos < tabCount) {
Tab _tab = getModelItem(upPos); Tab<?> _tab = getModelItem(upPos);
if (_tab != null) { if (_tab != null) {
bestTab = _tab; bestTab = _tab;
break; break;
@@ -174,12 +174,12 @@ public interface TabControl {
} }
} }
class Tab { class Tab<T extends Node> {
private final StringProperty id = new SimpleStringProperty(this, "id"); private final StringProperty id = new SimpleStringProperty(this, "id");
private final StringProperty text = new SimpleStringProperty(this, "text"); private final StringProperty text = new SimpleStringProperty(this, "text");
private final ReadOnlyBooleanWrapper selected = new ReadOnlyBooleanWrapper(this, "selected"); private final ReadOnlyBooleanWrapper selected = new ReadOnlyBooleanWrapper(this, "selected");
private final ObjectProperty<Node> node = new SimpleObjectProperty<>(this, "node"); private final ObjectProperty<T> node = new SimpleObjectProperty<>(this, "node");
private Supplier<Node> nodeSupplier; private Supplier<? extends T> nodeSupplier;
public Tab(String id) { public Tab(String id) {
setId(id); setId(id);
@@ -190,11 +190,11 @@ public interface TabControl {
setText(text); setText(text);
} }
public Supplier<Node> getNodeSupplier() { public Supplier<? extends T> getNodeSupplier() {
return nodeSupplier; return nodeSupplier;
} }
public void setNodeSupplier(Supplier<Node> nodeSupplier) { public void setNodeSupplier(Supplier<? extends T> nodeSupplier) {
this.nodeSupplier = nodeSupplier; this.nodeSupplier = nodeSupplier;
} }
@@ -234,16 +234,27 @@ public interface TabControl {
this.selected.set(selected); this.selected.set(selected);
} }
public Node getNode() { public T getNode() {
return node.get(); return node.get();
} }
public ObjectProperty<Node> nodeProperty() { public ObjectProperty<T> nodeProperty() {
return node; return node;
} }
public void setNode(Node node) { public void setNode(T node) {
this.node.set(node); this.node.set(node);
} }
public boolean initializeIfNeeded() {
if (getNode() == null) {
if (getNodeSupplier() == null) {
return false;
}
setNode(getNodeSupplier().get());
return true;
}
return false;
}
} }
} }

View File

@@ -41,32 +41,32 @@ import org.jackhuang.hmcl.util.javafx.MappedObservableList;
public class TabHeader extends Control implements TabControl { public class TabHeader extends Control implements TabControl {
public TabHeader(Tab... tabs) { public TabHeader(Tab<?>... tabs) {
getStyleClass().setAll("tab-header"); getStyleClass().setAll("tab-header");
if (tabs != null) { if (tabs != null) {
getTabs().addAll(tabs); getTabs().addAll(tabs);
} }
} }
private ObservableList<Tab> tabs = FXCollections.observableArrayList(); private ObservableList<Tab<?>> tabs = FXCollections.observableArrayList();
private ObjectProperty<Side> side = new SimpleObjectProperty<>(Side.TOP); private ObjectProperty<Side> side = new SimpleObjectProperty<>(Side.TOP);
@Override @Override
public ObservableList<Tab> getTabs() { public ObservableList<Tab<?>> getTabs() {
return tabs; return tabs;
} }
private final ObjectProperty<SingleSelectionModel<Tab>> selectionModel = new SimpleObjectProperty<>(this, "selectionModel", new TabControlSelectionModel(this)); private final ObjectProperty<SingleSelectionModel<Tab<?>>> selectionModel = new SimpleObjectProperty<>(this, "selectionModel", new TabControlSelectionModel(this));
public SingleSelectionModel<Tab> getSelectionModel() { public SingleSelectionModel<Tab<?>> getSelectionModel() {
return selectionModel.get(); return selectionModel.get();
} }
public ObjectProperty<SingleSelectionModel<Tab>> selectionModelProperty() { public ObjectProperty<SingleSelectionModel<Tab<?>>> selectionModelProperty() {
return selectionModel; return selectionModel;
} }
public void setSelectionModel(SingleSelectionModel<Tab> selectionModel) { public void setSelectionModel(SingleSelectionModel<Tab<?>> selectionModel) {
this.selectionModel.set(selectionModel); this.selectionModel.set(selectionModel);
} }
@@ -104,7 +104,7 @@ public class TabHeader extends Control implements TabControl {
private final HeaderContainer header; private final HeaderContainer header;
private boolean isSelectingTab = false; private boolean isSelectingTab = false;
private Tab selectedTab; private Tab<?> selectedTab;
protected TabHeaderSkin(TabHeader control) { protected TabHeaderSkin(TabHeader control) {
super(control); super(control);
@@ -537,12 +537,12 @@ public class TabHeader extends Control implements TabControl {
protected class TabHeaderContainer extends StackPane { protected class TabHeaderContainer extends StackPane {
private final Tab tab; private final Tab<?> tab;
private final Label tabText; private final Label tabText;
private final BorderPane inner; private final BorderPane inner;
private final JFXRippler rippler; private final JFXRippler rippler;
public TabHeaderContainer(Tab tab) { public TabHeaderContainer(Tab<?> tab) {
this.tab = tab; this.tab = tab;
tabText = new Label(); tabText = new Label();

View File

@@ -32,9 +32,7 @@ public abstract class DecoratorTabPage extends DecoratorTransitionPage implement
public DecoratorTabPage() { public DecoratorTabPage() {
getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> { getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> {
if (newValue.getNode() == null && newValue.getNodeSupplier() != null) { newValue.initializeIfNeeded();
newValue.setNode(newValue.getNodeSupplier().get());
}
if (newValue.getNode() != null) { if (newValue.getNode() != null) {
onNavigating(getCurrentPage()); onNavigating(getCurrentPage());
if (getCurrentPage() != null) getCurrentPage().fireEvent(new Navigator.NavigationEvent(null, getCurrentPage(), Navigation.NavigationDirection.NEXT, Navigator.NavigationEvent.NAVIGATING)); if (getCurrentPage() != null) getCurrentPage().fireEvent(new Navigator.NavigationEvent(null, getCurrentPage(), Navigation.NavigationDirection.NEXT, Navigator.NavigationEvent.NAVIGATING));
@@ -45,31 +43,31 @@ public abstract class DecoratorTabPage extends DecoratorTransitionPage implement
}); });
} }
public DecoratorTabPage(TabHeader.Tab... tabs) { public DecoratorTabPage(TabHeader.Tab<?>... tabs) {
this(); this();
if (tabs != null) { if (tabs != null) {
getTabs().addAll(tabs); getTabs().addAll(tabs);
} }
} }
private ObservableList<TabHeader.Tab> tabs = FXCollections.observableArrayList(); private ObservableList<TabHeader.Tab<?>> tabs = FXCollections.observableArrayList();
@Override @Override
public ObservableList<TabHeader.Tab> getTabs() { public ObservableList<TabHeader.Tab<?>> getTabs() {
return tabs; return tabs;
} }
private final ObjectProperty<SingleSelectionModel<TabHeader.Tab>> selectionModel = new SimpleObjectProperty<>(this, "selectionModel", new TabControl.TabControlSelectionModel(this)); private final ObjectProperty<SingleSelectionModel<TabHeader.Tab<?>>> selectionModel = new SimpleObjectProperty<>(this, "selectionModel", new TabControl.TabControlSelectionModel(this));
public SingleSelectionModel<TabHeader.Tab> getSelectionModel() { public SingleSelectionModel<TabHeader.Tab<?>> getSelectionModel() {
return selectionModel.get(); return selectionModel.get();
} }
public ObjectProperty<SingleSelectionModel<TabHeader.Tab>> selectionModelProperty() { public ObjectProperty<SingleSelectionModel<TabHeader.Tab<?>>> selectionModelProperty() {
return selectionModel; return selectionModel;
} }
public void setSelectionModel(SingleSelectionModel<TabHeader.Tab> selectionModel) { public void setSelectionModel(SingleSelectionModel<TabHeader.Tab<?>> selectionModel) {
this.selectionModel.set(selectionModel); this.selectionModel.set(selectionModel);
} }
} }

View File

@@ -44,7 +44,7 @@ import java.util.function.Function;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX; import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class InstallerListPage extends ListPageBase<InstallerItem> { public class InstallerListPage extends ListPageBase<InstallerItem> implements VersionPage.VersionLoadable {
private Profile profile; private Profile profile;
private String versionId; private String versionId;
private Version version; private Version version;
@@ -62,13 +62,14 @@ public class InstallerListPage extends ListPageBase<InstallerItem> {
return new InstallerListPageSkin(); return new InstallerListPageSkin();
} }
public CompletableFuture<?> loadVersion(Profile profile, String versionId) { @Override
public void loadVersion(Profile profile, String versionId) {
this.profile = profile; this.profile = profile;
this.versionId = versionId; this.versionId = versionId;
this.version = profile.getRepository().getVersion(versionId); this.version = profile.getRepository().getVersion(versionId);
this.gameVersion = null; this.gameVersion = null;
return CompletableFuture.supplyAsync(() -> { CompletableFuture.supplyAsync(() -> {
gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)).orElse(null); gameVersion = GameVersion.minecraftVersion(profile.getRepository().getVersionJar(version)).orElse(null);
return LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(versionId)); return LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(versionId));

View File

@@ -47,7 +47,7 @@ import java.util.stream.Collectors;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class ModDownloadListPage extends Control implements DecoratorPage { public class ModDownloadListPage extends Control implements DecoratorPage, VersionPage.VersionLoadable {
protected final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(); protected final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>();
private final BooleanProperty loading = new SimpleBooleanProperty(false); private final BooleanProperty loading = new SimpleBooleanProperty(false);
private final BooleanProperty failed = new SimpleBooleanProperty(false); private final BooleanProperty failed = new SimpleBooleanProperty(false);
@@ -66,6 +66,7 @@ public class ModDownloadListPage extends Control implements DecoratorPage {
this.callback = callback; this.callback = callback;
} }
@Override
public void loadVersion(Profile profile, String version) { public void loadVersion(Profile profile, String version) {
this.version.set(new Profile.ProfileVersion(profile, version)); this.version.set(new Profile.ProfileVersion(profile, version));

View File

@@ -32,7 +32,6 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.ListPageBase; import org.jackhuang.hmcl.ui.ListPageBase;
import org.jackhuang.hmcl.ui.construct.TabHeader;
import org.jackhuang.hmcl.util.Logging; import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.FileUtils;
@@ -50,16 +49,13 @@ import java.util.stream.Collectors;
import static org.jackhuang.hmcl.ui.FXUtils.runInFX; import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObject> { public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObject> implements VersionPage.VersionLoadable {
private final BooleanProperty modded = new SimpleBooleanProperty(this, "modded", false); private final BooleanProperty modded = new SimpleBooleanProperty(this, "modded", false);
private TabHeader.Tab tab;
private ModManager modManager; private ModManager modManager;
private LibraryAnalyzer libraryAnalyzer; private LibraryAnalyzer libraryAnalyzer;
public ModListPage(TabHeader.Tab tab) { public ModListPage() {
this.tab = tab;
FXUtils.applyDragListener(this, it -> Arrays.asList("jar", "zip", "litemod").contains(FileUtils.getExtension(it)), mods -> { FXUtils.applyDragListener(this, it -> Arrays.asList("jar", "zip", "litemod").contains(FileUtils.getExtension(it)), mods -> {
mods.forEach(it -> { mods.forEach(it -> {
try { try {
@@ -81,10 +77,11 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
loadMods(modManager); loadMods(modManager);
} }
public CompletableFuture<?> loadVersion(Profile profile, String id) { @Override
public void loadVersion(Profile profile, String id) {
libraryAnalyzer = LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(id)); libraryAnalyzer = LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(id));
modded.set(libraryAnalyzer.hasModLoader()); modded.set(libraryAnalyzer.hasModLoader());
return loadMods(profile.getRepository().getModManager(id)); loadMods(profile.getRepository().getModManager(id));
} }
private CompletableFuture<?> loadMods(ModManager modManager) { private CompletableFuture<?> loadMods(ModManager modManager) {
@@ -99,13 +96,10 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
} catch (IOException e) { } catch (IOException e) {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);
} }
}).whenCompleteAsync((list, exception) -> { }, Schedulers.defaultScheduler()).whenCompleteAsync((list, exception) -> {
loadingProperty().set(false); loadingProperty().set(false);
if (exception == null) if (exception == null)
getProperties().put(ModListPage.class, FXUtils.onWeakChangeAndOperate(tab.selectedProperty(), newValue -> { itemsProperty().setAll(list.stream().map(ModListPageSkin.ModInfoObject::new).sorted().collect(Collectors.toList()));
if (newValue)
itemsProperty().setAll(list.stream().map(ModListPageSkin.ModInfoObject::new).sorted().collect(Collectors.toList()));
}));
else else
getProperties().remove(ModListPage.class); getProperties().remove(ModListPage.class);
}, Platform::runLater); }, Platform::runLater);

View File

@@ -48,41 +48,45 @@ import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class VersionPage extends Control implements DecoratorPage, ModDownloadPage.DownloadCallback { public class VersionPage extends Control implements DecoratorPage, ModDownloadPage.DownloadCallback {
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(); private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>();
private final BooleanProperty loading = new SimpleBooleanProperty(); private final BooleanProperty loading = new SimpleBooleanProperty();
private final TabHeader.Tab versionSettingsTab = new TabHeader.Tab("versionSettingsTab"); private final TabHeader tab;
private final VersionSettingsPage versionSettingsPage = new VersionSettingsPage(); private final TabHeader.Tab<VersionSettingsPage> versionSettingsTab = new TabHeader.Tab<>("versionSettingsTab");
private final TabHeader.Tab modListTab = new TabHeader.Tab("modListTab"); private final TabHeader.Tab<ModListPage> modListTab = new TabHeader.Tab<>("modListTab");
private final ModListPage modListPage = new ModListPage(modListTab); private final TabHeader.Tab<ModDownloadListPage> curseModListTab = new TabHeader.Tab<>("modListTab");
private final TabHeader.Tab curseModListTab = new TabHeader.Tab("modListTab"); private final TabHeader.Tab<InstallerListPage> installerListTab = new TabHeader.Tab<>("installerListTab");
private final ModDownloadListPage curseModListPage = new ModDownloadListPage(CurseModManager.SECTION_MOD, this); private final TabHeader.Tab<WorldListPage> worldListTab = new TabHeader.Tab<>("worldList");
private final TabHeader.Tab installerListTab = new TabHeader.Tab("installerListTab");
private final InstallerListPage installerListPage = new InstallerListPage();
private final TabHeader.Tab worldListTab = new TabHeader.Tab("worldList");
private final WorldListPage worldListPage = new WorldListPage();
private final TransitionPane transitionPane = new TransitionPane(); private final TransitionPane transitionPane = new TransitionPane();
private final ObjectProperty<TabHeader.Tab> selectedTab = new SimpleObjectProperty<>();
private final BooleanProperty currentVersionUpgradable = new SimpleBooleanProperty(); private final BooleanProperty currentVersionUpgradable = new SimpleBooleanProperty();
private final ObjectProperty<Profile.ProfileVersion> version = new SimpleObjectProperty<>(); private final ObjectProperty<Profile.ProfileVersion> version = new SimpleObjectProperty<>();
private String preferredVersionName = null; private String preferredVersionName = null;
{ {
versionSettingsTab.setNode(versionSettingsPage); versionSettingsTab.setNodeSupplier(VersionSettingsPage::new);
modListTab.setNode(modListPage); modListTab.setNodeSupplier(ModListPage::new);
curseModListTab.setNode(curseModListPage); curseModListTab.setNodeSupplier(() -> new ModDownloadListPage(CurseModManager.SECTION_MOD, this));
installerListTab.setNode(installerListPage); installerListTab.setNodeSupplier(InstallerListPage::new);
worldListTab.setNode(worldListPage); worldListTab.setNodeSupplier(WorldListPage::new);
tab = new TabHeader(versionSettingsTab, modListTab, curseModListTab, installerListTab, worldListTab);
addEventHandler(Navigator.NavigationEvent.NAVIGATED, this::onNavigated); addEventHandler(Navigator.NavigationEvent.NAVIGATED, this::onNavigated);
selectedTab.set(versionSettingsTab); tab.getSelectionModel().select(versionSettingsTab);
FXUtils.onChangeAndOperate(selectedTab, newValue -> { FXUtils.onChangeAndOperate(tab.getSelectionModel().selectedItemProperty(), newValue -> {
if (newValue.initializeIfNeeded()) {
if (this.version.get() != null) {
if (newValue.getNode() instanceof VersionLoadable) {
((VersionLoadable) newValue.getNode()).loadVersion(version.get().getProfile(), version.get().getVersion());
}
}
}
transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer()); transitionPane.setContent(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer());
}); });
} }
@@ -103,14 +107,17 @@ public class VersionPage extends Control implements DecoratorPage, ModDownloadPa
setVersion(version, profile); setVersion(version, profile);
preferredVersionName = version; preferredVersionName = version;
versionSettingsPage.loadVersion(profile, version); if (versionSettingsTab.getNode() != null)
curseModListPage.loadVersion(profile, version); versionSettingsTab.getNode().loadVersion(profile, version);
if (modListTab.getNode() != null)
modListTab.getNode().loadVersion(profile, version);
if (curseModListTab.getNode() != null)
curseModListTab.getNode().loadVersion(profile, version);
if (installerListTab.getNode() != null)
installerListTab.getNode().loadVersion(profile, version);
if (worldListTab.getNode() != null)
worldListTab.getNode().loadVersion(profile, version);
currentVersionUpgradable.set(profile.getRepository().isModpack(version)); currentVersionUpgradable.set(profile.getRepository().isModpack(version));
CompletableFuture.allOf(
modListPage.loadVersion(profile, version),
installerListPage.loadVersion(profile, version),
worldListPage.loadVersion(profile, version));
} }
private void onNavigated(Navigator.NavigationEvent event) { private void onNavigated(Navigator.NavigationEvent event) {
@@ -269,40 +276,40 @@ public class VersionPage extends Control implements DecoratorPage, ModDownloadPa
versionSettingsItem.setTitle(i18n("settings")); versionSettingsItem.setTitle(i18n("settings"));
versionSettingsItem.setLeftGraphic(wrap(SVG.gearOutline(null, 20, 20))); versionSettingsItem.setLeftGraphic(wrap(SVG.gearOutline(null, 20, 20)));
versionSettingsItem.setActionButtonVisible(false); versionSettingsItem.setActionButtonVisible(false);
versionSettingsItem.activeProperty().bind(control.selectedTab.isEqualTo(control.versionSettingsTab)); versionSettingsItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.versionSettingsTab));
versionSettingsItem.setOnAction(e -> control.selectedTab.set(control.versionSettingsTab)); versionSettingsItem.setOnAction(e -> control.tab.getSelectionModel().select(control.versionSettingsTab));
AdvancedListItem modListItem = new AdvancedListItem(); AdvancedListItem modListItem = new AdvancedListItem();
modListItem.getStyleClass().add("navigation-drawer-item"); modListItem.getStyleClass().add("navigation-drawer-item");
modListItem.setTitle(i18n("mods")); modListItem.setTitle(i18n("mods"));
modListItem.setLeftGraphic(wrap(SVG.puzzle(null, 20, 20))); modListItem.setLeftGraphic(wrap(SVG.puzzle(null, 20, 20)));
modListItem.setActionButtonVisible(false); modListItem.setActionButtonVisible(false);
modListItem.activeProperty().bind(control.selectedTab.isEqualTo(control.modListTab)); modListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.modListTab));
modListItem.setOnAction(e -> control.selectedTab.set(control.modListTab)); modListItem.setOnAction(e -> control.tab.getSelectionModel().select(control.modListTab));
AdvancedListItem curseModListItem = new AdvancedListItem(); AdvancedListItem curseModListItem = new AdvancedListItem();
curseModListItem.getStyleClass().add("navigation-drawer-item"); curseModListItem.getStyleClass().add("navigation-drawer-item");
curseModListItem.setTitle(i18n("mods.download")); curseModListItem.setTitle(i18n("mods.download"));
curseModListItem.setLeftGraphic(wrap(SVG.fire(null, 20, 20))); curseModListItem.setLeftGraphic(wrap(SVG.fire(null, 20, 20)));
curseModListItem.setActionButtonVisible(false); curseModListItem.setActionButtonVisible(false);
curseModListItem.activeProperty().bind(control.selectedTab.isEqualTo(control.curseModListTab)); curseModListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.curseModListTab));
curseModListItem.setOnAction(e -> control.selectedTab.set(control.curseModListTab)); curseModListItem.setOnAction(e -> control.tab.getSelectionModel().select(control.curseModListTab));
AdvancedListItem installerListItem = new AdvancedListItem(); AdvancedListItem installerListItem = new AdvancedListItem();
installerListItem.getStyleClass().add("navigation-drawer-item"); installerListItem.getStyleClass().add("navigation-drawer-item");
installerListItem.setTitle(i18n("settings.tabs.installers")); installerListItem.setTitle(i18n("settings.tabs.installers"));
installerListItem.setLeftGraphic(wrap(SVG.cube(null, 20, 20))); installerListItem.setLeftGraphic(wrap(SVG.cube(null, 20, 20)));
installerListItem.setActionButtonVisible(false); installerListItem.setActionButtonVisible(false);
installerListItem.activeProperty().bind(control.selectedTab.isEqualTo(control.installerListTab)); installerListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.installerListTab));
installerListItem.setOnAction(e -> control.selectedTab.set(control.installerListTab)); installerListItem.setOnAction(e -> control.tab.getSelectionModel().select(control.installerListTab));
AdvancedListItem worldListItem = new AdvancedListItem(); AdvancedListItem worldListItem = new AdvancedListItem();
worldListItem.getStyleClass().add("navigation-drawer-item"); worldListItem.getStyleClass().add("navigation-drawer-item");
worldListItem.setTitle(i18n("world")); worldListItem.setTitle(i18n("world"));
worldListItem.setLeftGraphic(wrap(SVG.gamepad(null, 20, 20))); worldListItem.setLeftGraphic(wrap(SVG.gamepad(null, 20, 20)));
worldListItem.setActionButtonVisible(false); worldListItem.setActionButtonVisible(false);
worldListItem.activeProperty().bind(control.selectedTab.isEqualTo(control.worldListTab)); worldListItem.activeProperty().bind(control.tab.getSelectionModel().selectedItemProperty().isEqualTo(control.worldListTab));
worldListItem.setOnAction(e -> control.selectedTab.set(control.worldListTab)); worldListItem.setOnAction(e -> control.tab.getSelectionModel().select(control.worldListTab));
AdvancedListBox sideBar = new AdvancedListBox() AdvancedListBox sideBar = new AdvancedListBox()
.add(versionSettingsItem) .add(versionSettingsItem)
@@ -403,4 +410,7 @@ public class VersionPage extends Control implements DecoratorPage, ModDownloadPa
return stackPane; return stackPane;
} }
interface VersionLoadable {
void loadVersion(Profile profile, String version);
}
} }

View File

@@ -67,7 +67,7 @@ import static org.jackhuang.hmcl.ui.FXUtils.newImage;
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter; import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public final class VersionSettingsPage extends StackPane implements DecoratorPage { public final class VersionSettingsPage extends StackPane implements DecoratorPage, VersionPage.VersionLoadable {
private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(new State("", null, false, false, false)); private final ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(new State("", null, false, false, false));
private VersionSetting lastVersionSetting = null; private VersionSetting lastVersionSetting = null;
@@ -168,6 +168,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
advancedSettingsPane.disableProperty().bind(chkEnableSpecificSettings.selectedProperty().not()); advancedSettingsPane.disableProperty().bind(chkEnableSpecificSettings.selectedProperty().not());
} }
@Override
public void loadVersion(Profile profile, String versionId) { public void loadVersion(Profile profile, String versionId) {
this.profile = profile; this.profile = profile;
this.versionId = versionId; this.versionId = versionId;

View File

@@ -47,7 +47,7 @@ import java.util.stream.Stream;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class WorldListPage extends ListPageBase<WorldListItem> { public class WorldListPage extends ListPageBase<WorldListItem> implements VersionPage.VersionLoadable {
private final BooleanProperty showAll = new SimpleBooleanProperty(this, "showAll", false); private final BooleanProperty showAll = new SimpleBooleanProperty(this, "showAll", false);
private Path savesDir; private Path savesDir;
@@ -74,11 +74,11 @@ public class WorldListPage extends ListPageBase<WorldListItem> {
return new WorldListPageSkin(); return new WorldListPageSkin();
} }
public CompletableFuture<?> loadVersion(Profile profile, String id) { public void loadVersion(Profile profile, String id) {
this.profile = profile; this.profile = profile;
this.id = id; this.id = id;
this.savesDir = profile.getRepository().getRunDirectory(id).toPath().resolve("saves"); this.savesDir = profile.getRepository().getRunDirectory(id).toPath().resolve("saves");
return refresh(); refresh();
} }
public CompletableFuture<?> refresh() { public CompletableFuture<?> refresh() {