alt: some UI details

This commit is contained in:
huanghongxun 2020-02-21 12:35:40 +08:00
parent 5b1c72ad5c
commit 1726cc7ec7
9 changed files with 114 additions and 226 deletions

View File

@ -41,7 +41,6 @@ public abstract class ToolbarListPageSkin<T extends ListPageBase<? extends Node>
SpinnerPane spinnerPane = new SpinnerPane();
spinnerPane.getStyleClass().add("large-spinner-pane");
spinnerPane.getStyleClass().add("content-background");
BorderPane root = new BorderPane();

View File

@ -19,6 +19,7 @@ package org.jackhuang.hmcl.ui.construct;
import com.jfoenix.effects.JFXDepthManager;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.control.ListCell;
import javafx.scene.layout.StackPane;
@ -29,7 +30,9 @@ public abstract class FloatListCell<T> extends ListCell<T> {
setText(null);
setGraphic(null);
pane.setStyle("-fx-background-color: white; -fx-padding: 8; -fx-cursor: HAND");
pane.setStyle("-fx-background-color: white");
pane.setCursor(Cursor.HAND);
pane.setPadding(new Insets(8));
setPadding(new Insets(5));
JFXDepthManager.setDepth(pane, 1);
}
@ -37,13 +40,13 @@ public abstract class FloatListCell<T> extends ListCell<T> {
@Override
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
updateControl(item, empty);
if (empty) {
setGraphic(null);
} else {
updateControl(item);
setGraphic(pane);
}
}
protected abstract void updateControl(T dataItem);
protected abstract void updateControl(T dataItem, boolean empty);
}

View File

@ -1,135 +0,0 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.ui.construct;
import com.jfoenix.controls.JFXCheckBox;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TreeTableCell;
import javafx.scene.layout.StackPane;
import javafx.util.Callback;
import javafx.util.StringConverter;
public class JFXCheckBoxTreeTableCell<S,T> extends TreeTableCell<S,T> {
private final StackPane pane;
private final CheckBox checkBox;
private boolean showLabel;
private ObservableValue<Boolean> booleanProperty;
public JFXCheckBoxTreeTableCell() {
this(null, null);
}
public JFXCheckBoxTreeTableCell(
final Callback<Integer, ObservableValue<Boolean>> getSelectedProperty) {
this(getSelectedProperty, null);
}
public JFXCheckBoxTreeTableCell(
final Callback<Integer, ObservableValue<Boolean>> getSelectedProperty,
final StringConverter<T> converter) {
this.getStyleClass().add("check-box-tree-table-cell");
this.checkBox = new JFXCheckBox();
this.pane = new StackPane(checkBox);
this.pane.setAlignment(Pos.CENTER);
setGraphic(null);
setSelectedStateCallback(getSelectedProperty);
setConverter(converter);
}
private ObjectProperty<StringConverter<T>> converter =
new SimpleObjectProperty<StringConverter<T>>(this, "converter") {
protected void invalidated() {
updateShowLabel();
}
};
public final ObjectProperty<StringConverter<T>> converterProperty() {
return converter;
}
public final void setConverter(StringConverter<T> value) {
converterProperty().set(value);
}
public final StringConverter<T> getConverter() {
return converterProperty().get();
}
private ObjectProperty<Callback<Integer, ObservableValue<Boolean>>>
selectedStateCallback = new SimpleObjectProperty<>(this, "selectedStateCallback");
public final ObjectProperty<Callback<Integer, ObservableValue<Boolean>>> selectedStateCallbackProperty() {
return selectedStateCallback;
}
public final void setSelectedStateCallback(Callback<Integer, ObservableValue<Boolean>> value) {
selectedStateCallbackProperty().set(value);
}
public final Callback<Integer, ObservableValue<Boolean>> getSelectedStateCallback() {
return selectedStateCallbackProperty().get();
}
@SuppressWarnings("unchecked")
@Override public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
StringConverter<T> c = getConverter();
if (showLabel) {
setText(c.toString(item));
}
setGraphic(pane);
if (booleanProperty instanceof BooleanProperty) {
checkBox.selectedProperty().unbindBidirectional((BooleanProperty)booleanProperty);
}
ObservableValue<?> obsValue = getSelectedProperty();
if (obsValue instanceof BooleanProperty) {
booleanProperty = (ObservableValue<Boolean>) obsValue;
checkBox.selectedProperty().bindBidirectional((BooleanProperty)booleanProperty);
}
checkBox.disableProperty().bind(Bindings.not(
getTreeTableView().editableProperty().and(
getTableColumn().editableProperty()).and(
editableProperty())
));
}
}
private void updateShowLabel() {
this.showLabel = converter != null;
this.checkBox.setAlignment(showLabel ? Pos.CENTER_LEFT : Pos.CENTER);
}
private ObservableValue<?> getSelectedProperty() {
return getSelectedStateCallback() != null ?
getSelectedStateCallback().call(getIndex()) :
getTableColumn().getCellObservableValue(getIndex());
}
}

