Remove accountsPage
This commit is contained in:
@@ -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.YggdrasilAccount;
|
||||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccountFactory;
|
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccountFactory;
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||||
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
import org.jackhuang.hmcl.task.TaskResult;
|
||||||
import org.jackhuang.hmcl.util.*;
|
import org.jackhuang.hmcl.util.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -96,4 +98,8 @@ public final class Accounts {
|
|||||||
return response.getMeta().getServerName();
|
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.AccountFactory;
|
||||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
|
import org.jackhuang.hmcl.event.AccountLoadingEvent;
|
||||||
import org.jackhuang.hmcl.event.EventBus;
|
import org.jackhuang.hmcl.event.EventBus;
|
||||||
import org.jackhuang.hmcl.event.ProfileChangedEvent;
|
import org.jackhuang.hmcl.event.ProfileChangedEvent;
|
||||||
import org.jackhuang.hmcl.event.ProfileLoadingEvent;
|
import org.jackhuang.hmcl.event.ProfileLoadingEvent;
|
||||||
@@ -368,6 +369,7 @@ public class Settings {
|
|||||||
|
|
||||||
public void addAccount(Account account) {
|
public void addAccount(Account account) {
|
||||||
accounts.put(Accounts.getAccountId(account), account);
|
accounts.put(Accounts.getAccountId(account), account);
|
||||||
|
onAccountLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account getAccount(String name, String character) {
|
public Account getAccount(String name, String character) {
|
||||||
@@ -381,12 +383,14 @@ public class Settings {
|
|||||||
public void deleteAccount(String name, String character) {
|
public void deleteAccount(String name, String character) {
|
||||||
accounts.remove(Accounts.getAccountId(name, character));
|
accounts.remove(Accounts.getAccountId(name, character));
|
||||||
|
|
||||||
|
onAccountLoading();
|
||||||
selectedAccount.get();
|
selectedAccount.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAccount(Account account) {
|
public void deleteAccount(Account account) {
|
||||||
accounts.remove(Accounts.getAccountId(account));
|
accounts.remove(Accounts.getAccountId(account));
|
||||||
|
|
||||||
|
onAccountLoading();
|
||||||
selectedAccount.get();
|
selectedAccount.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,6 +510,7 @@ public class Settings {
|
|||||||
throw new IllegalArgumentException("Profile's name is empty");
|
throw new IllegalArgumentException("Profile's name is empty");
|
||||||
|
|
||||||
getProfileMap().put(ver.getName(), ver);
|
getProfileMap().put(ver.getName(), ver);
|
||||||
|
Schedulers.computation().schedule(this::onProfileLoading);
|
||||||
|
|
||||||
ver.nameProperty().setChangedListener(this::profileNameChanged);
|
ver.nameProperty().setChangedListener(this::profileNameChanged);
|
||||||
|
|
||||||
@@ -546,4 +551,8 @@ public class Settings {
|
|||||||
EventBus.EVENT_BUS.fireEvent(new ProfileLoadingEvent(SETTINGS));
|
EventBus.EVENT_BUS.fireEvent(new ProfileLoadingEvent(SETTINGS));
|
||||||
onProfileChanged();
|
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) {
|
} else if (account instanceof NoSelectedCharacterException) {
|
||||||
dialog.close();
|
dialog.close();
|
||||||
} else if (account instanceof Exception) {
|
} else if (account instanceof Exception) {
|
||||||
lblCreationWarning.setText(AccountsPage.accountException((Exception) account));
|
lblCreationWarning.setText(AddAccountPane.accountException((Exception) account));
|
||||||
}
|
}
|
||||||
|
|
||||||
progressBar.setVisible(false);
|
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.
|
* 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
|
* 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
|
* 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.concurrency.JFXUtilities;
|
||||||
import com.jfoenix.controls.*;
|
import com.jfoenix.controls.*;
|
||||||
import javafx.application.Platform;
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
|
||||||
import javafx.beans.property.StringProperty;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Hyperlink;
|
import javafx.scene.control.Hyperlink;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.ScrollPane;
|
|
||||||
import javafx.scene.control.ToggleGroup;
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.BorderPane;
|
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.AdvancedListBox;
|
||||||
import org.jackhuang.hmcl.ui.construct.IconedItem;
|
import org.jackhuang.hmcl.ui.construct.IconedItem;
|
||||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||||
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
@@ -60,13 +53,8 @@ import java.util.logging.Level;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public final class AccountsPage extends StackPane implements DecoratorPage {
|
public class AddAccountPane extends StackPane {
|
||||||
private final StringProperty title = new SimpleStringProperty(this, "title", Launcher.i18n("account"));
|
|
||||||
|
|
||||||
@FXML
|
|
||||||
private ScrollPane scrollPane;
|
|
||||||
@FXML private JFXMasonryPane masonryPane;
|
|
||||||
@FXML private JFXDialog dialog;
|
|
||||||
@FXML private JFXTextField txtUsername;
|
@FXML private JFXTextField txtUsername;
|
||||||
@FXML private JFXPasswordField txtPassword;
|
@FXML private JFXPasswordField txtPassword;
|
||||||
@FXML private Label lblCreationWarning;
|
@FXML private Label lblCreationWarning;
|
||||||
@@ -76,14 +64,15 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
|||||||
@FXML private JFXProgressBar progressBar;
|
@FXML private JFXProgressBar progressBar;
|
||||||
@FXML private Label lblAddInjectorServer;
|
@FXML private Label lblAddInjectorServer;
|
||||||
@FXML private Hyperlink linkAddInjectorServer;
|
@FXML private Hyperlink linkAddInjectorServer;
|
||||||
|
@FXML private JFXDialogLayout layout;
|
||||||
|
private final Runnable finalization;
|
||||||
|
|
||||||
{
|
public AddAccountPane(Runnable finalization) {
|
||||||
FXUtils.loadFXML(this, "/assets/fxml/account.fxml");
|
this.finalization = finalization;
|
||||||
|
|
||||||
getChildren().remove(dialog);
|
FXUtils.loadFXML(this, "/assets/fxml/account-add.fxml");
|
||||||
dialog.setDialogContainer(this);
|
|
||||||
|
|
||||||
FXUtils.smoothScrolling(scrollPane);
|
loadServers();
|
||||||
|
|
||||||
cboType.getItems().setAll(Launcher.i18n("account.methods.offline"), Launcher.i18n("account.methods.yggdrasil"), Launcher.i18n("account.methods.authlib_injector"));
|
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) -> {
|
cboType.getSelectionModel().selectedIndexProperty().addListener((a, b, newValue) -> {
|
||||||
@@ -103,38 +92,9 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
|||||||
txtUsername.setOnAction(e -> onCreationAccept());
|
txtUsername.setOnAction(e -> onCreationAccept());
|
||||||
txtUsername.getValidators().add(new Validator(Launcher.i18n("input.email"), str -> !txtPassword.isVisible() || str.contains("@")));
|
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() {
|
private void loadServers() {
|
||||||
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() {
|
|
||||||
Task.ofResult("list", () -> Settings.INSTANCE.getAuthlibInjectorServerURLs().parallelStream()
|
Task.ofResult("list", () -> Settings.INSTANCE.getAuthlibInjectorServerURLs().parallelStream()
|
||||||
.flatMap(serverURL -> {
|
.flatMap(serverURL -> {
|
||||||
try {
|
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
|
@FXML
|
||||||
private void onCreationAccept() {
|
private void onCreationAccept() {
|
||||||
int type = cboType.getSelectionModel().getSelectedIndex();
|
int type = cboType.getSelectionModel().getSelectedIndex();
|
||||||
@@ -183,23 +121,22 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
|||||||
progressBar.setVisible(true);
|
progressBar.setVisible(true);
|
||||||
lblCreationWarning.setText("");
|
lblCreationWarning.setText("");
|
||||||
Task.ofResult("create_account", () -> {
|
Task.ofResult("create_account", () -> {
|
||||||
AccountFactory<?> factory;
|
AccountFactory<?> factory;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.OFFLINE_ACCOUNT_KEY); break;
|
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 1: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.YGGDRASIL_ACCOUNT_KEY); break;
|
||||||
case 2: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.AUTHLIB_INJECTOR_ACCOUNT_KEY); break;
|
case 2: factory = Accounts.ACCOUNT_FACTORY.get(Accounts.AUTHLIB_INJECTOR_ACCOUNT_KEY); break;
|
||||||
default: throw new Error();
|
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 -> {
|
}).finalized(Schedulers.javafx(), variables -> {
|
||||||
Settings.INSTANCE.addAccount(variables.get("create_account"));
|
Settings.INSTANCE.addAccount(variables.get("create_account"));
|
||||||
dialog.close();
|
|
||||||
loadAccounts();
|
|
||||||
progressBar.setVisible(false);
|
progressBar.setVisible(false);
|
||||||
|
finalization.run();
|
||||||
}, exception -> {
|
}, exception -> {
|
||||||
if (exception instanceof NoSelectedCharacterException) {
|
if (exception instanceof NoSelectedCharacterException) {
|
||||||
dialog.close();
|
finalization.run();
|
||||||
} else {
|
} else {
|
||||||
lblCreationWarning.setText(accountException(exception));
|
lblCreationWarning.setText(accountException(exception));
|
||||||
}
|
}
|
||||||
@@ -209,46 +146,24 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void onCreationCancel() {
|
private void onCreationCancel() {
|
||||||
dialog.close();
|
finalization.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
@FXML
|
||||||
return title.get();
|
private void onAddInjecterServer() {
|
||||||
|
finalization.run();
|
||||||
|
Controllers.navigate(Controllers.getServersPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void showSelector(Node node) {
|
||||||
public StringProperty titleProperty() {
|
getChildren().setAll(node);
|
||||||
return title;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTitle(String title) {
|
private void closeSelector() {
|
||||||
this.title.set(title);
|
getChildren().setAll(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String accountException(Exception exception) {
|
private class Selector extends BorderPane implements CharacterSelector {
|
||||||
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 final AdvancedListBox listBox = new AdvancedListBox();
|
private final AdvancedListBox listBox = new AdvancedListBox();
|
||||||
private final JFXButton cancel = new JFXButton();
|
private final JFXButton cancel = new JFXButton();
|
||||||
|
|
||||||
@@ -303,20 +218,43 @@ public final class AccountsPage extends StackPane implements DecoratorPage {
|
|||||||
listBox.add(accountItem);
|
listBox.add(accountItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
JFXUtilities.runInFX(() -> Controllers.dialog(this));
|
JFXUtilities.runInFX(() -> showSelector(this));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
latch.await();
|
latch.await();
|
||||||
|
|
||||||
JFXUtilities.runInFX(Controllers::closeDialog);
|
|
||||||
|
|
||||||
if (selectedProfile == null)
|
if (selectedProfile == null)
|
||||||
throw new NoSelectedCharacterException(account);
|
throw new NoSelectedCharacterException(account);
|
||||||
|
|
||||||
|
JFXUtilities.runInFX(AddAccountPane.this::closeSelector);
|
||||||
|
|
||||||
return selectedProfile;
|
return selectedProfile;
|
||||||
} catch (InterruptedException ignore) {
|
} catch (InterruptedException ignore) {
|
||||||
throw new NoSelectedCharacterException(account);
|
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.concurrency.JFXUtilities;
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
|
import com.jfoenix.controls.JFXListView;
|
||||||
|
import com.jfoenix.controls.JFXPopup;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.input.MouseButton;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.scene.text.Text;
|
|
||||||
import org.jackhuang.hmcl.Launcher;
|
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.auth.yggdrasil.YggdrasilAccount;
|
||||||
import org.jackhuang.hmcl.event.EventBus;
|
import org.jackhuang.hmcl.event.*;
|
||||||
import org.jackhuang.hmcl.event.ProfileChangedEvent;
|
|
||||||
import org.jackhuang.hmcl.event.ProfileLoadingEvent;
|
|
||||||
import org.jackhuang.hmcl.event.RefreshedVersionsEvent;
|
|
||||||
import org.jackhuang.hmcl.game.AccountHelper;
|
import org.jackhuang.hmcl.game.AccountHelper;
|
||||||
import org.jackhuang.hmcl.game.HMCLGameRepository;
|
import org.jackhuang.hmcl.game.HMCLGameRepository;
|
||||||
import org.jackhuang.hmcl.game.ModpackHelper;
|
import org.jackhuang.hmcl.game.ModpackHelper;
|
||||||
import org.jackhuang.hmcl.mod.Modpack;
|
import org.jackhuang.hmcl.mod.Modpack;
|
||||||
import org.jackhuang.hmcl.mod.UnsupportedModpackException;
|
import org.jackhuang.hmcl.mod.UnsupportedModpackException;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.*;
|
||||||
import org.jackhuang.hmcl.setting.Profiles;
|
|
||||||
import org.jackhuang.hmcl.setting.Settings;
|
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.ui.construct.AdvancedListBox;
|
import org.jackhuang.hmcl.ui.construct.AdvancedListBox;
|
||||||
@@ -55,50 +54,53 @@ import java.util.Objects;
|
|||||||
public final class LeftPaneController {
|
public final class LeftPaneController {
|
||||||
private final AdvancedListBox leftPane;
|
private final AdvancedListBox leftPane;
|
||||||
private final VBox profilePane = new VBox();
|
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) {
|
public LeftPaneController(AdvancedListBox leftPane) {
|
||||||
this.leftPane = leftPane;
|
this.leftPane = leftPane;
|
||||||
|
|
||||||
leftPane.startCategory(Launcher.i18n("account").toUpperCase())
|
leftPane
|
||||||
.add(Lang.apply(new RipplerContainer(accountItem), rippler -> {
|
.add(new ClassTitle(Launcher.i18n("account").toUpperCase(), Lang.apply(new JFXButton(), button -> {
|
||||||
rippler.setOnMouseClicked(e -> Controllers.navigate(new AccountsPage()));
|
button.setGraphic(SVG.plus(Theme.blackFillBinding(), 10, 10));
|
||||||
accountItem.setOnSettingsButtonClicked(() -> Controllers.navigate(new AccountsPage()));
|
button.getStyleClass().add("toggle-icon-tiny");
|
||||||
}))
|
button.setOnMouseClicked(e -> addNewAccount());
|
||||||
|
})))
|
||||||
|
.add(accountPane)
|
||||||
.startCategory(Launcher.i18n("launcher").toUpperCase())
|
.startCategory(Launcher.i18n("launcher").toUpperCase())
|
||||||
.add(Lang.apply(new IconedItem(SVG.gear(Theme.blackFillBinding(), 20, 20), Launcher.i18n("settings.launcher")), iconedItem -> {
|
.add(Lang.apply(new IconedItem(SVG.gear(Theme.blackFillBinding(), 20, 20), Launcher.i18n("settings.launcher")), iconedItem -> {
|
||||||
iconedItem.prefWidthProperty().bind(leftPane.widthProperty());
|
iconedItem.prefWidthProperty().bind(leftPane.widthProperty());
|
||||||
iconedItem.setOnMouseClicked(e -> Controllers.navigate(Controllers.getSettingsPage()));
|
iconedItem.setOnMouseClicked(e -> Controllers.navigate(Controllers.getSettingsPage()));
|
||||||
}))
|
}))
|
||||||
.add(new ClassTitle(Lang.apply(new BorderPane(), borderPane -> {
|
.add(new ClassTitle(Launcher.i18n("profile.title").toUpperCase(), Lang.apply(new JFXButton(), button -> {
|
||||||
borderPane.setLeft(Lang.apply(new VBox(), vBox -> vBox.getChildren().setAll(new Text(Launcher.i18n("profile.title").toUpperCase()))));
|
button.setGraphic(SVG.plus(Theme.blackFillBinding(), 10, 10));
|
||||||
JFXButton addProfileButton = new JFXButton();
|
button.getStyleClass().add("toggle-icon-tiny");
|
||||||
addProfileButton.setGraphic(SVG.plus(Theme.blackFillBinding(), 10, 10));
|
button.setOnMouseClicked(e ->
|
||||||
addProfileButton.getStyleClass().add("toggle-icon-tiny");
|
|
||||||
addProfileButton.setOnMouseClicked(e ->
|
|
||||||
Controllers.getDecorator().showPage(new ProfilePage(null)));
|
Controllers.getDecorator().showPage(new ProfilePage(null)));
|
||||||
borderPane.setRight(addProfileButton);
|
|
||||||
})))
|
})))
|
||||||
.add(profilePane);
|
.add(profilePane);
|
||||||
|
|
||||||
|
EventBus.EVENT_BUS.channel(AccountLoadingEvent.class).register(this::onAccountsLoading);
|
||||||
EventBus.EVENT_BUS.channel(ProfileLoadingEvent.class).register(this::onProfilesLoading);
|
EventBus.EVENT_BUS.channel(ProfileLoadingEvent.class).register(this::onProfilesLoading);
|
||||||
EventBus.EVENT_BUS.channel(ProfileChangedEvent.class).register(this::onProfileChanged);
|
EventBus.EVENT_BUS.channel(ProfileChangedEvent.class).register(this::onProfileChanged);
|
||||||
EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(this::onRefreshedVersions);
|
EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).register(this::onRefreshedVersions);
|
||||||
|
|
||||||
FXUtils.onChangeAndOperate(Settings.INSTANCE.selectedAccountProperty(), it -> {
|
FXUtils.onChangeAndOperate(Settings.INSTANCE.selectedAccountProperty(), this::onSelectedAccountChanged);
|
||||||
if (it == null) {
|
onAccountsLoading();
|
||||||
accountItem.setVersionName(Launcher.i18n("account.missing"));
|
}
|
||||||
accountItem.setGameVersion(Launcher.i18n("message.unknown"));
|
|
||||||
} else {
|
|
||||||
accountItem.setVersionName(it.getCharacter());
|
|
||||||
accountItem.setGameVersion(AccountsPage.accountType(it));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (it instanceof YggdrasilAccount) {
|
private void addNewAccount() {
|
||||||
Image image = AccountHelper.getSkin((YggdrasilAccount) it, 4);
|
Controllers.dialog(new AddAccountPane(Controllers::closeDialog));
|
||||||
accountItem.setImage(image, AccountHelper.getViewport(4));
|
}
|
||||||
} else
|
|
||||||
accountItem.setImage(AccountHelper.getDefaultSkin(it, 4), AccountHelper.getViewport(4));
|
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));
|
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 boolean checkedModpack = false;
|
||||||
|
|
||||||
private void onRefreshedVersions(RefreshedVersionsEvent event) {
|
private void onRefreshedVersions(RefreshedVersionsEvent event) {
|
||||||
@@ -162,8 +231,8 @@ public final class LeftPaneController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAccount() {
|
public void checkAccount() {
|
||||||
if (Settings.INSTANCE.getAccounts().isEmpty())
|
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.construct.TaskExecutorDialogPane;
|
||||||
import org.jackhuang.hmcl.ui.download.DownloadWizardProvider;
|
import org.jackhuang.hmcl.ui.download.DownloadWizardProvider;
|
||||||
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
import org.jackhuang.hmcl.ui.wizard.DecoratorPage;
|
||||||
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
import org.jackhuang.hmcl.util.OperatingSystem;
|
import org.jackhuang.hmcl.util.OperatingSystem;
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
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 final StringProperty title = new SimpleStringProperty(this, "title", Launcher.i18n("main_page"));
|
||||||
|
|
||||||
private Profile profile;
|
private Profile profile;
|
||||||
private String rightClickedVersion;
|
|
||||||
private HMCLGameRepository rightClickedRepository;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton btnRefresh;
|
private JFXButton btnRefresh;
|
||||||
@@ -71,10 +70,6 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
private JFXSpinner spinner;
|
private JFXSpinner spinner;
|
||||||
@FXML
|
@FXML
|
||||||
private JFXMasonryPane masonryPane;
|
private JFXMasonryPane masonryPane;
|
||||||
@FXML
|
|
||||||
private JFXListView versionList;
|
|
||||||
|
|
||||||
private final JFXPopup versionPopup;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
FXUtils.loadFXML(this, "/assets/fxml/main.fxml");
|
FXUtils.loadFXML(this, "/assets/fxml/main.fxml");
|
||||||
@@ -93,9 +88,6 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
this.profile = event.getProfile();
|
this.profile = event.getProfile();
|
||||||
});
|
});
|
||||||
|
|
||||||
versionPopup = new JFXPopup(versionList);
|
|
||||||
getChildren().remove(versionList);
|
|
||||||
|
|
||||||
btnAdd.setOnMouseClicked(e -> Controllers.getDecorator().startWizard(new DownloadWizardProvider(), Launcher.i18n("install")));
|
btnAdd.setOnMouseClicked(e -> Controllers.getDecorator().startWizard(new DownloadWizardProvider(), Launcher.i18n("install")));
|
||||||
FXUtils.installTooltip(btnAdd, Launcher.i18n("install"));
|
FXUtils.installTooltip(btnAdd, Launcher.i18n("install"));
|
||||||
btnRefresh.setOnMouseClicked(e -> Settings.INSTANCE.getSelectedProfile().getRepository().refreshVersionsAsync().start());
|
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.setLibraries(libraries.toString());
|
||||||
item.setOnLaunchButtonClicked(e -> {
|
item.setOnLaunchButtonClicked(e -> {
|
||||||
if (Settings.INSTANCE.getSelectedAccount() == null)
|
if (Settings.INSTANCE.getSelectedAccount() == null)
|
||||||
Controllers.dialog(Launcher.i18n("login.empty_username"));
|
Controllers.getLeftPaneController().checkAccount();
|
||||||
else
|
else
|
||||||
LauncherHelper.INSTANCE.launch(profile, Settings.INSTANCE.getSelectedAccount(), id, null);
|
LauncherHelper.INSTANCE.launch(profile, Settings.INSTANCE.getSelectedAccount(), id, null);
|
||||||
});
|
});
|
||||||
@@ -174,9 +166,34 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
});
|
});
|
||||||
item.setOnMouseClicked(event -> {
|
item.setOnMouseClicked(event -> {
|
||||||
if (event.getButton() == MouseButton.SECONDARY) {
|
if (event.getButton() == MouseButton.SECONDARY) {
|
||||||
rightClickedVersion = id;
|
JFXListView<String> versionList = new JFXListView<>();
|
||||||
rightClickedRepository = repository;
|
JFXPopup versionPopup = new JFXPopup(versionList);
|
||||||
versionList.getSelectionModel().select(-1);
|
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());
|
versionPopup.show(item, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT, event.getX(), event.getY());
|
||||||
} else if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) {
|
} else if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) {
|
||||||
if (Settings.INSTANCE.getSelectedAccount() == null)
|
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() {
|
public String getTitle() {
|
||||||
return title.get();
|
return title.get();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,13 @@
|
|||||||
package org.jackhuang.hmcl.ui.construct;
|
package org.jackhuang.hmcl.ui.construct;
|
||||||
|
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.layout.BorderPane;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.shape.Rectangle;
|
import javafx.scene.shape.Rectangle;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
@@ -48,6 +50,13 @@ public class ClassTitle extends StackPane {
|
|||||||
getStyleClass().add("class-title");
|
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() {
|
public Node getContent() {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,9 +60,14 @@ public class ComponentList extends StackPane {
|
|||||||
child.getStyleClass().add("options-list-item-ahead");
|
child.getStyleClass().add("options-list-item-ahead");
|
||||||
else
|
else
|
||||||
child.getStyleClass().add("options-list-item");
|
child.getStyleClass().add("options-list-item");
|
||||||
|
child.getProperties().put("node", node);
|
||||||
vbox.getChildren().add(child);
|
vbox.getChildren().add(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeChildren(Node node) {
|
||||||
|
vbox.getChildren().removeIf(node1 -> node1.getProperties().get("node") == node);
|
||||||
|
}
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title.get();
|
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>
|
<actions>
|
||||||
<Label fx:id="lblCreationWarning" />
|
<Label fx:id="lblCreationWarning" />
|
||||||
<JFXButton onMouseClicked="#onAccept" text="%button.ok" styleClass="dialog-accept"/>
|
<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>
|
</actions>
|
||||||
</JFXDialogLayout>
|
</JFXDialogLayout>
|
||||||
<JFXProgressBar fx:id="progressBar" visible="false" StackPane.alignment="TOP_CENTER"/>
|
<JFXProgressBar fx:id="progressBar" visible="false" StackPane.alignment="TOP_CENTER"/>
|
||||||
|
|||||||
@@ -4,72 +4,79 @@
|
|||||||
<?import com.jfoenix.validation.RequiredFieldValidator?>
|
<?import com.jfoenix.validation.RequiredFieldValidator?>
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?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"
|
<fx:root xmlns="http://javafx.com/javafx"
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
xmlns:fx="http://javafx.com/fxml"
|
||||||
type="StackPane">
|
type="StackPane">
|
||||||
<ScrollPane fitToHeight="true" fitToWidth="true" fx:id="scrollPane" hbarPolicy="NEVER">
|
<ScrollPane fx:id="scroll" fitToHeight="true" fitToWidth="true">
|
||||||
<JFXMasonryPane fx:id="masonryPane" HSpacing="3" VSpacing="3" cellWidth="182" cellHeight="160">
|
<VBox fx:id="rootPane" style="-fx-padding: 20;">
|
||||||
</JFXMasonryPane>
|
|
||||||
|
<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>
|
</ScrollPane>
|
||||||
<AnchorPane pickOnBounds="false">
|
<BorderPane pickOnBounds="false" style="-fx-padding: 20;">
|
||||||
<JFXButton onMouseClicked="#addNewAccount" AnchorPane.bottomAnchor="16" AnchorPane.rightAnchor="16" buttonType="RAISED" prefWidth="40" prefHeight="40" styleClass="jfx-button-raised-round">
|
<left>
|
||||||
<graphic>
|
<JFXButton BorderPane.alignment="BOTTOM_LEFT" fx:id="btnDelete" onMouseClicked="#onDelete" prefWidth="100" prefHeight="40"
|
||||||
<fx:include source="/assets/svg/plus.fxml" />
|
buttonType="RAISED" text="%button.delete" styleClass="jfx-button-raised" />
|
||||||
</graphic>
|
</left>
|
||||||
</JFXButton>
|
<right>
|
||||||
</AnchorPane>
|
<JFXButton BorderPane.alignment="BOTTOM_RIGHT" fx:id="btnRefresh" prefWidth="100" prefHeight="40"
|
||||||
|
buttonType="RAISED" text="%button.refresh" styleClass="jfx-button-raised"/>
|
||||||
<JFXDialog fx:id="dialog">
|
</right>
|
||||||
<StackPane>
|
</BorderPane>
|
||||||
<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>
|
|
||||||
</fx:root>
|
</fx:root>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
<Label text="%account.injector.add" />
|
<Label text="%account.injector.add" />
|
||||||
</heading>
|
</heading>
|
||||||
<body>
|
<body>
|
||||||
<JFXTextField fx:id="txtServerIp" promptText="%account.injector.server_ip" labelFloat="true">
|
<JFXTextField fx:id="txtServerIp" promptText="%account.injector.server_ip">
|
||||||
<validators>
|
<validators>
|
||||||
<URLValidator message="%input.url">
|
<URLValidator message="%input.url">
|
||||||
</URLValidator>
|
</URLValidator>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import com.jfoenix.controls.JFXButton?>
|
<?import com.jfoenix.controls.JFXButton?>
|
||||||
<?import com.jfoenix.controls.JFXListView?>
|
|
||||||
<?import com.jfoenix.controls.JFXMasonryPane?>
|
<?import com.jfoenix.controls.JFXMasonryPane?>
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.scene.layout.StackPane?>
|
<?import javafx.scene.layout.StackPane?>
|
||||||
@@ -30,13 +29,4 @@
|
|||||||
</graphic>
|
</graphic>
|
||||||
</JFXButton>
|
</JFXButton>
|
||||||
</VBox>
|
</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>
|
</fx:root>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ about.open_source=Open Source
|
|||||||
about.open_source.statement=GPL v3 (https://github.com/huanghongxun/HMCL/)
|
about.open_source.statement=GPL v3 (https://github.com/huanghongxun/HMCL/)
|
||||||
|
|
||||||
account=Accounts
|
account=Accounts
|
||||||
|
account.character=character
|
||||||
account.choose=Choose a character
|
account.choose=Choose a character
|
||||||
account.current=Current
|
account.current=Current
|
||||||
account.create=Create a new account
|
account.create=Create a new account
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ about.open_source=开源
|
|||||||
about.open_source.statement=GPL v3 (https://github.com/huanghongxun/HMCL/)
|
about.open_source.statement=GPL v3 (https://github.com/huanghongxun/HMCL/)
|
||||||
|
|
||||||
account=账户
|
account=账户
|
||||||
|
account.character=角色
|
||||||
account.choose=选择一个角色
|
account.choose=选择一个角色
|
||||||
account.current=当前账户
|
account.current=当前账户
|
||||||
account.create=新建账户
|
account.create=新建账户
|
||||||
|
|||||||
Reference in New Issue
Block a user