add: upload skin

This commit is contained in:
huanghongxun
2020-05-28 23:16:56 +08:00
parent 476c41b29b
commit bfb55a3813
14 changed files with 210 additions and 12 deletions

View File

@@ -186,4 +186,8 @@ public final class SVG {
public static Node wrench(ObjectBinding<? extends Paint> fill, double width, double height) {
return createSVGPath("M22.7,19L13.6,9.9C14.5,7.6 14,4.9 12.1,3C10.1,1 7.1,0.6 4.7,1.7L9,6L6,9L1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1C4.8,14 7.5,14.5 9.8,13.6L18.9,22.7C19.3,23.1 19.9,23.1 20.3,22.7L22.6,20.4C23.1,20 23.1,19.3 22.7,19Z", fill, width, height);
}
public static Node upload(ObjectBinding<? extends Paint> fill, double width, double height) {
return createSVGPath("M9,16V10H5L12,3L19,10H15V16H9M5,20V18H19V20H5Z", fill, width, height);
}
}

View File

@@ -23,23 +23,28 @@ import javafx.beans.property.*;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Skin;
import javafx.scene.image.Image;
import javafx.stage.FileChooser;
import org.jackhuang.hmcl.auth.Account;
import org.jackhuang.hmcl.auth.AuthenticationException;
import org.jackhuang.hmcl.auth.CredentialExpiredException;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer;
import org.jackhuang.hmcl.auth.offline.OfflineAccount;
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
import org.jackhuang.hmcl.game.TexturesLoader;
import org.jackhuang.hmcl.setting.Accounts;
import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.DialogController;
import org.jackhuang.hmcl.ui.construct.PromptDialogPane;
import java.io.File;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import static org.jackhuang.hmcl.util.Lang.thread;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
public class AccountListItem extends RadioButton {
private final Account account;
@@ -96,6 +101,36 @@ public class AccountListItem extends RadioButton {
});
}
public boolean canUploadSkin() {
return account instanceof YggdrasilAccount && !(account instanceof AuthlibInjectorAccount);
}
public void uploadSkin() {
if (!(account instanceof YggdrasilAccount)) {
return;
}
FileChooser chooser = new FileChooser();
chooser.setTitle(i18n("account.skin.upload"));
chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(i18n("account.skin.file"), "*.png"));
File selectedFile = chooser.showOpenDialog(Controllers.getStage());
if (selectedFile == null) {
return;
}
Controllers.prompt(new PromptDialogPane.Builder(i18n("account.skin.upload"), (questions, resolve, reject) -> {
PromptDialogPane.Builder.CandidatesQuestion q = (PromptDialogPane.Builder.CandidatesQuestion) questions.get(0);
String model = q.getValue() == 0 ? "" : "slim";
try {
((YggdrasilAccount) account).uploadSkin(model, selectedFile.toPath());
resolve.run();
} catch (AuthenticationException e) {
reject.accept(AddAccountPane.accountException(e));
}
}).addQuestion(new PromptDialogPane.Builder.CandidatesQuestion(i18n("account.skin.model"),
i18n("account.skin.model.default"), i18n("account.skin.model.slim"))));
}
public void remove() {
Accounts.getAccounts().remove(account);
}

View File

@@ -84,6 +84,7 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
HBox right = new HBox();
right.setAlignment(Pos.CENTER_RIGHT);
JFXButton btnRefresh = new JFXButton();
btnRefresh.setOnMouseClicked(e -> skinnable.refresh());
btnRefresh.getStyleClass().add("toggle-icon4");
@@ -91,6 +92,15 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
runInFX(() -> FXUtils.installFastTooltip(btnRefresh, i18n("button.refresh")));
right.getChildren().add(btnRefresh);
if (skinnable.canUploadSkin()) {
JFXButton btnUpload = new JFXButton();
btnUpload.setOnMouseClicked(e -> skinnable.uploadSkin());
btnUpload.getStyleClass().add("toggle-icon4");
btnUpload.setGraphic(SVG.upload(Theme.blackFillBinding(), -1, -1));
runInFX(() -> FXUtils.installFastTooltip(btnUpload, i18n("account.skin.upload")));
right.getChildren().add(btnUpload);
}
JFXButton btnRemove = new JFXButton();
btnRemove.setOnMouseClicked(e -> skinnable.remove());
btnRemove.getStyleClass().add("toggle-icon4");

