add: switch game by scrolling on the launch button
This commit is contained in:
@@ -15,23 +15,6 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
* Hello Minecraft! Launcher
|
|
||||||
* Copyright (C) 2019 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;
|
package org.jackhuang.hmcl.ui;
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ public class AccountAdvancedListItem extends AdvancedListItem {
|
|||||||
ObservableList<Account> accounts = Accounts.getAccounts();
|
ObservableList<Account> accounts = Accounts.getAccounts();
|
||||||
int currentIndex = accounts.indexOf(account.get());
|
int currentIndex = accounts.indexOf(account.get());
|
||||||
if (event.getDeltaY() > 0) { // up
|
if (event.getDeltaY() > 0) { // up
|
||||||
currentIndex += 1;
|
currentIndex--;
|
||||||
} else { // down
|
} else { // down
|
||||||
currentIndex -= 1;
|
currentIndex++;
|
||||||
}
|
}
|
||||||
Accounts.setSelectedAccount(accounts.get((currentIndex + accounts.size()) % accounts.size()));
|
Accounts.setSelectedAccount(accounts.get((currentIndex + accounts.size()) % accounts.size()));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import javafx.scene.layout.VBox;
|
|||||||
import javafx.scene.shape.Rectangle;
|
import javafx.scene.shape.Rectangle;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import org.jackhuang.hmcl.Metadata;
|
import org.jackhuang.hmcl.Metadata;
|
||||||
|
import org.jackhuang.hmcl.game.Version;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.setting.Profiles;
|
import org.jackhuang.hmcl.setting.Profiles;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
@@ -44,10 +45,15 @@ import org.jackhuang.hmcl.ui.SVG;
|
|||||||
import org.jackhuang.hmcl.ui.construct.PopupMenu;
|
import org.jackhuang.hmcl.ui.construct.PopupMenu;
|
||||||
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
||||||
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
||||||
|
import org.jackhuang.hmcl.ui.versions.GameItem;
|
||||||
import org.jackhuang.hmcl.ui.versions.Versions;
|
import org.jackhuang.hmcl.ui.versions.Versions;
|
||||||
import org.jackhuang.hmcl.upgrade.RemoteVersion;
|
import org.jackhuang.hmcl.upgrade.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.upgrade.UpdateChecker;
|
import org.jackhuang.hmcl.upgrade.UpdateChecker;
|
||||||
import org.jackhuang.hmcl.upgrade.UpdateHandler;
|
import org.jackhuang.hmcl.upgrade.UpdateHandler;
|
||||||
|
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.ui.FXUtils.SINE;
|
import static org.jackhuang.hmcl.ui.FXUtils.SINE;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
@@ -61,7 +67,9 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
private final StringProperty currentGame = new SimpleStringProperty(this, "currentGame");
|
private final StringProperty currentGame = new SimpleStringProperty(this, "currentGame");
|
||||||
private final BooleanProperty showUpdate = new SimpleBooleanProperty(this, "showUpdate");
|
private final BooleanProperty showUpdate = new SimpleBooleanProperty(this, "showUpdate");
|
||||||
private final StringProperty latestVersion = new SimpleStringProperty(this, "latestVersion");
|
private final StringProperty latestVersion = new SimpleStringProperty(this, "latestVersion");
|
||||||
private final ObservableList<Node> versions = FXCollections.observableArrayList();
|
private final ObservableList<Version> versions = FXCollections.observableArrayList();
|
||||||
|
private final ObservableList<Node> versionNodes;
|
||||||
|
private Profile profile;
|
||||||
|
|
||||||
private StackPane updatePane;
|
private StackPane updatePane;
|
||||||
private JFXButton menuButton;
|
private JFXButton menuButton;
|
||||||
@@ -109,6 +117,18 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
StackPane launchPane = new StackPane();
|
StackPane launchPane = new StackPane();
|
||||||
launchPane.setMaxWidth(230);
|
launchPane.setMaxWidth(230);
|
||||||
launchPane.setMaxHeight(55);
|
launchPane.setMaxHeight(55);
|
||||||
|
launchPane.setOnScroll(event -> {
|
||||||
|
int index = IntStream.range(0, versions.size())
|
||||||
|
.filter(i -> versions.get(i).getId().equals(getCurrentGame()))
|
||||||
|
.findFirst().orElse(-1);
|
||||||
|
if (index < 0) return;
|
||||||
|
if (event.getDeltaY() > 0) {
|
||||||
|
index--;
|
||||||
|
} else {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
profile.setSelectedVersion(versions.get((index + versions.size()) % versions.size()).getId());
|
||||||
|
});
|
||||||
StackPane.setAlignment(launchPane, Pos.BOTTOM_RIGHT);
|
StackPane.setAlignment(launchPane, Pos.BOTTOM_RIGHT);
|
||||||
{
|
{
|
||||||
JFXButton launchButton = new JFXButton();
|
JFXButton launchButton = new JFXButton();
|
||||||
@@ -128,7 +148,13 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
launchLabel.setStyle("-fx-font-size: 16px;");
|
launchLabel.setStyle("-fx-font-size: 16px;");
|
||||||
Label currentLabel = new Label();
|
Label currentLabel = new Label();
|
||||||
currentLabel.setStyle("-fx-font-size: 12px;");
|
currentLabel.setStyle("-fx-font-size: 12px;");
|
||||||
currentLabel.textProperty().bind(currentGameProperty());
|
currentLabel.textProperty().bind(Bindings.createStringBinding(() -> {
|
||||||
|
if (getCurrentGame() == null) {
|
||||||
|
return i18n("version.empty");
|
||||||
|
} else {
|
||||||
|
return getCurrentGame();
|
||||||
|
}
|
||||||
|
}, currentGameProperty()));
|
||||||
graphic.getChildren().setAll(launchLabel, currentLabel);
|
graphic.getChildren().setAll(launchLabel, currentLabel);
|
||||||
|
|
||||||
launchButton.setGraphic(graphic);
|
launchButton.setGraphic(graphic);
|
||||||
@@ -165,7 +191,12 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
menu.setMaxWidth(545);
|
menu.setMaxWidth(545);
|
||||||
menu.setAlwaysShowingVBar(true);
|
menu.setAlwaysShowingVBar(true);
|
||||||
menu.setOnMouseClicked(e -> popup.hide());
|
menu.setOnMouseClicked(e -> popup.hide());
|
||||||
Bindings.bindContent(menu.getContent(), versions);
|
versionNodes = MappedObservableList.create(versions, version -> {
|
||||||
|
Node node = PopupMenu.wrapPopupMenuItem(new GameItem(profile, version.getId()));
|
||||||
|
node.setOnMouseClicked(e -> profile.setSelectedVersion(version.getId()));
|
||||||
|
return node;
|
||||||
|
});
|
||||||
|
Bindings.bindContent(menu.getContent(), versionNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doAnimation(boolean show) {
|
private void doAnimation(boolean show) {
|
||||||
@@ -254,7 +285,9 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
this.latestVersion.set(latestVersion);
|
this.latestVersion.set(latestVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableList<Node> getVersions() {
|
public void initVersions(Profile profile, List<Version> versions) {
|
||||||
return versions;
|
FXUtils.checkFxUserThread();
|
||||||
|
this.profile = profile;
|
||||||
|
this.versions.setAll(versions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,19 +89,13 @@ public class RootPage extends DecoratorNavigatorPage {
|
|||||||
|
|
||||||
private MainPage getMainPage() {
|
private MainPage getMainPage() {
|
||||||
if (mainPage == null) {
|
if (mainPage == null) {
|
||||||
mainPage = new MainPage();
|
MainPage mainPage = new MainPage();
|
||||||
FXUtils.applyDragListener(mainPage, it -> "zip".equals(FileUtils.getExtension(it)), modpacks -> {
|
FXUtils.applyDragListener(mainPage, it -> "zip".equals(FileUtils.getExtension(it)), modpacks -> {
|
||||||
File modpack = modpacks.get(0);
|
File modpack = modpacks.get(0);
|
||||||
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(Profiles.getSelectedProfile(), modpack), i18n("install.modpack"));
|
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(Profiles.getSelectedProfile(), modpack), i18n("install.modpack"));
|
||||||
});
|
});
|
||||||
|
|
||||||
FXUtils.onChangeAndOperate(Profiles.selectedVersionProperty(), version -> {
|
FXUtils.onChangeAndOperate(Profiles.selectedVersionProperty(), mainPage::setCurrentGame);
|
||||||
if (version != null) {
|
|
||||||
mainPage.setCurrentGame(version);
|
|
||||||
} else {
|
|
||||||
mainPage.setCurrentGame(i18n("version.empty"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mainPage.showUpdateProperty().bind(UpdateChecker.outdatedProperty());
|
mainPage.showUpdateProperty().bind(UpdateChecker.outdatedProperty());
|
||||||
mainPage.latestVersionProperty().bind(
|
mainPage.latestVersionProperty().bind(
|
||||||
BindingMapping.of(UpdateChecker.latestVersionProperty())
|
BindingMapping.of(UpdateChecker.latestVersionProperty())
|
||||||
@@ -109,21 +103,17 @@ public class RootPage extends DecoratorNavigatorPage {
|
|||||||
|
|
||||||
Profiles.registerVersionsListener(profile -> {
|
Profiles.registerVersionsListener(profile -> {
|
||||||
HMCLGameRepository repository = profile.getRepository();
|
HMCLGameRepository repository = profile.getRepository();
|
||||||
List<Node> children = repository.getVersions().parallelStream()
|
List<Version> children = repository.getVersions().parallelStream()
|
||||||
.filter(version -> !version.isHidden())
|
.filter(version -> !version.isHidden())
|
||||||
.sorted(Comparator.comparing((Version version) -> version.getReleaseTime() == null ? new Date(0L) : version.getReleaseTime())
|
.sorted(Comparator.comparing((Version version) -> version.getReleaseTime() == null ? new Date(0L) : version.getReleaseTime())
|
||||||
.thenComparing(a -> VersionNumber.asVersion(a.getId())))
|
.thenComparing(a -> VersionNumber.asVersion(a.getId())))
|
||||||
.map(version -> {
|
|
||||||
Node node = PopupMenu.wrapPopupMenuItem(new GameItem(profile, version.getId()));
|
|
||||||
node.setOnMouseClicked(e -> profile.setSelectedVersion(version.getId()));
|
|
||||||
return node;
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
runInFX(() -> {
|
runInFX(() -> {
|
||||||
if (profile == Profiles.getSelectedProfile())
|
if (profile == Profiles.getSelectedProfile())
|
||||||
mainPage.getVersions().setAll(children);
|
mainPage.initVersions(profile, children);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
this.mainPage = mainPage;
|
||||||
}
|
}
|
||||||
return mainPage;
|
return mainPage;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user