mirror of
https://github.com/correl/mage.git
synced 2025-04-06 17:00:12 -09:00
Merge pull request #4173 from JayDi85/new-card-render
Add new fallback card render with round corners
This commit is contained in:
commit
dce77f0800
10 changed files with 239 additions and 65 deletions
.gitignore
Mage.Client/src/main/java
mage/client
org/mage
card/arcane
plugins/card/images
Mage.Common/src/main/java/mage/cards
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,7 +4,7 @@ syntax: glob
|
||||||
Mage.Client/*.dck
|
Mage.Client/*.dck
|
||||||
Mage.Client/db
|
Mage.Client/db
|
||||||
Mage.Client/gamelogs
|
Mage.Client/gamelogs
|
||||||
Mage.Client/mageclient.log
|
Mage.Client/*.log
|
||||||
Mage.Client/plugins/images
|
Mage.Client/plugins/images
|
||||||
Mage.Client/plugins/plugin.data
|
Mage.Client/plugins/plugin.data
|
||||||
Mage.Client/target
|
Mage.Client/target
|
||||||
|
|
|
@ -562,7 +562,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTextOffset(int yOffset) {
|
public void setCardCaptionTopOffset(int yOffsetPercent) {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class CardArea extends JPanel implements MouseListener {
|
||||||
private boolean reloaded = false;
|
private boolean reloaded = false;
|
||||||
private final javax.swing.JLayeredPane cardArea;
|
private final javax.swing.JLayeredPane cardArea;
|
||||||
private final javax.swing.JScrollPane scrollPane;
|
private final javax.swing.JScrollPane scrollPane;
|
||||||
private int yTextOffset;
|
private int yCardCaptionOffsetPercent = 0; // card caption offset (use for moving card caption view center, below mana icons -- for more good UI)
|
||||||
private Dimension cardDimension;
|
private Dimension cardDimension;
|
||||||
private int verticalCardOffset;
|
private int verticalCardOffset;
|
||||||
|
|
||||||
|
@ -68,8 +68,6 @@ public class CardArea extends JPanel implements MouseListener {
|
||||||
setGUISize();
|
setGUISize();
|
||||||
cardArea = new JLayeredPane();
|
cardArea = new JLayeredPane();
|
||||||
scrollPane.setViewportView(cardArea);
|
scrollPane.setViewportView(cardArea);
|
||||||
yTextOffset = 10;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
|
@ -103,10 +101,10 @@ public class CardArea extends JPanel implements MouseListener {
|
||||||
this.reloaded = true;
|
this.reloaded = true;
|
||||||
cardArea.removeAll();
|
cardArea.removeAll();
|
||||||
if (showCards != null && showCards.size() < 10) {
|
if (showCards != null && showCards.size() < 10) {
|
||||||
yTextOffset = 10;
|
yCardCaptionOffsetPercent = 8; // TODO: need to test
|
||||||
loadCardsFew(showCards, bigCard, gameId);
|
loadCardsFew(showCards, bigCard, gameId);
|
||||||
} else {
|
} else {
|
||||||
yTextOffset = 0;
|
yCardCaptionOffsetPercent = 0;
|
||||||
loadCardsMany(showCards, bigCard, gameId);
|
loadCardsMany(showCards, bigCard, gameId);
|
||||||
}
|
}
|
||||||
cardArea.revalidate();
|
cardArea.revalidate();
|
||||||
|
@ -118,8 +116,10 @@ public class CardArea extends JPanel implements MouseListener {
|
||||||
public void loadCardsNarrow(CardsView showCards, BigCard bigCard, UUID gameId) {
|
public void loadCardsNarrow(CardsView showCards, BigCard bigCard, UUID gameId) {
|
||||||
this.reloaded = true;
|
this.reloaded = true;
|
||||||
cardArea.removeAll();
|
cardArea.removeAll();
|
||||||
yTextOffset = 0;
|
|
||||||
|
yCardCaptionOffsetPercent = 0; // TODO: need to test
|
||||||
loadCardsMany(showCards, bigCard, gameId);
|
loadCardsMany(showCards, bigCard, gameId);
|
||||||
|
|
||||||
cardArea.revalidate();
|
cardArea.revalidate();
|
||||||
|
|
||||||
this.revalidate();
|
this.revalidate();
|
||||||
|
@ -152,7 +152,10 @@ public class CardArea extends JPanel implements MouseListener {
|
||||||
cardArea.moveToFront(cardPanel);
|
cardArea.moveToFront(cardPanel);
|
||||||
cardPanel.update(card);
|
cardPanel.update(card);
|
||||||
cardPanel.setCardBounds(rectangle.x, rectangle.y, cardDimension.width, cardDimension.height);
|
cardPanel.setCardBounds(rectangle.x, rectangle.y, cardDimension.width, cardDimension.height);
|
||||||
cardPanel.setTextOffset(yTextOffset);
|
|
||||||
|
// new card have same settings as current view
|
||||||
|
cardPanel.setCardCaptionTopOffset(yCardCaptionOffsetPercent);
|
||||||
|
|
||||||
cardPanel.showCardTitle();
|
cardPanel.showCardTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1726,7 +1726,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
|
||||||
// Create the card view
|
// Create the card view
|
||||||
final MageCard cardPanel = Plugins.instance.getMageCard(card, lastBigCard, new Dimension(getCardWidth(), getCardHeight()), null, true, true);
|
final MageCard cardPanel = Plugins.instance.getMageCard(card, lastBigCard, new Dimension(getCardWidth(), getCardHeight()), null, true, true);
|
||||||
cardPanel.update(card);
|
cardPanel.update(card);
|
||||||
cardPanel.setTextOffset(0);
|
cardPanel.setCardCaptionTopOffset(0);
|
||||||
|
|
||||||
// Remove mouse wheel listeners so that scrolling works
|
// Remove mouse wheel listeners so that scrolling works
|
||||||
// Scrolling works on all areas without cards or by using the scroll bar, that's enough
|
// Scrolling works on all areas without cards or by using the scroll bar, that's enough
|
||||||
|
|
|
@ -236,6 +236,7 @@ public class MageBook extends JComponent {
|
||||||
for (int i = 0; i < Math.min(conf.CARDS_PER_PAGE / 2, size); i++) {
|
for (int i = 0; i < Math.min(conf.CARDS_PER_PAGE / 2, size); i++) {
|
||||||
Card card = cards.get(i).getMockCard();
|
Card card = cards.get(i).getMockCard();
|
||||||
addCard(new CardView(card), bigCard, null, rectangle);
|
addCard(new CardView(card), bigCard, null, rectangle);
|
||||||
|
|
||||||
rectangle = CardPosition.translatePosition(i, rectangle, conf);
|
rectangle = CardPosition.translatePosition(i, rectangle, conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +342,8 @@ public class MageBook extends JComponent {
|
||||||
cardImg.update(card);
|
cardImg.update(card);
|
||||||
cardImg.setCardBounds(rectangle.x, rectangle.y, cardDimensions.frameWidth, cardDimensions.frameHeight);
|
cardImg.setCardBounds(rectangle.x, rectangle.y, cardDimensions.frameWidth, cardDimensions.frameHeight);
|
||||||
|
|
||||||
|
cardImg.setCardCaptionTopOffset(8); // card caption below real card caption to see full name even with mana icons
|
||||||
|
|
||||||
boolean implemented = card.getRarity() != Rarity.NA;
|
boolean implemented = card.getRarity() != Rarity.NA;
|
||||||
|
|
||||||
GlowText label = new GlowText();
|
GlowText label = new GlowText();
|
||||||
|
|
|
@ -91,7 +91,8 @@ public abstract class CardPanel extends MagePermanent implements MouseListener,
|
||||||
|
|
||||||
private JPanel cardArea;
|
private JPanel cardArea;
|
||||||
|
|
||||||
private int yTextOffset = 10;
|
// default offset, e.g. for battlefield
|
||||||
|
private int yCardCaptionOffsetPercent = 8; // card caption offset (use for moving card caption view center, below mana icons -- for more good UI)
|
||||||
|
|
||||||
// if this is set, it's opened if the user right clicks on the card panel
|
// if this is set, it's opened if the user right clicks on the card panel
|
||||||
private JPopupMenu popupMenu;
|
private JPopupMenu popupMenu;
|
||||||
|
@ -819,12 +820,12 @@ public abstract class CardPanel extends MagePermanent implements MouseListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTextOffset(int yOffset) {
|
public void setCardCaptionTopOffset(int yOffsetPercent) {
|
||||||
yTextOffset = yOffset;
|
yCardCaptionOffsetPercent = yOffsetPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTextOffset() {
|
public int getCardCaptionTopOffset() {
|
||||||
return yTextOffset;
|
return yCardCaptionOffsetPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -34,7 +34,7 @@ import static org.mage.plugins.card.constants.Constants.THUMBNAIL_SIZE_FULL;
|
||||||
* Class for drawing the mage card object by using a form based JComponent
|
* Class for drawing the mage card object by using a form based JComponent
|
||||||
* approach
|
* approach
|
||||||
*
|
*
|
||||||
* @author arcane, nantuko, noxx, stravant
|
* @author arcane, nantuko, noxx, stravant, JayDi85
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public class CardPanelComponentImpl extends CardPanel {
|
public class CardPanelComponentImpl extends CardPanel {
|
||||||
|
@ -47,9 +47,14 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
|
|
||||||
private static final float ROUNDED_CORNER_SIZE = 0.1f;
|
private static final float ROUNDED_CORNER_SIZE = 0.1f;
|
||||||
private static final float BLACK_BORDER_SIZE = 0.03f;
|
private static final float BLACK_BORDER_SIZE = 0.03f;
|
||||||
|
private static final float SELECTION_BORDER_SIZE = 0.03f;
|
||||||
private static final int TEXT_GLOW_SIZE = 6;
|
private static final int TEXT_GLOW_SIZE = 6;
|
||||||
private static final float TEXT_GLOW_INTENSITY = 3f;
|
private static final float TEXT_GLOW_INTENSITY = 3f;
|
||||||
|
|
||||||
|
// size to show icons and text (help to see full size card without text)
|
||||||
|
private static final int CARD_MIN_SIZE_FOR_ICONS = 60;
|
||||||
|
private static final int CARD_MAX_SIZE_FOR_ICONS = 200;
|
||||||
|
|
||||||
public final ScaledImagePanel imagePanel;
|
public final ScaledImagePanel imagePanel;
|
||||||
public ImagePanel overlayPanel;
|
public ImagePanel overlayPanel;
|
||||||
|
|
||||||
|
@ -177,6 +182,34 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap((Function<Key, BufferedImage>) key -> createImage(key)));
|
IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap((Function<Key, BufferedImage>) key -> createImage(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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{
|
||||||
|
Rectangle rectFull;
|
||||||
|
Rectangle rectSelection;
|
||||||
|
Rectangle rectBorder;
|
||||||
|
Rectangle rectCard;
|
||||||
|
|
||||||
|
CardSizes(int offsetX, int offsetY, int fullWidth, int fullHeight){
|
||||||
|
|
||||||
|
int realBorderSizeX = Math.round(fullWidth * BLACK_BORDER_SIZE);
|
||||||
|
int realBorderSizeY = Math.round(fullWidth * BLACK_BORDER_SIZE);
|
||||||
|
int realSelectionSizeX = Math.round(fullWidth * SELECTION_BORDER_SIZE);
|
||||||
|
int realSelectionSizeY = Math.round(fullWidth * SELECTION_BORDER_SIZE);
|
||||||
|
|
||||||
|
// card full size = select border + black border + real card
|
||||||
|
rectFull = new Rectangle(offsetX, offsetY, fullWidth, fullHeight);
|
||||||
|
rectSelection = new Rectangle(rectFull.x, rectFull.y, rectFull.width, rectFull.height);
|
||||||
|
rectBorder = new Rectangle(rectSelection.x + realSelectionSizeX, rectSelection.y + realSelectionSizeY, rectSelection.width - 2 * realSelectionSizeX, rectSelection.height - 2 * realSelectionSizeY);
|
||||||
|
rectCard = new Rectangle(rectBorder.x + realBorderSizeX, rectBorder.y + realBorderSizeY, rectBorder.width - 2 * realBorderSizeX, rectBorder.height - 2 * realBorderSizeY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public CardPanelComponentImpl(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension) {
|
public CardPanelComponentImpl(CardView newGameCard, UUID gameId, final boolean loadImage, ActionCallback callback, final boolean foil, Dimension dimension) {
|
||||||
// Call to super
|
// Call to super
|
||||||
super(newGameCard, gameId, loadImage, callback, foil, dimension);
|
super(newGameCard, gameId, loadImage, callback, foil, dimension);
|
||||||
|
@ -368,32 +401,45 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
Graphics2D g2d = image.createGraphics();
|
Graphics2D g2d = image.createGraphics();
|
||||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
if (!key.hasImage) {
|
// card full size = select border + black border + real card
|
||||||
g2d.setColor(new Color(30, 200, 200, 120));
|
CardSizes sizes = new CardSizes(cardXOffset, cardYOffset, cardWidth, cardHeight);
|
||||||
} else {
|
|
||||||
g2d.setColor(new Color(0, 0, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
int cornerSize = Math.max(4, Math.round(cardWidth * ROUNDED_CORNER_SIZE));
|
// corners for selection and for border
|
||||||
g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize);
|
int cornerSizeSelection = Math.max(4, Math.round(sizes.rectSelection.width * ROUNDED_CORNER_SIZE));
|
||||||
|
int cornerSizeBorder = Math.max(4, Math.round(sizes.rectBorder.width * ROUNDED_CORNER_SIZE));
|
||||||
|
|
||||||
|
// DRAW ORDER from big to small: select -> select info -> border -> card
|
||||||
|
|
||||||
|
// draw selection
|
||||||
if (key.isSelected) {
|
if (key.isSelected) {
|
||||||
g2d.setColor(Color.green);
|
g2d.setColor(Color.green);
|
||||||
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
g2d.fillRoundRect(sizes.rectSelection.x + 1, sizes.rectSelection.y + 1, sizes.rectSelection.width - 2, sizes.rectSelection.height - 2, cornerSizeSelection, cornerSizeSelection);
|
||||||
} else if (key.isChoosable) {
|
} else if (key.isChoosable) {
|
||||||
g2d.setColor(new Color(250, 250, 0, 230));
|
g2d.setColor(new Color(250, 250, 0, 230));
|
||||||
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
g2d.fillRoundRect(sizes.rectSelection.x + 1, sizes.rectSelection.y + 1, sizes.rectSelection.width - 2, sizes.rectSelection.height - 2, cornerSizeSelection, cornerSizeSelection);
|
||||||
} else if (key.isPlayable) {
|
} else if (key.isPlayable) {
|
||||||
g2d.setColor(new Color(153, 102, 204, 200));
|
g2d.setColor(new Color(153, 102, 204, 200));
|
||||||
//g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
g2d.fillRoundRect(sizes.rectSelection.x, sizes.rectSelection.y, sizes.rectSelection.width, sizes.rectSelection.height, cornerSizeSelection, cornerSizeSelection);
|
||||||
g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw empty card with border
|
||||||
|
if (!key.hasImage) {
|
||||||
|
// gray 1 px border
|
||||||
|
g2d.setColor(new Color(125, 125, 125, 255));
|
||||||
|
g2d.fillRoundRect(sizes.rectBorder.x, sizes.rectBorder.y, sizes.rectBorder.width, sizes.rectBorder.height, cornerSizeBorder, cornerSizeBorder);
|
||||||
|
// color plate
|
||||||
|
g2d.setColor(new Color(30, 200, 200, 200));
|
||||||
|
g2d.fillRoundRect(sizes.rectBorder.x + 1, sizes.rectBorder.y + 1, sizes.rectBorder.width - 2, sizes.rectBorder.height - 2, cornerSizeBorder, cornerSizeBorder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw attack border (inner part of selection)
|
||||||
if (key.canAttack) {
|
if (key.canAttack) {
|
||||||
g2d.setColor(new Color(0, 0, 255, 230));
|
g2d.setColor(new Color(0, 0, 255, 230));
|
||||||
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
|
g2d.fillRoundRect(sizes.rectBorder.x + 1, sizes.rectBorder.y + 1, sizes.rectBorder.width - 2, sizes.rectBorder.height - 2, cornerSizeBorder, cornerSizeBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw real card by component (see imagePanel and other layout's items)
|
||||||
|
|
||||||
//TODO:uncomment
|
//TODO:uncomment
|
||||||
/*
|
/*
|
||||||
if (gameCard.isAttacking()) {
|
if (gameCard.isAttacking()) {
|
||||||
|
@ -409,18 +455,54 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
protected void paintChildren(Graphics g) {
|
protected void paintChildren(Graphics g) {
|
||||||
super.paintChildren(g);
|
super.paintChildren(g);
|
||||||
|
|
||||||
if (getShowCastingCost() && !isAnimationPanel() && getCardWidth() < 200 && getCardWidth() > 60) {
|
CardSizes realCard = new CardSizes(getCardXOffset(), getCardYOffset(), getCardWidth(), getCardHeight());
|
||||||
|
|
||||||
|
/*
|
||||||
|
// draw recs for debug
|
||||||
|
|
||||||
|
// 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)) {
|
||||||
|
|
||||||
String manaCost = ManaSymbols.getStringManaCost(gameCard.getManaCost());
|
String manaCost = ManaSymbols.getStringManaCost(gameCard.getManaCost());
|
||||||
int width = getWidth(manaCost);
|
int manaWidth = getManaWidth(manaCost);
|
||||||
|
|
||||||
|
// 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 manaX = getCardXOffset() + getCardWidth() - manaMarginRight - manaWidth;
|
||||||
|
int manaY = getCardYOffset() + manaMarginTop;
|
||||||
|
|
||||||
if (hasImage) {
|
if (hasImage) {
|
||||||
ManaSymbols.draw(g, manaCost, getCardXOffset() + getCardWidth() - width - 5, getCardYOffset() + 5, getSymbolWidth());
|
// top right corner if have image like real card
|
||||||
|
ManaSymbols.draw(g, manaCost, manaX, manaY, getSymbolWidth());
|
||||||
} else {
|
} else {
|
||||||
ManaSymbols.draw(g, manaCost, getCardXOffset() + 8, getCardHeight() - 9, getSymbolWidth());
|
// old version - bottom left corner if haven't card
|
||||||
|
// ManaSymbols.draw(g, manaCost, getCardXOffset() + manaMarginRight, getCardYOffset() + getCardHeight() - manaMarginTop - getSymbolWidth(), getSymbolWidth());
|
||||||
|
|
||||||
|
// new version - like a normal image (it's best to view and construct decks)
|
||||||
|
ManaSymbols.draw(g, manaCost, manaX, manaY, getSymbolWidth());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getWidth(String manaCost) {
|
private int getManaWidth(String manaCost) {
|
||||||
int width = 0;
|
int width = 0;
|
||||||
manaCost = manaCost.replace("\\", "");
|
manaCost = manaCost.replace("\\", "");
|
||||||
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
StringTokenizer tok = new StringTokenizer(manaCost, " ");
|
||||||
|
@ -439,24 +521,28 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
int cardHeight = getCardHeight();
|
int cardHeight = getCardHeight();
|
||||||
int cardXOffset = getCardXOffset();
|
int cardXOffset = getCardXOffset();
|
||||||
int cardYOffset = getCardYOffset();
|
int cardYOffset = getCardYOffset();
|
||||||
int borderSize = Math.round(cardWidth * BLACK_BORDER_SIZE);
|
|
||||||
imagePanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize);
|
CardSizes sizes = new CardSizes(cardXOffset, cardYOffset, cardWidth, cardHeight);
|
||||||
imagePanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2);
|
|
||||||
|
// origin card without selection
|
||||||
|
Rectangle realCardSize = sizes.rectBorder;
|
||||||
|
imagePanel.setLocation(realCardSize.x, realCardSize.y);
|
||||||
|
imagePanel.setSize(realCardSize.width, realCardSize.height);
|
||||||
|
|
||||||
if (hasSickness() && gameCard.isCreature() && isPermanent()) {
|
if (hasSickness() && gameCard.isCreature() && isPermanent()) {
|
||||||
overlayPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize);
|
overlayPanel.setLocation(realCardSize.x, realCardSize.y);
|
||||||
overlayPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2);
|
overlayPanel.setSize(realCardSize.width, realCardSize.height);
|
||||||
} else {
|
} else {
|
||||||
overlayPanel.setVisible(false);
|
overlayPanel.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iconPanel != null) {
|
if (iconPanel != null) {
|
||||||
iconPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize);
|
iconPanel.setLocation(realCardSize.x, realCardSize.y);
|
||||||
iconPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2);
|
iconPanel.setSize(realCardSize.width, realCardSize.height);
|
||||||
}
|
}
|
||||||
if (counterPanel != null) {
|
if (counterPanel != null) {
|
||||||
counterPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize);
|
counterPanel.setLocation(realCardSize.x, realCardSize.y);
|
||||||
counterPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2);
|
counterPanel.setSize(realCardSize.width, realCardSize.height);
|
||||||
int size = cardWidth > WIDTH_LIMIT ? 40 : 20;
|
int size = cardWidth > WIDTH_LIMIT ? 40 : 20;
|
||||||
|
|
||||||
minusCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size * 2);
|
minusCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size * 2);
|
||||||
|
@ -472,32 +558,52 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
otherCounterLabel.setSize(size, size);
|
otherCounterLabel.setSize(size, size);
|
||||||
|
|
||||||
}
|
}
|
||||||
int fontHeight = Math.round(cardHeight * (27f / 680));
|
|
||||||
boolean showText = (!isAnimationPanel() && fontHeight < 12);
|
// TITLE
|
||||||
|
|
||||||
|
//old version - text hide on small fonts, why?
|
||||||
|
//int fontHeight = Math.round(cardHeight * (26f / 672));
|
||||||
|
//boolean showText = (!isAnimationPanel() && fontHeight < 12);
|
||||||
|
|
||||||
|
boolean showText = !isAnimationPanel() && canShowCardIcons(cardWidth, hasImage);
|
||||||
titleText.setVisible(showText);
|
titleText.setVisible(showText);
|
||||||
ptText.setVisible(showText);
|
ptText.setVisible(showText);
|
||||||
fullImageText.setVisible(fullImagePath != null);
|
fullImageText.setVisible(fullImagePath != null);
|
||||||
|
|
||||||
if (showText) {
|
if (showText) {
|
||||||
int fontSize = cardHeight / 11;
|
int fontSize = cardHeight / 13; // startup font size (it same size on all zoom levels)
|
||||||
titleText.setFont(getFont().deriveFont(Font.BOLD, fontSize));
|
titleText.setFont(getFont().deriveFont(Font.BOLD, fontSize));
|
||||||
|
|
||||||
int titleX = Math.round(cardWidth * (20f / 480));
|
// margins from card black border to text, not need? text show up good without margins
|
||||||
int titleY = Math.round(cardHeight * (9f / 680)) + getTextOffset();
|
int titleMarginLeft = 0; //Math.round(28f / 672f * cardWidth);
|
||||||
titleText.setBounds(cardXOffset + titleX, cardYOffset + titleY, cardWidth - titleX, cardHeight - titleY);
|
int titleMarginRight = 0;
|
||||||
|
int titleMarginTop = 0 + Math.round(getCardCaptionTopOffset() / 100f * cardHeight);//Math.round(28f / 936f * cardHeight);
|
||||||
|
int titleMarginBottom = 0;
|
||||||
|
titleText.setBounds(
|
||||||
|
imagePanel.getX() + titleMarginLeft,
|
||||||
|
imagePanel.getY() + titleMarginTop,
|
||||||
|
imagePanel.getBounds().width - titleMarginLeft - titleMarginRight,
|
||||||
|
imagePanel.getBounds().height - titleMarginTop - titleMarginBottom
|
||||||
|
);
|
||||||
|
|
||||||
fullImageText.setFont(getFont().deriveFont(Font.PLAIN, 10));
|
fullImageText.setFont(getFont().deriveFont(Font.PLAIN, 10));
|
||||||
fullImageText.setBounds(cardXOffset, cardYOffset + titleY, cardWidth, cardHeight - titleY);
|
fullImageText.setBounds(titleText.getX(), titleText.getY(), titleText.getBounds().width, titleText.getBounds().height);
|
||||||
|
|
||||||
|
// life points location (font as title)
|
||||||
ptText.setFont(getFont().deriveFont(Font.BOLD, fontSize));
|
ptText.setFont(getFont().deriveFont(Font.BOLD, fontSize));
|
||||||
Dimension ptSize = ptText.getPreferredSize();
|
Dimension ptSize = ptText.getPreferredSize();
|
||||||
ptText.setSize(ptSize.width, ptSize.height);
|
ptText.setSize(ptSize.width, ptSize.height);
|
||||||
int ptX = Math.round(cardWidth * (420f / 480)) - ptSize.width / 2;
|
|
||||||
int ptY = Math.round(cardHeight * (675f / 680)) - ptSize.height;
|
|
||||||
|
|
||||||
int offsetX = Math.round((CARD_SIZE_FULL.width - cardWidth) / 10.0f);
|
// right bottom corner with margin (sizes from any sample card)
|
||||||
|
int ptMarginRight = Math.round(64f / 672f * cardWidth);
|
||||||
|
int ptMarginBottom = Math.round(62f / 936f * cardHeight);
|
||||||
|
|
||||||
ptText.setLocation(cardXOffset + ptX - TEXT_GLOW_SIZE / 2 - offsetX, cardYOffset + ptY - TEXT_GLOW_SIZE / 2);
|
int ptX = cardXOffset + cardWidth - ptMarginRight - ptSize.width;
|
||||||
|
int ptY = cardYOffset + cardHeight - ptMarginBottom - ptSize.height;
|
||||||
|
ptText.setLocation(ptX, ptY);
|
||||||
|
|
||||||
|
// old version was with TEXT_GLOW_SIZE
|
||||||
|
//ptText.setLocation(cardXOffset + ptX - TEXT_GLOW_SIZE / 2 - offsetX, cardYOffset + ptY - TEXT_GLOW_SIZE / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,7 +687,7 @@ public class CardPanelComponentImpl extends CardPanel {
|
||||||
} else if (this.gameCard instanceof StackAbilityView) {
|
} else if (this.gameCard instanceof StackAbilityView) {
|
||||||
return ImageCache.getMorphImage();
|
return ImageCache.getMorphImage();
|
||||||
} else {
|
} else {
|
||||||
return ImageCache.loadImage(new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename));
|
return ImageCache.getCardbackImage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -410,7 +410,7 @@ public class CardPanelRenderImpl extends CardPanel {
|
||||||
} else if (this.gameCard instanceof StackAbilityView) {
|
} else if (this.gameCard instanceof StackAbilityView) {
|
||||||
return ImageCache.getMorphImage();
|
return ImageCache.getMorphImage();
|
||||||
} else {
|
} else {
|
||||||
return ImageCache.loadImage(new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename));
|
return ImageCache.getCardbackImage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@ package org.mage.plugins.card.images;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ComputationException;
|
import com.google.common.collect.ComputationException;
|
||||||
import com.google.common.collect.MapMaker;
|
import com.google.common.collect.MapMaker;
|
||||||
import java.awt.Graphics2D;
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -82,12 +84,14 @@ public final class ImageCache {
|
||||||
|
|
||||||
CardDownloadData info = new CardDownloadData(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor);
|
CardDownloadData info = new CardDownloadData(name, set, collectorId, usesVariousArt, type, tokenSetCode, tokenDescriptor);
|
||||||
|
|
||||||
|
boolean cardback = false;
|
||||||
String path;
|
String path;
|
||||||
if (collectorId.isEmpty() || "0".equals(collectorId)) {
|
if (collectorId.isEmpty() || "0".equals(collectorId)) {
|
||||||
info.setToken(true);
|
info.setToken(true);
|
||||||
path = CardImageUtils.generateTokenImagePath(info);
|
path = CardImageUtils.generateTokenImagePath(info);
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
path = DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename;
|
cardback = true;
|
||||||
|
path = DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename; // TODO: replace empty token by other default card, not cardback
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
path = CardImageUtils.generateImagePath(info);
|
path = CardImageUtils.generateImagePath(info);
|
||||||
|
@ -102,6 +106,7 @@ public final class ImageCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thumbnail && path.endsWith(".jpg")) {
|
if (thumbnail && path.endsWith(".jpg")) {
|
||||||
|
// need thumbnail image
|
||||||
String thumbnailPath = buildThumbnailPath(path);
|
String thumbnailPath = buildThumbnailPath(path);
|
||||||
TFile thumbnailFile = null;
|
TFile thumbnailFile = null;
|
||||||
try {
|
try {
|
||||||
|
@ -119,19 +124,35 @@ public final class ImageCache {
|
||||||
if (exists) {
|
if (exists) {
|
||||||
LOGGER.debug("loading thumbnail for " + key + ", path=" + thumbnailPath);
|
LOGGER.debug("loading thumbnail for " + key + ", path=" + thumbnailPath);
|
||||||
BufferedImage thumbnailImage = loadImage(thumbnailFile);
|
BufferedImage thumbnailImage = loadImage(thumbnailFile);
|
||||||
|
|
||||||
if (thumbnailImage == null) { // thumbnail exists but broken for some reason
|
if (thumbnailImage == null) { // thumbnail exists but broken for some reason
|
||||||
LOGGER.warn("failed loading thumbnail for " + key + ", path=" + thumbnailPath
|
LOGGER.warn("failed loading thumbnail for " + key + ", path=" + thumbnailPath
|
||||||
+ ", thumbnail file is probably broken, attempting to recreate it...");
|
+ ", thumbnail file is probably broken, attempting to recreate it...");
|
||||||
thumbnailImage = makeThumbnailByFile(key, file, thumbnailPath);
|
thumbnailImage = makeThumbnailByFile(key, file, thumbnailPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cardback){
|
||||||
|
// unknown tokens on opponent desk
|
||||||
|
thumbnailImage = getRoundCorner(thumbnailImage);
|
||||||
|
}
|
||||||
|
|
||||||
return thumbnailImage;
|
return thumbnailImage;
|
||||||
} else {
|
} else {
|
||||||
return makeThumbnailByFile(key, file, thumbnailPath);
|
return makeThumbnailByFile(key, file, thumbnailPath);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
BufferedImage image = loadImage(file);
|
if (cardback){
|
||||||
image = getWizardsCard(image);
|
// need cardback image
|
||||||
return image;
|
BufferedImage image = loadImage(file);
|
||||||
|
image = getRoundCorner(image);
|
||||||
|
return image;
|
||||||
|
}else {
|
||||||
|
// need normal card image
|
||||||
|
BufferedImage image = loadImage(file);
|
||||||
|
image = getWizardsCard(image);
|
||||||
|
image = getRoundCorner(image);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
|
@ -149,6 +170,7 @@ public final class ImageCache {
|
||||||
public BufferedImage makeThumbnailByFile(String key, TFile file, String thumbnailPath) {
|
public BufferedImage makeThumbnailByFile(String key, TFile file, String thumbnailPath) {
|
||||||
BufferedImage image = loadImage(file);
|
BufferedImage image = loadImage(file);
|
||||||
image = getWizardsCard(image);
|
image = getWizardsCard(image);
|
||||||
|
image = getRoundCorner(image);
|
||||||
if (image == null) {
|
if (image == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +261,7 @@ public final class ImageCache {
|
||||||
info.setToken(true);
|
info.setToken(true);
|
||||||
path = CardImageUtils.generateFullTokenImagePath(info);
|
path = CardImageUtils.generateFullTokenImagePath(info);
|
||||||
if (path == null) {
|
if (path == null) {
|
||||||
path = DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename;
|
path = DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename; // TODO: replace empty token by other default card, not cardback
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
path = CardImageUtils.generateImagePath(info);
|
path = CardImageUtils.generateImagePath(info);
|
||||||
|
@ -257,6 +279,12 @@ public final class ImageCache {
|
||||||
private ImageCache() {
|
private ImageCache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BufferedImage getCardbackImage() {
|
||||||
|
BufferedImage image = ImageCache.loadImage(new TFile(DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename));
|
||||||
|
image = getRoundCorner(image);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
public static BufferedImage getMorphImage() {
|
public static BufferedImage getMorphImage() {
|
||||||
CardDownloadData info = new CardDownloadData("Morph", "KTK", "0", false, 0, "KTK", "");
|
CardDownloadData info = new CardDownloadData("Morph", "KTK", "0", false, 0, "KTK", "");
|
||||||
info.setToken(true);
|
info.setToken(true);
|
||||||
|
@ -265,7 +293,10 @@ public final class ImageCache {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
TFile file = getTFile(path);
|
TFile file = getTFile(path);
|
||||||
return loadImage(file);
|
|
||||||
|
BufferedImage image = loadImage(file);
|
||||||
|
image = getRoundCorner(image);
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BufferedImage getManifestImage() {
|
public static BufferedImage getManifestImage() {
|
||||||
|
@ -276,7 +307,10 @@ public final class ImageCache {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
TFile file = getTFile(path);
|
TFile file = getTFile(path);
|
||||||
return loadImage(file);
|
|
||||||
|
BufferedImage image = loadImage(file);
|
||||||
|
image = getRoundCorner(image);
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String buildThumbnailPath(String path) {
|
private static String buildThumbnailPath(String path) {
|
||||||
|
@ -289,6 +323,32 @@ public final class ImageCache {
|
||||||
return thumbnailPath;
|
return thumbnailPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BufferedImage getRoundCorner(BufferedImage image){
|
||||||
|
if (image != null) {
|
||||||
|
BufferedImage cornerImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
|
||||||
|
// corner
|
||||||
|
float ROUNDED_CORNER_SIZE = 0.15f; // see CardPanelComponentImpl
|
||||||
|
int cornerSizeBorder = Math.max(4, Math.round(image.getWidth() * ROUNDED_CORNER_SIZE));
|
||||||
|
|
||||||
|
// corner mask
|
||||||
|
Graphics2D gg = cornerImage.createGraphics();
|
||||||
|
gg.setComposite(AlphaComposite.Src);
|
||||||
|
gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
gg.setColor(Color.white);
|
||||||
|
gg.fill(new RoundRectangle2D.Float(0, 0, cornerImage.getWidth(), cornerImage.getHeight(), cornerSizeBorder, cornerSizeBorder));
|
||||||
|
|
||||||
|
// image draw to buffer
|
||||||
|
gg.setComposite(AlphaComposite.SrcAtop);
|
||||||
|
gg.drawImage(image, 0, 0, null);
|
||||||
|
//gg.dispose();
|
||||||
|
|
||||||
|
return cornerImage;
|
||||||
|
} else {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static BufferedImage getWizardsCard(BufferedImage image) {
|
public static BufferedImage getWizardsCard(BufferedImage image) {
|
||||||
if (image != null && image.getWidth() == 265 && image.getHeight() == 370) {
|
if (image != null && image.getWidth() == 265 && image.getHeight() == 370) {
|
||||||
BufferedImage crop = new BufferedImage(256, 360, BufferedImage.TYPE_INT_RGB);
|
BufferedImage crop = new BufferedImage(256, 360, BufferedImage.TYPE_INT_RGB);
|
||||||
|
@ -404,6 +464,7 @@ public final class ImageCache {
|
||||||
// return alternateName + "#" + card.getExpansionSetCode() + "#" +card.getType()+ "#" + card.getCardNumber() + "#"
|
// return alternateName + "#" + card.getExpansionSetCode() + "#" +card.getType()+ "#" + card.getCardNumber() + "#"
|
||||||
// + (card.getTokenSetCode() == null ? "":card.getTokenSetCode());
|
// + (card.getTokenSetCode() == null ? "":card.getTokenSetCode());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load image from file
|
* Load image from file
|
||||||
*
|
*
|
||||||
|
|
|
@ -25,8 +25,8 @@ public abstract class MageCard extends JPanel {
|
||||||
|
|
||||||
public abstract CardView getOriginal();
|
public abstract CardView getOriginal();
|
||||||
|
|
||||||
// sets the vertical text offset for the card name on the image
|
// sets the vertical text offset for the card name on the image, use to move caption to card center
|
||||||
public abstract void setTextOffset(int yOffset);
|
public abstract void setCardCaptionTopOffset(int yOffsetPercent);
|
||||||
|
|
||||||
public abstract void setCardBounds(int x, int y, int width, int height);
|
public abstract void setCardBounds(int x, int y, int width, int height);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue