Merge pull request #457 from andylizi/add-helmet-support

支持在头像中显示头盔层
This commit is contained in:
huanghongxun 2018-09-24 17:28:17 +08:00 committed by GitHub
commit 4d366397a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 35 deletions

View File

@ -17,7 +17,7 @@
*/ */
package org.jackhuang.hmcl.game; package org.jackhuang.hmcl.game;
import javafx.geometry.Rectangle2D; import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.Launcher;
import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.Account;
@ -32,6 +32,8 @@ import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.DialogController; import org.jackhuang.hmcl.ui.DialogController;
import org.jackhuang.hmcl.util.io.NetworkUtils; import org.jackhuang.hmcl.util.io.NetworkUtils;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
@ -91,9 +93,19 @@ public final class AccountHelper {
return scale(url, scaleRatio); return scale(url, scaleRatio);
} }
public static Rectangle2D getViewport(double scaleRatio) { public static Image getHead(Image skin, int scaleRatio) {
double size = 8.0 * scaleRatio; final int size = 8 * scaleRatio;
return new Rectangle2D(size, size, size, size); final int faceOffset = (int) Math.floor(scaleRatio * 4d / 9d);
BufferedImage image = SwingFXUtils.fromFXImage(skin, null);
BufferedImage head = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = head.createGraphics();
g2d.drawImage(image, faceOffset, faceOffset, size - faceOffset, size - faceOffset,
size, size, size + size, size + size, null);
if (image.getHeight() > 32) {
g2d.drawImage(image, 0, 0, size, size,
40 * scaleRatio, 8 * scaleRatio, 48 * scaleRatio, 16 * scaleRatio, null);
}
return SwingFXUtils.toFXImage(head, null);
} }
private static class SkinLoadTask extends Task { private static class SkinLoadTask extends Task {

View File

@ -39,18 +39,18 @@ public class AccountAdvancedListItem extends AdvancedListItem {
titleProperty().set(i18n("account.missing")); titleProperty().set(i18n("account.missing"));
subtitleProperty().set(i18n("account.missing.add")); subtitleProperty().set(i18n("account.missing.add"));
imageProperty().set(new Image("/assets/img/craft_table.png")); imageProperty().set(new Image("/assets/img/craft_table.png"));
viewportProperty().set(null);
} else { } else {
titleProperty().set(account.getCharacter()); titleProperty().set(account.getCharacter());
subtitleProperty().set(accountSubtitle(account)); subtitleProperty().set(accountSubtitle(account));
imageProperty().set(AccountHelper.getDefaultSkin(account.getUUID(), 4)); final int scaleRatio = 4;
viewportProperty().set(AccountHelper.getViewport(4)); Image defaultSkin = AccountHelper.getDefaultSkin(account.getUUID(), scaleRatio);
imageProperty().set(AccountHelper.getHead(defaultSkin, scaleRatio));
if (account instanceof YggdrasilAccount) { if (account instanceof YggdrasilAccount) {
AccountHelper.loadSkinAsync((YggdrasilAccount) account).subscribe(Schedulers.javafx(), () -> { AccountHelper.loadSkinAsync((YggdrasilAccount) account).subscribe(Schedulers.javafx(), () -> {
Image image = AccountHelper.getSkin((YggdrasilAccount) account, 4); Image image = AccountHelper.getSkin((YggdrasilAccount) account, scaleRatio);
imageProperty().set(image); imageProperty().set(AccountHelper.getHead(image, scaleRatio));
}); });
} }
} }

View File

@ -18,7 +18,6 @@
package org.jackhuang.hmcl.ui.account; package org.jackhuang.hmcl.ui.account;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.geometry.Rectangle2D;
import javafx.scene.control.Control; import javafx.scene.control.Control;
import javafx.scene.control.Skin; import javafx.scene.control.Skin;
import javafx.scene.control.ToggleGroup; import javafx.scene.control.ToggleGroup;
@ -41,7 +40,6 @@ public class AccountListItem extends Control {
private final StringProperty subtitle = new SimpleStringProperty(); private final StringProperty subtitle = new SimpleStringProperty();
private final BooleanProperty selected = new SimpleBooleanProperty(); private final BooleanProperty selected = new SimpleBooleanProperty();
private final ObjectProperty<Image> image = new SimpleObjectProperty<>(); private final ObjectProperty<Image> image = new SimpleObjectProperty<>();
private final ObjectProperty<Rectangle2D> viewport = new SimpleObjectProperty<>();
public AccountListItem(ToggleGroup toggleGroup, Account account) { public AccountListItem(ToggleGroup toggleGroup, Account account) {
this.account = account; this.account = account;
@ -60,13 +58,11 @@ public class AccountListItem extends Control {
subtitle.set(subtitleString.toString()); subtitle.set(subtitleString.toString());
selected.set(Accounts.selectedAccountProperty().get() == account); selected.set(Accounts.selectedAccountProperty().get() == account);
viewport.set(AccountHelper.getViewport(4)); final int scaleRatio = 4;
if (account instanceof YggdrasilAccount) { Image image = account instanceof YggdrasilAccount ?
Image image = AccountHelper.getSkin((YggdrasilAccount) account, 4); AccountHelper.getSkin((YggdrasilAccount) account, scaleRatio) :
this.image.set(image); AccountHelper.getDefaultSkin(account.getUUID(), scaleRatio);
} else { this.image.set(AccountHelper.getHead(image, scaleRatio));
this.image.set(AccountHelper.getDefaultSkin(account.getUUID(), 4));
}
} }
@Override @Override
@ -98,10 +94,6 @@ public class AccountListItem extends Control {
return image; return image;
} }
public ObjectProperty<Rectangle2D> viewportProperty() {
return viewport;
}
public void refresh() { public void refresh() {
if (account instanceof YggdrasilAccount) { if (account instanceof YggdrasilAccount) {
// progressBar.setVisible(true); // progressBar.setVisible(true);
@ -110,8 +102,9 @@ public class AccountListItem extends Control {
// progressBar.setVisible(false); // progressBar.setVisible(false);
if (isDependentsSucceeded) { if (isDependentsSucceeded) {
Image image = AccountHelper.getSkin((YggdrasilAccount) account, 4); final int scaleRatio = 4;
this.image.set(image); Image image = AccountHelper.getSkin((YggdrasilAccount) account, scaleRatio);
this.image.set(AccountHelper.getHead(image, scaleRatio));
} }
}).start(); }).start();
} }

View File

@ -59,7 +59,6 @@ public class AccountListItemSkin extends SkinBase<AccountListItem> {
ImageView imageView = new ImageView(); ImageView imageView = new ImageView();
FXUtils.limitSize(imageView, 32, 32); FXUtils.limitSize(imageView, 32, 32);
imageView.imageProperty().bind(skinnable.imageProperty()); imageView.imageProperty().bind(skinnable.imageProperty());
imageView.viewportProperty().bind(skinnable.viewportProperty());
imageViewContainer.getChildren().setAll(imageView); imageViewContainer.getChildren().setAll(imageView);
TwoLineListItem item = new TwoLineListItem(); TwoLineListItem item = new TwoLineListItem();

View File

@ -221,17 +221,17 @@ public class AddAccountPane extends StackPane {
for (GameProfile profile : names) { for (GameProfile profile : names) {
Image image; Image image;
final int scaleRatio = 4;
try { try {
image = AccountHelper.getSkinImmediately(yggdrasilAccount, profile, 4); image = AccountHelper.getSkinImmediately(yggdrasilAccount, profile, scaleRatio);
} catch (Exception e) { } catch (Exception e) {
Logging.LOG.log(Level.WARNING, "Failed to get skin for " + profile.getName(), e); Logging.LOG.log(Level.WARNING, "Failed to get skin for " + profile.getName(), e);
image = AccountHelper.getDefaultSkin(profile.getId(), 4); image = AccountHelper.getDefaultSkin(profile.getId(), scaleRatio);
} }
ImageView portraitView = new ImageView(); ImageView portraitView = new ImageView();
portraitView.setSmooth(false); portraitView.setSmooth(false);
portraitView.setImage(image); portraitView.setImage(AccountHelper.getHead(image, scaleRatio));
portraitView.setViewport(AccountHelper.getViewport(4));
FXUtils.limitSize(portraitView, 32, 32); FXUtils.limitSize(portraitView, 32, 32);
IconedItem accountItem = new IconedItem(portraitView, profile.getName()); IconedItem accountItem = new IconedItem(portraitView, profile.getName());

View File

@ -30,7 +30,6 @@ import javafx.scene.image.Image;
public class AdvancedListItem extends Control { public class AdvancedListItem extends Control {
private final ObjectProperty<Image> image = new SimpleObjectProperty<>(); private final ObjectProperty<Image> image = new SimpleObjectProperty<>();
private final ObjectProperty<Rectangle2D> viewport = new SimpleObjectProperty<>();
private final StringProperty title = new SimpleStringProperty(); private final StringProperty title = new SimpleStringProperty();
private final StringProperty subtitle = new SimpleStringProperty(); private final StringProperty subtitle = new SimpleStringProperty();
@ -38,10 +37,6 @@ public class AdvancedListItem extends Control {
return image; return image;
} }
public ObjectProperty<Rectangle2D> viewportProperty() {
return viewport;
}
public StringProperty titleProperty() { public StringProperty titleProperty() {
return title; return title;
} }

View File

@ -54,7 +54,6 @@ public class AdvancedListItemSkin extends SkinBase<AdvancedListItem> {
FXUtils.limitSize(imageView, 32, 32); FXUtils.limitSize(imageView, 32, 32);
imageView.setPreserveRatio(true); imageView.setPreserveRatio(true);
imageView.imageProperty().bind(skinnable.imageProperty()); imageView.imageProperty().bind(skinnable.imageProperty());
imageView.viewportProperty().bind(skinnable.viewportProperty());
imageViewContainer.getChildren().setAll(imageView); imageViewContainer.getChildren().setAll(imageView);
VBox vbox = new VBox(); VBox vbox = new VBox();