mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
Refactored CardPanelRenderModes to make them more readable (#9574)
This commit is contained in:
parent
393ea1e7ba
commit
2ff5cddbce
3 changed files with 516 additions and 663 deletions
|
@ -26,6 +26,7 @@ import javax.swing.*;
|
|||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
@ -93,13 +94,13 @@ public enum Plugins implements MagePlugins {
|
|||
@Override
|
||||
public MageCard getMagePermanent(PermanentView card, BigCard bigCard, CardIconRenderSettings cardIconRenderSettings, Dimension dimension, UUID gameId, boolean loadImage, int renderMode, boolean needFullPermanentRender) {
|
||||
MageCard mageCard;
|
||||
if (cardPlugin != null) {
|
||||
if (cardPlugin == null) {
|
||||
throw new IllegalArgumentException("Card's plugin must be loaded");
|
||||
}
|
||||
mageActionCallback.refreshSession();
|
||||
mageActionCallback.setCardPreviewComponent(bigCard);
|
||||
mageCard = cardPlugin.getMagePermanent(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage, renderMode, needFullPermanentRender);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Card's plugin must be loaded");
|
||||
}
|
||||
|
||||
return createLayeredCard(mageCard, dimension, cardIconRenderSettings);
|
||||
}
|
||||
|
||||
|
@ -108,15 +109,14 @@ public enum Plugins implements MagePlugins {
|
|||
// Card icons panels must be put outside of the card like MTG Arena.
|
||||
// So for compatibility purposes: keep free space for icons and change card dimention
|
||||
MageCard mageCard;
|
||||
if (cardPlugin != null) {
|
||||
if (cardPlugin == null) {
|
||||
throw new IllegalArgumentException("Card's plugin must be loaded");
|
||||
}
|
||||
if (previewable) {
|
||||
mageActionCallback.refreshSession();
|
||||
mageActionCallback.setCardPreviewComponent(bigCard);
|
||||
}
|
||||
mageCard = cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage, renderMode, needFullPermanentRender);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Card's plugin must be loaded");
|
||||
}
|
||||
return createLayeredCard(mageCard, dimension, cardIconRenderSettings);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.mage.plugins.card.utils.impl.ImageManagerImpl;
|
|||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Objects;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -36,6 +37,8 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
|
||||
private static final long serialVersionUID = -3272134219262184411L;
|
||||
|
||||
private final static SoftValuesLoadingCache<Key, BufferedImage> IMAGE_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(CardPanelRenderModeImage::createImage));
|
||||
|
||||
private static final int WIDTH_LIMIT = 90; // card width limit to create smaller counter
|
||||
|
||||
private static final float ROUNDED_CORNER_SIZE = 0.1f;
|
||||
|
@ -79,33 +82,9 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
private boolean displayTitleAnyway;
|
||||
private final boolean displayFullImagePath;
|
||||
|
||||
private final static SoftValuesLoadingCache<Key, BufferedImage> IMAGE_CACHE;
|
||||
private int updateArtImageStamp;
|
||||
|
||||
public ImagePanel getOverlayPanel() {
|
||||
return overlayPanel;
|
||||
}
|
||||
|
||||
public void setOverlayPanel(ImagePanel overlayPanel) {
|
||||
this.overlayPanel = overlayPanel;
|
||||
}
|
||||
|
||||
public JPanel getTypeIconPanel() {
|
||||
return typeIconPanel;
|
||||
}
|
||||
|
||||
public void setTypeIconPanel(JPanel typeIconPanel) {
|
||||
this.typeIconPanel = typeIconPanel;
|
||||
}
|
||||
|
||||
public JPanel getCounterPanel() {
|
||||
return counterPanel;
|
||||
}
|
||||
|
||||
public void setCounterPanel(JPanel counterPanel) {
|
||||
this.counterPanel = counterPanel;
|
||||
}
|
||||
|
||||
static class Key {
|
||||
private static class Key {
|
||||
|
||||
final Insets border;
|
||||
final int width;
|
||||
|
@ -137,98 +116,34 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
this.canBlock = canBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 19 * hash + this.border.left;
|
||||
hash = 19 * hash + this.border.right;
|
||||
hash = 19 * hash + this.border.top;
|
||||
hash = 19 * hash + this.border.bottom;
|
||||
hash = 19 * hash + this.width;
|
||||
hash = 19 * hash + this.height;
|
||||
hash = 19 * hash + this.cardWidth;
|
||||
hash = 19 * hash + this.cardHeight;
|
||||
hash = 19 * hash + this.cardXOffset;
|
||||
hash = 19 * hash + this.cardYOffset;
|
||||
hash = 19 * hash + (this.hasImage ? 1 : 0);
|
||||
hash = 19 * hash + (this.isSelected ? 1 : 0);
|
||||
hash = 19 * hash + (this.isChoosable ? 1 : 0);
|
||||
hash = 19 * hash + (this.isPlayable ? 1 : 0);
|
||||
hash = 19 * hash + (this.canAttack ? 1 : 0);
|
||||
hash = 19 * hash + (this.canBlock ? 1 : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
if (obj == null || this.getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Key other = (Key) obj;
|
||||
if (this.border.left != other.border.left) {
|
||||
return false;
|
||||
}
|
||||
if (this.border.right != other.border.right) {
|
||||
return false;
|
||||
}
|
||||
if (this.border.top != other.border.top) {
|
||||
return false;
|
||||
}
|
||||
if (this.border.bottom != other.border.bottom) {
|
||||
return false;
|
||||
}
|
||||
if (this.width != other.width) {
|
||||
return false;
|
||||
}
|
||||
if (this.height != other.height) {
|
||||
return false;
|
||||
}
|
||||
if (this.cardWidth != other.cardWidth) {
|
||||
return false;
|
||||
}
|
||||
if (this.cardHeight != other.cardHeight) {
|
||||
return false;
|
||||
}
|
||||
if (this.cardXOffset != other.cardXOffset) {
|
||||
return false;
|
||||
}
|
||||
if (this.cardYOffset != other.cardYOffset) {
|
||||
return false;
|
||||
}
|
||||
if (this.hasImage != other.hasImage) {
|
||||
return false;
|
||||
}
|
||||
if (this.isSelected != other.isSelected) {
|
||||
return false;
|
||||
}
|
||||
if (this.isChoosable != other.isChoosable) {
|
||||
return false;
|
||||
}
|
||||
if (this.isPlayable != other.isPlayable) {
|
||||
return false;
|
||||
}
|
||||
if (this.canAttack != other.canAttack) {
|
||||
return false;
|
||||
}
|
||||
return this.canBlock == other.canBlock;
|
||||
}
|
||||
Key that = (Key) obj;
|
||||
return Objects.equals(this.border, that.border)
|
||||
&& this.width == that.width
|
||||
&& this.height == that.height
|
||||
&& this.cardWidth == that.cardWidth
|
||||
&& this.cardHeight == that.cardHeight
|
||||
&& this.cardXOffset == that.cardXOffset
|
||||
&& this.cardYOffset == that.cardYOffset
|
||||
&& this.hasImage == that.hasImage
|
||||
&& this.isSelected == that.isSelected
|
||||
&& this.isChoosable == that.isChoosable
|
||||
&& this.isPlayable == that.isPlayable
|
||||
&& this.canAttack == that.canAttack
|
||||
&& this.canBlock == that.canBlock;
|
||||
}
|
||||
|
||||
static {
|
||||
IMAGE_CACHE = ImageCaches.register(SoftValuesLoadingCache.from(CardPanelRenderModeImage::createImage));
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(border, width, height, cardWidth, cardHeight, cardXOffset, cardYOffset, hasImage, isSelected, isChoosable, isPlayable, canAttack, canBlock);
|
||||
}
|
||||
|
||||
static private boolean canShowCardIcons(int cardFullWidth, boolean cardHasImage) {
|
||||
// cards without images show icons and text always
|
||||
// TODO: apply "card names on card" setting to icon too?
|
||||
// TODO: fix card min-max size to hide (compare to settings size, not direct 60 and 200)
|
||||
return ((cardFullWidth > 60) && (cardFullWidth < 200)) || (!cardHasImage);
|
||||
}
|
||||
|
||||
private static class CardSizes {
|
||||
|
@ -254,195 +169,11 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
}
|
||||
}
|
||||
|
||||
public CardPanelRenderModeImage(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension, boolean needFullPermanentRender) {
|
||||
// Call to super
|
||||
super(newGameCard, gameId, loadImage, callback, foil, dimension, needFullPermanentRender);
|
||||
|
||||
// Counter panel
|
||||
if (!newGameCard.isAbility()) {
|
||||
// panel to show counters on the card
|
||||
setCounterPanel(new JPanel());
|
||||
getCounterPanel().setLayout(null);
|
||||
getCounterPanel().setOpaque(false);
|
||||
add(getCounterPanel());
|
||||
|
||||
plusCounterLabel = new JLabel("");
|
||||
plusCounterLabel.setToolTipText("+1/+1");
|
||||
getCounterPanel().add(plusCounterLabel);
|
||||
|
||||
minusCounterLabel = new JLabel("");
|
||||
minusCounterLabel.setToolTipText("-1/-1");
|
||||
getCounterPanel().add(minusCounterLabel);
|
||||
|
||||
loyaltyCounterLabel = new JLabel("");
|
||||
loyaltyCounterLabel.setToolTipText("loyalty");
|
||||
getCounterPanel().add(loyaltyCounterLabel);
|
||||
|
||||
otherCounterLabel = new JLabel("");
|
||||
getCounterPanel().add(otherCounterLabel);
|
||||
|
||||
getCounterPanel().setVisible(false);
|
||||
}
|
||||
|
||||
// Ability icon
|
||||
if (newGameCard.isAbility()) {
|
||||
if (newGameCard.getAbilityType() == AbilityType.TRIGGERED) {
|
||||
setTypeIcon(ImageManagerImpl.instance.getTriggeredAbilityImage(), "Triggered Ability");
|
||||
} else if (newGameCard.getAbilityType() == AbilityType.ACTIVATED) {
|
||||
setTypeIcon(ImageManagerImpl.instance.getActivatedAbilityImage(), "Activated Ability");
|
||||
}
|
||||
}
|
||||
|
||||
// Token icon
|
||||
if (this.getGameCard().isToken()) {
|
||||
setTypeIcon(ImageManagerImpl.instance.getTokenIconImage(), "Token Permanent");
|
||||
}
|
||||
|
||||
displayTitleAnyway = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_CARD_NAMES, "true").equals("true");
|
||||
displayFullImagePath = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_FULL_IMAGE_PATH, "false").equals("true");
|
||||
|
||||
// Title Text
|
||||
titleText = new GlowText();
|
||||
setTitle(getGameCard());
|
||||
titleText.setForeground(Color.white);
|
||||
titleText.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
|
||||
titleText.setWrap(true);
|
||||
add(titleText);
|
||||
|
||||
// Full path to image text
|
||||
fullImageText = new JLabel();
|
||||
fullImageText.setText(fullImagePath);
|
||||
fullImageText.setForeground(Color.BLACK);
|
||||
add(fullImageText);
|
||||
|
||||
// PT Text
|
||||
ptPanel = new JPanel();
|
||||
ptPanel.setOpaque(false);
|
||||
ptPanel.setLayout(new BoxLayout(ptPanel, BoxLayout.X_AXIS));
|
||||
ptPanel.add(new Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(Integer.MAX_VALUE, 0)));
|
||||
ptText1 = new GlowText();
|
||||
ptText2 = new GlowText();
|
||||
ptText3 = new GlowText();
|
||||
updatePTTexts(getGameCard());
|
||||
ptPanel.add(ptText1);
|
||||
ptPanel.add(ptText2);
|
||||
ptPanel.add(ptText3);
|
||||
//
|
||||
add(ptPanel);
|
||||
|
||||
// Sickness overlay
|
||||
BufferedImage sickness = ImageManagerImpl.instance.getSicknessImage();
|
||||
setOverlayPanel(new ImagePanel(sickness, ImagePanelStyle.SCALED));
|
||||
getOverlayPanel().setOpaque(false);
|
||||
add(getOverlayPanel());
|
||||
|
||||
// Imagel panel
|
||||
imagePanel = new ScaledImagePanel();
|
||||
if (DebugUtil.GUI_RENDER_IMAGE_DRAW_IMAGE_BORDER) {
|
||||
imagePanel.setBorder(BorderFactory.createLineBorder(Color.white));
|
||||
}
|
||||
add(imagePanel);
|
||||
|
||||
// Do we need to load?
|
||||
if (loadImage) {
|
||||
initialDraw();
|
||||
} else {
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
private void setTypeIcon(BufferedImage bufferedImage, String toolTipText) {
|
||||
setTypeIconPanel(new JPanel());
|
||||
getTypeIconPanel().setLayout(null);
|
||||
getTypeIconPanel().setOpaque(false);
|
||||
add(getTypeIconPanel());
|
||||
|
||||
typeIconButton = new JButton("");
|
||||
typeIconButton.setLocation(2, 2);
|
||||
typeIconButton.setSize(25, 25);
|
||||
|
||||
getTypeIconPanel().setVisible(true);
|
||||
typeIconButton.setIcon(new ImageIcon(bufferedImage));
|
||||
if (toolTipText != null) {
|
||||
typeIconButton.setToolTipText(toolTipText);
|
||||
}
|
||||
getTypeIconPanel().add(typeIconButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
super.cleanUp();
|
||||
this.setCounterPanel(null);
|
||||
}
|
||||
|
||||
private void setTitle(CardView card) {
|
||||
titleText.setText(!displayTitleAnyway && hasImage ? "" : card.getDisplayName());
|
||||
}
|
||||
|
||||
private void setImage(BufferedImage srcImage) {
|
||||
synchronized (imagePanel) {
|
||||
if (srcImage != null) {
|
||||
imagePanel.setImage(srcImage);
|
||||
} else {
|
||||
imagePanel.clearImage();
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
doLayout();
|
||||
}
|
||||
|
||||
private void setFullPath(String fullImagePath) {
|
||||
this.fullImagePath = fullImagePath;
|
||||
this.fullImagePath = this.fullImagePath.replaceAll("\\\\", "\\\\<br>");
|
||||
this.fullImagePath = this.fullImagePath.replaceAll("/", "/<br>");
|
||||
this.fullImagePath = "<html>" + this.fullImagePath + "</html>";
|
||||
fullImageText.setText(!displayFullImagePath ? "" : this.fullImagePath);
|
||||
doLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transferResources(final CardPanel panelAbstract) {
|
||||
if (panelAbstract instanceof CardPanelRenderModeImage) {
|
||||
CardPanelRenderModeImage panel = (CardPanelRenderModeImage) panelAbstract;
|
||||
synchronized (panel.imagePanel) {
|
||||
if (panel.imagePanel.hasImage()) {
|
||||
setImage(panel.imagePanel.getSrcImage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(boolean isSelected) {
|
||||
super.setSelected(isSelected);
|
||||
if (isSelected) {
|
||||
this.titleText.setGlowColor(Color.green);
|
||||
} else {
|
||||
this.titleText.setGlowColor(Color.black);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintCard(Graphics2D g2d) {
|
||||
float alpha = getAlpha();
|
||||
if (alpha != 1.0f) {
|
||||
AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha);
|
||||
g2d.setComposite(composite);
|
||||
}
|
||||
|
||||
// draw background (selected/chooseable/playable)
|
||||
MageCardLocation cardLocation = getCardLocation();
|
||||
g2d.drawImage(
|
||||
IMAGE_CACHE.getOrThrow(
|
||||
new Key(getInsets(),
|
||||
cardLocation.getCardWidth(), cardLocation.getCardHeight(),
|
||||
cardLocation.getCardWidth(), cardLocation.getCardHeight(),
|
||||
0,
|
||||
0,
|
||||
hasImage, isSelected(), isChoosable(), getGameCard().isPlayable(), getGameCard().isCanAttack(),
|
||||
getGameCard().isCanBlock())),
|
||||
0, 0, cardLocation.getCardWidth(), cardLocation.getCardHeight(), null);
|
||||
g2d.dispose();
|
||||
static private boolean canShowCardIcons(int cardFullWidth, boolean cardHasImage) {
|
||||
// cards without images show icons and text always
|
||||
// TODO: apply "card names on card" setting to icon too?
|
||||
// TODO: fix card min-max size to hide (compare to settings size, not direct 60 and 200)
|
||||
return ((cardFullWidth > 60) && (cardFullWidth < 200)) || (!cardHasImage);
|
||||
}
|
||||
|
||||
private static BufferedImage createImage(Key key) {
|
||||
|
@ -501,62 +232,125 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
return image;
|
||||
}
|
||||
|
||||
private static ImageIcon getCounterImageWithAmount(int amount, BufferedImage image, int cardWidth) {
|
||||
int factor = cardWidth > WIDTH_LIMIT ? 2 : 1;
|
||||
int xOffset = amount > 9 ? 2 : 5;
|
||||
int fontSize = factor == 1 ? amount < 10 ? 12 : amount < 100 ? 10 : amount < 1000 ? 7 : 6
|
||||
: amount < 10 ? 19 : amount < 100 ? 15 : amount < 1000 ? 12 : amount < 10000 ? 9 : 8;
|
||||
BufferedImage newImage;
|
||||
if (cardWidth > WIDTH_LIMIT) {
|
||||
newImage = ImageManagerImpl.deepCopy(image);
|
||||
} else {
|
||||
newImage = ImageHelper.getResizedImage(image, 20, 20);
|
||||
}
|
||||
Graphics graphics = newImage.getGraphics();
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.setFont(new Font("Arial Black", amount > 100 ? Font.PLAIN : Font.BOLD, fontSize));
|
||||
graphics.drawString(Integer.toString(amount), xOffset * factor, 11 * factor);
|
||||
return new ImageIcon(newImage);
|
||||
}
|
||||
|
||||
public CardPanelRenderModeImage(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension, boolean needFullPermanentRender) {
|
||||
// Call to super
|
||||
super(newGameCard, gameId, loadImage, callback, foil, dimension, needFullPermanentRender);
|
||||
|
||||
// Counter panel
|
||||
if (!newGameCard.isAbility()) {
|
||||
// panel to show counters on the card
|
||||
counterPanel = new JPanel();
|
||||
counterPanel.setLayout(null);
|
||||
counterPanel.setOpaque(false);
|
||||
add(counterPanel);
|
||||
|
||||
plusCounterLabel = new JLabel("");
|
||||
plusCounterLabel.setToolTipText("+1/+1");
|
||||
counterPanel.add(plusCounterLabel);
|
||||
|
||||
minusCounterLabel = new JLabel("");
|
||||
minusCounterLabel.setToolTipText("-1/-1");
|
||||
counterPanel.add(minusCounterLabel);
|
||||
|
||||
loyaltyCounterLabel = new JLabel("");
|
||||
loyaltyCounterLabel.setToolTipText("loyalty");
|
||||
counterPanel.add(loyaltyCounterLabel);
|
||||
|
||||
otherCounterLabel = new JLabel("");
|
||||
counterPanel.add(otherCounterLabel);
|
||||
|
||||
counterPanel.setVisible(false);
|
||||
}
|
||||
|
||||
// Ability icon
|
||||
if (newGameCard.isAbility()) {
|
||||
if (newGameCard.getAbilityType() == AbilityType.TRIGGERED) {
|
||||
setTypeIcon(ImageManagerImpl.instance.getTriggeredAbilityImage(), "Triggered Ability");
|
||||
} else if (newGameCard.getAbilityType() == AbilityType.ACTIVATED) {
|
||||
setTypeIcon(ImageManagerImpl.instance.getActivatedAbilityImage(), "Activated Ability");
|
||||
}
|
||||
}
|
||||
|
||||
// Token icon
|
||||
if (this.getGameCard().isToken()) {
|
||||
setTypeIcon(ImageManagerImpl.instance.getTokenIconImage(), "Token Permanent");
|
||||
}
|
||||
|
||||
displayTitleAnyway = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_CARD_NAMES, "true").equals("true");
|
||||
displayFullImagePath = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_FULL_IMAGE_PATH, "false").equals("true");
|
||||
|
||||
// Title Text
|
||||
titleText = new GlowText();
|
||||
setTitle(getGameCard());
|
||||
titleText.setForeground(Color.white);
|
||||
titleText.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
|
||||
titleText.setWrap(true);
|
||||
add(titleText);
|
||||
|
||||
// Full path to image text
|
||||
fullImageText = new JLabel();
|
||||
fullImageText.setText(fullImagePath);
|
||||
fullImageText.setForeground(Color.BLACK);
|
||||
add(fullImageText);
|
||||
|
||||
// PT Text
|
||||
ptPanel = new JPanel();
|
||||
ptPanel.setOpaque(false);
|
||||
ptPanel.setLayout(new BoxLayout(ptPanel, BoxLayout.X_AXIS));
|
||||
ptPanel.add(new Box.Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(Integer.MAX_VALUE, 0)));
|
||||
ptText1 = new GlowText();
|
||||
ptText2 = new GlowText();
|
||||
ptText3 = new GlowText();
|
||||
updatePTTexts(getGameCard());
|
||||
ptPanel.add(ptText1);
|
||||
ptPanel.add(ptText2);
|
||||
ptPanel.add(ptText3);
|
||||
//
|
||||
add(ptPanel);
|
||||
|
||||
// Sickness overlay
|
||||
BufferedImage sickness = ImageManagerImpl.instance.getSicknessImage();
|
||||
overlayPanel = new ImagePanel(sickness, ImagePanelStyle.SCALED);
|
||||
overlayPanel.setOpaque(false);
|
||||
add(overlayPanel);
|
||||
|
||||
// Imagel panel
|
||||
imagePanel = new ScaledImagePanel();
|
||||
if (DebugUtil.GUI_RENDER_IMAGE_DRAW_IMAGE_BORDER) {
|
||||
imagePanel.setBorder(BorderFactory.createLineBorder(Color.white));
|
||||
}
|
||||
add(imagePanel);
|
||||
|
||||
// Do we need to load?
|
||||
if (loadImage) {
|
||||
initialDraw();
|
||||
} else {
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintChildren(Graphics g) {
|
||||
super.paintChildren(g);
|
||||
|
||||
/*
|
||||
// debug draw recs
|
||||
|
||||
// full card
|
||||
g.setColor(new Color(255, 0, 0));
|
||||
g.drawRect(realCard.rectFull.x, realCard.rectFull.y, realCard.rectFull.width, realCard.rectFull.height);
|
||||
|
||||
// real card - image
|
||||
g.setColor(new Color(0, 0, 255));
|
||||
g.drawRect(imagePanel.getX(), imagePanel.getY(), imagePanel.getBounds().width, imagePanel.getBounds().height);
|
||||
|
||||
// caption
|
||||
g.setColor(new Color(0, 255, 255));
|
||||
g.drawRect(titleText.getX(), titleText.getY(), titleText.getBounds().width, titleText.getBounds().height);
|
||||
|
||||
// life points
|
||||
g.setColor(new Color(120, 0, 120));
|
||||
g.drawRect(ptText.getX(), ptText.getY(), ptText.getBounds().width, ptText.getBounds().height);
|
||||
//*/
|
||||
|
||||
if (getShowCastingCost() && !isAnimationPanel() && canShowCardIcons(getCardWidth(), hasImage)) {
|
||||
|
||||
int symbolMarginX = 2; // 2 px between icons
|
||||
|
||||
String manaCost = ManaSymbols.getClearManaCost(getGameCard().getManaCostStr());
|
||||
int manaWidth = getManaWidth(manaCost, symbolMarginX);
|
||||
|
||||
// right top corner with margin (sizes from any sample card, length from black border to mana icon)
|
||||
int manaMarginRight = Math.round(22f / 672f * getCardWidth());
|
||||
int manaMarginTop = Math.round(24f / 936f * getCardHeight());
|
||||
|
||||
int cardOffsetX = 0;
|
||||
int cardOffsetY = 0;
|
||||
int manaX = cardOffsetX + getCardWidth() - manaMarginRight - manaWidth;
|
||||
int manaY = cardOffsetY + manaMarginTop;
|
||||
|
||||
ManaSymbols.draw(g, manaCost, manaX, manaY, getSymbolWidth(), ModernCardRenderer.MANA_ICONS_TEXT_COLOR, symbolMarginX);
|
||||
}
|
||||
}
|
||||
|
||||
private int getManaWidth(String manaCost, int symbolMarginX) {
|
||||
int width = 0;
|
||||
manaCost = manaCost.replace("\\", "");
|
||||
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
||||
while (tok.hasMoreTokens()) {
|
||||
tok.nextToken();
|
||||
if (width != 0) {
|
||||
width += symbolMarginX;
|
||||
}
|
||||
width += getSymbolWidth();
|
||||
}
|
||||
return width;
|
||||
public void cleanUp() {
|
||||
super.cleanUp();
|
||||
counterPanel = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -588,32 +382,32 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
imagePanel.setSize(realCardSize.width, realCardSize.height);
|
||||
|
||||
if (hasSickness() && getGameCard().isCreature() && isPermanent()) {
|
||||
getOverlayPanel().setLocation(realCardSize.x, realCardSize.y);
|
||||
getOverlayPanel().setSize(realCardSize.width, realCardSize.height);
|
||||
overlayPanel.setLocation(realCardSize.x, realCardSize.y);
|
||||
overlayPanel.setSize(realCardSize.width, realCardSize.height);
|
||||
} else {
|
||||
getOverlayPanel().setVisible(false);
|
||||
overlayPanel.setVisible(false);
|
||||
}
|
||||
|
||||
if (getTypeIconPanel() != null) {
|
||||
getTypeIconPanel().setLocation(realCardSize.x, realCardSize.y);
|
||||
getTypeIconPanel().setSize(realCardSize.width, realCardSize.height);
|
||||
if (typeIconPanel != null) {
|
||||
typeIconPanel.setLocation(realCardSize.x, realCardSize.y);
|
||||
typeIconPanel.setSize(realCardSize.width, realCardSize.height);
|
||||
}
|
||||
|
||||
if (getCounterPanel() != null) {
|
||||
getCounterPanel().setLocation(realCardSize.x, realCardSize.y);
|
||||
getCounterPanel().setSize(realCardSize.width, realCardSize.height);
|
||||
if (counterPanel != null) {
|
||||
counterPanel.setLocation(realCardSize.x, realCardSize.y);
|
||||
counterPanel.setSize(realCardSize.width, realCardSize.height);
|
||||
int size = cardWidth > WIDTH_LIMIT ? 40 : 20;
|
||||
|
||||
minusCounterLabel.setLocation(getCounterPanel().getWidth() - size, getCounterPanel().getHeight() - size * 2);
|
||||
minusCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size * 2);
|
||||
minusCounterLabel.setSize(size, size);
|
||||
|
||||
plusCounterLabel.setLocation(5, getCounterPanel().getHeight() - size * 2);
|
||||
plusCounterLabel.setLocation(5, counterPanel.getHeight() - size * 2);
|
||||
plusCounterLabel.setSize(size, size);
|
||||
|
||||
loyaltyCounterLabel.setLocation(getCounterPanel().getWidth() - size, getCounterPanel().getHeight() - size);
|
||||
loyaltyCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size);
|
||||
loyaltyCounterLabel.setSize(size, size);
|
||||
|
||||
otherCounterLabel.setLocation(5, getCounterPanel().getHeight() - size);
|
||||
otherCounterLabel.setLocation(5, counterPanel.getHeight() - size);
|
||||
otherCounterLabel.setSize(size, size);
|
||||
|
||||
}
|
||||
|
@ -668,41 +462,83 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
}
|
||||
}
|
||||
|
||||
private void prepareGlowFont(GlowText label, int fontSize, MageInt value, boolean drawAsDamaged) {
|
||||
label.setFont(getFont().deriveFont(Font.BOLD, fontSize));
|
||||
label.setForeground(CardRendererUtils.getCardTextColor(value, drawAsDamaged, titleText.getForeground(), true));
|
||||
Dimension ptSize = label.getPreferredSize();
|
||||
label.setSize(ptSize.width, ptSize.height);
|
||||
}
|
||||
|
||||
private void updatePTTexts(CardView card) {
|
||||
if (card.isCreature() || card.getSubTypes().contains(SubType.VEHICLE)) {
|
||||
ptText1.setText(getGameCard().getPower());
|
||||
ptText2.setText("/");
|
||||
ptText3.setText(CardRendererUtils.getCardLifeWithDamage(getGameCard()));
|
||||
} else if (card.isPlanesWalker()) {
|
||||
ptText1.setText("");
|
||||
ptText2.setText("");
|
||||
ptText3.setText(getGameCard().getLoyalty());
|
||||
@Override
|
||||
public Image getImage() {
|
||||
if (this.hasImage) {
|
||||
if (getGameCard().isFaceDown()) {
|
||||
return getFaceDownImage();
|
||||
} else {
|
||||
ptText1.setText("");
|
||||
ptText2.setText("");
|
||||
ptText3.setText("");
|
||||
return ImageCache.getImageOriginal(getGameCard());
|
||||
}
|
||||
|
||||
ptText1.setForeground(Color.white);
|
||||
ptText1.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
|
||||
|
||||
ptText2.setForeground(Color.white);
|
||||
ptText2.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
|
||||
|
||||
ptText3.setForeground(Color.white);
|
||||
ptText3.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getGameCard().toString();
|
||||
protected void paintCard(Graphics2D g2d) {
|
||||
float alpha = getAlpha();
|
||||
if (alpha != 1.0f) {
|
||||
AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha);
|
||||
g2d.setComposite(composite);
|
||||
}
|
||||
|
||||
// draw background (selected/chooseable/playable)
|
||||
MageCardLocation cardLocation = getCardLocation();
|
||||
g2d.drawImage(
|
||||
IMAGE_CACHE.getOrThrow(
|
||||
new Key(getInsets(),
|
||||
cardLocation.getCardWidth(), cardLocation.getCardHeight(),
|
||||
cardLocation.getCardWidth(), cardLocation.getCardHeight(),
|
||||
0,
|
||||
0,
|
||||
hasImage, isSelected(), isChoosable(), getGameCard().isPlayable(), getGameCard().isCanAttack(),
|
||||
getGameCard().isCanBlock())),
|
||||
0, 0, cardLocation.getCardWidth(), cardLocation.getCardHeight(), null);
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintChildren(Graphics g) {
|
||||
super.paintChildren(g);
|
||||
|
||||
/*
|
||||
// debug draw recs
|
||||
|
||||
// full card
|
||||
g.setColor(new Color(255, 0, 0));
|
||||
g.drawRect(realCard.rectFull.x, realCard.rectFull.y, realCard.rectFull.width, realCard.rectFull.height);
|
||||
|
||||
// real card - image
|
||||
g.setColor(new Color(0, 0, 255));
|
||||
g.drawRect(imagePanel.getX(), imagePanel.getY(), imagePanel.getBounds().width, imagePanel.getBounds().height);
|
||||
|
||||
// caption
|
||||
g.setColor(new Color(0, 255, 255));
|
||||
g.drawRect(titleText.getX(), titleText.getY(), titleText.getBounds().width, titleText.getBounds().height);
|
||||
|
||||
// life points
|
||||
g.setColor(new Color(120, 0, 120));
|
||||
g.drawRect(ptText.getX(), ptText.getY(), ptText.getBounds().width, ptText.getBounds().height);
|
||||
//*/
|
||||
|
||||
if (getShowCastingCost() && !isAnimationPanel() && canShowCardIcons(getCardWidth(), hasImage)) {
|
||||
|
||||
int symbolMarginX = 2; // 2 px between icons
|
||||
|
||||
String manaCost = ManaSymbols.getClearManaCost(getGameCard().getManaCostStr());
|
||||
int manaWidth = getManaWidth(manaCost, symbolMarginX);
|
||||
|
||||
// right top corner with margin (sizes from any sample card, length from black border to mana icon)
|
||||
int manaMarginRight = Math.round(22f / 672f * getCardWidth());
|
||||
int manaMarginTop = Math.round(24f / 936f * getCardHeight());
|
||||
|
||||
int cardOffsetX = 0;
|
||||
int cardOffsetY = 0;
|
||||
int manaX = cardOffsetX + getCardWidth() - manaMarginRight - manaWidth;
|
||||
int manaY = cardOffsetY + manaMarginTop;
|
||||
|
||||
ManaSymbols.draw(g, manaCost, manaX, manaY, getSymbolWidth(), ModernCardRenderer.MANA_ICONS_TEXT_COLOR, symbolMarginX);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -734,9 +570,59 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Image updating code
|
||||
private int updateArtImageStamp;
|
||||
@Override
|
||||
public void setSelected(boolean isSelected) {
|
||||
super.setSelected(isSelected);
|
||||
if (isSelected) {
|
||||
this.titleText.setGlowColor(Color.green);
|
||||
} else {
|
||||
this.titleText.setGlowColor(Color.black);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCardTitle() {
|
||||
displayTitleAnyway = true;
|
||||
setTitle(getGameCard());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getGameCard().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transferResources(final CardPanel panelAbstract) {
|
||||
if (panelAbstract instanceof CardPanelRenderModeImage) {
|
||||
CardPanelRenderModeImage panel = (CardPanelRenderModeImage) panelAbstract;
|
||||
synchronized (panel.imagePanel) {
|
||||
if (panel.imagePanel.hasImage()) {
|
||||
setImage(panel.imagePanel.getSrcImage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(CardView card) {
|
||||
// Super
|
||||
super.update(card);
|
||||
|
||||
// real card to show stores in getGameCard (e.g. after user clicks on night icon -- night card must be rendered)
|
||||
updatePTTexts(getGameCard());
|
||||
setTitle(getGameCard());
|
||||
|
||||
// Summoning Sickness overlay
|
||||
overlayPanel.setVisible(hasSickness() && getGameCard().isCreature() && isPermanent());
|
||||
|
||||
// Update counters panel
|
||||
if (counterPanel != null) {
|
||||
updateCounters(card);
|
||||
}
|
||||
|
||||
// Finally, queue a repaint
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateArtImage() {
|
||||
|
@ -787,32 +673,69 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCardTitle() {
|
||||
displayTitleAnyway = true;
|
||||
setTitle(getGameCard());
|
||||
private int getManaWidth(String manaCost, int symbolMarginX) {
|
||||
int width = 0;
|
||||
manaCost = manaCost.replace("\\", "");
|
||||
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
||||
while (tok.hasMoreTokens()) {
|
||||
tok.nextToken();
|
||||
if (width != 0) {
|
||||
width += symbolMarginX;
|
||||
}
|
||||
width += getSymbolWidth();
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(CardView card) {
|
||||
// Super
|
||||
super.update(card);
|
||||
|
||||
// real card to show stores in getGameCard (e.g. after user clicks on night icon -- night card must be rendered)
|
||||
updatePTTexts(getGameCard());
|
||||
setTitle(getGameCard());
|
||||
|
||||
// Summoning Sickness overlay
|
||||
getOverlayPanel().setVisible(hasSickness() && getGameCard().isCreature() && isPermanent());
|
||||
|
||||
// Update counters panel
|
||||
if (getCounterPanel() != null) {
|
||||
updateCounters(card);
|
||||
private void prepareGlowFont(GlowText label, int fontSize, MageInt value, boolean drawAsDamaged) {
|
||||
label.setFont(getFont().deriveFont(Font.BOLD, fontSize));
|
||||
label.setForeground(CardRendererUtils.getCardTextColor(value, drawAsDamaged, titleText.getForeground(), true));
|
||||
Dimension ptSize = label.getPreferredSize();
|
||||
label.setSize(ptSize.width, ptSize.height);
|
||||
}
|
||||
|
||||
// Finally, queue a repaint
|
||||
private void setFullPath(String fullImagePath) {
|
||||
this.fullImagePath = fullImagePath;
|
||||
this.fullImagePath = this.fullImagePath.replaceAll("\\\\", "\\\\<br>");
|
||||
this.fullImagePath = this.fullImagePath.replaceAll("/", "/<br>");
|
||||
this.fullImagePath = "<html>" + this.fullImagePath + "</html>";
|
||||
fullImageText.setText(!displayFullImagePath ? "" : this.fullImagePath);
|
||||
doLayout();
|
||||
}
|
||||
|
||||
private void setImage(BufferedImage srcImage) {
|
||||
synchronized (imagePanel) {
|
||||
if (srcImage != null) {
|
||||
imagePanel.setImage(srcImage);
|
||||
} else {
|
||||
imagePanel.clearImage();
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
doLayout();
|
||||
}
|
||||
|
||||
private void setTitle(CardView card) {
|
||||
titleText.setText(!displayTitleAnyway && hasImage ? "" : card.getDisplayName());
|
||||
}
|
||||
|
||||
private void setTypeIcon(BufferedImage bufferedImage, String toolTipText) {
|
||||
typeIconPanel = new JPanel();
|
||||
typeIconPanel.setLayout(null);
|
||||
typeIconPanel.setOpaque(false);
|
||||
add(typeIconPanel);
|
||||
|
||||
typeIconButton = new JButton("");
|
||||
typeIconButton.setLocation(2, 2);
|
||||
typeIconButton.setSize(25, 25);
|
||||
|
||||
typeIconPanel.setVisible(true);
|
||||
typeIconButton.setIcon(new ImageIcon(bufferedImage));
|
||||
if (toolTipText != null) {
|
||||
typeIconButton.setToolTipText(toolTipText);
|
||||
}
|
||||
typeIconPanel.add(typeIconButton);
|
||||
}
|
||||
|
||||
private void updateCounters(CardView card) {
|
||||
if (card.getCounters() != null && !card.getCounters().isEmpty()) {
|
||||
|
@ -865,43 +788,38 @@ public class CardPanelRenderModeImage extends CardPanel {
|
|||
}
|
||||
}
|
||||
|
||||
getCounterPanel().setVisible(true);
|
||||
counterPanel.setVisible(true);
|
||||
} else {
|
||||
plusCounterLabel.setVisible(false);
|
||||
minusCounterLabel.setVisible(false);
|
||||
loyaltyCounterLabel.setVisible(false);
|
||||
otherCounterLabel.setVisible(false);
|
||||
getCounterPanel().setVisible(false);
|
||||
counterPanel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static ImageIcon getCounterImageWithAmount(int amount, BufferedImage image, int cardWidth) {
|
||||
int factor = cardWidth > WIDTH_LIMIT ? 2 : 1;
|
||||
int xOffset = amount > 9 ? 2 : 5;
|
||||
int fontSize = factor == 1 ? amount < 10 ? 12 : amount < 100 ? 10 : amount < 1000 ? 7 : 6
|
||||
: amount < 10 ? 19 : amount < 100 ? 15 : amount < 1000 ? 12 : amount < 10000 ? 9 : 8;
|
||||
BufferedImage newImage;
|
||||
if (cardWidth > WIDTH_LIMIT) {
|
||||
newImage = ImageManagerImpl.deepCopy(image);
|
||||
private void updatePTTexts(CardView card) {
|
||||
if (card.isCreature() || card.getSubTypes().contains(SubType.VEHICLE)) {
|
||||
ptText1.setText(getGameCard().getPower());
|
||||
ptText2.setText("/");
|
||||
ptText3.setText(CardRendererUtils.getCardLifeWithDamage(getGameCard()));
|
||||
} else if (card.isPlanesWalker()) {
|
||||
ptText1.setText("");
|
||||
ptText2.setText("");
|
||||
ptText3.setText(getGameCard().getLoyalty());
|
||||
} else {
|
||||
newImage = ImageHelper.getResizedImage(image, 20, 20);
|
||||
}
|
||||
Graphics graphics = newImage.getGraphics();
|
||||
graphics.setColor(Color.BLACK);
|
||||
graphics.setFont(new Font("Arial Black", amount > 100 ? Font.PLAIN : Font.BOLD, fontSize));
|
||||
graphics.drawString(Integer.toString(amount), xOffset * factor, 11 * factor);
|
||||
return new ImageIcon(newImage);
|
||||
ptText1.setText("");
|
||||
ptText2.setText("");
|
||||
ptText3.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getImage() {
|
||||
if (this.hasImage) {
|
||||
if (getGameCard().isFaceDown()) {
|
||||
return getFaceDownImage();
|
||||
} else {
|
||||
return ImageCache.getImageOriginal(getGameCard());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
ptText1.setForeground(Color.white);
|
||||
ptText1.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
|
||||
|
||||
ptText2.setForeground(Color.white);
|
||||
ptText2.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
|
||||
|
||||
ptText3.setForeground(Color.white);
|
||||
ptText3.setGlow(Color.black, TEXT_GLOW_SIZE, TEXT_GLOW_INTENSITY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.mage.plugins.card.images.ImageCache;
|
|||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -25,94 +26,67 @@ import java.util.concurrent.TimeUnit;
|
|||
*/
|
||||
public class CardPanelRenderModeMTGO extends CardPanel {
|
||||
|
||||
private static boolean cardViewEquals(CardView a, CardView b) {
|
||||
// Map of generated images
|
||||
private final static Cache<ImageKey, BufferedImage> IMAGE_CACHE = CacheBuilder
|
||||
.newBuilder()
|
||||
.maximumSize(3000)
|
||||
.expireAfterAccess(60, TimeUnit.MINUTES)
|
||||
.softValues()
|
||||
.build();
|
||||
|
||||
// The art image for the card, loaded in from the disk
|
||||
private BufferedImage artImage;
|
||||
|
||||
// The faceart image for the card, loaded in from the disk (based on artid from mtgo)
|
||||
private BufferedImage faceArtImage;
|
||||
|
||||
// Factory to generate card appropriate views
|
||||
private final CardRendererFactory cardRendererFactory = new CardRendererFactory();
|
||||
|
||||
// The rendered card image, with or without the art image loaded yet
|
||||
// = null while invalid
|
||||
private BufferedImage cardImage;
|
||||
private CardRenderer cardRenderer;
|
||||
|
||||
private int updateArtImageStamp;
|
||||
|
||||
private static boolean cardViewEquals(CardView a, CardView b) { // TODO: This belongs in CardView
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
if (a.getClass() != b.getClass()) {
|
||||
if (a == null || b == null || a.getClass() != b.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (!a.getDisplayName().equals(b.getDisplayName())) {
|
||||
|
||||
if (!(a.getDisplayName().equals(b.getDisplayName()) // TODO: Original code not checking everything. Why is it only checking these values?
|
||||
&& a.getPower().equals(b.getPower())
|
||||
&& a.getToughness().equals(b.getToughness())
|
||||
&& a.getLoyalty().equals(b.getLoyalty())
|
||||
&& 0 == a.getColor().compareTo(b.getColor())
|
||||
&& a.getCardTypes().equals(b.getCardTypes())
|
||||
&& a.getSubTypes().equals(b.getSubTypes())
|
||||
&& a.getSuperTypes().equals(b.getSuperTypes())
|
||||
&& a.getManaCostStr().equals(b.getManaCostStr())
|
||||
&& a.getRules().equals(b.getRules())
|
||||
&& Objects.equals(a.getRarity(), b.getRarity())
|
||||
&& Objects.equals(a.getCardNumber(), b.getCardNumber())
|
||||
&& Objects.equals(a.getExpansionSetCode(), b.getExpansionSetCode())
|
||||
&& a.getFrameStyle() == b.getFrameStyle()
|
||||
&& Objects.equals(a.getCounters(), b.getCounters())
|
||||
&& a.isFaceDown() == b.isFaceDown())) {
|
||||
return false;
|
||||
}
|
||||
if (!a.getPower().equals(b.getPower())) {
|
||||
return false;
|
||||
}
|
||||
if (!a.getToughness().equals(b.getToughness())) {
|
||||
return false;
|
||||
}
|
||||
if (!a.getLoyalty().equals(b.getLoyalty())) {
|
||||
return false;
|
||||
}
|
||||
if (0 != a.getColor().compareTo(b.getColor())) {
|
||||
return false;
|
||||
}
|
||||
if (!a.getCardTypes().equals(b.getCardTypes())) {
|
||||
return false;
|
||||
}
|
||||
if (!a.getSubTypes().equals(b.getSubTypes())) {
|
||||
return false;
|
||||
}
|
||||
if (!a.getSuperTypes().equals(b.getSuperTypes())) {
|
||||
return false;
|
||||
}
|
||||
if (!a.getManaCostStr().equals(b.getManaCostStr())) {
|
||||
return false;
|
||||
}
|
||||
if (!a.getRules().equals(b.getRules())) {
|
||||
return false;
|
||||
}
|
||||
if (a.getRarity() == null || b.getRarity() == null) {
|
||||
return false;
|
||||
}
|
||||
if (a.getRarity() != b.getRarity()) {
|
||||
return false;
|
||||
}
|
||||
if (a.getCardNumber() != null && !a.getCardNumber().equals(b.getCardNumber())) {
|
||||
return false;
|
||||
}
|
||||
// Expansion set code, with null checking:
|
||||
// TODO: The null checks should not be necessary, but thanks to Issue #2260
|
||||
// some tokens / commandobjects will be missing expansion set codes.
|
||||
String expA = a.getExpansionSetCode();
|
||||
if (expA == null) {
|
||||
expA = "";
|
||||
}
|
||||
String expB = b.getExpansionSetCode();
|
||||
if (expB == null) {
|
||||
expB = "";
|
||||
}
|
||||
if (!expA.equals(expB)) {
|
||||
return false;
|
||||
}
|
||||
if (a.getFrameStyle() != b.getFrameStyle()) {
|
||||
return false;
|
||||
}
|
||||
if (a.getCounters() == null) {
|
||||
if (b.getCounters() != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!a.getCounters().equals(b.getCounters())) {
|
||||
return false;
|
||||
}
|
||||
if (a.isFaceDown() != b.isFaceDown()) {
|
||||
return false;
|
||||
}
|
||||
if ((a instanceof PermanentView)) {
|
||||
PermanentView aa = (PermanentView) a;
|
||||
PermanentView bb = (PermanentView) b;
|
||||
if (aa.hasSummoningSickness() != bb.hasSummoningSickness()) {
|
||||
// Note: b must be a permanentview too as we aleady checked that classes
|
||||
// are the same for a and b
|
||||
return false;
|
||||
}
|
||||
return aa.getDamage() == bb.getDamage();
|
||||
}
|
||||
|
||||
if (!(a instanceof PermanentView)) {
|
||||
return true;
|
||||
}
|
||||
PermanentView aa = (PermanentView) a;
|
||||
PermanentView bb = (PermanentView) b;
|
||||
return aa.hasSummoningSickness() == bb.hasSummoningSickness()
|
||||
&& aa.getDamage() == bb.getDamage();
|
||||
}
|
||||
|
||||
static class ImageKey {
|
||||
|
||||
private static class ImageKey {
|
||||
final BufferedImage artImage;
|
||||
final int width;
|
||||
final int height;
|
||||
|
@ -133,7 +107,7 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
this.hashCode = hashCodeImpl();
|
||||
}
|
||||
|
||||
private int hashCodeImpl() {
|
||||
private int hashCodeImpl() { // TODO: Why is this using a string builder???
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append((char) (artImage != null ? 1 : 0));
|
||||
sb.append((char) width);
|
||||
|
@ -185,60 +159,23 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
// Initial checks
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object == null) {
|
||||
if (object == null || this.getClass() != object.getClass()) {
|
||||
return false;
|
||||
}
|
||||
if (!(object instanceof ImageKey)) {
|
||||
return false;
|
||||
}
|
||||
final ImageKey other = (ImageKey) object;
|
||||
final ImageKey that = (ImageKey) object;
|
||||
|
||||
// Compare
|
||||
if ((artImage == null) == (other.artImage != null)) {
|
||||
return false;
|
||||
}
|
||||
if (width != other.width) {
|
||||
return false;
|
||||
}
|
||||
if (height != other.height) {
|
||||
return false;
|
||||
}
|
||||
if (isChoosable != other.isChoosable) {
|
||||
return false;
|
||||
}
|
||||
if (isSelected != other.isSelected) {
|
||||
return false;
|
||||
}
|
||||
return cardViewEquals(view, other.view);
|
||||
return (artImage == null) == (that.artImage == null)
|
||||
&& this.width == that.width
|
||||
&& this.height == that.height
|
||||
&& this.isChoosable == that.isChoosable
|
||||
&& this.isSelected == that.isSelected
|
||||
&& cardViewEquals(this.view, that.view);
|
||||
}
|
||||
}
|
||||
|
||||
// Map of generated images
|
||||
private final static Cache<ImageKey, BufferedImage> IMAGE_CACHE = CacheBuilder
|
||||
.newBuilder()
|
||||
.maximumSize(3000)
|
||||
.expireAfterAccess(60, TimeUnit.MINUTES)
|
||||
.softValues()
|
||||
.build();
|
||||
|
||||
// The art image for the card, loaded in from the disk
|
||||
private BufferedImage artImage;
|
||||
|
||||
// The faceart image for the card, loaded in from the disk (based on artid from mtgo)
|
||||
private BufferedImage faceArtImage;
|
||||
|
||||
// Factory to generate card appropriate views
|
||||
private final CardRendererFactory cardRendererFactory = new CardRendererFactory();
|
||||
|
||||
// The rendered card image, with or without the art image loaded yet
|
||||
// = null while invalid
|
||||
private BufferedImage cardImage;
|
||||
private CardRenderer cardRenderer;
|
||||
|
||||
public CardPanelRenderModeMTGO(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback,
|
||||
final boolean foil, Dimension dimension, boolean needFullPermanentRender) {
|
||||
// Call to super
|
||||
|
@ -252,16 +189,14 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void transferResources(CardPanel panel) {
|
||||
if (panel instanceof CardPanelRenderModeMTGO) {
|
||||
CardPanelRenderModeMTGO impl = (CardPanelRenderModeMTGO) panel;
|
||||
|
||||
// Use the art image and current rendered image from the card
|
||||
artImage = impl.artImage;
|
||||
cardRenderer.setArtImage(artImage);
|
||||
faceArtImage = impl.faceArtImage;
|
||||
cardRenderer.setFaceArtImage(faceArtImage);
|
||||
cardImage = impl.cardImage;
|
||||
public Image getImage() {
|
||||
if (artImage == null) {
|
||||
return null;
|
||||
}
|
||||
if (getGameCard().isFaceDown()) {
|
||||
return getFaceDownImage();
|
||||
} else {
|
||||
return ImageCache.getImageOriginal(getGameCard());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,38 +223,72 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
g.drawImage(cardImage, cardOffsetX, cardOffsetY, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the card to a new BufferedImage at it's current dimensions
|
||||
*
|
||||
* @return image
|
||||
*/
|
||||
private BufferedImage renderCard() {
|
||||
int cardWidth = getCardWidth();
|
||||
int cardHeight = getCardHeight();
|
||||
@Override
|
||||
public void setCardBounds(int x, int y, int cardWidth, int cardHeight) {
|
||||
int oldCardWidth = getCardWidth();
|
||||
int oldCardHeight = getCardHeight();
|
||||
|
||||
// Create image to render to
|
||||
BufferedImage image
|
||||
= GraphicsUtilities.createCompatibleTranslucentImage(cardWidth, cardHeight);
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
super.setCardBounds(x, y, cardWidth, cardHeight);
|
||||
|
||||
// Render with Antialialsing
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
|
||||
// Draw card itself
|
||||
cardRenderer.draw(g2d, getAttributes(), image);
|
||||
|
||||
// Done
|
||||
g2d.dispose();
|
||||
return image;
|
||||
// Rerender if card size changed
|
||||
if (getCardWidth() != oldCardWidth || getCardHeight() != oldCardHeight) {
|
||||
cardImage = null;
|
||||
}
|
||||
}
|
||||
|
||||
private CardPanelAttributes getAttributes() {
|
||||
return new CardPanelAttributes(getCardWidth(), getCardHeight(), isChoosable(), isSelected(), isTransformed());
|
||||
@Override
|
||||
public void setChoosable(boolean choosable) {
|
||||
if (choosable != isChoosable()) {
|
||||
super.setChoosable(choosable);
|
||||
// Invalidate our render and trigger a repaint
|
||||
cardImage = null;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
private int updateArtImageStamp;
|
||||
@Override
|
||||
public void setSelected(boolean selected) {
|
||||
if (selected != isSelected()) {
|
||||
super.setSelected(selected);
|
||||
// Invalidate our render and trigger a repaint
|
||||
cardImage = null;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCardTitle() {
|
||||
// Nothing to do, rendered cards always have a title
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transferResources(CardPanel panel) {
|
||||
if (panel instanceof CardPanelRenderModeMTGO) {
|
||||
CardPanelRenderModeMTGO impl = (CardPanelRenderModeMTGO) panel;
|
||||
|
||||
// Use the art image and current rendered image from the card
|
||||
artImage = impl.artImage;
|
||||
cardRenderer.setArtImage(artImage);
|
||||
faceArtImage = impl.faceArtImage;
|
||||
cardRenderer.setFaceArtImage(faceArtImage);
|
||||
cardImage = impl.cardImage;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(CardView card) {
|
||||
// Update super
|
||||
super.update(card);
|
||||
|
||||
// Update renderer
|
||||
cardImage = null;
|
||||
cardRenderer = cardRendererFactory.create(getGameCard());
|
||||
cardRenderer.setArtImage(artImage);
|
||||
cardRenderer.setFaceArtImage(faceArtImage);
|
||||
|
||||
// Repaint
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateArtImage() {
|
||||
|
@ -379,32 +348,8 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(CardView card) {
|
||||
// Update super
|
||||
super.update(card);
|
||||
|
||||
// Update renderer
|
||||
cardImage = null;
|
||||
cardRenderer = cardRendererFactory.create(getGameCard());
|
||||
cardRenderer.setArtImage(artImage);
|
||||
cardRenderer.setFaceArtImage(faceArtImage);
|
||||
|
||||
// Repaint
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCardBounds(int x, int y, int cardWidth, int cardHeight) {
|
||||
int oldCardWidth = getCardWidth();
|
||||
int oldCardHeight = getCardHeight();
|
||||
|
||||
super.setCardBounds(x, y, cardWidth, cardHeight);
|
||||
|
||||
// Rerender if card size changed
|
||||
if (getCardWidth() != oldCardWidth || getCardHeight() != oldCardHeight) {
|
||||
cardImage = null;
|
||||
}
|
||||
private CardPanelAttributes getAttributes() {
|
||||
return new CardPanelAttributes(getCardWidth(), getCardHeight(), isChoosable(), isSelected(), isTransformed());
|
||||
}
|
||||
|
||||
private BufferedImage getFaceDownImage() {
|
||||
|
@ -422,40 +367,30 @@ public class CardPanelRenderModeMTGO extends CardPanel {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(boolean selected) {
|
||||
if (selected != isSelected()) {
|
||||
super.setSelected(selected);
|
||||
// Invalidate our render and trigger a repaint
|
||||
cardImage = null;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Render the card to a new BufferedImage at it's current dimensions
|
||||
*
|
||||
* @return image
|
||||
*/
|
||||
private BufferedImage renderCard() {
|
||||
int cardWidth = getCardWidth();
|
||||
int cardHeight = getCardHeight();
|
||||
|
||||
@Override
|
||||
public void setChoosable(boolean choosable) {
|
||||
if (choosable != isChoosable()) {
|
||||
super.setChoosable(choosable);
|
||||
// Invalidate our render and trigger a repaint
|
||||
cardImage = null;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
// Create image to render to
|
||||
BufferedImage image
|
||||
= GraphicsUtilities.createCompatibleTranslucentImage(cardWidth, cardHeight);
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
|
||||
@Override
|
||||
public Image getImage() {
|
||||
if (artImage != null) {
|
||||
if (getGameCard().isFaceDown()) {
|
||||
return getFaceDownImage();
|
||||
} else {
|
||||
return ImageCache.getImageOriginal(getGameCard());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// Render with Antialialsing
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
|
||||
@Override
|
||||
public void showCardTitle() {
|
||||
// Nothing to do, rendered cards always have a title
|
||||
// Draw card itself
|
||||
cardRenderer.draw(g2d, getAttributes(), image);
|
||||
|
||||
// Done
|
||||
g2d.dispose();
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue