From d9a1cc13342c7458d9ebd9af4d764da1c00e3615 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 22 Aug 2014 02:38:10 +0200 Subject: [PATCH] Added display of counters on card panel (needs probably some more fine adjusting and testing). --- .../java/org/mage/card/arcane/CardPanel.java | 202 ++++++++++++++---- .../mage/plugins/card/utils/ImageManager.java | 5 +- .../card/utils/impl/ImageManagerImpl.java | 65 ++++-- .../src/main/resources/card/counter_grey.png | Bin 0 -> 1613 bytes .../src/main/resources/card/counter_red.png | Bin 0 -> 1512 bytes .../main/resources/card/counter_violet.png | Bin 0 -> 1529 bytes 6 files changed, 219 insertions(+), 53 deletions(-) create mode 100644 Mage.Client/src/main/resources/card/counter_grey.png create mode 100644 Mage.Client/src/main/resources/card/counter_red.png create mode 100644 Mage.Client/src/main/resources/card/counter_violet.png diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java index 7a1adcec5b8..3358fbefb97 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/CardPanel.java @@ -1,12 +1,40 @@ package org.mage.card.arcane; import de.schlichtherle.truezip.file.TFile; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; import mage.cards.MagePermanent; import mage.cards.TextPopup; import mage.cards.action.ActionCallback; import mage.cards.action.TransferData; import mage.client.plugins.adapters.MageActionCallback; import mage.client.plugins.impl.Plugins; +import mage.client.util.ImageHelper; import mage.client.util.audio.AudioManager; import mage.components.ImagePanel; import mage.constants.AbilityType; @@ -15,6 +43,7 @@ import mage.constants.EnlargeMode; import mage.utils.CardUtil; import mage.view.AbilityView; import mage.view.CardView; +import mage.view.CounterView; import mage.view.PermanentView; import mage.view.StackAbilityView; import org.apache.log4j.Logger; @@ -24,16 +53,6 @@ import org.mage.plugins.card.dl.sources.DirectLinksForDownload; import org.mage.plugins.card.images.ImageCache; import org.mage.plugins.card.utils.impl.ImageManagerImpl; -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.image.BufferedImage; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import mage.view.CounterView; - /** * Main class for drawing Mage card object. * @@ -45,6 +64,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti private static final Logger log = Logger.getLogger(CardPanel.class); + private static final int WIDTH_LIMIT = 90; // card width limit to create smaller counter public static final double TAPPED_ANGLE = Math.PI / 2; public static final double FLIPPED_ANGLE = Math.PI; public static final float ASPECT_RATIO = 3.5f / 2.5f; @@ -71,11 +91,27 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti public double flippedAngle = 0; public final ScaledImagePanel imagePanel; public ImagePanel overlayPanel; + public JPanel buttonPanel; - public JPanel iconPanel; + private JButton dayNightButton; + public JPanel copyIconPanel; - public JLabel counterLabel; + private JButton showCopySourceButton; + public JPanel iconPanel; + private JButton typeButton; + + public JPanel counterPanel; + private JLabel loyaltyCounterLabel; + private JLabel plusCounterLabel; + private JLabel otherCounterLabel; + private JLabel minusCounterLabel; + private int loyaltyCounter; + private int plusCounter; + private int otherCounter; + private int minusCounter; + private int lastCardWidth; + private GlowText titleText; private GlowText ptText; private boolean displayEnabled = true; @@ -106,10 +142,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti private boolean transformed; private boolean animationInProgress = false; - private JButton dayNightButton; - private JButton typeButton; - private JButton showCopySourceButton; - private boolean displayTitleAnyway; private JPanel cardArea; @@ -159,6 +191,29 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti }); } + // 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); + if (newGameCard.isAbility()) { if (AbilityType.TRIGGERED.equals(newGameCard.getAbilityType())) { setTypeIcon(ImageManagerImpl.getInstance().getTriggeredAbilityImage(),"Triggered Ability"); @@ -308,7 +363,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti // this holds reference to ActionCallback forever so set it to null to prevent this.callback = null; this.data = null; - this.counterLabel = null; + this.counterPanel = null; } private void setText(CardView card) { @@ -495,6 +550,26 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti if (copyIconPanel != null) { copyIconPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); copyIconPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); + } + if (counterPanel != null) { + counterPanel.setLocation(cardXOffset + borderSize, cardYOffset + borderSize); + counterPanel.setSize(cardWidth - borderSize * 2, cardHeight - borderSize * 2); + int size = cardWidth > WIDTH_LIMIT ? 40: 20; + + + minusCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size * 2); + minusCounterLabel.setSize(size, size); + + plusCounterLabel.setLocation(5, counterPanel.getHeight() - size * 2); + plusCounterLabel.setSize(size, size); + + loyaltyCounterLabel.setLocation(counterPanel.getWidth() - size, counterPanel.getHeight() - size); + loyaltyCounterLabel.setSize(size, size); + + otherCounterLabel.setLocation(5, counterPanel.getHeight() - size); + otherCounterLabel.setSize(size, size); + + } int fontHeight = Math.round(cardHeight * (27f / 680)); boolean showText = (!isAnimationPanel && fontHeight < 12); @@ -741,32 +816,79 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti } -// if (card.getCounters() != null && !card.getCounters().isEmpty()) { -// ImageIcon image = new ImageIcon(ImageManagerImpl.getInstance().getCounterImage()); -// String amount = ""; -// String name = ""; -// for (CounterView counterView:card.getCounters()) { -// amount = Integer.toString(counterView.getCount()); -// name = counterView.getName(); -// break; -// } -// if (counterLabel == null) { -// counterLabel = new JLabel(amount, image, JLabel.CENTER); -// } -// counterLabel.setToolTipText(name); -// counterLabel.setLocation(50,50); -// -// this.add(counterLabel); -// counterLabel.setVisible(true); -// } else { -// if (counterLabel != null) { -// this.remove(counterLabel); -// counterLabel = null; -// } -// } + if (card.getCounters() != null && !card.getCounters().isEmpty()) { + String name = ""; + if (lastCardWidth != cardWidth) { + lastCardWidth = cardWidth; + plusCounter = 0; + minusCounter = 0; + otherCounter = 0; + loyaltyCounter = 0; + } + plusCounterLabel.setVisible(false); + minusCounterLabel.setVisible(false); + loyaltyCounterLabel.setVisible(false); + otherCounterLabel.setVisible(false); + for (CounterView counterView:card.getCounters()) { + switch(counterView.getName()) { + case "+1/+1": + if (counterView.getCount() != plusCounter) { + plusCounter = counterView.getCount(); + plusCounterLabel.setIcon(getCounterImageWithAmount(plusCounter, ImageManagerImpl.getInstance().getCounterImageGreen(), cardWidth)); + } + plusCounterLabel.setVisible(true); + break; + case "-1/-1": + if (counterView.getCount() != minusCounter) { + minusCounter = counterView.getCount(); + minusCounterLabel.setIcon(getCounterImageWithAmount(minusCounter, ImageManagerImpl.getInstance().getCounterImageRed(), cardWidth)); + } + minusCounterLabel.setVisible(true); + break; + case "Loyalty": + if (counterView.getCount() != loyaltyCounter) { + loyaltyCounter = counterView.getCount(); + loyaltyCounterLabel.setIcon(getCounterImageWithAmount(loyaltyCounter, ImageManagerImpl.getInstance().getCounterImageViolet(), cardWidth)); + } + loyaltyCounterLabel.setVisible(true); + break; + default: + if (name.isEmpty()) { // only first other counter is shown + name = counterView.getName(); + otherCounter = counterView.getCount(); + otherCounterLabel.setToolTipText(name); + otherCounterLabel.setIcon(getCounterImageWithAmount(otherCounter, ImageManagerImpl.getInstance().getCounterImageGrey(), cardWidth)); + otherCounterLabel.setVisible(true); + } + } + } + + counterPanel.setVisible(true); + } else { + plusCounterLabel.setVisible(false); + minusCounterLabel.setVisible(false); + loyaltyCounterLabel.setVisible(false); + otherCounterLabel.setVisible(false); + counterPanel.setVisible(false); + } repaint(); } + private static ImageIcon getCounterImageWithAmount(int amount, BufferedImage image, int cardWidth) { + int factor = cardWidth > WIDTH_LIMIT ? 2 :1; + 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", Font.BOLD, factor * 9 )); + graphics.drawString(Integer.toString(amount), 4 * factor, 11 * factor); + return new ImageIcon(newImage); + } + @Override public boolean contains(int x, int y) { if (containsThis(x, y, true)) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/ImageManager.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/ImageManager.java index 89161504c32..3d79777b22b 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/ImageManager.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/ImageManager.java @@ -16,7 +16,10 @@ public interface ImageManager { Image getTriggeredAbilityImage(); Image getActivatedAbilityImage(); Image getCopyInformIconImage(); - Image getCounterImage(); + Image getCounterImageViolet(); + Image getCounterImageRed(); + Image getCounterImageGreen(); + Image getCounterImageGrey(); Image getDlgAcceptButtonImage(); Image getDlgActiveAcceptButtonImage(); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/impl/ImageManagerImpl.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/impl/ImageManagerImpl.java index 8dbf56490d7..bca793d9187 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/impl/ImageManagerImpl.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/impl/ImageManagerImpl.java @@ -1,17 +1,21 @@ package org.mage.plugins.card.utils.impl; -import mage.client.util.gui.BufferedImageBuilder; -import org.mage.plugins.card.utils.ImageManager; -import org.mage.plugins.card.utils.Transparency; - -import javax.imageio.ImageIO; -import java.awt.*; +import java.awt.Color; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Toolkit; import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; import java.awt.image.CropImageFilter; import java.awt.image.FilteredImageSource; +import java.awt.image.WritableRaster; import java.net.URL; import java.util.HashMap; import java.util.Map; +import javax.imageio.ImageIO; +import mage.client.util.gui.BufferedImageBuilder; +import org.mage.plugins.card.utils.ImageManager; +import org.mage.plugins.card.utils.Transparency; public class ImageManagerImpl implements ImageManager { @@ -134,12 +138,39 @@ public class ImageManagerImpl implements ImageManager { } @Override - public BufferedImage getCounterImage() { - if (imageCounter == null) { - Image image = getImageFromResourceTransparent("/card/counter_green.png", Color.WHITE, new Rectangle(32, 32)); - imageCounter = BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB); + public BufferedImage getCounterImageViolet() { + if (imageCounterViolet == null) { + Image image = getImageFromResourceTransparent("/card/counter_violet.png", Color.WHITE, new Rectangle(32, 32)); + imageCounterViolet = BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB); } - return imageCounter; + return imageCounterViolet; + } + + @Override + public BufferedImage getCounterImageGreen() { + if (imageCounterGreen == null) { + Image image = getImageFromResourceTransparent("/card/counter_green.png", Color.WHITE, new Rectangle(32, 32)); + imageCounterGreen = BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB); + } + return imageCounterGreen; + } + + @Override + public BufferedImage getCounterImageRed() { + if (imageCounterRed == null) { + Image image = getImageFromResourceTransparent("/card/counter_red.png", Color.WHITE, new Rectangle(32, 32)); + imageCounterRed = BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB); + } + return imageCounterRed; + } + + @Override + public BufferedImage getCounterImageGrey() { + if (imageCounterGrey == null) { + Image image = getImageFromResourceTransparent("/card/counter_grey.png", Color.WHITE, new Rectangle(32, 32)); + imageCounterGrey = BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB); + } + return imageCounterGrey; } @Override @@ -253,6 +284,13 @@ public class ImageManagerImpl implements ImageManager { return image; } + public static BufferedImage deepCopy(BufferedImage bi) { + ColorModel cm = bi.getColorModel(); + boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); + WritableRaster raster = bi.copyData(null); + return new BufferedImage(cm, raster, isAlphaPremultiplied, null); + } + private static BufferedImage appImage; private static BufferedImage appSmallImage; private static BufferedImage appImageFlashed; @@ -265,7 +303,10 @@ public class ImageManagerImpl implements ImageManager { private static BufferedImage triggeredAbilityIcon; private static BufferedImage activatedAbilityIcon; private static BufferedImage imageCopyIcon; - private static BufferedImage imageCounter; + private static BufferedImage imageCounterGreen; + private static BufferedImage imageCounterGrey; + private static BufferedImage imageCounterRed; + private static BufferedImage imageCounterViolet; private static BufferedImage imageDlgAcceptButton; private static BufferedImage imageDlgActiveAcceptButton; diff --git a/Mage.Client/src/main/resources/card/counter_grey.png b/Mage.Client/src/main/resources/card/counter_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..addabfc9eabc99b95c69a81828c178d0683df05f GIT binary patch literal 1613 zcmV-T2D15yP)vo)6FW;rkwZ&xhxE@O%%R z_TYIMN^2}EER+_mUqAQJr=On5<#NCMR|3J<$jIrD;o(yqnGWsyK5FK<+4JGWiFh8g zr=himQVL5;OZ54dU%vCfhabKLpwtXRHM^NeB!-@znD}aRcw{P>OiEAd>W8)VYUXJN z9Iieh5#39tQgZz8;faBPfvGE3uYO%D7IWJY$h5bQA3bv9i=MrE2OMBMc$|zESqQGZ z7!ltQQCg$Fudj1#boBV|H*S1;cX|1C98cEyJP3xyMn*qLr_$YkfDnKX0s_L#n@l>B z5>iSiDWR0Ak@J1*3d1%$Jly^ItFL|1o=y*KMIaa(9(h02*4AB14iU=~5lyK66L2KM zi-?pAiFjJW_kEWWQsJ?o1Kn?&Jo!F=U=xACfrn2&*xfyX|9M2-ipEn%kB+=N_2TI| z0*ORouy6nVQ}GvV?AJ{;nrctj*mKsxTKAMO7RDG5Gs@*MhzQ0othKP#;<;y^IhAQ| zAFL+f(4z<5?&|Cuj~HvEpu$pe*9uDM*tPqwl!B59vT71ihAS2Vu#N~bgPB3ZAR+{b zgtXQsXD?s=SORECwY5!G*Ja&GBerof*1{TR#+aBf*f5w0M1%?vD&-2w4>8{SM$;QMnwsD09TxSkgvII+pBnc7(2!!AkMlpntu4*h`tpT&C zdWo2DaBOr^CxT$SF8P{(M{YJ@ESV)J2JB+)5-@sSu?(}{F|gJ;^6WxDL}+bo9oL?x zdp3C>4qOFQZnex{l8}NxQHjOCtubKb64HrSR76oi8W0nh7@p_%Xdz^#k$|Ycsl;c-Xq~AxJ4fM37QAa1vGZ zt5uBim@*2IC8Usb0u&`R8-@wJKuplqnjC;lUSQ@B*tt8pj(P)74{nWyQ3f2YUPcKR z(=B6-6RFUn8yg!rU8zvE8G$+yQbG`gZbt*Si@VVViWQ`ivG_NHz(y*`U^ZA^|2wOT zrP2(5gUtvSV?b5l2pmpws{&N^#BoGV)a9fO-Ok4OUiGW|Xz|frs|(dugj? zVy&$LP#j|=jmph*?6iRV5Y#c;Xmq<-l&kU(l*b8bU z7;kR1cPz5Ev!xq1Z=Tlx)(R^t=hCUvEB9-wM6|g#7z3qD*qkIJD@Y-n`>P@p3qq)f zj=-IB0M--$tgfxicXxK3^nG96k3Ys2;%E7@x4hVHM0pr(Et3Q)dKpbM8So+y{g zc@?fMFQwYk+0ikv-3B8LSXTu$Os-hZsHtcy_RN^QGI#cmZ1%mzZFz9y@c57aW>+L- zZTsbFUqD19*d%GKwYYif*3}D_Ev}5ok^#U2SL!X69SEmi{sbK4Vw`{ z?p|*3yC1$kMnsEEx8+2XTU}fGc28^T3p*vzOupm5k>&IG#n~%!&;PZ$I(Of5L9tZ4 zy|jGyv*hmGldUZ+o&U$i^v>eq)t_d6KDOEbzU9e?h;rFGx8G&vL~{4;BimKSR%3mA zoqoM`?d+BLUrxl`{;v+Fi9}-X;r@X)Q*CY2_YW=+Dlk#a+L~Yi>1=c(%q$RmUFosAJ6{*q_}4GD^=%=00000 LNkvXXu0mjf-unBb literal 0 HcmV?d00001 diff --git a/Mage.Client/src/main/resources/card/counter_red.png b/Mage.Client/src/main/resources/card/counter_red.png new file mode 100644 index 0000000000000000000000000000000000000000..6409d17c5284645561de5466b7237b13238e572c GIT binary patch literal 1512 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 fP3X literal 0 HcmV?d00001