mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-18 08:16:58 -04:00
Remove accountsPage
This commit is contained in:
parent
eba0990538
commit
5e1e2c6047
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2018 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* 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 {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.event;
|
||||
|
||||
/**
|
||||
* This event gets fired when loading accounts.
|
||||
* <br>
|
||||
* This event is fired on the {@link org.jackhuang.hmcl.event.EventBus#EVENT_BUS}
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AccountLoadingEvent extends Event {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param source {@link org.jackhuang.hmcl.setting.Settings}
|
||||
*/
|
||||
public AccountLoadingEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ import org.jackhuang.hmcl.auth.yggdrasil.MojangYggdrasilProvider;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccountFactory;
|
||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.task.TaskResult;
|
||||
import org.jackhuang.hmcl.util.*;
|
||||
|
||||
import java.io.File;
|
||||
@ -96,4 +98,8 @@ public final class Accounts {
|
||||
return response.getMeta().getServerName();
|
||||
}
|
||||
}
|
||||
|
||||
public static TaskResult<String> getAuthlibInjectorServerNameAsync(AuthlibInjectorAccount account) {
|
||||
return Task.ofResult("serverName", () -> Accounts.getAuthlibInjectorServerName(account.getServerBaseURL()));
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import org.jackhuang.hmcl.auth.Account;
|
||||
import org.jackhuang.hmcl.auth.AccountFactory;
|
||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||
import org.jackhuang.hmcl.event.AccountLoadingEvent;
|
||||
import org.jackhuang.hmcl.event.EventBus;
|
||||
import org.jackhuang.hmcl.event.ProfileChangedEvent;
|
||||
import org.jackhuang.hmcl.event.ProfileLoadingEvent;
|
||||
@ -368,6 +369,7 @@ public class Settings {
|
||||
|
||||
public void addAccount(Account account) {
|
||||
accounts.put(Accounts.getAccountId(account), account);
|
||||
onAccountLoading();
|
||||
}
|
||||
|
||||
public Account getAccount(String name, String character) {
|
||||
@ -381,12 +383,14 @@ public class Settings {
|
||||
public void deleteAccount(String name, String character) {
|
||||
accounts.remove(Accounts.getAccountId(name, character));
|
||||
|
||||
onAccountLoading();
|
||||
selectedAccount.get();
|
||||
}
|
||||
|
||||
public void deleteAccount(Account account) {
|
||||
accounts.remove(Accounts.getAccountId(account));
|
||||
|
||||
onAccountLoading();
|
||||
selectedAccount.get();
|
||||
}
|
||||
|
||||
@ -506,6 +510,7 @@ public class Settings {
|
||||
throw new IllegalArgumentException("Profile's name is empty");
|
||||
|
||||
getProfileMap().put(ver.getName(), ver);
|
||||
Schedulers.computation().schedule(this::onProfileLoading);
|
||||
|
||||
ver.nameProperty().setChangedListener(this::profileNameChanged);
|
||||
|
||||
@ -546,4 +551,8 @@ public class Settings {
|
||||
EventBus.EVENT_BUS.fireEvent(new ProfileLoadingEvent(SETTINGS));
|
||||
onProfileChanged();
|
||||
}
|
||||
|
||||
public void onAccountLoading() {
|
||||
EventBus.EVENT_BUS.fireEvent(new AccountLoadingEvent(SETTINGS));
|
||||
}
|
||||
}
|
||||
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2018 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* 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 {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXProgressBar;
|
||||
import com.jfoenix.controls.JFXRadioButton;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.effect.BlurType;
|
||||
import javafx.scene.effect.DropShadow;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.jackhuang.hmcl.auth.Account;
|
||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
||||
import org.jackhuang.hmcl.auth.offline.OfflineAccount;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
|
||||
import org.jackhuang.hmcl.game.AccountHelper;
|
||||
import org.jackhuang.hmcl.setting.Accounts;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.setting.Theme;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
|
||||
public final class AccountItem extends StackPane {
|
||||
|
||||
private final Account account;
|
||||
|
||||
@FXML
|
||||
private Pane icon;
|
||||
@FXML private VBox content;
|
||||
@FXML private StackPane header;
|
||||
@FXML private StackPane body;
|
||||
@FXML private JFXButton btnDelete;
|
||||
@FXML private JFXButton btnRefresh;
|
||||
@FXML private Label lblUser;
|
||||
@FXML private Label lblType;
|
||||
@FXML private Label lblEmail;
|
||||
@FXML private Label lblServer;
|
||||
@FXML private Label lblCurrentAccount;
|
||||
@FXML private JFXRadioButton chkSelected;
|
||||
@FXML private JFXProgressBar pgsSkin;
|
||||
@FXML private ImageView portraitView;
|
||||
@FXML private HBox buttonPane;
|
||||
|
||||
public AccountItem(int i, Account account, ToggleGroup toggleGroup) {
|
||||
this.account = account;
|
||||
|
||||
FXUtils.loadFXML(this, "/assets/fxml/account-item.fxml");
|
||||
|
||||
setEffect(new DropShadow(BlurType.GAUSSIAN, Color.rgb(0, 0, 0, 0.26), 5.0, 0.12, -0.5, 1.0));
|
||||
|
||||
chkSelected.setToggleGroup(toggleGroup);
|
||||
btnDelete.setGraphic(SVG.delete(Theme.blackFillBinding(), 15, 15));
|
||||
btnRefresh.setGraphic(SVG.refresh(Theme.blackFillBinding(), 15, 15));
|
||||
|
||||
// create image view
|
||||
icon.translateYProperty().bind(Bindings.createDoubleBinding(() -> header.getBoundsInParent().getHeight() - icon.getHeight() / 2 - 16, header.boundsInParentProperty(), icon.heightProperty()));
|
||||
|
||||
chkSelected.getProperties().put("account", account);
|
||||
setSelected(Settings.INSTANCE.getSelectedAccount() == account);
|
||||
|
||||
lblUser.setText(account.getCharacter());
|
||||
lblType.setText(AccountsPage.accountType(account));
|
||||
lblEmail.setText(account.getUsername());
|
||||
|
||||
if (account instanceof AuthlibInjectorAccount) {
|
||||
Task.ofResult("serverName", () -> Accounts.getAuthlibInjectorServerName(((AuthlibInjectorAccount) account).getServerBaseURL()))
|
||||
.subscribe(Schedulers.javafx(), variables -> lblServer.setText(variables.get("serverName")));
|
||||
}
|
||||
|
||||
if (account instanceof YggdrasilAccount) {
|
||||
btnRefresh.setOnMouseClicked(e -> {
|
||||
pgsSkin.setVisible(true);
|
||||
AccountHelper.refreshSkinAsync((YggdrasilAccount) account)
|
||||
.subscribe(Schedulers.javafx(), this::loadSkin);
|
||||
});
|
||||
AccountHelper.loadSkinAsync((YggdrasilAccount) account)
|
||||
.subscribe(Schedulers.javafx(), this::loadSkin);
|
||||
} else
|
||||
loadSkin();
|
||||
|
||||
if (account instanceof OfflineAccount) { // Offline Account cannot be refreshed,
|
||||
buttonPane.getChildren().remove(btnRefresh);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSkin() {
|
||||
pgsSkin.setVisible(false);
|
||||
portraitView.setViewport(AccountHelper.getViewport(4));
|
||||
if (account instanceof YggdrasilAccount)
|
||||
portraitView.setImage(AccountHelper.getSkin((YggdrasilAccount) account, 4));
|
||||
else
|
||||
portraitView.setImage(AccountHelper.getDefaultSkin(account, 4));
|
||||
FXUtils.limitSize(portraitView, 32, 32);
|
||||
}
|
||||
|
||||
public Account getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
lblCurrentAccount.setVisible(selected);
|
||||
chkSelected.setSelected(selected);
|
||||
}
|
||||
|
||||
public void setOnDeleteButtonMouseClicked(EventHandler<? super MouseEvent> eventHandler) {
|
||||
btnDelete.setOnMouseClicked(eventHandler);
|
||||
}
|
||||
}
|
@ -73,7 +73,7 @@ public class AccountLoginPane extends StackPane {
|
||||
} else if (account instanceof NoSelectedCharacterException) {
|
||||
dialog.close();
|
||||
} else if (account instanceof Exception) {
|
||||
lblCreationWarning.setText(AccountsPage.accountException((Exception) account));
|
||||
lblCreationWarning.setText(AddAccountPane.accountException((Exception) account));
|
||||
}
|
||||
|
||||
progressBar.setVisible(false);
|
||||
|
104
HMCL/src/main/java/org/jackhuang/hmcl/ui/AccountPage.java
Normal file
104
HMCL/src/main/java/org/jackhuang/hmcl/ui/AccountPage.java
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* 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 {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import org.jackhuang.hmcl.Launcher;
|
||||
import org.jackhuang.hmcl.auth.Account;
|
||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
||||
import org.jackhuang.hmcl.auth.offline.OfflineAccount;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
|
||||
import org.jackhuang.hmcl.game.AccountHelper;
|
||||
import org.jackhuang.hmcl.setting.Accounts;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.construct.ComponentList;
|
||||
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
||||
|
||||
public class AccountPage extends StackPane implements DecoratorPage {
|
||||
private final StringProperty title;
|
||||
|
||||
private final Account account;
|
||||
|
||||
@FXML
|
||||
private Label lblType;
|
||||
@FXML
|
||||
private Label lblServer;
|
||||
@FXML
|
||||
private Label lblCharacter;
|
||||
@FXML
|
||||
private Label lblEmail;
|
||||
@FXML
|
||||
private BorderPane paneServer;
|
||||
@FXML
|
||||
private ComponentList componentList;
|
||||
@FXML
|
||||
private JFXButton btnRefresh;
|
||||
|
||||
public AccountPage(Account account) {
|
||||
this.account = account;
|
||||
title = new SimpleStringProperty(this, "title", Launcher.i18n("account") + " - " + account.getCharacter());
|
||||
|
||||
FXUtils.loadFXML(this, "/assets/fxml/account.fxml");
|
||||
|
||||
if (account instanceof AuthlibInjectorAccount) {
|
||||
Task.ofResult("serverName", () -> Accounts.getAuthlibInjectorServerName(((AuthlibInjectorAccount) account).getServerBaseURL()))
|
||||
.subscribe(Schedulers.javafx(), variables -> lblServer.setText(variables.get("serverName")));
|
||||
} else {
|
||||
componentList.removeChildren(paneServer);
|
||||
}
|
||||
|
||||
lblCharacter.setText(account.getCharacter());
|
||||
lblType.setText(AddAccountPane.accountType(account));
|
||||
lblEmail.setText(account.getUsername());
|
||||
|
||||
btnRefresh.setDisable(account instanceof OfflineAccount);
|
||||
|
||||
if (account instanceof YggdrasilAccount) {
|
||||
btnRefresh.setOnMouseClicked(e -> {
|
||||
AccountHelper.refreshSkinAsync((YggdrasilAccount) account).start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onDelete() {
|
||||
Settings.INSTANCE.deleteAccount(account);
|
||||
Controllers.navigate(null);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringProperty titleProperty() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title.set(title);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2018 huangyuhui <huanghongxun2008@126.com>
|
||||
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* 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
|
||||
@ -19,16 +19,11 @@ package org.jackhuang.hmcl.ui;
|
||||
|
||||
import com.jfoenix.concurrency.JFXUtilities;
|
||||
import com.jfoenix.controls.*;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
@ -48,11 +43,9 @@ import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.construct.AdvancedListBox;
|
||||
import org.jackhuang.hmcl.ui.construct.IconedItem;
|
||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
@ -60,13 +53,8 @@ import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class AccountsPage extends StackPane implements DecoratorPage {
|
||||
private final StringProperty title = new SimpleStringProperty(this, "title", Launcher.i18n("account"));
|
||||
public class AddAccountPane extends StackPane {
|
||||
|
||||
@FXML
|
||||
private ScrollPane scrollPane;
|
||||
@FXML private JFXMasonryPane masonryPane;
|
||||
@FXML private JFXDialog dialog;
|
||||
@FXML private JFXTextField txtUsername;
|
||||
@FXML private JFXPasswordField txtPassword;
|
||||
@FXML private Label lblCreationWarning;
|
||||
@ -76,14 +64,15 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
||||
@FXML private JFXProgressBar progressBar;
|
||||
@FXML private Label lblAddInjectorServer;
|
||||
@FXML private Hyperlink linkAddInjectorServer;
|
||||
@FXML private JFXDialogLayout layout;
|
||||
private final Runnable finalization;
|
||||
|
||||
{
|
||||
FXUtils.loadFXML(this, "/assets/fxml/account.fxml");
|
||||
public AddAccountPane(Runnable finalization) {
|
||||
this.finalization = finalization;
|
||||
|
||||
getChildren().remove(dialog);
|
||||
dialog.setDialogContainer(this);
|
||||
FXUtils.loadFXML(this, "/assets/fxml/account-add.fxml");
|
||||
|
||||
FXUtils.smoothScrolling(scrollPane);
|
||||
loadServers();
|
||||
|
||||
cboType.getItems().setAll(Launcher.i18n("account.methods.offline"), Launcher.i18n("account.methods.yggdrasil"), Launcher.i18n("account.methods.authlib_injector"));
|
||||
cboType.getSelectionModel().selectedIndexProperty().addListener((a, b, newValue) -> {
|
||||
@ -103,38 +92,9 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
||||
txtUsername.setOnAction(e -> onCreationAccept());
|
||||
txtUsername.getValidators().add(new Validator(Launcher.i18n("input.email"), str -> !txtPassword.isVisible() || str.contains("@")));
|
||||
|
||||
FXUtils.onChangeAndOperate(Settings.INSTANCE.selectedAccountProperty(), account -> {
|
||||
for (Node node : masonryPane.getChildren())
|
||||
if (node instanceof AccountItem)
|
||||
((AccountItem) node).setSelected(account == ((AccountItem) node).getAccount());
|
||||
});
|
||||
|
||||
loadAccounts();
|
||||
loadServers();
|
||||
|
||||
if (Settings.INSTANCE.getAccounts().isEmpty())
|
||||
addNewAccount();
|
||||
}
|
||||
|
||||
public void loadAccounts() {
|
||||
List<Node> children = new LinkedList<>();
|
||||
int i = 0;
|
||||
ToggleGroup group = new ToggleGroup();
|
||||
for (Account account : Settings.INSTANCE.getAccounts()) {
|
||||
children.add(buildNode(++i, account, group));
|
||||
}
|
||||
group.selectedToggleProperty().addListener((a, b, newValue) -> {
|
||||
if (newValue != null)
|
||||
Settings.INSTANCE.setSelectedAccount((Account) newValue.getProperties().get("account"));
|
||||
});
|
||||
FXUtils.resetChildren(masonryPane, children);
|
||||
Platform.runLater(() -> {
|
||||
masonryPane.requestLayout();
|
||||
scrollPane.requestLayout();
|
||||
});
|
||||
}
|
||||
|
||||
public void loadServers() {
|
||||
private void loadServers() {
|
||||
Task.ofResult("list", () -> Settings.INSTANCE.getAuthlibInjectorServerURLs().parallelStream()
|
||||
.flatMap(serverURL -> {
|
||||
try {
|
||||
@ -152,28 +112,6 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
||||
}));
|
||||
}
|
||||
|
||||
private Node buildNode(int i, Account account, ToggleGroup group) {
|
||||
AccountItem item = new AccountItem(i, account, group);
|
||||
item.setOnDeleteButtonMouseClicked(e -> {
|
||||
Settings.INSTANCE.deleteAccount(account);
|
||||
Platform.runLater(this::loadAccounts);
|
||||
});
|
||||
return item;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void addNewAccount() {
|
||||
txtUsername.setText("");
|
||||
txtPassword.setText("");
|
||||
lblCreationWarning.setText("");
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onAddInjecterServer() {
|
||||
Controllers.navigate(Controllers.getServersPage());
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onCreationAccept() {
|
||||
int type = cboType.getSelectionModel().getSelectedIndex();
|
||||
@ -183,23 +121,22 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
||||
progressBar.setVisible(true);
|
||||
lblCreationWarning.setText("");
|
||||
Task.ofResult("create_account", () -> {
|
||||
AccountFactory<?> factory;
|
||||
switch (type) {
|
||||
case 0: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.OFFLINE_ACCOUNT_KEY); break;
|
||||
case 1: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.YGGDRASIL_ACCOUNT_KEY); break;
|
||||
case 2: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.AUTHLIB_INJECTOR_ACCOUNT_KEY); break;
|
||||
default: throw new Error();
|
||||
}
|
||||
AccountFactory<?> factory;
|
||||
switch (type) {
|
||||
case 0: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.OFFLINE_ACCOUNT_KEY); break;
|
||||
case 1: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.YGGDRASIL_ACCOUNT_KEY); break;
|
||||
case 2: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.AUTHLIB_INJECTOR_ACCOUNT_KEY); break;
|
||||
default: throw new Error();
|
||||
}
|
||||
|
||||
return factory.create(new Selector(), username, password, apiRoot, Settings.INSTANCE.getProxy());
|
||||
return factory.create(new Selector(), username, password, apiRoot, Settings.INSTANCE.getProxy());
|
||||
}).finalized(Schedulers.javafx(), variables -> {
|
||||
Settings.INSTANCE.addAccount(variables.get("create_account"));
|
||||
dialog.close();
|
||||
loadAccounts();
|
||||
progressBar.setVisible(false);
|
||||
finalization.run();
|
||||
}, exception -> {
|
||||
if (exception instanceof NoSelectedCharacterException) {
|
||||
dialog.close();
|
||||
finalization.run();
|
||||
} else {
|
||||
lblCreationWarning.setText(accountException(exception));
|
||||
}
|
||||
@ -209,46 +146,24 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
||||
|
||||
@FXML
|
||||
private void onCreationCancel() {
|
||||
dialog.close();
|
||||
finalization.run();
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title.get();
|
||||
@FXML
|
||||
private void onAddInjecterServer() {
|
||||
finalization.run();
|
||||
Controllers.navigate(Controllers.getServersPage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringProperty titleProperty() {
|
||||
return title;
|
||||
private void showSelector(Node node) {
|
||||
getChildren().setAll(node);
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title.set(title);
|
||||
private void closeSelector() {
|
||||
getChildren().setAll(layout);
|
||||
}
|
||||
|
||||
public static String accountException(Exception exception) {
|
||||
if (exception instanceof InvalidCredentialsException) {
|
||||
return Launcher.i18n("account.failed.invalid_credentials");
|
||||
} else if (exception instanceof NoCharacterException) {
|
||||
return Launcher.i18n("account.failed.no_charactor");
|
||||
} else if (exception instanceof ServerDisconnectException) {
|
||||
return Launcher.i18n("account.failed.connect_authentication_server");
|
||||
} else if (exception instanceof InvalidTokenException) {
|
||||
return Launcher.i18n("account.failed.invalid_token");
|
||||
} else if (exception instanceof InvalidPasswordException) {
|
||||
return Launcher.i18n("account.failed.invalid_password");
|
||||
} else {
|
||||
return exception.getClass() + ": " + exception.getLocalizedMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public static String accountType(Account account) {
|
||||
if (account instanceof OfflineAccount) return Launcher.i18n("account.methods.offline");
|
||||
else if (account instanceof AuthlibInjectorAccount) return Launcher.i18n("account.methods.authlib_injector");
|
||||
else if (account instanceof YggdrasilAccount) return Launcher.i18n("account.methods.yggdrasil");
|
||||
else throw new Error(Launcher.i18n("account.methods.no_method") + ": " + account);
|
||||
}
|
||||
|
||||
private static class Selector extends BorderPane implements CharacterSelector {
|
||||
private class Selector extends BorderPane implements CharacterSelector {
|
||||
private final AdvancedListBox listBox = new AdvancedListBox();
|
||||
private final JFXButton cancel = new JFXButton();
|
||||
|
||||
@ -303,20 +218,43 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
||||
listBox.add(accountItem);
|
||||
}
|
||||
|
||||
JFXUtilities.runInFX(() -> Controllers.dialog(this));
|
||||
JFXUtilities.runInFX(() -> showSelector(this));
|
||||
|
||||
try {
|
||||
latch.await();
|
||||
|
||||
JFXUtilities.runInFX(Controllers::closeDialog);
|
||||
|
||||
if (selectedProfile == null)
|
||||
throw new NoSelectedCharacterException(account);
|
||||
|
||||
JFXUtilities.runInFX(AddAccountPane.this::closeSelector);
|
||||
|
||||
return selectedProfile;
|
||||
} catch (InterruptedException ignore) {
|
||||
throw new NoSelectedCharacterException(account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String accountException(Exception exception) {
|
||||
if (exception instanceof InvalidCredentialsException) {
|
||||
return Launcher.i18n("account.failed.invalid_credentials");
|
||||
} else if (exception instanceof NoCharacterException) {
|
||||
return Launcher.i18n("account.failed.no_charactor");
|
||||
} else if (exception instanceof ServerDisconnectException) {
|
||||
return Launcher.i18n("account.failed.connect_authentication_server");
|
||||
} else if (exception instanceof InvalidTokenException) {
|
||||
return Launcher.i18n("account.failed.invalid_token");
|
||||
} else if (exception instanceof InvalidPasswordException) {
|
||||
return Launcher.i18n("account.failed.invalid_password");
|
||||
} else {
|
||||
return exception.getClass() + ": " + exception.getLocalizedMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public static String accountType(Account account) {
|
||||
if (account instanceof OfflineAccount) return Launcher.i18n("account.methods.offline");
|
||||
else if (account instanceof AuthlibInjectorAccount) return Launcher.i18n("account.methods.authlib_injector");
|
||||
else if (account instanceof YggdrasilAccount) return Launcher.i18n("account.methods.yggdrasil");
|
||||
else throw new Error(Launcher.i18n("account.methods.no_method") + ": " + account);
|
||||
}
|
||||
}
|
@ -19,27 +19,26 @@ package org.jackhuang.hmcl.ui;
|
||||
|
||||
import com.jfoenix.concurrency.JFXUtilities;
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXListView;
|
||||
import com.jfoenix.controls.JFXPopup;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import org.jackhuang.hmcl.Launcher;
|
||||
import org.jackhuang.hmcl.auth.Account;
|
||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
||||
import org.jackhuang.hmcl.auth.offline.OfflineAccount;
|
||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
|
||||
import org.jackhuang.hmcl.event.EventBus;
|
||||
import org.jackhuang.hmcl.event.ProfileChangedEvent;
|
||||
import org.jackhuang.hmcl.event.ProfileLoadingEvent;
|
||||
import org.jackhuang.hmcl.event.RefreshedVersionsEvent;
|
||||
import org.jackhuang.hmcl.event.*;
|
||||
import org.jackhuang.hmcl.game.AccountHelper;
|
||||
import org.jackhuang.hmcl.game.HMCLGameRepository;
|
||||
import org.jackhuang.hmcl.game.ModpackHelper;
|
||||
import org.jackhuang.hmcl.mod.Modpack;
|
||||
import org.jackhuang.hmcl.mod.UnsupportedModpackException;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.setting.Profiles;
|
||||
import org.jackhuang.hmcl.setting.Settings;
|
||||
import org.jackhuang.hmcl.setting.Theme;
|
||||
import org.jackhuang.hmcl.setting.*;
|
||||
import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.construct.AdvancedListBox;
|
||||
@ -55,50 +54,53 @@ import java.util.Objects;
|
||||
public final class LeftPaneController {
|
||||
private final AdvancedListBox leftPane;
|
||||
private final VBox profilePane = new VBox();
|
||||
private final VersionListItem accountItem = new VersionListItem("", "");
|
||||
private final VBox accountPane = new VBox();
|
||||
private final VersionListItem missingAccountItem = new VersionListItem(Launcher.i18n("account.missing"), Launcher.i18n("message.unknown"));
|
||||
|
||||
public LeftPaneController(AdvancedListBox leftPane) {
|
||||
this.leftPane = leftPane;
|
||||
|
||||
leftPane.startCategory(Launcher.i18n("account").toUpperCase())
|
||||
.add(Lang.apply(new RipplerContainer(accountItem), rippler -> {
|
||||
rippler.setOnMouseClicked(e -> Controllers.navigate(new AccountsPage()));
|
||||
accountItem.setOnSettingsButtonClicked(() -> Controllers.navigate(new AccountsPage()));
|
||||
}))
|
||||
leftPane
|
||||
.add(new ClassTitle(Launcher.i18n("account").toUpperCase(), Lang.apply(new JFXButton(), button -> {
|
||||
button.setGraphic(SVG.plus(Theme.blackFillBinding(), 10, 10));
|
||||
button.getStyleClass().add("toggle-icon-tiny");
|
||||
button.setOnMouseClicked(e -> addNewAccount());
|
||||
})))
|
||||
.add(accountPane)
|
||||
.startCategory(Launcher.i18n("launcher").toUpperCase())
|
||||
.add(Lang.apply(new IconedItem(SVG.gear(Theme.blackFillBinding(), 20, 20), Launcher.i18n("settings.launcher")), iconedItem -> {
|
||||
iconedItem.prefWidthProperty().bind(leftPane.widthProperty());
|
||||
iconedItem.setOnMouseClicked(e -> Controllers.navigate(Controllers.getSettingsPage()));
|
||||
}))
|
||||
.add(new ClassTitle(Lang.apply(new BorderPane(), borderPane -> {
|
||||
borderPane.setLeft(Lang.apply(new VBox(), vBox -> vBox.getChildren().setAll(new Text(Launcher.i18n("profile.title").toUpperCase()))));
|
||||
JFXButton addProfileButton = new JFXButton();
|
||||
addProfileButton.setGraphic(SVG.plus(Theme.blackFillBinding(), 10, 10));
|
||||
addProfileButton.getStyleClass().add("toggle-icon-tiny");
|
||||
addProfileButton.setOnMouseClicked(e ->
|
||||
.add(new ClassTitle(Launcher.i18n("profile.title").toUpperCase(), Lang.apply(new JFXButton(), button -> {
|
||||
button.setGraphic(SVG.plus(Theme.blackFillBinding(), 10, 10));
|
||||
button.getStyleClass().add("toggle-icon-tiny");
|
||||
button.setOnMouseClicked(e ->
|
||||
Controllers.getDecorator().showPage(new ProfilePage(null)));
|
||||
borderPane.setRight(addProfileButton);
|
||||
})))
|
||||
.add(profilePane);
|
||||
|
||||
EventBus.EVENT_BUS.channel(AccountLoadingEvent.class).register(this::onAccountsLoading);
|
||||
EventBus.EVENT_BUS.channel(ProfileLoadingEvent.class).register(this::onProfilesLoading);
|
||||
EventBus.EVENT_BUS.channel(ProfileChangedEvent.class).register(this::onProfileChanged);
|
||||
EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(this::onRefreshedVersions);
|
||||
|
||||
FXUtils.onChangeAndOperate(Settings.INSTANCE.selectedAccountProperty(), it -> {
|
||||
if (it == null) {
|
||||
accountItem.setVersionName(Launcher.i18n("account.missing"));
|
||||
accountItem.setGameVersion(Launcher.i18n("message.unknown"));
|
||||
} else {
|
||||
accountItem.setVersionName(it.getCharacter());
|
||||
accountItem.setGameVersion(AccountsPage.accountType(it));
|
||||
}
|
||||
FXUtils.onChangeAndOperate(Settings.INSTANCE.selectedAccountProperty(), this::onSelectedAccountChanged);
|
||||
onAccountsLoading();
|
||||
}
|
||||
|
||||
if (it instanceof YggdrasilAccount) {
|
||||
Image image = AccountHelper.getSkin((YggdrasilAccount) it, 4);
|
||||
accountItem.setImage(image, AccountHelper.getViewport(4));
|
||||
} else
|
||||
accountItem.setImage(AccountHelper.getDefaultSkin(it, 4), AccountHelper.getViewport(4));
|
||||
private void addNewAccount() {
|
||||
Controllers.dialog(new AddAccountPane(Controllers::closeDialog));
|
||||
}
|
||||
|
||||
private void onSelectedAccountChanged(Account newAccount) {
|
||||
Platform.runLater(() -> {
|
||||
for (Node node : accountPane.getChildren()) {
|
||||
if (node instanceof RipplerContainer && node.getProperties().get("account") instanceof Account) {
|
||||
boolean current = Objects.equals(node.getProperties().get("account"), newAccount);
|
||||
((RipplerContainer) node).setSelected(current);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -130,6 +132,73 @@ public final class LeftPaneController {
|
||||
Platform.runLater(() -> profilePane.getChildren().setAll(list));
|
||||
}
|
||||
|
||||
private static String accountType(Account account) {
|
||||
if (account instanceof OfflineAccount) return Launcher.i18n("account.methods.offline");
|
||||
else if (account instanceof YggdrasilAccount) return account.getUsername();
|
||||
else throw new Error(Launcher.i18n("account.methods.no_method") + ": " + account);
|
||||
}
|
||||
|
||||
private void onAccountsLoading() {
|
||||
LinkedList<RipplerContainer> list = new LinkedList<>();
|
||||
Account selectedAccount = Settings.INSTANCE.getSelectedAccount();
|
||||
for (Account account : Settings.INSTANCE.getAccounts()) {
|
||||
VersionListItem item = new VersionListItem(account.getCharacter(), accountType(account));
|
||||
RipplerContainer ripplerContainer = new RipplerContainer(item);
|
||||
item.setOnSettingsButtonClicked(() -> Controllers.getDecorator().showPage(new AccountPage(account)));
|
||||
ripplerContainer.setOnMouseClicked(e -> {
|
||||
if (e.getButton() == MouseButton.PRIMARY)
|
||||
Settings.INSTANCE.setSelectedAccount(account);
|
||||
else if (e.getButton() == MouseButton.SECONDARY) {
|
||||
JFXListView<String> listView = new JFXListView<>();
|
||||
JFXPopup popup = new JFXPopup(listView);
|
||||
listView.getStyleClass().add("option-list-view");
|
||||
listView.getItems().add(Launcher.i18n("button.delete"));
|
||||
if (account instanceof YggdrasilAccount)
|
||||
listView.getItems().add(Launcher.i18n("button.refresh"));
|
||||
listView.setOnMouseClicked(e2 ->{
|
||||
popup.hide();
|
||||
switch (listView.getSelectionModel().getSelectedIndex()) {
|
||||
case 0:
|
||||
Settings.INSTANCE.deleteAccount(account);
|
||||
break;
|
||||
case 1:
|
||||
if (account instanceof YggdrasilAccount)
|
||||
AccountHelper.refreshSkinAsync((YggdrasilAccount) account).start();
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}});
|
||||
popup.show(item, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT, e.getX(), e.getY());
|
||||
}
|
||||
});
|
||||
ripplerContainer.getProperties().put("account", account);
|
||||
ripplerContainer.maxWidthProperty().bind(leftPane.widthProperty());
|
||||
|
||||
if (account instanceof YggdrasilAccount) {
|
||||
Image image = AccountHelper.getSkin((YggdrasilAccount) account, 4);
|
||||
item.setImage(image, AccountHelper.getViewport(4));
|
||||
} else
|
||||
item.setImage(AccountHelper.getDefaultSkin(account, 4), AccountHelper.getViewport(4));
|
||||
|
||||
if (account instanceof AuthlibInjectorAccount)
|
||||
Accounts.getAuthlibInjectorServerNameAsync((AuthlibInjectorAccount) account)
|
||||
.subscribe(Schedulers.javafx(), variables -> FXUtils.installTooltip(ripplerContainer, 500, 5000, 0, new Tooltip(variables.get("serverName"))));
|
||||
|
||||
if (selectedAccount == account)
|
||||
ripplerContainer.setSelected(true);
|
||||
|
||||
list.add(ripplerContainer);
|
||||
}
|
||||
|
||||
if (Settings.INSTANCE.getAccounts().isEmpty()) {
|
||||
RipplerContainer container = new RipplerContainer(missingAccountItem);
|
||||
missingAccountItem.setOnSettingsButtonClicked(this::addNewAccount);
|
||||
list.add(container);
|
||||
}
|
||||
|
||||
Platform.runLater(() -> accountPane.getChildren().setAll(list));
|
||||
}
|
||||
|
||||
private boolean checkedModpack = false;
|
||||
|
||||
private void onRefreshedVersions(RefreshedVersionsEvent event) {
|
||||
@ -162,8 +231,8 @@ public final class LeftPaneController {
|
||||
});
|
||||
}
|
||||
|
||||
private void checkAccount() {
|
||||
public void checkAccount() {
|
||||
if (Settings.INSTANCE.getAccounts().isEmpty())
|
||||
Controllers.navigate(new AccountsPage());
|
||||
addNewAccount();
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ import org.jackhuang.hmcl.ui.construct.MessageBox;
|
||||
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
|
||||
import org.jackhuang.hmcl.ui.download.DownloadWizardProvider;
|
||||
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.OperatingSystem;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
|
||||
@ -58,8 +59,6 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
||||
private final StringProperty title = new SimpleStringProperty(this, "title", Launcher.i18n("main_page"));
|
||||
|
||||
private Profile profile;
|
||||
private String rightClickedVersion;
|
||||
private HMCLGameRepository rightClickedRepository;
|
||||
|
||||
@FXML
|
||||
private JFXButton btnRefresh;
|
||||
@ -71,10 +70,6 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
||||
private JFXSpinner spinner;
|
||||
@FXML
|
||||
private JFXMasonryPane masonryPane;
|
||||
@FXML
|
||||
private JFXListView versionList;
|
||||
|
||||
private final JFXPopup versionPopup;
|
||||
|
||||
{
|
||||
FXUtils.loadFXML(this, "/assets/fxml/main.fxml");
|
||||
@ -93,9 +88,6 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
||||
this.profile = event.getProfile();
|
||||
});
|
||||
|
||||
versionPopup = new JFXPopup(versionList);
|
||||
getChildren().remove(versionList);
|
||||
|
||||
btnAdd.setOnMouseClicked(e -> Controllers.getDecorator().startWizard(new DownloadWizardProvider(), Launcher.i18n("install")));
|
||||
FXUtils.installTooltip(btnAdd, Launcher.i18n("install"));
|
||||
btnRefresh.setOnMouseClicked(e -> Settings.INSTANCE.getSelectedProfile().getRepository().refreshVersionsAsync().start());
|
||||
@ -126,7 +118,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
||||
item.setLibraries(libraries.toString());
|
||||
item.setOnLaunchButtonClicked(e -> {
|
||||
if (Settings.INSTANCE.getSelectedAccount() == null)
|
||||
Controllers.dialog(Launcher.i18n("login.empty_username"));
|
||||
Controllers.getLeftPaneController().checkAccount();
|
||||
else
|
||||
LauncherHelper.INSTANCE.launch(profile, Settings.INSTANCE.getSelectedAccount(), id, null);
|
||||
});
|
||||
@ -174,9 +166,34 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
||||
});
|
||||
item.setOnMouseClicked(event -> {
|
||||
if (event.getButton() == MouseButton.SECONDARY) {
|
||||
rightClickedVersion = id;
|
||||
rightClickedRepository = repository;
|
||||
versionList.getSelectionModel().select(-1);
|
||||
JFXListView<String> versionList = new JFXListView<>();
|
||||
JFXPopup versionPopup = new JFXPopup(versionList);
|
||||
versionList.getStyleClass().add("option-list-view");
|
||||
FXUtils.setLimitWidth(versionList, 150);
|
||||
versionList.getItems().setAll(Lang.immutableListOf(
|
||||
Launcher.i18n("version.manage.rename"),
|
||||
Launcher.i18n("version.manage.remove"),
|
||||
Launcher.i18n("modpack.export"),
|
||||
Launcher.i18n("folder.game")
|
||||
));
|
||||
versionList.setOnMouseClicked(e ->{
|
||||
versionPopup.hide();
|
||||
switch (versionList.getSelectionModel().getSelectedIndex()) {
|
||||
case 0:
|
||||
VersionPage.renameVersion(profile, id);
|
||||
break;
|
||||
case 1:
|
||||
VersionPage.deleteVersion(profile, id);
|
||||
break;
|
||||
case 2:
|
||||
VersionPage.exportVersion(profile, id);
|
||||
break;
|
||||
case 3:
|
||||
FXUtils.openFolder(repository.getRunDirectory(id));
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}});
|
||||
versionPopup.show(item, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT, event.getX(), event.getY());
|
||||
} else if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) {
|
||||
if (Settings.INSTANCE.getSelectedAccount() == null)
|
||||
@ -209,27 +226,6 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
||||
});
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onVersionManagement() {
|
||||
versionPopup.hide();
|
||||
switch (versionList.getSelectionModel().getSelectedIndex()) {
|
||||
case 0:
|
||||
VersionPage.renameVersion(rightClickedRepository.getProfile(), rightClickedVersion);
|
||||
break;
|
||||
case 1:
|
||||
VersionPage.deleteVersion(rightClickedRepository.getProfile(), rightClickedVersion);
|
||||
break;
|
||||
case 2:
|
||||
VersionPage.exportVersion(rightClickedRepository.getProfile(), rightClickedVersion);
|
||||
break;
|
||||
case 3:
|
||||
FXUtils.openFolder(rightClickedRepository.getRunDirectory(rightClickedVersion));
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title.get();
|
||||
}
|
||||
|
@ -18,11 +18,13 @@
|
||||
package org.jackhuang.hmcl.ui.construct;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import javafx.scene.text.Text;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
|
||||
/**
|
||||
* @author huangyuhui
|
||||
@ -48,6 +50,13 @@ public class ClassTitle extends StackPane {
|
||||
getStyleClass().add("class-title");
|
||||
}
|
||||
|
||||
public ClassTitle(String text, Node rightNode) {
|
||||
this(Lang.apply(new BorderPane(), borderPane -> {
|
||||
borderPane.setLeft(Lang.apply(new VBox(), vBox -> vBox.getChildren().setAll(new Text(text))));
|
||||
borderPane.setRight(rightNode);
|
||||
}));
|
||||
}
|
||||
|
||||
public Node getContent() {
|
||||
return content;
|
||||
}
|
||||
|
@ -60,9 +60,14 @@ public class ComponentList extends StackPane {
|
||||
child.getStyleClass().add("options-list-item-ahead");
|
||||
else
|
||||
child.getStyleClass().add("options-list-item");
|
||||
child.getProperties().put("node", node);
|
||||
vbox.getChildren().add(child);
|
||||
}
|
||||
|
||||
public void removeChildren(Node node) {
|
||||
vbox.getChildren().removeIf(node1 -> node1.getProperties().get("node") == node);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title.get();
|
||||
}
|
||||
|
64
HMCL/src/main/resources/assets/fxml/account-add.fxml
Normal file
64
HMCL/src/main/resources/assets/fxml/account-add.fxml
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import com.jfoenix.controls.*?>
|
||||
<?import com.jfoenix.validation.RequiredFieldValidator?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import org.jackhuang.hmcl.ui.FXUtils?>
|
||||
<fx:root xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
type="StackPane">
|
||||
<JFXDialogLayout fx:id="layout">
|
||||
<heading>
|
||||
<Label text="%account.create"/>
|
||||
</heading>
|
||||
<body>
|
||||
<GridPane vgap="15" hgap="15" style="-fx-padding: 15 0 0 0;">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints maxWidth="70" minWidth="70"/>
|
||||
<ColumnConstraints/>
|
||||
<ColumnConstraints minWidth="140"/>
|
||||
</columnConstraints>
|
||||
|
||||
<Label text="%account.methods" GridPane.halignment="RIGHT" GridPane.columnIndex="0"
|
||||
GridPane.rowIndex="0"/>
|
||||
|
||||
<JFXComboBox fx:id="cboType" GridPane.columnIndex="1" GridPane.rowIndex="0" GridPane.columnSpan="2"/>
|
||||
|
||||
<Label fx:id="lblAddInjectorServer" text="%account.injector.server" GridPane.halignment="RIGHT"
|
||||
GridPane.columnIndex="0" GridPane.rowIndex="1"/>
|
||||
|
||||
<JFXComboBox fx:id="cboServers" maxHeight="25" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
|
||||
|
||||
<Hyperlink fx:id="linkAddInjectorServer" text="%account.injector.add"
|
||||
onMouseClicked="#onAddInjecterServer" GridPane.columnIndex="2" GridPane.rowIndex="1"/>
|
||||
|
||||
<Label text="%account.username" GridPane.rowIndex="2" GridPane.columnIndex="0"/>
|
||||
|
||||
<JFXTextField fx:id="txtUsername" GridPane.columnIndex="1" GridPane.rowIndex="2" GridPane.columnSpan="2"
|
||||
FXUtils.validateWhileTextChanged="true">
|
||||
<validators>
|
||||
<RequiredFieldValidator message="%input.not_empty">
|
||||
</RequiredFieldValidator>
|
||||
</validators>
|
||||
</JFXTextField>
|
||||
|
||||
<Label fx:id="lblPassword" text="%account.password" GridPane.rowIndex="3" GridPane.columnIndex="0"/>
|
||||
|
||||
<JFXPasswordField fx:id="txtPassword" GridPane.columnIndex="1" GridPane.rowIndex="3"
|
||||
GridPane.columnSpan="2" FXUtils.validateWhileTextChanged="true">
|
||||
<validators>
|
||||
<RequiredFieldValidator message="%input.not_empty">
|
||||
</RequiredFieldValidator>
|
||||
</validators>
|
||||
</JFXPasswordField>
|
||||
</GridPane>
|
||||
</body>
|
||||
<actions>
|
||||
<Label fx:id="lblCreationWarning"/>
|
||||
<JFXButton onMouseClicked="#onCreationAccept" text="%button.ok" styleClass="dialog-accept"/>
|
||||
<JFXButton onMouseClicked="#onCreationCancel" text="%button.cancel" styleClass="dialog-cancel"/>
|
||||
</actions>
|
||||
</JFXDialogLayout>
|
||||
<JFXProgressBar fx:id="progressBar" visible="false" StackPane.alignment="TOP_CENTER"/>
|
||||
</fx:root>
|
@ -26,7 +26,7 @@
|
||||
<actions>
|
||||
<Label fx:id="lblCreationWarning" />
|
||||
<JFXButton onMouseClicked="#onAccept" text="%button.ok" styleClass="dialog-accept"/>
|
||||
<JFXButton onMouseClicked="#onCancel" text="%button.cancel" styleClass="dialog-cancel"/>
|
||||
<JFXButton onMouseClicked="#finalization" text="%button.cancel" styleClass="dialog-cancel"/>
|
||||
</actions>
|
||||
</JFXDialogLayout>
|
||||
<JFXProgressBar fx:id="progressBar" visible="false" StackPane.alignment="TOP_CENTER"/>
|
||||
|
@ -4,72 +4,79 @@
|
||||
<?import com.jfoenix.validation.RequiredFieldValidator?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import org.jackhuang.hmcl.ui.FXUtils?>
|
||||
<?import org.jackhuang.hmcl.ui.construct.FileItem?>
|
||||
<?import org.jackhuang.hmcl.ui.construct.ComponentList?>
|
||||
<fx:root xmlns="http://javafx.com/javafx"
|
||||
xmlns:fx="http://javafx.com/fxml"
|
||||
type="StackPane">
|
||||
<ScrollPane fitToHeight="true" fitToWidth="true" fx:id="scrollPane" hbarPolicy="NEVER">
|
||||
<JFXMasonryPane fx:id="masonryPane" HSpacing="3" VSpacing="3" cellWidth="182" cellHeight="160">
|
||||
</JFXMasonryPane>
|
||||
<ScrollPane fx:id="scroll" fitToHeight="true" fitToWidth="true">
|
||||
<VBox fx:id="rootPane" style="-fx-padding: 20;">
|
||||
|
||||
<ComponentList fx:id="componentList" depth="1">
|
||||
|
||||
<BorderPane> <!-- Name -->
|
||||
<left>
|
||||
<VBox>
|
||||
<Label text="%account.methods" BorderPane.alignment="CENTER_LEFT"/>
|
||||
</VBox>
|
||||
</left>
|
||||
<right>
|
||||
<VBox>
|
||||
<Label fx:id="lblType" BorderPane.alignment="CENTER_LEFT"/>
|
||||
</VBox>
|
||||
</right>
|
||||
</BorderPane>
|
||||
|
||||
<BorderPane> <!-- Name -->
|
||||
<left>
|
||||
<VBox>
|
||||
<Label text="%account.character" BorderPane.alignment="CENTER_LEFT"/>
|
||||
</VBox>
|
||||
</left>
|
||||
<right>
|
||||
<VBox>
|
||||
<Label fx:id="lblCharacter" BorderPane.alignment="CENTER_LEFT"/>
|
||||
</VBox>
|
||||
</right>
|
||||
</BorderPane>
|
||||
|
||||
<BorderPane> <!-- Name -->
|
||||
<left>
|
||||
<VBox>
|
||||
<Label text="%account.email" BorderPane.alignment="CENTER_LEFT"/>
|
||||
</VBox>
|
||||
</left>
|
||||
<right>
|
||||
<VBox>
|
||||
<Label fx:id="lblEmail" BorderPane.alignment="CENTER_LEFT"/>
|
||||
</VBox>
|
||||
</right>
|
||||
</BorderPane>
|
||||
|
||||
<BorderPane fx:id="paneServer"> <!-- Name -->
|
||||
<left>
|
||||
<VBox>
|
||||
<Label text="%account.injector.server" BorderPane.alignment="CENTER_LEFT"/>
|
||||
</VBox>
|
||||
</left>
|
||||
<right>
|
||||
<VBox>
|
||||
<Label fx:id="lblServer" BorderPane.alignment="CENTER_LEFT"/>
|
||||
</VBox>
|
||||
</right>
|
||||
</BorderPane>
|
||||
</ComponentList>
|
||||
|
||||
</VBox>
|
||||
</ScrollPane>
|
||||
<AnchorPane pickOnBounds="false">
|
||||
<JFXButton onMouseClicked="#addNewAccount" AnchorPane.bottomAnchor="16" AnchorPane.rightAnchor="16" buttonType="RAISED" prefWidth="40" prefHeight="40" styleClass="jfx-button-raised-round">
|
||||
<graphic>
|
||||
<fx:include source="/assets/svg/plus.fxml" />
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
</AnchorPane>
|
||||
|
||||
<JFXDialog fx:id="dialog">
|
||||
<StackPane>
|
||||
<JFXDialogLayout>
|
||||
<heading>
|
||||
<Label text="%account.create" />
|
||||
</heading>
|
||||
<body>
|
||||
<GridPane vgap="15" hgap="15" style="-fx-padding: 15 0 0 0;">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints maxWidth="70" minWidth="70"/>
|
||||
<ColumnConstraints />
|
||||
<ColumnConstraints minWidth="140" />
|
||||
</columnConstraints>
|
||||
|
||||
<Label text="%account.methods" GridPane.halignment="RIGHT" GridPane.columnIndex="0" GridPane.rowIndex="0" />
|
||||
|
||||
<JFXComboBox fx:id="cboType" GridPane.columnIndex="1" GridPane.rowIndex="0" GridPane.columnSpan="2" />
|
||||
|
||||
<Label fx:id="lblAddInjectorServer" text="%account.injector.server" GridPane.halignment="RIGHT" GridPane.columnIndex="0" GridPane.rowIndex="1" />
|
||||
|
||||
<JFXComboBox fx:id="cboServers" maxHeight="25" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||
|
||||
<Hyperlink fx:id="linkAddInjectorServer" text="%account.injector.add" onMouseClicked="#onAddInjecterServer" GridPane.columnIndex="2" GridPane.rowIndex="1" />
|
||||
|
||||
<Label text="%account.username" GridPane.rowIndex="2" GridPane.columnIndex="0" />
|
||||
|
||||
<JFXTextField fx:id="txtUsername" GridPane.columnIndex="1" GridPane.rowIndex="2" GridPane.columnSpan="2" FXUtils.validateWhileTextChanged="true">
|
||||
<validators>
|
||||
<RequiredFieldValidator message="%input.not_empty">
|
||||
</RequiredFieldValidator>
|
||||
</validators>
|
||||
</JFXTextField>
|
||||
|
||||
<Label fx:id="lblPassword" text="%account.password" GridPane.rowIndex="3" GridPane.columnIndex="0" />
|
||||
|
||||
<JFXPasswordField fx:id="txtPassword" GridPane.columnIndex="1" GridPane.rowIndex="3" GridPane.columnSpan="2" FXUtils.validateWhileTextChanged="true">
|
||||
<validators>
|
||||
<RequiredFieldValidator message="%input.not_empty">
|
||||
</RequiredFieldValidator>
|
||||
</validators>
|
||||
</JFXPasswordField>
|
||||
</GridPane>
|
||||
</body>
|
||||
<actions>
|
||||
<Label fx:id="lblCreationWarning" />
|
||||
<JFXButton onMouseClicked="#onCreationAccept" text="%button.ok" styleClass="dialog-accept" />
|
||||
<JFXButton onMouseClicked="#onCreationCancel" text="%button.cancel" styleClass="dialog-cancel" />
|
||||
</actions>
|
||||
</JFXDialogLayout>
|
||||
<JFXProgressBar fx:id="progressBar" visible="false" StackPane.alignment="TOP_CENTER" />
|
||||
</StackPane>
|
||||
</JFXDialog>
|
||||
<BorderPane pickOnBounds="false" style="-fx-padding: 20;">
|
||||
<left>
|
||||
<JFXButton BorderPane.alignment="BOTTOM_LEFT" fx:id="btnDelete" onMouseClicked="#onDelete" prefWidth="100" prefHeight="40"
|
||||
buttonType="RAISED" text="%button.delete" styleClass="jfx-button-raised" />
|
||||
</left>
|
||||
<right>
|
||||
<JFXButton BorderPane.alignment="BOTTOM_RIGHT" fx:id="btnRefresh" prefWidth="100" prefHeight="40"
|
||||
buttonType="RAISED" text="%button.refresh" styleClass="jfx-button-raised"/>
|
||||
</right>
|
||||
</BorderPane>
|
||||
</fx:root>
|
||||
|
@ -32,7 +32,7 @@
|
||||
<Label text="%account.injector.add" />
|
||||
</heading>
|
||||
<body>
|
||||
<JFXTextField fx:id="txtServerIp" promptText="%account.injector.server_ip" labelFloat="true">
|
||||
<JFXTextField fx:id="txtServerIp" promptText="%account.injector.server_ip">
|
||||
<validators>
|
||||
<URLValidator message="%input.url">
|
||||
</URLValidator>
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXListView?>
|
||||
<?import com.jfoenix.controls.JFXMasonryPane?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
@ -30,13 +29,4 @@
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
</VBox>
|
||||
|
||||
|
||||
<JFXListView fx:id="versionList" styleClass="option-list-view" onMouseClicked="#onVersionManagement"
|
||||
maxWidth="150.0" minWidth="150.0">
|
||||
<Label text="%version.manage.rename"/>
|
||||
<Label text="%version.manage.remove"/>
|
||||
<Label text="%modpack.export"/>
|
||||
<Label text="%folder.game"/>
|
||||
</JFXListView>
|
||||
</fx:root>
|
||||
|
@ -29,6 +29,7 @@ about.open_source=Open Source
|
||||
about.open_source.statement=GPL v3 (https://github.com/huanghongxun/HMCL/)
|
||||
|
||||
account=Accounts
|
||||
account.character=character
|
||||
account.choose=Choose a character
|
||||
account.current=Current
|
||||
account.create=Create a new account
|
||||
|
@ -29,6 +29,7 @@ about.open_source=开源
|
||||
about.open_source.statement=GPL v3 (https://github.com/huanghongxun/HMCL/)
|
||||
|
||||
account=账户
|
||||
account.character=角色
|
||||
account.choose=选择一个角色
|
||||
account.current=当前账户
|
||||
account.create=新建账户
|
||||
|
Loading…
x
Reference in New Issue
Block a user