优化游戏下载界面 (#4405)
This commit is contained in:
@@ -52,6 +52,7 @@ import javafx.stage.Stage;
|
|||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
import org.jackhuang.hmcl.task.CacheFileTask;
|
import org.jackhuang.hmcl.task.CacheFileTask;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
@@ -1159,6 +1160,13 @@ public final class FXUtils {
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static JFXButton newToggleButton4(SVG icon) {
|
||||||
|
JFXButton button = new JFXButton();
|
||||||
|
button.getStyleClass().add("toggle-icon4");
|
||||||
|
button.setGraphic(icon.createIcon(Theme.blackFill(), -1));
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
public static Label truncatedLabel(String text, int limit) {
|
public static Label truncatedLabel(String text, int limit) {
|
||||||
Label label = new Label();
|
Label label = new Label();
|
||||||
if (text.length() <= limit) {
|
if (text.length() <= limit) {
|
||||||
|
|||||||
@@ -19,12 +19,13 @@ package org.jackhuang.hmcl.ui.download;
|
|||||||
|
|
||||||
import com.jfoenix.controls.*;
|
import com.jfoenix.controls.*;
|
||||||
import javafx.beans.InvalidationListener;
|
import javafx.beans.InvalidationListener;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.*;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
@@ -41,7 +42,6 @@ import org.jackhuang.hmcl.download.neoforge.NeoForgeRemoteVersion;
|
|||||||
import org.jackhuang.hmcl.download.optifine.OptiFineRemoteVersion;
|
import org.jackhuang.hmcl.download.optifine.OptiFineRemoteVersion;
|
||||||
import org.jackhuang.hmcl.download.quilt.QuiltAPIRemoteVersion;
|
import org.jackhuang.hmcl.download.quilt.QuiltAPIRemoteVersion;
|
||||||
import org.jackhuang.hmcl.download.quilt.QuiltRemoteVersion;
|
import org.jackhuang.hmcl.download.quilt.QuiltRemoteVersion;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
|
||||||
import org.jackhuang.hmcl.setting.VersionIconType;
|
import org.jackhuang.hmcl.setting.VersionIconType;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
@@ -73,17 +73,23 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
|
|||||||
private final String libraryId;
|
private final String libraryId;
|
||||||
private final String title;
|
private final String title;
|
||||||
private final Navigation navigation;
|
private final Navigation navigation;
|
||||||
|
private final DownloadProvider downloadProvider;
|
||||||
private final VersionList<?> versionList;
|
private final VersionList<?> versionList;
|
||||||
private final Runnable callback;
|
private final Runnable callback;
|
||||||
|
|
||||||
private final ObservableList<RemoteVersion> versions = FXCollections.observableArrayList();
|
private final ObservableList<RemoteVersion> versions = FXCollections.observableArrayList();
|
||||||
private final ObjectProperty<Status> status = new SimpleObjectProperty<>(Status.LOADING);
|
private final ObjectProperty<Status> status = new SimpleObjectProperty<>(Status.LOADING);
|
||||||
|
|
||||||
public VersionsPage(Navigation navigation, String title, String gameVersion, DownloadProvider downloadProvider, String libraryId, Runnable callback) {
|
public VersionsPage(Navigation navigation,
|
||||||
|
String title, String gameVersion,
|
||||||
|
DownloadProvider downloadProvider,
|
||||||
|
String libraryId,
|
||||||
|
Runnable callback) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.gameVersion = gameVersion;
|
this.gameVersion = gameVersion;
|
||||||
this.libraryId = libraryId;
|
this.libraryId = libraryId;
|
||||||
this.navigation = navigation;
|
this.navigation = navigation;
|
||||||
|
this.downloadProvider = downloadProvider;
|
||||||
this.versionList = downloadProvider.getVersionListById(libraryId);
|
this.versionList = downloadProvider.getVersionListById(libraryId);
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
|
||||||
@@ -130,10 +136,6 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
|
|||||||
navigation.onPrev(true);
|
navigation.onPrev(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSponsor() {
|
|
||||||
FXUtils.openLink("https://bmclapidoc.bangbang93.com");
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum Status {
|
private enum Status {
|
||||||
LOADING,
|
LOADING,
|
||||||
FAILED,
|
FAILED,
|
||||||
@@ -149,22 +151,61 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class RemoteVersionListCell extends ListCell<RemoteVersion> {
|
private static class RemoteVersionListCell extends ListCell<RemoteVersion> {
|
||||||
private final IconedTwoLineListItem content = new IconedTwoLineListItem();
|
private final VersionsPage control;
|
||||||
private final RipplerContainer ripplerContainer = new RipplerContainer(content);
|
|
||||||
|
private final TwoLineListItem twoLineListItem = new TwoLineListItem();
|
||||||
|
private final ImageView imageView = new ImageView();
|
||||||
private final StackPane pane = new StackPane();
|
private final StackPane pane = new StackPane();
|
||||||
|
|
||||||
private final Holder<RemoteVersionListCell> lastCell;
|
private final Holder<RemoteVersionListCell> lastCell;
|
||||||
|
|
||||||
RemoteVersionListCell(Holder<RemoteVersionListCell> lastCell, String libraryId) {
|
RemoteVersionListCell(Holder<RemoteVersionListCell> lastCell, VersionsPage control) {
|
||||||
this.lastCell = lastCell;
|
this.lastCell = lastCell;
|
||||||
if ("game".equals(libraryId)) {
|
this.control = control;
|
||||||
content.getExternalLinkButton().setGraphic(SVG.GLOBE_BOOK.createIcon(Theme.blackFill(), -1));
|
|
||||||
FXUtils.installFastTooltip(content.getExternalLinkButton(), i18n("wiki.tooltip"));
|
HBox hbox = new HBox(16);
|
||||||
|
HBox.setHgrow(twoLineListItem, Priority.ALWAYS);
|
||||||
|
hbox.setAlignment(Pos.CENTER);
|
||||||
|
|
||||||
|
HBox actions = new HBox(8);
|
||||||
|
actions.setAlignment(Pos.CENTER);
|
||||||
|
{
|
||||||
|
if ("game".equals(control.libraryId)) {
|
||||||
|
JFXButton wikiButton = newToggleButton4(SVG.GLOBE_BOOK);
|
||||||
|
wikiButton.setOnAction(event -> onOpenWiki());
|
||||||
|
FXUtils.installFastTooltip(wikiButton, i18n("wiki.tooltip"));
|
||||||
|
actions.getChildren().add(wikiButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
JFXButton actionButton = newToggleButton4(SVG.ARROW_FORWARD);
|
||||||
|
actionButton.setOnAction(e -> onAction());
|
||||||
|
actions.getChildren().add(actionButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hbox.getChildren().setAll(imageView, twoLineListItem, actions);
|
||||||
|
|
||||||
pane.getStyleClass().add("md-list-cell");
|
pane.getStyleClass().add("md-list-cell");
|
||||||
StackPane.setMargin(content, new Insets(10, 16, 10, 16));
|
StackPane.setMargin(hbox, new Insets(10, 16, 10, 16));
|
||||||
pane.getChildren().setAll(ripplerContainer);
|
pane.getChildren().setAll(new RipplerContainer(hbox));
|
||||||
|
|
||||||
|
FXUtils.onClicked(this, this::onAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onAction() {
|
||||||
|
RemoteVersion item = getItem();
|
||||||
|
if (item == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
control.navigation.getSettings().put(control.libraryId, item);
|
||||||
|
control.callback.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onOpenWiki() {
|
||||||
|
RemoteVersion item = getItem();
|
||||||
|
if (!(item instanceof GameRemoteVersion))
|
||||||
|
return;
|
||||||
|
|
||||||
|
FXUtils.openLink(I18n.getWikiLink((GameRemoteVersion) item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -182,37 +223,36 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
|
|||||||
}
|
}
|
||||||
setGraphic(pane);
|
setGraphic(pane);
|
||||||
|
|
||||||
content.setTitle(I18n.getDisplaySelfVersion(remoteVersion));
|
twoLineListItem.setTitle(I18n.getDisplaySelfVersion(remoteVersion));
|
||||||
if (remoteVersion.getReleaseDate() != null) {
|
if (remoteVersion.getReleaseDate() != null) {
|
||||||
content.setSubtitle(I18n.formatDateTime(remoteVersion.getReleaseDate()));
|
twoLineListItem.setSubtitle(I18n.formatDateTime(remoteVersion.getReleaseDate()));
|
||||||
} else {
|
} else {
|
||||||
content.setSubtitle(null);
|
twoLineListItem.setSubtitle(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remoteVersion instanceof GameRemoteVersion) {
|
if (remoteVersion instanceof GameRemoteVersion) {
|
||||||
RemoteVersion.Type versionType = remoteVersion.getVersionType();
|
RemoteVersion.Type versionType = remoteVersion.getVersionType();
|
||||||
switch (versionType) {
|
switch (versionType) {
|
||||||
case RELEASE:
|
case RELEASE:
|
||||||
content.getTags().setAll(i18n("version.game.release"));
|
twoLineListItem.getTags().setAll(i18n("version.game.release"));
|
||||||
content.setImage(VersionIconType.GRASS.getIcon());
|
imageView.setImage(VersionIconType.GRASS.getIcon());
|
||||||
break;
|
break;
|
||||||
case PENDING:
|
case PENDING:
|
||||||
case SNAPSHOT:
|
case SNAPSHOT:
|
||||||
if (versionType == RemoteVersion.Type.SNAPSHOT
|
if (versionType == RemoteVersion.Type.SNAPSHOT
|
||||||
&& GameVersionNumber.asGameVersion(remoteVersion.getGameVersion()).isAprilFools()) {
|
&& GameVersionNumber.asGameVersion(remoteVersion.getGameVersion()).isAprilFools()) {
|
||||||
content.getTags().setAll(i18n("version.game.april_fools"));
|
twoLineListItem.getTags().setAll(i18n("version.game.april_fools"));
|
||||||
content.setImage(VersionIconType.APRIL_FOOLS.getIcon());
|
imageView.setImage(VersionIconType.APRIL_FOOLS.getIcon());
|
||||||
} else {
|
} else {
|
||||||
content.getTags().setAll(i18n("version.game.snapshot"));
|
twoLineListItem.getTags().setAll(i18n("version.game.snapshot"));
|
||||||
content.setImage(VersionIconType.COMMAND.getIcon());
|
imageView.setImage(VersionIconType.COMMAND.getIcon());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
content.getTags().setAll(i18n("version.game.old"));
|
twoLineListItem.getTags().setAll(i18n("version.game.old"));
|
||||||
content.setImage(VersionIconType.CRAFT_TABLE.getIcon());
|
imageView.setImage(VersionIconType.CRAFT_TABLE.getIcon());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
content.setExternalLink(I18n.getWikiLink((GameRemoteVersion) remoteVersion));
|
|
||||||
} else {
|
} else {
|
||||||
VersionIconType iconType;
|
VersionIconType iconType;
|
||||||
if (remoteVersion instanceof LiteLoaderRemoteVersion)
|
if (remoteVersion instanceof LiteLoaderRemoteVersion)
|
||||||
@@ -230,14 +270,13 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
|
|||||||
else if (remoteVersion instanceof QuiltRemoteVersion || remoteVersion instanceof QuiltAPIRemoteVersion)
|
else if (remoteVersion instanceof QuiltRemoteVersion || remoteVersion instanceof QuiltAPIRemoteVersion)
|
||||||
iconType = VersionIconType.QUILT;
|
iconType = VersionIconType.QUILT;
|
||||||
else
|
else
|
||||||
iconType = null;
|
iconType = VersionIconType.COMMAND;
|
||||||
|
|
||||||
content.setImage(iconType != null ? iconType.getIcon() : null);
|
imageView.setImage(iconType.getIcon());
|
||||||
if (content.getSubtitle() == null)
|
if (twoLineListItem.getSubtitle() == null)
|
||||||
content.setSubtitle(remoteVersion.getGameVersion());
|
twoLineListItem.setSubtitle(remoteVersion.getGameVersion());
|
||||||
else
|
else
|
||||||
content.getTags().setAll(remoteVersion.getGameVersion());
|
twoLineListItem.getTags().setAll(remoteVersion.getGameVersion());
|
||||||
content.setExternalLink(null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -355,14 +394,7 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
|
|||||||
control.versions.addListener((InvalidationListener) o -> updateList());
|
control.versions.addListener((InvalidationListener) o -> updateList());
|
||||||
|
|
||||||
Holder<RemoteVersionListCell> lastCell = new Holder<>();
|
Holder<RemoteVersionListCell> lastCell = new Holder<>();
|
||||||
list.setCellFactory(listView -> new RemoteVersionListCell(lastCell, control.libraryId));
|
list.setCellFactory(listView -> new RemoteVersionListCell(lastCell, control));
|
||||||
|
|
||||||
FXUtils.onClicked(list, () -> {
|
|
||||||
if (list.getSelectionModel().getSelectedIndex() < 0)
|
|
||||||
return;
|
|
||||||
control.navigation.getSettings().put(control.libraryId, list.getSelectionModel().getSelectedItem());
|
|
||||||
control.callback.run();
|
|
||||||
});
|
|
||||||
|
|
||||||
ComponentList.setVgrow(list, Priority.ALWAYS);
|
ComponentList.setVgrow(list, Priority.ALWAYS);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user