fix(download): installer items overflow. Closes #1645.

This commit is contained in:
huanghongxun 2022-08-21 21:20:00 +08:00
parent b80c787b60
commit 1fa63a528d
9 changed files with 97 additions and 30 deletions

View File

@ -20,6 +20,7 @@ package org.jackhuang.hmcl.ui;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.css.PseudoClass;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -32,9 +33,7 @@ import javafx.scene.control.SkinBase;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import org.jackhuang.hmcl.download.LibraryAnalyzer; import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.setting.Theme;
import org.jackhuang.hmcl.ui.construct.RipplerContainer; import org.jackhuang.hmcl.ui.construct.RipplerContainer;
@ -59,6 +58,13 @@ public class InstallerItem extends Control {
public final ObjectProperty<EventHandler<? super MouseEvent>> removeAction = new SimpleObjectProperty<>(); public final ObjectProperty<EventHandler<? super MouseEvent>> removeAction = new SimpleObjectProperty<>();
public final ObjectProperty<EventHandler<? super MouseEvent>> action = new SimpleObjectProperty<>(); public final ObjectProperty<EventHandler<? super MouseEvent>> action = new SimpleObjectProperty<>();
private Style style = Style.LIST_ITEM;
public enum Style {
LIST_ITEM,
CARD,
}
public InstallerItem(LibraryAnalyzer.LibraryType id) { public InstallerItem(LibraryAnalyzer.LibraryType id) {
this(id.getPatchId()); this(id.getPatchId());
} }
@ -93,6 +99,10 @@ public class InstallerItem extends Control {
} }
} }
public void setStyleMode(Style style) {
this.style = style;
}
public void setState(String libraryVersion, boolean incompatibleWithGame, boolean removable) { public void setState(String libraryVersion, boolean incompatibleWithGame, boolean removable) {
this.libraryVersion.set(libraryVersion); this.libraryVersion.set(libraryVersion);
this.incompatibleWithGame.set(incompatibleWithGame); this.incompatibleWithGame.set(incompatibleWithGame);
@ -177,37 +187,50 @@ public class InstallerItem extends Control {
public static class InstallerItemSkin extends SkinBase<InstallerItem> { public static class InstallerItemSkin extends SkinBase<InstallerItem> {
private static final PseudoClass LIST_ITEM = PseudoClass.getPseudoClass("list-item");
private static final PseudoClass CARD = PseudoClass.getPseudoClass("card");
InstallerItemSkin(InstallerItem control) { InstallerItemSkin(InstallerItem control) {
super(control); super(control);
HBox hbox = new HBox(); Pane pane;
hbox.getStyleClass().add("md-list-cell"); if (control.style == Style.CARD) {
hbox.setPadding(new Insets(8)); pane = new VBox();
RipplerContainer container = new RipplerContainer(hbox); } else {
pane = new HBox();
}
pane.getStyleClass().add("installer-item");
RipplerContainer container = new RipplerContainer(pane);
getChildren().setAll(container); getChildren().setAll(container);
hbox.setAlignment(Pos.CENTER_LEFT); pane.pseudoClassStateChanged(LIST_ITEM, control.style == Style.LIST_ITEM);
pane.pseudoClassStateChanged(CARD, control.style == Style.CARD);
if (control.imageUrl != null) { if (control.imageUrl != null) {
ImageView view = new ImageView(new Image(control.imageUrl, 32, 32, true, true)); ImageView view = new ImageView(new Image(control.imageUrl, 32, 32, true, true));
Node node = FXUtils.limitingSize(view, 32, 32); Node node = FXUtils.limitingSize(view, 32, 32);
node.setMouseTransparent(true); node.setMouseTransparent(true);
hbox.getChildren().add(node); node.getStyleClass().add("installer-item-image");
pane.getChildren().add(node);
if (control.style == Style.CARD) {
VBox.setMargin(node, new Insets(8, 0, 16, 0));
}
} }
Label nameLabel = new Label(); Label nameLabel = new Label();
nameLabel.getStyleClass().add("installer-item-name");
nameLabel.setMouseTransparent(true); nameLabel.setMouseTransparent(true);
hbox.getChildren().add(nameLabel); pane.getChildren().add(nameLabel);
nameLabel.setPrefWidth(80);
nameLabel.textProperty().set(I18n.hasKey("install.installer." + control.id) ? i18n("install.installer." + control.id) : control.id); nameLabel.textProperty().set(I18n.hasKey("install.installer." + control.id) ? i18n("install.installer." + control.id) : control.id);
HBox.setMargin(nameLabel, new Insets(0, 4, 0, 4)); HBox.setMargin(nameLabel, new Insets(0, 4, 0, 4));
Label label = new Label(); Label statusLabel = new Label();
label.setMouseTransparent(true); statusLabel.getStyleClass().add("installer-item-status");
hbox.getChildren().add(label); statusLabel.setMouseTransparent(true);
label.setMaxWidth(Double.MAX_VALUE); pane.getChildren().add(statusLabel);
HBox.setHgrow(label, Priority.ALWAYS); HBox.setHgrow(statusLabel, Priority.ALWAYS);
label.textProperty().bind(Bindings.createStringBinding(() -> { statusLabel.textProperty().bind(Bindings.createStringBinding(() -> {
String incompatibleWith = control.incompatibleLibraryName.get(); String incompatibleWith = control.incompatibleLibraryName.get();
String version = control.libraryVersion.get(); String version = control.libraryVersion.get();
if (control.incompatibleWithGame.get()) { if (control.incompatibleWithGame.get()) {
@ -220,8 +243,13 @@ public class InstallerItem extends Control {
return i18n("install.installer.version", version); return i18n("install.installer.version", version);
} }
}, control.incompatibleLibraryName, control.incompatibleWithGame, control.libraryVersion)); }, control.incompatibleLibraryName, control.incompatibleWithGame, control.libraryVersion));
BorderPane.setMargin(label, new Insets(0, 0, 0, 8)); BorderPane.setMargin(statusLabel, new Insets(0, 0, 0, 8));
BorderPane.setAlignment(label, Pos.CENTER_LEFT); BorderPane.setAlignment(statusLabel, Pos.CENTER_LEFT);
HBox buttonsContainer = new HBox();
buttonsContainer.setSpacing(8);
buttonsContainer.setAlignment(Pos.CENTER);
pane.getChildren().add(buttonsContainer);
JFXButton closeButton = new JFXButton(); JFXButton closeButton = new JFXButton();
closeButton.setGraphic(SVG.close(Theme.blackFillBinding(), -1, -1)); closeButton.setGraphic(SVG.close(Theme.blackFillBinding(), -1, -1));
@ -229,7 +257,7 @@ public class InstallerItem extends Control {
closeButton.visibleProperty().bind(control.removable); closeButton.visibleProperty().bind(control.removable);
closeButton.managedProperty().bind(closeButton.visibleProperty()); closeButton.managedProperty().bind(closeButton.visibleProperty());
closeButton.onMouseClickedProperty().bind(control.removeAction); closeButton.onMouseClickedProperty().bind(control.removeAction);
hbox.getChildren().add(closeButton); buttonsContainer.getChildren().add(closeButton);
JFXButton arrowButton = new JFXButton(); JFXButton arrowButton = new JFXButton();
arrowButton.graphicProperty().bind(Bindings.createObjectBinding(() -> control.upgradable.get() arrowButton.graphicProperty().bind(Bindings.createObjectBinding(() -> control.upgradable.get()
@ -242,16 +270,16 @@ public class InstallerItem extends Control {
control.installable, control.incompatibleLibraryName)); control.installable, control.incompatibleLibraryName));
arrowButton.managedProperty().bind(arrowButton.visibleProperty()); arrowButton.managedProperty().bind(arrowButton.visibleProperty());
arrowButton.onMouseClickedProperty().bind(control.action); arrowButton.onMouseClickedProperty().bind(control.action);
hbox.getChildren().add(arrowButton); buttonsContainer.getChildren().add(arrowButton);
FXUtils.onChangeAndOperate(arrowButton.visibleProperty(), clickable -> { FXUtils.onChangeAndOperate(arrowButton.visibleProperty(), clickable -> {
if (clickable) { if (clickable) {
container.onMouseClickedProperty().bind(control.action); container.onMouseClickedProperty().bind(control.action);
hbox.setCursor(Cursor.HAND); pane.setCursor(Cursor.HAND);
} else { } else {
container.onMouseClickedProperty().unbind(); container.onMouseClickedProperty().unbind();
container.onMouseClickedProperty().set(null); container.onMouseClickedProperty().set(null);
hbox.setCursor(Cursor.DEFAULT); pane.setCursor(Cursor.DEFAULT);
} }
}); });
} }

View File

@ -29,6 +29,7 @@ import javafx.scene.control.Label;
import javafx.scene.control.Skin; import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase; import javafx.scene.control.SkinBase;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import org.jackhuang.hmcl.download.DownloadProvider; import org.jackhuang.hmcl.download.DownloadProvider;
@ -67,6 +68,10 @@ public class InstallersPage extends Control implements WizardPage {
group.game.installable.setValue(false); group.game.installable.setValue(false);
for (InstallerItem item : group.getLibraries()) {
item.setStyleMode(InstallerItem.Style.CARD);
}
for (InstallerItem library : group.getLibraries()) { for (InstallerItem library : group.getLibraries()) {
String libraryId = library.getLibraryId(); String libraryId = library.getLibraryId();
if (libraryId.equals("game")) continue; if (libraryId.equals("game")) continue;
@ -140,22 +145,23 @@ public class InstallersPage extends Control implements WizardPage {
BorderPane root = new BorderPane(); BorderPane root = new BorderPane();
root.setPadding(new Insets(16)); root.setPadding(new Insets(16));
ComponentList list = new ComponentList();
list.getStyleClass().add("no-padding");
root.setCenter(list);
{ {
HBox versionNamePane = new HBox(8); HBox versionNamePane = new HBox(8);
versionNamePane.getStyleClass().add("card-non-transparent");
versionNamePane.setStyle("-fx-padding: 20 8 20 16");
versionNamePane.setAlignment(Pos.CENTER_LEFT); versionNamePane.setAlignment(Pos.CENTER_LEFT);
versionNamePane.setPadding(new Insets(20, 8, 20, 16));
control.txtName.setMaxWidth(300); control.txtName.setMaxWidth(300);
versionNamePane.getChildren().setAll(new Label(i18n("archive.name")), control.txtName); versionNamePane.getChildren().setAll(new Label(i18n("archive.name")), control.txtName);
list.getContent().add(versionNamePane); root.setTop(versionNamePane);
} }
{ {
VBox libraryPane = new VBox(control.group.getLibraries()); FlowPane libraryPane = new FlowPane(control.group.getLibraries());
list.getContent().add(libraryPane); BorderPane.setMargin(libraryPane, new Insets(16, 0, 16, 0));
libraryPane.setVgap(16);
libraryPane.setHgap(16);
root.setCenter(libraryPane);
} }

View File

@ -315,6 +315,33 @@
-fx-cursor: hand; -fx-cursor: hand;
} }
.installer-item {
-fx-padding: 8px;
}
.installer-item:list-item {
-fx-border-color: #e0e0e0;
-fx-border-width: 0 0 1 0;
-fx-alignment: center-left;
}
.installer-item:list-item > .installer-item-name {
-fx-pref-width: 80px;
}
.installer-item:list-item > .installer-item-status {
-fx-max-width: infinity;
}
.installer-item:card {
-fx-background-color: white;
-fx-background-radius: 4;
-fx-alignment: center;
-fx-pref-width: 180px;
-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.26), 10, 0.12, -1, 2);
}
/******************************************************************************* /*******************************************************************************
* * * *
* Main Page * * Main Page *

View File

@ -600,6 +600,7 @@ install.installer.liteloader=LiteLoader
install.installer.not_installed=Not Selected install.installer.not_installed=Not Selected
install.installer.optifine=OptiFine install.installer.optifine=OptiFine
install.installer.quilt=Quilt install.installer.quilt=Quilt
install.installer.quilt-api=Quilt API
install.installer.version=%s install.installer.version=%s
install.modpack=Install a Modpack install.modpack=Install a Modpack
install.new_game=Add a New Instance install.new_game=Add a New Instance

View File

@ -589,6 +589,7 @@ install.installer.liteloader=LiteLoader
install.installer.not_installed=No seleccionado install.installer.not_installed=No seleccionado
install.installer.optifine=OptiFine install.installer.optifine=OptiFine
install.installer.quilt=Quilt install.installer.quilt=Quilt
install.installer.quilt-api=Quilt API
install.installer.version=%s install.installer.version=%s
install.modpack=Instalar un Modpack install.modpack=Instalar un Modpack
install.new_game=Añadir instancia install.new_game=Añadir instancia

View File

@ -445,6 +445,7 @@ install.installer.liteloader=LiteLoader
install.installer.not_installed=インストールされていません install.installer.not_installed=インストールされていません
install.installer.optifine=OptiFine install.installer.optifine=OptiFine
install.installer.quilt=Quilt install.installer.quilt=Quilt
install.installer.quilt-api=Quilt API
install.installer.version=%s install.installer.version=%s
install.modpack=modpackを導入 install.modpack=modpackを導入
install.new_game=新規作成 install.new_game=新規作成

View File

@ -447,6 +447,7 @@ install.installer.liteloader=LiteLoader
install.installer.not_installed=Не установлен install.installer.not_installed=Не установлен
install.installer.optifine=OptiFine install.installer.optifine=OptiFine
install.installer.quilt=Quilt install.installer.quilt=Quilt
install.installer.quilt-api=Quilt API
install.installer.version=%s install.installer.version=%s
install.modpack=Установить модпак install.modpack=Установить модпак
install.new_game=Установить новую игру install.new_game=Установить новую игру

View File

@ -455,6 +455,7 @@ install.installer.liteloader=LiteLoader
install.installer.not_installed=不安裝 install.installer.not_installed=不安裝
install.installer.optifine=OptiFine install.installer.optifine=OptiFine
install.installer.quilt=Quilt install.installer.quilt=Quilt
install.installer.quilt-api=Quilt API
install.installer.version=%s install.installer.version=%s
install.modpack=安裝模組包 install.modpack=安裝模組包
install.new_game=安裝新遊戲版本 install.new_game=安裝新遊戲版本

View File

@ -455,6 +455,7 @@ install.installer.liteloader=LiteLoader
install.installer.not_installed=不安装 install.installer.not_installed=不安装
install.installer.optifine=OptiFine install.installer.optifine=OptiFine
install.installer.quilt=Quilt install.installer.quilt=Quilt
install.installer.quilt-api=Quilt API
install.installer.version=%s install.installer.version=%s
install.modpack=安装整合包 install.modpack=安装整合包
install.new_game=安装新游戏版本 install.new_game=安装新游戏版本