Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import javafx.animation.PauseTransition;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
Expand All @@ -33,6 +34,7 @@
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.SkinBase;
import javafx.scene.image.Image;
Expand All @@ -51,6 +53,7 @@
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
import org.jackhuang.hmcl.ui.animation.TransitionPane;
import org.jackhuang.hmcl.ui.construct.*;
import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -79,10 +82,15 @@ final class DataPackListPageSkin extends SkinBase<DataPackListPage> {
private final JFXListView<DataPackInfoObject> listView;
private final FilteredList<DataPackInfoObject> filteredList;

/// Whether the search mechanism is currently active.
private final BooleanProperty isSearching = new SimpleBooleanProperty(false);

private final BooleanProperty isSelecting = new SimpleBooleanProperty(false);
private final JFXTextField searchField;

/// Timer for debouncing search input to avoid executing search on every keystroke.
private final PauseTransition searchPause = new PauseTransition(Duration.millis(100));

private static final AtomicInteger lastShiftClickIndex = new AtomicInteger(-1);
final Consumer<Integer> toggleSelect;

Expand Down Expand Up @@ -148,16 +156,21 @@ final class DataPackListPageSkin extends SkinBase<DataPackListPage> {
searchField = new JFXTextField();
searchField.setPromptText(i18n("search"));
HBox.setHgrow(searchField, Priority.ALWAYS);
PauseTransition pause = new PauseTransition(Duration.millis(100));
pause.setOnFinished(e -> filteredList.setPredicate(skinnable.updateSearchPredicate(searchField.getText())));
searchPause.setOnFinished(e -> filteredList.setPredicate(skinnable.updateSearchPredicate(searchField.getText())));
searchField.textProperty().addListener((observable, oldValue, newValue) -> {
pause.setRate(1);
pause.playFromStart();
if (isSearching.get() || !StringUtils.isBlank(newValue)) {
Comment thread
KSSJW marked this conversation as resolved.
searchPause.setRate(1);
searchPause.playFromStart();
}
});
JFXButton closeSearchBar = createToolbarButton2(null, SVG.CLOSE,
() -> {
isSearching.set(false);
searchField.clear();
searchPause.stop();
Comment thread
KSSJW marked this conversation as resolved.

filteredList.setPredicate(null);

isSearching.set(false);
});
FXUtils.onEscPressed(searchField, closeSearchBar::fire);
searchBar.getChildren().addAll(searchField, closeSearchBar);
Expand Down Expand Up @@ -193,6 +206,23 @@ final class DataPackListPageSkin extends SkinBase<DataPackListPage> {

listView.setCellFactory(x -> new DataPackInfoListCell(listView, getSkinnable().readOnly));
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

StackPane placeholderContainer = new StackPane();
placeholderContainer.getStyleClass().add("notice-pane");
Label placeholderLabel = new Label(i18n("datapack.empty"));
placeholderLabel.textProperty().bind(
Bindings.createStringBinding(() -> {
if (isSearching.get()) {
return i18n("search.no_results_found");
} else {
return i18n("datapack.empty");
}
},
isSearching)
);
placeholderContainer.getChildren().add(placeholderLabel);
listView.setPlaceholder(placeholderContainer);

this.listView.setItems(filteredList);
listView.getItems().addListener(listener);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ListChangeListener;
import javafx.css.PseudoClass;
import javafx.geometry.Insets;
Expand Down Expand Up @@ -88,10 +89,14 @@ final class ModListPageSkin extends SkinBase<ModListPage> {
private final HBox toolbarSelecting;

private final JFXListView<ModInfoObject> listView;

/// Whether the search mechanism is currently active.
private final BooleanProperty isSearching = new SimpleBooleanProperty(false);

private final JFXTextField searchField;

@FXThread
private boolean isSearching = false;
/// Timer for debouncing search input to avoid executing search on every keystroke.
private final PauseTransition searchPause = new PauseTransition(Duration.millis(100));
Comment thread
KSSJW marked this conversation as resolved.

ModListPageSkin(ModListPage skinnable) {
super(skinnable);
Expand All @@ -118,19 +123,22 @@ final class ModListPageSkin extends SkinBase<ModListPage> {
searchField = new JFXTextField();
searchField.setPromptText(i18n("search"));
HBox.setHgrow(searchField, Priority.ALWAYS);
PauseTransition pause = new PauseTransition(Duration.millis(100));
pause.setOnFinished(e -> search());
searchPause.setOnFinished(e -> search());
searchField.textProperty().addListener((observable, oldValue, newValue) -> {
pause.setRate(1);
pause.playFromStart();
if (isSearching.get() || !StringUtils.isBlank(newValue)) {
searchPause.setRate(1);
searchPause.playFromStart();
}
});

JFXButton closeSearchBar = createToolbarButton2(null, SVG.CLOSE,
() -> {
changeToolbar(toolbarNormal);

isSearching = false;
searchField.clear();
searchPause.stop();

isSearching.set(false);
Bindings.bindContent(listView.getItems(), getSkinnable().getItems());
});

Expand Down Expand Up @@ -192,7 +200,7 @@ final class ModListPageSkin extends SkinBase<ModListPage> {
FXUtils.onChangeAndOperate(listView.getSelectionModel().selectedItemProperty(),
selectedItem -> {
if (selectedItem == null)
changeToolbar(isSearching ? searchBar : toolbarNormal);
changeToolbar(isSearching.get() ? searchBar : toolbarNormal);
else
changeToolbar(toolbarSelecting);
});
Expand All @@ -219,9 +227,26 @@ final class ModListPageSkin extends SkinBase<ModListPage> {

listView.setCellFactory(x -> new ModInfoListCell(listView));
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

StackPane placeholderContainer = new StackPane();
placeholderContainer.getStyleClass().add("notice-pane");
Label placeholderLabel = new Label(i18n("mods.empty"));
Comment thread
KSSJW marked this conversation as resolved.
placeholderLabel.textProperty().bind(
Bindings.createStringBinding(() -> {
if (isSearching.get()) {
return i18n("search.no_results_found");
} else {
return i18n("mods.empty");
}
},
isSearching)
);
placeholderContainer.getChildren().add(placeholderLabel);
listView.setPlaceholder(placeholderContainer);

Bindings.bindContent(listView.getItems(), skinnable.getItems());
skinnable.getItems().addListener((ListChangeListener<? super ModInfoObject>) c -> {
if (isSearching) {
if (isSearching.get()) {
search();
}
});
Expand Down Expand Up @@ -264,7 +289,7 @@ private void changeToolbar(HBox newToolbar) {
}

private void search() {
isSearching = true;
isSearching.set(true);

Bindings.unbindContent(listView.getItems(), getSkinnable().getItems());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,11 @@ private static final class ResourcePackListPageSkin extends SkinBase<ResourcePac
private final HBox toolbarNormal = new HBox();
private final HBox toolbarSelecting = new HBox();

private boolean isSearching;
/// Whether the search mechanism is currently active.
private final BooleanProperty isSearching = new SimpleBooleanProperty(false);

/// Timer for debouncing search input to avoid executing search on every keystroke.
private final PauseTransition searchPause = new PauseTransition(Duration.millis(100));

private ResourcePackListPageSkin(ResourcePackListPage control) {
super(control);
Expand Down Expand Up @@ -309,19 +313,22 @@ private ResourcePackListPageSkin(ResourcePackListPage control) {
searchBar.setPadding(new Insets(0, 5, 0, 5));
searchField.setPromptText(i18n("search"));
HBox.setHgrow(searchField, Priority.ALWAYS);
PauseTransition pause = new PauseTransition(Duration.millis(100));
pause.setOnFinished(e -> search());
searchPause.setOnFinished(e -> search());
FXUtils.onChange(searchField.textProperty(), newValue -> {
pause.setRate(1);
pause.playFromStart();
if (isSearching.get() || !StringUtils.isBlank(newValue)) {
searchPause.setRate(1);
searchPause.playFromStart();
}
});

JFXButton closeSearchBar = createToolbarButton2(null, SVG.CLOSE,
() -> {
changeToolbar(toolbarNormal);

isSearching = false;
searchField.clear();
searchPause.stop();

isSearching.set(false);
Bindings.bindContent(listView.getItems(), getSkinnable().getItems());
});

Expand All @@ -346,7 +353,7 @@ private ResourcePackListPageSkin(ResourcePackListPage control) {
FXUtils.onChangeAndOperate(listView.getSelectionModel().selectedItemProperty(),
selectedItem -> {
if (selectedItem == null)
changeToolbar(isSearching ? searchBar : toolbarNormal);
changeToolbar(isSearching.get() ? searchBar : toolbarNormal);
else
changeToolbar(toolbarSelecting);
});
Expand All @@ -371,6 +378,23 @@ private ResourcePackListPageSkin(ResourcePackListPage control) {

listView.setCellFactory(x -> new ResourcePackListCell(listView, control));
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

StackPane placeholderContainer = new StackPane();
placeholderContainer.getStyleClass().add("notice-pane");
Label placeholderLabel = new Label(i18n("resourcepack.empty"));
placeholderLabel.textProperty().bind(
Bindings.createStringBinding(() -> {
if (isSearching.get()) {
return i18n("search.no_results_found");
} else {
return i18n("resourcepack.empty");
}
},
isSearching)
);
placeholderContainer.getChildren().add(placeholderLabel);
listView.setPlaceholder(placeholderContainer);

Bindings.bindContent(listView.getItems(), control.getItems());

listView.setOnContextMenuRequested(event -> {
Expand Down Expand Up @@ -403,7 +427,7 @@ private void changeToolbar(HBox newToolbar) {
}

private void search() {
isSearching = true;
isSearching.set(true);

Bindings.unbindContent(listView.getItems(), getSkinnable().getItems());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,12 @@ protected void updateItem(Item item, boolean empty) {
private final class SchematicsPageSkin extends ToolbarListPageSkin<Item, SchematicsPage> {
SchematicsPageSkin() {
super(SchematicsPage.this);

StackPane placeholderContainer = new StackPane();
placeholderContainer.getStyleClass().add("notice-pane");
Label placeholderLabel = new Label(i18n("schematics.empty"));
placeholderContainer.getChildren().add(placeholderLabel);
listView.setPlaceholder(placeholderContainer);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase;
import javafx.scene.layout.BorderPane;
Expand Down Expand Up @@ -162,6 +163,12 @@ private final class WorldBackupsPageSkin extends ToolbarListPageSkin<BackupInfo,

WorldBackupsPageSkin() {
super(WorldBackupsPage.this);

StackPane placeholderContainer = new StackPane();
placeholderContainer.getStyleClass().add("notice-pane");
Label placeholderLabel = new Label(i18n("world.backup.empty"));
placeholderContainer.getChildren().add(placeholderLabel);
listView.setPlaceholder(placeholderContainer);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.Skin;
import javafx.scene.control.Tooltip;
Expand Down Expand Up @@ -216,6 +217,12 @@ private final class WorldListPageSkin extends ToolbarListPageSkin<World, WorldLi

WorldListPageSkin() {
super(WorldListPage.this);

StackPane placeholderContainer = new StackPane();
placeholderContainer.getStyleClass().add("notice-pane");
Label placeholderLabel = new Label(i18n("world.empty"));
placeholderContainer.getChildren().add(placeholderLabel);
listView.setPlaceholder(placeholderContainer);
}

@Override
Expand Down
7 changes: 7 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,7 @@ mods.disable=Disable
mods.download=Download Mod
mods.download.title=Download Mod - %1s
mods.download.recommend=Recommended Mod Version - Minecraft %1s
mods.empty=No Mods
mods.enable=Enable
mods.game.version=Game Version
mods.manage=Mods
Expand Down Expand Up @@ -1184,6 +1185,7 @@ nbt.title=View File - %s
datapack=Data Packs
datapack.add=Add
datapack.add.title=Choose data pack archive you want to add
datapack.empty=No Data Packs
datapack.reload.toast=Minecraft is running. Use the /reload command to reload data packs
datapack.title=World [%s] - Data Packs

Expand All @@ -1202,6 +1204,7 @@ world.backup.create.new_one=New Backup
world.backup.create.failed=Failed to create backup.\n%s
world.backup.create.success=Successfully created a new backup: %s
world.backup.delete=Delete this backup
world.backup.empty=No Backup
world.backup.processing=Backing up ...
world.chunkbase=Chunk Base
world.chunkbase.end_city=End City
Expand All @@ -1221,6 +1224,7 @@ world.delete=Delete the World
world.delete.failed=Failed to delete world.\n%s
world.download=Download
world.download.title=Download World - %1s
world.empty=No Worlds
world.export=Export the World
world.export.title=Choose the directory for this exported world
world.export.location=Save As
Expand Down Expand Up @@ -1295,6 +1299,7 @@ resourcepack.add.title=Choose resource pack archive you want to add
resourcepack.delete.failed=Failed to delete resource pack
resourcepack.download=Download
resourcepack.download.title=Download Resource Pack - %1s
resourcepack.empty=No Resource Packs
resourcepack.manage=Resource Packs
resourcepack.update_in_modpack.warning=Updating resource packs in a modpack can lead to irreparable results, possibly leading to incorrect textures and sounds. Are you sure you want to update?
resourcepack.warning.invalid=Invalid pack meta
Expand All @@ -1317,6 +1322,7 @@ schematics.create_directory.failed=Failed to create directory
schematics.create_directory.failed.already_exists=Directory already exists
schematics.create_directory.failed.empty_name=Name cannot be empty
schematics.create_directory.failed.invalid_name=Name contains invalid characters
schematics.empty=No Schematics
schematics.info.description=Description
schematics.info.enclosing_size=Enclosing Size
schematics.info.name=Name
Expand All @@ -1338,6 +1344,7 @@ search.sort=Sort By
search.first_page=First
search.previous_page=Previous
search.next_page=Next
search.no_results_found=No results found
search.last_page=Last
search.page_n=%1$d / %2$s

Expand Down
Loading
Loading