diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java index df8644085..019e403be 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java @@ -93,10 +93,7 @@ import java.nio.file.PathMatcher; import java.util.List; import java.util.*; 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.function.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -1370,6 +1367,27 @@ public final class FXUtils { }); } + public static void onScroll(Node node, List list, + ToIntFunction> finder, + Consumer updater + ) { + node.addEventHandler(ScrollEvent.SCROLL, event -> { + double deltaY = event.getDeltaY(); + if (deltaY == 0) + return; + + int index = finder.applyAsInt(list); + if (index < 0) return; + if (deltaY > 0) // up + index--; + else // down + index++; + + updater.accept(list.get((index + list.size()) % list.size())); + event.consume(); + }); + } + public static void copyOnDoubleClick(Labeled label) { label.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> { if (e.getButton() == MouseButton.PRIMARY && e.getClickCount() == 2) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountAdvancedListItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountAdvancedListItem.java index 811af1a32..8c9da5ec1 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountAdvancedListItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/account/AccountAdvancedListItem.java @@ -21,7 +21,6 @@ import javafx.beans.binding.Bindings; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; -import javafx.collections.ObservableList; import javafx.scene.canvas.Canvas; import javafx.scene.control.Tooltip; import org.jackhuang.hmcl.auth.Account; @@ -77,25 +76,9 @@ public class AccountAdvancedListItem extends AdvancedListItem { setActionButtonVisible(false); - setOnScroll(event -> { - double deltaY = event.getDeltaY(); - if (deltaY == 0) - return; - - Account current = account.get(); - if (current == null) return; - - ObservableList accounts = Accounts.getAccounts(); - int currentIndex = accounts.indexOf(current); - if (currentIndex < 0) return; - - if (deltaY > 0) // up - currentIndex--; - else // down - currentIndex++; - - Accounts.setSelectedAccount(accounts.get((currentIndex + accounts.size()) % accounts.size())); - }); + FXUtils.onScroll(this, Accounts.getAccounts(), + accounts -> accounts.indexOf(account.get()), + Accounts::setSelectedAccount); } public ObjectProperty accountProperty() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java index 1fde8095e..17af90f9b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java @@ -208,20 +208,11 @@ public final class MainPage extends StackPane implements DecoratorPage { launchPane.getStyleClass().add("launch-pane"); launchPane.setMaxWidth(230); launchPane.setMaxHeight(55); - launchPane.setOnScroll(event -> { - double deltaY = event.getDeltaY(); - if (deltaY == 0) - return; - + FXUtils.onScroll(launchPane, versions, list -> { String currentId = getCurrentGame(); - int index = Lang.indexWhere(versions, instance -> instance.getId().equals(currentId)); - if (index < 0) return; - if (deltaY > 0) // up - index--; - else // down - index++; - profile.setSelectedVersion(versions.get((index + versions.size()) % versions.size()).getId()); - }); + return Lang.indexWhere(list, instance -> instance.getId().equals(currentId)); + }, it -> profile.setSelectedVersion(it.getId())); + StackPane.setAlignment(launchPane, Pos.BOTTOM_RIGHT); { JFXButton launchButton = new JFXButton(); @@ -435,6 +426,10 @@ public final class MainPage extends StackPane implements DecoratorPage { return state; } + public Profile getProfile() { + return profile; + } + public String getCurrentGame() { return currentGame.get(); } @@ -447,6 +442,10 @@ public final class MainPage extends StackPane implements DecoratorPage { this.currentGame.set(currentGame); } + public ObservableList getVersions() { + return versions; + } + public boolean isShowUpdate() { return showUpdate.get(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java index 3988f44b9..61402b4ad 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/RootPage.java @@ -154,6 +154,10 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage { Versions.modifyGameSettings(profile, version); } }); + FXUtils.onScroll(gameListItem, getSkinnable().getMainPage().getVersions(), list -> { + String currentId = getSkinnable().getMainPage().getCurrentGame(); + return Lang.indexWhere(list, instance -> instance.getId().equals(currentId)); + }, it -> getSkinnable().getMainPage().getProfile().setSelectedVersion(it.getId())); // third item in left sidebar AdvancedListItem gameItem = new AdvancedListItem(); @@ -194,8 +198,7 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage { .add(downloadItem) .startCategory(i18n("settings.launcher.general").toUpperCase(Locale.ROOT)) .add(launcherSettingsItem) - .add(chatItem) - ; + .add(chatItem); // the root page, with the sidebar in left, navigator in center. setLeft(sideBar);