fix: ModListPage not loading mods.
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user