View File

@ -123,7 +123,8 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
}
@Override
protected void updateControl(RemoteVersion remoteVersion) {
protected void updateControl(RemoteVersion remoteVersion, boolean empty) {
if (empty) return;
content.setTitle(remoteVersion.getSelfVersion());
content.setSubtitle(remoteVersion.getGameVersion());

View File

@ -21,7 +21,6 @@ import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
import javafx.scene.control.Skin;
import javafx.scene.control.TreeItem;
import javafx.stage.FileChooser;
import org.jackhuang.hmcl.mod.Datapack;
import org.jackhuang.hmcl.task.Schedulers;
@ -103,9 +102,8 @@ public class DatapackListPage extends ListPageBase<DatapackListPageSkin.Datapack
datapack.loadFromDir();
}
void removeSelected(ObservableList<TreeItem<DatapackListPageSkin.DatapackInfoObject>> selectedItems) {
void removeSelected(ObservableList<DatapackListPageSkin.DatapackInfoObject> selectedItems) {
selectedItems.stream()
.map(TreeItem::getValue)
.map(DatapackListPageSkin.DatapackInfoObject::getPackInfo)
.forEach(pack -> {
try {
@ -117,16 +115,14 @@ public class DatapackListPage extends ListPageBase<DatapackListPageSkin.Datapack
});
}
void enableSelected(ObservableList<TreeItem<DatapackListPageSkin.DatapackInfoObject>> selectedItems) {
void enableSelected(ObservableList<DatapackListPageSkin.DatapackInfoObject> selectedItems) {
selectedItems.stream()
.map(TreeItem::getValue)
.map(DatapackListPageSkin.DatapackInfoObject::getPackInfo)
.forEach(info -> info.setActive(true));
}
void disableSelected(ObservableList<TreeItem<DatapackListPageSkin.DatapackInfoObject>> selectedItems) {
void disableSelected(ObservableList<DatapackListPageSkin.DatapackInfoObject> selectedItems) {
selectedItems.stream()
.map(TreeItem::getValue)
.map(DatapackListPageSkin.DatapackInfoObject::getPackInfo)
.forEach(info -> info.setActive(false));
}

View File

@ -17,30 +17,27 @@
*/
package org.jackhuang.hmcl.ui.versions;
import com.jfoenix.controls.JFXTreeTableColumn;
import com.jfoenix.controls.JFXTreeTableView;
import com.jfoenix.controls.RecursiveTreeItem;
import com.jfoenix.controls.JFXCheckBox;
import com.jfoenix.controls.JFXListView;
import com.jfoenix.controls.datamodels.treetable.RecursiveTreeObject;
import com.jfoenix.effects.JFXDepthManager;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.geometry.Pos;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.SkinBase;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import org.jackhuang.hmcl.mod.Datapack;
import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.ui.construct.JFXCheckBoxTreeTableCell;
import org.jackhuang.hmcl.ui.construct.FloatListCell;
import org.jackhuang.hmcl.ui.construct.SpinnerPane;
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
import org.jackhuang.hmcl.util.StringUtils;
import static org.jackhuang.hmcl.ui.FXUtils.setupCellValueFactory;
import static org.jackhuang.hmcl.ui.FXUtils.wrapMargin;
import static org.jackhuang.hmcl.ui.ToolbarListPageSkin.createToolbarButton;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
@ -50,7 +47,7 @@ class DatapackListPageSkin extends SkinBase<DatapackListPage> {
super(skinnable);
BorderPane root = new BorderPane();
JFXTreeTableView<DatapackInfoObject> tableView = new JFXTreeTableView<>();
JFXListView<DatapackInfoObject> listView = new JFXListView<>();
{
HBox toolbar = new HBox();
@ -62,13 +59,13 @@ class DatapackListPageSkin extends SkinBase<DatapackListPage> {
toolbar.getChildren().add(createToolbarButton(i18n("datapack.add"), SVG::plus, skinnable::add));
toolbar.getChildren().add(createToolbarButton(i18n("button.remove"), SVG::delete, () -> {
Controllers.confirmDialog(i18n("button.remove.confirm"), i18n("button.remove"), () -> {
skinnable.removeSelected(tableView.getSelectionModel().getSelectedItems());
skinnable.removeSelected(listView.getSelectionModel().getSelectedItems());
}, null);
}));
toolbar.getChildren().add(createToolbarButton(i18n("mods.enable"), SVG::check, () ->
skinnable.enableSelected(tableView.getSelectionModel().getSelectedItems())));
skinnable.enableSelected(listView.getSelectionModel().getSelectedItems())));
toolbar.getChildren().add(createToolbarButton(i18n("mods.disable"), SVG::close, () ->
skinnable.disableSelected(tableView.getSelectionModel().getSelectedItems())));
skinnable.disableSelected(listView.getSelectionModel().getSelectedItems())));
root.setTop(toolbar);
}
@ -77,26 +74,43 @@ class DatapackListPageSkin extends SkinBase<DatapackListPage> {
center.getStyleClass().add("large-spinner-pane");
center.loadingProperty().bind(skinnable.loadingProperty());
tableView.getStyleClass().addAll("no-header");
tableView.setShowRoot(false);
tableView.setEditable(true);
tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
tableView.setRoot(new RecursiveTreeItem<>(skinnable.getItems(), RecursiveTreeObject::getChildren));
listView.setCellFactory(x -> new FloatListCell<DatapackInfoObject>() {
JFXCheckBox checkBox = new JFXCheckBox();
TwoLineListItem content = new TwoLineListItem();
BooleanProperty booleanProperty;
JFXTreeTableColumn<DatapackInfoObject, Boolean> activeColumn = new JFXTreeTableColumn<>();
setupCellValueFactory(activeColumn, DatapackInfoObject::activeProperty);
activeColumn.setCellFactory(c -> new JFXCheckBoxTreeTableCell<>());
activeColumn.setEditable(true);
activeColumn.setMaxWidth(40);
activeColumn.setMinWidth(40);
{
Region clippedContainer = (Region)listView.lookup(".clipped-container");
setPrefWidth(0);
HBox container = new HBox(8);
container.setPadding(new Insets(0, 0, 0, 6));
container.setAlignment(Pos.CENTER_LEFT);
pane.getChildren().add(container);
pane.setPadding(new Insets(8, 8, 8, 0));
if (clippedContainer != null) {
maxWidthProperty().bind(clippedContainer.widthProperty());
prefWidthProperty().bind(clippedContainer.widthProperty());
minWidthProperty().bind(clippedContainer.widthProperty());
}
JFXTreeTableColumn<DatapackInfoObject, Node> detailColumn = new JFXTreeTableColumn<>();
setupCellValueFactory(detailColumn, DatapackInfoObject::nodeProperty);
container.getChildren().setAll(checkBox, content);
}
tableView.getColumns().setAll(activeColumn, detailColumn);
@Override
protected void updateControl(DatapackInfoObject dataItem, boolean empty) {
if (empty) return;
content.setTitle(dataItem.getTitle());
content.setSubtitle(dataItem.getSubtitle());
if (booleanProperty != null) {
checkBox.selectedProperty().unbindBidirectional(booleanProperty);
}
checkBox.selectedProperty().bindBidirectional(booleanProperty = dataItem.active);
}
});
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
Bindings.bindContent(listView.getItems(), skinnable.getItems());
tableView.setColumnResizePolicy(JFXTreeTableView.CONSTRAINED_RESIZE_POLICY);
center.setContent(tableView);
center.setContent(listView);
root.setCenter(center);
}
@ -106,21 +120,18 @@ class DatapackListPageSkin extends SkinBase<DatapackListPage> {
static class DatapackInfoObject extends RecursiveTreeObject<DatapackInfoObject> {
private final BooleanProperty active;
private final Datapack.Pack packInfo;
private final ObjectProperty<Node> node;
DatapackInfoObject(Datapack.Pack packInfo) {
this.packInfo = packInfo;
this.active = packInfo.activeProperty();
this.node = new SimpleObjectProperty<>(wrapMargin(new TwoLineListItem(packInfo.getId(), StringUtils.parseColorEscapes(packInfo.getDescription())),
new Insets(8, 0, 8, 0)));
}
BooleanProperty activeProperty() {
return active;
String getTitle() {
return packInfo.getId();
}
ObjectProperty<Node> nodeProperty() {
return node;
String getSubtitle() {
return StringUtils.parseColorEscapes(packInfo.getDescription());
}
Datapack.Pack getPackInfo() {

View File

@ -29,6 +29,7 @@ import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.setting.Profiles;
import org.jackhuang.hmcl.ui.*;
import org.jackhuang.hmcl.ui.construct.Navigator;
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
import org.jackhuang.hmcl.ui.download.ModpackInstallWizardProvider;
import org.jackhuang.hmcl.ui.download.VanillaInstallWizardProvider;
@ -56,6 +57,7 @@ public class GameList extends ListPageBase<GameListItem> implements DecoratorPag
});
Profiles.registerVersionsListener(this::loadVersions);
addEventHandler(Navigator.NavigationEvent.NAVIGATING, this::onDecoratorPageNavigating);
}
private void loadVersions(Profile profile) {

View File

@ -22,7 +22,6 @@ import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ObservableList;
import javafx.scene.control.Skin;
import javafx.scene.control.TreeItem;
import javafx.stage.FileChooser;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.mod.ModInfo;
@ -139,11 +138,9 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
this.parentTab = parentTab;
}
public void removeSelected(ObservableList<TreeItem<ModListPageSkin.ModInfoObject>> selectedItems) {
public void removeSelected(ObservableList<ModListPageSkin.ModInfoObject> selectedItems) {
try {
modManager.removeMods(selectedItems.stream()
.filter(Objects::nonNull)
.map(TreeItem::getValue)
.filter(Objects::nonNull)
.map(ModListPageSkin.ModInfoObject::getModInfo)
.toArray(ModInfo[]::new));
@ -153,16 +150,16 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
}
}
public void enableSelected(ObservableList<TreeItem<ModListPageSkin.ModInfoObject>> selectedItems) {
public void enableSelected(ObservableList<ModListPageSkin.ModInfoObject> selectedItems) {
selectedItems.stream()
.map(TreeItem::getValue)
.filter(Objects::nonNull)
.map(ModListPageSkin.ModInfoObject::getModInfo)
.forEach(info -> info.setActive(true));
}
public void disableSelected(ObservableList<TreeItem<ModListPageSkin.ModInfoObject>> selectedItems) {
public void disableSelected(ObservableList<ModListPageSkin.ModInfoObject> selectedItems) {
selectedItems.stream()
.map(TreeItem::getValue)
.filter(Objects::nonNull)
.map(ModListPageSkin.ModInfoObject::getModInfo)
.forEach(info -> info.setActive(false));
}

View File

@ -17,32 +17,29 @@
*/
package org.jackhuang.hmcl.ui.versions;
import com.jfoenix.controls.JFXTreeTableColumn;
import com.jfoenix.controls.JFXTreeTableView;
import com.jfoenix.controls.RecursiveTreeItem;
import com.jfoenix.controls.JFXCheckBox;
import com.jfoenix.controls.JFXListView;
import com.jfoenix.controls.datamodels.treetable.RecursiveTreeObject;
import com.jfoenix.effects.JFXDepthManager;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.SkinBase;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import org.jackhuang.hmcl.mod.ModInfo;
import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.ui.construct.JFXCheckBoxTreeTableCell;
import org.jackhuang.hmcl.ui.construct.FloatListCell;
import org.jackhuang.hmcl.ui.construct.SpinnerPane;
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
import static org.jackhuang.hmcl.ui.FXUtils.setupCellValueFactory;
import static org.jackhuang.hmcl.ui.FXUtils.wrapMargin;
import static org.jackhuang.hmcl.ui.ToolbarListPageSkin.createToolbarButton;
import static org.jackhuang.hmcl.util.StringUtils.isNotBlank;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
@ -56,7 +53,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
pane.getStyleClass().addAll("notice-pane");
BorderPane root = new BorderPane();
JFXTreeTableView<ModInfoObject> tableView = new JFXTreeTableView<>();
JFXListView<ModInfoObject> listView = new JFXListView<>();
{
HBox toolbar = new HBox();
@ -68,13 +65,13 @@ class ModListPageSkin extends SkinBase<ModListPage> {
toolbar.getChildren().add(createToolbarButton(i18n("mods.add"), SVG::plus, skinnable::add));
toolbar.getChildren().add(createToolbarButton(i18n("button.remove"), SVG::delete, () -> {
Controllers.confirmDialog(i18n("button.remove.confirm"), i18n("button.remove"), () -> {
skinnable.removeSelected(tableView.getSelectionModel().getSelectedItems());
skinnable.removeSelected(listView.getSelectionModel().getSelectedItems());
}, null);
}));
toolbar.getChildren().add(createToolbarButton(i18n("mods.enable"), SVG::check, () ->
skinnable.enableSelected(tableView.getSelectionModel().getSelectedItems())));
skinnable.enableSelected(listView.getSelectionModel().getSelectedItems())));
toolbar.getChildren().add(createToolbarButton(i18n("mods.disable"), SVG::close, () ->
skinnable.disableSelected(tableView.getSelectionModel().getSelectedItems())));
skinnable.disableSelected(listView.getSelectionModel().getSelectedItems())));
root.setTop(toolbar);
}
@ -83,26 +80,43 @@ class ModListPageSkin extends SkinBase<ModListPage> {
center.getStyleClass().add("large-spinner-pane");
center.loadingProperty().bind(skinnable.loadingProperty());
tableView.getStyleClass().add("no-header");
tableView.setShowRoot(false);
tableView.setEditable(true);
tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
tableView.setRoot(new RecursiveTreeItem<>(skinnable.getItems(), RecursiveTreeObject::getChildren));
listView.setCellFactory(x -> new FloatListCell<ModInfoObject>() {
JFXCheckBox checkBox = new JFXCheckBox();
TwoLineListItem content = new TwoLineListItem();
BooleanProperty booleanProperty;
JFXTreeTableColumn<ModInfoObject, Boolean> activeColumn = new JFXTreeTableColumn<>();
setupCellValueFactory(activeColumn, ModInfoObject::activeProperty);
activeColumn.setCellFactory(c -> new JFXCheckBoxTreeTableCell<>());
activeColumn.setEditable(true);
activeColumn.setMaxWidth(40);
activeColumn.setMinWidth(40);
{
Region clippedContainer = (Region)listView.lookup(".clipped-container");
setPrefWidth(0);
HBox container = new HBox(8);
container.setPadding(new Insets(0, 0, 0, 6));
container.setAlignment(Pos.CENTER_LEFT);
pane.getChildren().add(container);
pane.setPadding(new Insets(8, 8, 8, 0));
if (clippedContainer != null) {
maxWidthProperty().bind(clippedContainer.widthProperty());
prefWidthProperty().bind(clippedContainer.widthProperty());
minWidthProperty().bind(clippedContainer.widthProperty());
}
JFXTreeTableColumn<ModInfoObject, Node> detailColumn = new JFXTreeTableColumn<>();
setupCellValueFactory(detailColumn, ModInfoObject::nodeProperty);
container.getChildren().setAll(checkBox, content);
}
tableView.getColumns().setAll(activeColumn, detailColumn);
@Override
protected void updateControl(ModInfoObject dataItem, boolean empty) {
if (empty) return;
content.setTitle(dataItem.getTitle());
content.setSubtitle(dataItem.getSubtitle());
if (booleanProperty != null) {
checkBox.selectedProperty().unbindBidirectional(booleanProperty);
}
checkBox.selectedProperty().bindBidirectional(booleanProperty = dataItem.active);
}
});
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
Bindings.bindContent(listView.getItems(), skinnable.getItems());
tableView.setColumnResizePolicy(JFXTreeTableView.CONSTRAINED_RESIZE_POLICY);
center.setContent(tableView);
center.setContent(listView);
root.setCenter(center);
}
@ -120,7 +134,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
static class ModInfoObject extends RecursiveTreeObject<ModInfoObject> {
private final BooleanProperty active;
private final ModInfo modInfo;
private final ObjectProperty<Node> node;
private final String message;
ModInfoObject(ModInfo modInfo) {
this.modInfo = modInfo;
@ -132,15 +146,15 @@ class ModListPageSkin extends SkinBase<ModListPage> {
message.append(", ").append(i18n("archive.game_version")).append(": ").append(modInfo.getGameVersion());
if (isNotBlank(modInfo.getAuthors()))
message.append(", ").append(i18n("archive.author")).append(": ").append(modInfo.getAuthors());
this.node = new SimpleObjectProperty<>(wrapMargin(new TwoLineListItem(modInfo.getFileName(), message.toString()), new Insets(8, 0, 8, 0)));
this.message = message.toString();
}
BooleanProperty activeProperty() {
return active;
String getTitle() {
return modInfo.getFileName();
}
ObjectProperty<Node> nodeProperty() {
return node;
String getSubtitle() {
return message;
}
ModInfo getModInfo() {