mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-09 03:46:18 -04:00
模组列表页中按下 Esc 时取消选中 (#3523)
* 模组列表页中按下 Esc 时取消选中
目前在模组列表页中选中模组后,按下 Esc 是不会有任何反应的,因为 [ListView](5b074c4c2b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/ListViewBehavior.java (L108)
) 会处理这个事件,认为是取消编辑,而不论是否处于编辑模式中。
这个 PR 添加了 `FXUtils.ignoreEvent()` 函数,用于忽略掉对特定事件的处理。然后,我们就可以让 ListView 不处理 Esc 按下事件,然后在模组页添加 Esc 处理逻辑(必须让 ListView 忽略掉这个事件,不然就会被它优先处理)。
理论上所有用了 ListView / JFXListView 的地方都会有这个问题,即当焦点在 ListView 中时,按下 Esc 不会触发正常的事件处理(如返回上一页、关闭对话框)。比如在游戏下载页面中,对某个版本按下右键后,焦点就会转移到其上,此时再按 Esc 就毫无反应。
* 修复 Esc 在版本下载页/模组下载页/数据包页不工作
This commit is contained in:
parent
01f9a452f1
commit
72d8b75643
@ -27,6 +27,9 @@ import javafx.beans.WeakInvalidationListener;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.value.*;
|
||||
import javafx.event.Event;
|
||||
import javafx.event.EventDispatcher;
|
||||
import javafx.event.EventType;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Cursor;
|
||||
@ -86,6 +89,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
@ -234,6 +238,21 @@ public final class FXUtils {
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Event> void ignoreEvent(Node node, EventType<T> type, Predicate<? super T> filter) {
|
||||
EventDispatcher oldDispatcher = node.getEventDispatcher();
|
||||
node.setEventDispatcher((event, tail) -> {
|
||||
EventType<?> t = event.getEventType();
|
||||
while (t != null && t != type)
|
||||
t = t.getSuperType();
|
||||
if (t == type && filter.test((T) event)) {
|
||||
return tail.dispatchEvent(event);
|
||||
} else {
|
||||
return oldDispatcher.dispatchEvent(event, tail);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <K, T> void setupCellValueFactory(JFXTreeTableColumn<K, T> column, Function<K, ObservableValue<T>> mapper) {
|
||||
column.setCellValueFactory(param -> {
|
||||
if (column.validateValue(param))
|
||||
|
@ -29,6 +29,8 @@ import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.util.Duration;
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
@ -66,6 +68,7 @@ import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.ignoreEvent;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||
import static org.jackhuang.hmcl.ui.ToolbarListPageSkin.wrap;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
@ -150,6 +153,9 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
|
||||
list.getStyleClass().add("jfx-list-view-float");
|
||||
VBox.setVgrow(list, Priority.ALWAYS);
|
||||
|
||||
// ListViewBehavior would consume ESC pressed event, preventing us from handling it, so we ignore it here
|
||||
ignoreEvent(list, KeyEvent.KEY_PRESSED, e -> e.getCode() == KeyCode.ESCAPE);
|
||||
|
||||
centrePane.getContent().setAll(checkPane, list);
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,8 @@ import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.SelectionMode;
|
||||
import javafx.scene.control.SkinBase;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Region;
|
||||
@ -38,6 +40,7 @@ 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.ignoreEvent;
|
||||
import static org.jackhuang.hmcl.ui.ToolbarListPageSkin.createToolbarButton;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@ -110,6 +113,9 @@ class DatapackListPageSkin extends SkinBase<DatapackListPage> {
|
||||
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||
Bindings.bindContent(listView.getItems(), skinnable.getItems());
|
||||
|
||||
// ListViewBehavior would consume ESC pressed event, preventing us from handling it, so we ignore it here
|
||||
ignoreEvent(listView, KeyEvent.KEY_PRESSED, e -> e.getCode() == KeyCode.ESCAPE);
|
||||
|
||||
center.setContent(listView);
|
||||
root.setCenter(center);
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Skin;
|
||||
import javafx.scene.control.SkinBase;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.*;
|
||||
import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.mod.RemoteMod;
|
||||
@ -64,6 +66,7 @@ import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.ignoreEvent;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.stringConverter;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
import static org.jackhuang.hmcl.util.javafx.ExtendedProperties.selectedItemPropertyFor;
|
||||
@ -493,6 +496,9 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
|
||||
RemoteMod selectedItem = listView.getSelectionModel().getSelectedItem();
|
||||
Controllers.navigate(new DownloadPage(getSkinnable(), selectedItem, getSkinnable().getProfileVersion(), getSkinnable().callback));
|
||||
});
|
||||
|
||||
// ListViewBehavior would consume ESC pressed event, preventing us from handling it, so we ignore it here
|
||||
ignoreEvent(listView, KeyEvent.KEY_PRESSED, e -> e.getCode() == KeyCode.ESCAPE);
|
||||
listView.setCellFactory(x -> new FloatListCell<RemoteMod>(listView) {
|
||||
TwoLineListItem content = new TwoLineListItem();
|
||||
ImageView imageView = new ImageView();
|
||||
|
@ -31,6 +31,8 @@ import javafx.scene.control.SelectionMode;
|
||||
import javafx.scene.control.SkinBase;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.StackPane;
|
||||
@ -70,6 +72,7 @@ import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.ignoreEvent;
|
||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||
import static org.jackhuang.hmcl.ui.ToolbarListPageSkin.createToolbarButton2;
|
||||
import static org.jackhuang.hmcl.util.Lang.mapOf;
|
||||
@ -170,6 +173,16 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
changeToolbar(toolbarSelecting);
|
||||
});
|
||||
root.getContent().add(toolbarPane);
|
||||
|
||||
// Clear selection when pressing ESC
|
||||
root.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
|
||||
if (e.getCode() == KeyCode.ESCAPE) {
|
||||
if (listView.getSelectionModel().getSelectedItem() != null) {
|
||||
listView.getSelectionModel().clearSelection();
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
@ -196,6 +209,10 @@ class ModListPageSkin extends SkinBase<ModListPage> {
|
||||
}
|
||||
});
|
||||
|
||||
// ListViewBehavior would consume ESC pressed event, preventing us from handling it
|
||||
// So we ignore it here
|
||||
ignoreEvent(listView, KeyEvent.KEY_PRESSED, e -> e.getCode() == KeyCode.ESCAPE);
|
||||
|
||||
center.setContent(listView);
|
||||
root.getContent().add(center);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user