View File

@@ -148,6 +148,7 @@ public class MultiFileItem<T> extends ComponentSublist {
pane.setLeft(left);
Label right = new Label(subtitle);
right.setWrapText(true);
right.getStyleClass().add("subtitle-label");
right.setStyle("-fx-font-size: 10;");
pane.setRight(right);

View File

@@ -19,6 +19,7 @@ package org.jackhuang.hmcl.ui.construct;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXCheckBox;
import com.jfoenix.controls.JFXComboBox;
import com.jfoenix.controls.JFXTextField;
import com.jfoenix.validation.base.ValidatorBase;
import javafx.beans.binding.Bindings;
@@ -81,6 +82,18 @@ public class PromptDialogPane extends StackPane {
checkBox.selectedProperty().addListener((a, b, newValue) -> ((Builder.BooleanQuestion) question).value = newValue);
checkBox.setText(question.question);
vbox.getChildren().add(hBox);
} else if (question instanceof Builder.CandidatesQuestion) {
HBox hBox = new HBox();
JFXComboBox<String> comboBox = new JFXComboBox<>();
hBox.getChildren().setAll(comboBox);
comboBox.getItems().setAll(((Builder.CandidatesQuestion) question).candidates);
comboBox.getSelectionModel().selectedIndexProperty().addListener((a, b, newValue) ->
((Builder.CandidatesQuestion) question).value = newValue.intValue());
comboBox.getSelectionModel().select(0);
if (StringUtils.isNotBlank(question.question)) {
vbox.getChildren().add(new Label(question.question));
}
vbox.getChildren().add(hBox);
}
}
@@ -146,6 +159,19 @@ public class PromptDialogPane extends StackPane {
}
}
public static class CandidatesQuestion extends Question<Integer> {
protected final List<String> candidates;
public CandidatesQuestion(String question, String... candidates) {
super(question);
this.value = null;
if (candidates == null || candidates.length == 0) {
throw new IllegalArgumentException("At least one candidate required");
}
this.candidates = new ArrayList<>(Arrays.asList(candidates));
}
}
public static class BooleanQuestion extends Question<Boolean> {
public BooleanQuestion(String question, boolean defaultValue) {

View File

@@ -62,6 +62,11 @@ account.methods.yggdrasil=Mojang
account.missing=No Account
account.missing.add=Click here to add
account.password=Password
account.skin.file=Skin file
account.skin.model=Character model
account.skin.model.default=Steve
account.skin.model.slim=Alex
account.skin.upload=Upload skin
account.username=Name
archive.author=Authors

View File

@@ -62,6 +62,11 @@ account.methods.yggdrasil=正版登入
account.missing=沒有遊戲帳戶
account.missing.add=按一下此處加入帳戶
account.password=密碼
account.skin.file=皮膚圖片檔案
account.skin.model=人物模型
account.skin.model.default=Steve
account.skin.model.slim=Alex
account.skin.upload=上傳皮膚
account.username=使用者名稱
archive.author=作者

View File

@@ -62,6 +62,11 @@ account.methods.yggdrasil=正版登录
account.missing=没有游戏账户
account.missing.add=点击此处添加账户
account.password=密码
account.skin.file=皮肤图片文件
account.skin.model=人物模型
account.skin.model.default=Steve
account.skin.model.slim=Alex
account.skin.upload=上传皮肤
account.username=用户名
archive.author=作者