[mage.client] Foil cards support. For now have strange noise that is only with JInternalFrame, works for JFrame nicely so possibly will need to reimplement all dialogs.

For now every 5 card is a foil and the property is not attached to the card and may differ in various zone (need to change card entity).
This commit is contained in:
magenoxx 2011-01-05 13:14:39 +03:00
parent 7bea472fff
commit 3cf90f2875
19 changed files with 1424 additions and 1041 deletions

View file

@ -34,26 +34,6 @@
package mage.client;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.JToolBar.Separator;
import com.sun.java.swing.Painter;
import mage.cards.decks.Deck;
import mage.client.cards.CardsStorage;
import mage.client.components.MageComponents;
@ -69,8 +49,25 @@ import mage.client.util.gui.ArrowBuilder;
import mage.components.ImagePanel;
import mage.util.Logging;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.JToolBar.Separator;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.Preferences;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class MageFrame extends javax.swing.JFrame {
@ -100,23 +97,23 @@ public class MageFrame extends javax.swing.JFrame {
return prefs;
}
/** Creates new form MageFrame */
/**
* Creates new form MageFrame
*/
public MageFrame() {
setTitle("Mage, version 0.5.1");
EDTExceptionHandler.registerExceptionHandler();
addWindowListener(new WindowAdapter()
{
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
public void windowClosing(WindowEvent e) {
exitApp();
}
});
try {
UIManager.put("desktop", new Color(0,0,0,0));
UIManager.put("desktop", new Color(0, 0, 0, 0));
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
//MageSynthStyleFactory f = new MageSynthStyleFactory(SynthLookAndFeel.getStyleFactory());
//SynthLookAndFeel.setStyleFactory(f);
@ -127,7 +124,7 @@ public class MageFrame extends javax.swing.JFrame {
Plugins.getInstance().loadPlugins();
initComponents();
setSize(1024,768);
setSize(1024, 768);
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
session = new Session(this);
@ -149,17 +146,17 @@ public class MageFrame extends javax.swing.JFrame {
desktopPane.add(ArrowBuilder.getArrowsPanel(), JLayeredPane.DRAG_LAYER);
desktopPane.addComponentListener(new ComponentAdapter(){
desktopPane.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
int width = ((JComponent)e.getSource()).getWidth();
int height = ((JComponent)e.getSource()).getHeight();
int width = ((JComponent) e.getSource()).getWidth();
int height = ((JComponent) e.getSource()).getHeight();
backgroundPane.setSize(width, height);
JPanel arrowsPanel = ArrowBuilder.getArrowsPanelRef();
if (arrowsPanel != null) arrowsPanel.setSize(width, height);
if (title != null) {
//title.setBorder(BorderFactory.createLineBorder(Color.red));
title.setBounds((int)(width - titleRectangle.getWidth())/2, (int)(height - titleRectangle.getHeight())/2, titleRectangle.width, titleRectangle.height);
title.setBounds((int) (width - titleRectangle.getWidth()) / 2, (int) (height - titleRectangle.getHeight()) / 2, titleRectangle.width, titleRectangle.height);
}
}
});
@ -222,7 +219,7 @@ public class MageFrame extends javax.swing.JFrame {
final JEditorPane cardInfoPane = (JEditorPane) Plugins.getInstance().getCardInfoPane();
cardInfoPane.setSize(320, 201);
cardInfoPane.setLocation(40, 40);
cardInfoPane.setBackground(new Color(0,0,0,0));
cardInfoPane.setBackground(new Color(0, 0, 0, 0));
MageRoundPane popupContainer = new MageRoundPane();
popupContainer.setLayout(null);
@ -261,7 +258,7 @@ public class MageFrame extends javax.swing.JFrame {
InputStream is = this.getClass().getResourceAsStream(filename);
float ratio = 1179.0f / 678.0f;
titleRectangle = new Rectangle(640, (int)(640 / ratio));
titleRectangle = new Rectangle(640, (int) (640 / ratio));
if (is != null) {
BufferedImage image = ImageIO.read(is);
//ImageIcon resized = new ImageIcon(image.getScaledInstance(titleRectangle.width, titleRectangle.height, java.awt.Image.SCALE_SMOOTH));
@ -334,19 +331,18 @@ public class MageFrame extends javax.swing.JFrame {
setCursor(new Cursor(Cursor.WAIT_CURSOR));
if (MageFrame.connect(userName, server, port)) {
return true;
}
else {
} else {
JOptionPane.showMessageDialog(rootPane, "Unable to connect to server");
}
}
finally {
} finally {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
}
return false;
}
/** This method is called from within the constructor to
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
@ -527,8 +523,7 @@ public class MageFrame extends javax.swing.JFrame {
if (JOptionPane.showConfirmDialog(this, "Are you sure you want to disconnect?", "Confirm disconnect", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
session.disconnect();
}
}
else {
} else {
connectDialog.showDialog();
}
}//GEN-LAST:event_btnConnectActionPerformed
@ -578,7 +573,7 @@ public class MageFrame extends javax.swing.JFrame {
static void renderSplashFrame(Graphics2D g) {
g.setComposite(AlphaComposite.Clear);
g.fillRect(120,140,200,40);
g.fillRect(120, 140, 200, 40);
g.setPaintMode();
g.setColor(Color.white);
g.drawString("Version 0.5.1", 560, 460);

View file

@ -34,43 +34,51 @@
package mage.client.cards;
import static mage.constants.Constants.CONTENT_MAX_XOFFSET;
import static mage.constants.Constants.FRAME_MAX_HEIGHT;
import static mage.constants.Constants.FRAME_MAX_WIDTH;
import static mage.constants.Constants.TEXT_MAX_HEIGHT;
import static mage.constants.Constants.TEXT_MAX_WIDTH;
import static mage.constants.Constants.TEXT_MAX_YOFFSET;
import mage.client.plugins.impl.Plugins;
import mage.client.util.gui.BufferedImageBuilder;
import mage.filters.FilterFactory;
import mage.filters.impl.HueFilter;
import mage.utils.ThreadUtils;
import org.jdesktop.swingx.JXPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.List;
import java.util.UUID;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
import mage.client.plugins.impl.Plugins;
import org.jdesktop.swingx.JXPanel;
import static mage.constants.Constants.*;
/**
* Class for displaying big image of the card
*
* @author BetaSteward_at_googlemail.com
* @author BetaSteward_at_googlemail.com, nantuko
*/
public class BigCard extends javax.swing.JPanel {
public class BigCard extends JComponent {
protected Image bigImage;
protected BufferedImage source;
protected volatile BufferedImage foil;
protected UUID cardId;
protected JXPanel panel;
protected boolean initState;
protected boolean foilState;
protected Thread foilThread;
protected float hue = 0.005f;
static private final int DEFAULT_DELAY_PERIOD = 25;
public BigCard() {
initComponents();
if (!Plugins.getInstance().isCardPluginLoaded()) {
initBounds();
}
setDoubleBuffered(true);
setOpaque(true);
}
protected void initBounds() {
@ -79,13 +87,17 @@ public class BigCard extends javax.swing.JPanel {
scrollPane.setBounds(new Rectangle(CONTENT_MAX_XOFFSET, TEXT_MAX_YOFFSET, TEXT_MAX_WIDTH, TEXT_MAX_HEIGHT));
}
public void setCard(UUID cardId, Image image, List<String> strings) {
public void setCard(UUID cardId, Image image, List<String> strings, boolean foil) {
if (this.cardId == null || !this.cardId.equals(cardId)) {
if (this.panel != null) remove(this.panel);
this.cardId = cardId;
bigImage = image;
this.repaint();
synchronized (this) {
source = null;
hue = 0.000f;
}
drawText(strings);
setFoil(foil);
}
}
@ -98,17 +110,30 @@ public class BigCard extends javax.swing.JPanel {
StyledDocument doc = text.getStyledDocument();
try {
for (String line: strings) {
for (String line : strings) {
doc.insertString(doc.getLength(), line + "\n", doc.getStyle("regular"));
}
} catch (BadLocationException ble) { }
} catch (BadLocationException ble) {
}
text.setCaretPosition(0);
}
@Override
public void paintComponent(Graphics graphics) {
if (bigImage != null)
if (foilState) {
if (source != null) {
synchronized (BigCard.class) {
if (source != null) {
graphics.drawImage(foil, 0, 0, this);
}
}
}
} else {
if (bigImage != null) {
graphics.drawImage(bigImage, 0, 0, this);
}
}
super.paintComponent(graphics);
}
@ -117,10 +142,78 @@ public class BigCard extends javax.swing.JPanel {
}
public void showTextComponent() {
if (!initState) {initBounds();}
if (!initState) {
initBounds();
}
this.scrollPane.setVisible(true);
}
public void setFoil(boolean foil) {
if (foil) {
if (foilThread == null) {
synchronized (this) {
if (foilThread == null) {
foilThread = getFoilThread();
foilThread.setDaemon(true);
foilThread.start();
}
}
}
if (foil != foilState) {
synchronized (this) {
if (foil != foilState) {
hue = 0.005f;
foilState = foil;
}
}
}
}
repaint();
}
private Thread getFoilThread() {
return new Thread(new Runnable() {
@Override
public void run() {
if (bigImage == null) {
return;
}
final HueFilter filter = FilterFactory.getHueFilter();
while (true) {
boolean prevState = foilState;
while (!foilState) {
ThreadUtils.sleep(10);
}
if (prevState == foilState) {
ThreadUtils.sleep(DEFAULT_DELAY_PERIOD);
}
hue += 0.005F;
if (hue >= 1.0D) {
hue = 0.000F;
}
filter.setHue(hue);
BufferedImage f = null;
synchronized (BigCard.this) {
if (source == null) {
source = BufferedImageBuilder.bufferImage(bigImage);
}
f = filter.filter(source, null);
}
synchronized (BigCard.class) {
foil = f;
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
BigCard.this.repaint();
}
});
}
}
});
}
public void addJXPanel(UUID cardId, JXPanel jxPanel) {
bigImage = null;
synchronized (this) {
@ -132,7 +225,8 @@ public class BigCard extends javax.swing.JPanel {
}
/** This method is called from within the constructor to
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.

View file

@ -135,12 +135,12 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
Style s = doc.addStyle("small", regular);
StyleConstants.setFontSize(s, 9);
addMouseListener(this);
text.addMouseListener(this);
addFocusListener(this);
addMouseMotionListener(this);
text.addMouseMotionListener(this);
addComponentListener(this);
//addMouseListener(this);
//text.addMouseListener(this);
//addFocusListener(this);
//addMouseMotionListener(this);
//text.addMouseMotionListener(this);
//addComponentListener(this);
}
public UUID getCardId() {
@ -347,7 +347,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
@Override
public void mouseMoved(MouseEvent arg0) {
this.bigCard.showTextComponent();
this.bigCard.setCard(card.getId(), image, getRules());
this.bigCard.setCard(card.getId(), image, getRules(), false);
}
@Override
@ -480,6 +480,15 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
return image;
}
@Override
public void setFoil(boolean foil) {
}
@Override
public boolean isFoil() {
return false;
}
@Override
public PermanentView getOriginalPermanent() {
return null;

View file

@ -26,11 +26,10 @@ public class ManaSymbols {
"BR", "G", "GU", "GW", "R", "RG", "RW", "S", "T", "U", "UB", "UR", "W", "WB", "WU", "X" /*, "Y", "Z", "slash"*/};
for (String symbol : symbols) {
File file = new File(Constants.RESOURCE_PATH_MANA_LARGE + "/" + symbol + ".jpg");
BufferedImageBuilder builder = new BufferedImageBuilder();
Rectangle r = new Rectangle(11, 11);
try {
Image image = UI.getImageIcon(file.getAbsolutePath()).getImage();
BufferedImage resized = ImageResizeUtil.getResizedImage(builder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
BufferedImage resized = ImageResizeUtil.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
manaImages.put(symbol, resized);
} catch (Exception e) {
noManaSymbols = true;

View file

@ -37,6 +37,7 @@ package mage.client.deckeditor;
import mage.cards.Card;
import mage.cards.decks.Deck;
import mage.client.MageFrame;
import mage.client.deckeditor.collection.viewer.Huerotator2;
import mage.client.plugins.impl.Plugins;
import mage.client.util.Event;
import mage.client.util.Listener;

View file

@ -184,14 +184,13 @@ public class MageActionCallback implements ActionCallback {
Image image = card.getImage();
if (image != null && image instanceof BufferedImage) {
image = ImageHelper.getResizedImage((BufferedImage) image, bigCard.getWidth(), bigCard.getHeight());
bigCard.setCard(card.getOriginal().getId(), image, card.getOriginal().getRules());
bigCard.setCard(card.getOriginal().getId(), image, card.getOriginal().getRules(), card.isFoil());
bigCard.showTextComponent();
if (card.getOriginal().isAbility()) {
bigCard.showTextComponent();
} else {
bigCard.hideTextComponent();
}
;
} else {
JXPanel panel = GuiDisplayUtil.getDescription(card.getOriginal(), bigCard.getWidth(), bigCard.getHeight());
panel.setVisible(true);

View file

@ -4,15 +4,27 @@ import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
/**
* Utility class for creating BufferedImage object from Image instance.
*
* @author nantuko
*/
public class BufferedImageBuilder {
private static final int DEFAULT_IMAGE_TYPE = BufferedImage.TYPE_INT_RGB;
public BufferedImage bufferImage(Image image) {
/**
* Hide constructor
*/
private BufferedImageBuilder() {
}
public static BufferedImage bufferImage(Image image) {
return bufferImage(image, DEFAULT_IMAGE_TYPE);
}
public BufferedImage bufferImage(Image image, int type) {
public static BufferedImage bufferImage(Image image, int type) {
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
Graphics2D g = bufferedImage.createGraphics();
g.drawImage(image, null, null);
@ -50,7 +62,6 @@ public class BufferedImageBuilder {
}
class ImageLoadStatus {
public boolean widthDone = false;
public boolean heightDone = false;
}

View file

@ -19,4 +19,6 @@ public abstract class MageCard extends JPanel {
abstract public void setCardBounds(int x, int y, int width, int height);
abstract public void update(CardView card);
abstract public Image getImage();
abstract public void setFoil(boolean foil);
abstract public boolean isFoil();
}

View file

@ -0,0 +1,17 @@
package mage.filters;
import mage.filters.impl.HueFilter;
/**
* Creates filter instances.
*
* @author nantuko
*/
public class FilterFactory {
private static final HueFilter hueFilter = new HueFilter();
public static HueFilter getHueFilter() {
return hueFilter;
}
}

View file

@ -0,0 +1,68 @@
package mage.filters;
import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorModel;
/**
* Mage abstract class that implements single-input/single-output
* operations performed on {@link java.awt.image.BufferedImage}.
*
* @author nantuko
*/
public abstract class MageBufferedImageOp implements BufferedImageOp {
/**
* Creates compatible image for @param src image.
*/
public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dest) {
if (dest == null) {
dest = src.getColorModel();
}
return new BufferedImage(dest, dest.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dest.isAlphaPremultiplied(), null);
}
public RenderingHints getRenderingHints() {
return null;
}
public Rectangle2D getBounds2D(BufferedImage src) {
return new Rectangle(0, 0, src.getWidth(), src.getHeight());
}
public Point2D getPoint2D(Point2D srcPt, Point2D destPt) {
if (destPt == null) {
destPt = new Point2D.Double();
}
destPt.setLocation(srcPt.getX(), srcPt.getY());
return destPt;
}
/**
* Gets ARGB pixels from image. Solves the performance
* issue of BufferedImage.getRGB method.
*/
public int[] getRGB(BufferedImage image, int x, int y, int width, int height, int[] pixels) {
int type = image.getType();
if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB) {
return (int[]) image.getRaster().getDataElements(x, y, width, height, pixels);
}
return image.getRGB(x, y, width, height, pixels, 0, width);
}
/**
* Sets ARGB pixels in image. Solves the performance
* issue of BufferedImage.setRGB method.
*/
public void setRGB(BufferedImage image, int x, int y, int width, int height, int[] pixels) {
int type = image.getType();
if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB) {
image.getRaster().setDataElements(x, y, width, height, pixels);
} else {
image.setRGB(x, y, width, height, pixels, 0, width);
}
}
}

View file

@ -0,0 +1,69 @@
/*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mage.filters;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
/**
* An abstract super class for filters that work with points.
* Takes into account image type to avoid performance issue with getRGB and setRGB methods of BufferedImage.
*
* @author nantuko
*/
public abstract class PointFilter extends MageBufferedImageOp {
protected boolean canFilterIndexColorModel = false;
public BufferedImage filter(BufferedImage src, BufferedImage dst) {
int width = src.getWidth();
int height = src.getHeight();
int type = src.getType();
WritableRaster srcRaster = src.getRaster();
if (dst == null) {
dst = createCompatibleDestImage(src, null);
}
WritableRaster dstRaster = dst.getRaster();
setDimensions(width, height);
int[] inPixels = new int[width];
for (int y = 0; y < height; y++) {
if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB) {
srcRaster.getDataElements(0, y, width, 1, inPixels);
for (int x = 0; x < width; x++) {
inPixels[x] = filterRGB(x, y, inPixels[x]);
}
dstRaster.setDataElements(0, y, width, 1, inPixels);
} else {
src.getRGB(0, y, width, 1, inPixels, 0, width);
for (int x = 0; x < width; x++) {
inPixels[x] = filterRGB(x, y, inPixels[x]);
}
dst.setRGB(0, y, width, 1, inPixels, 0, width);
}
}
return dst;
}
public void setDimensions(int width, int height) {
}
public abstract int filterRGB(int x, int y, int rgb);
}

View file

@ -0,0 +1,68 @@
/*
Copyright 2006 Jerry Huxtable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mage.filters.impl;
import mage.filters.PointFilter;
import java.awt.*;
/**
* Point filter that changes hue of the image.
*
* @author nantuko
*/
public class HueFilter extends PointFilter {
public float hue;
private float[] hsb = new float[3];
public HueFilter() {
this(0);
}
public HueFilter(float hue) {
this.hue = hue;
canFilterIndexColorModel = true;
}
public void setHue(float hue) {
this.hue = hue;
}
public float getHue() {
return hue;
}
public int filterRGB(int x, int y, int rgb) {
int a = rgb & 0xff000000;
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
Color.RGBtoHSB(r, g, b, hsb);
hsb[0] += hue;
while (hsb[0] < 0) {
hsb[0] += Math.PI*2;
}
rgb = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
return a | (rgb & 0xffffff);
}
public String toString() {
return "Change HUE filter";
}
}

View file

@ -1,15 +1,27 @@
package org.mage.card.arcane;
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 mage.Constants.CardType;
import mage.cards.MagePermanent;
import mage.cards.TextPopup;
import mage.cards.action.ActionCallback;
import mage.cards.action.TransferData;
import mage.components.ImagePanel;
import mage.filters.FilterFactory;
import mage.filters.impl.HueFilter;
import mage.utils.CardUtil;
import mage.view.AbilityView;
import mage.view.CardView;
import mage.view.PermanentView;
import mage.view.StackAbilityView;
import org.apache.log4j.Logger;
import org.mage.card.arcane.ScaledImagePanel.MultipassType;
import org.mage.card.arcane.ScaledImagePanel.ScalingType;
import org.mage.plugins.card.images.ImageCache;
import org.mage.plugins.card.utils.BufferedImageBuilder;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
@ -18,30 +30,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.swing.BorderFactory;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import mage.Constants.CardType;
import mage.cards.MagePermanent;
import mage.cards.TextPopup;
import mage.cards.action.ActionCallback;
import mage.cards.action.TransferData;
import mage.components.ImagePanel;
import mage.utils.CardUtil;
import mage.view.AbilityView;
import mage.view.CardView;
import mage.view.PermanentView;
import mage.view.StackAbilityView;
import org.apache.log4j.Logger;
import org.mage.card.arcane.ScaledImagePanel.MultipassType;
import org.mage.card.arcane.ScaledImagePanel.ScalingType;
import org.mage.plugins.card.images.ImageCache;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
@SuppressWarnings({"unchecked","rawtypes"})
/**
* Main class for drawing Mage card object.
*
* @author arcane, nantuko
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class CardPanel extends MagePermanent implements MouseListener, MouseMotionListener {
private static final long serialVersionUID = -3272134219262184410L;
@ -64,6 +58,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
static private final float rotCenterToTopCorner = 1.0295630140987000315797369464196f;
static private final float rotCenterToBottomCorner = 0.7071067811865475244008443621048f;
static private final int DEFAULT_DELAY_PERIOD = 300;
public CardView gameCard;
//public List<CardPanel> attachedPanels = new ArrayList();
private List<MagePermanent> links = new ArrayList<MagePermanent>();
@ -73,7 +69,6 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
private GlowText titleText;
private GlowText ptText;
private List<CardPanel> imageLoadListeners = new ArrayList(2);
private boolean displayEnabled = true;
private boolean isAnimationPanel;
private int cardXOffset, cardYOffset, cardWidth, cardHeight;
@ -92,8 +87,9 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
private boolean isPermanent;
private boolean hasSickness;
private boolean isFoil;
public CardPanel(CardView newGameCard, UUID gameId, boolean loadImage, ActionCallback callback) {
public CardPanel(CardView newGameCard, UUID gameId, boolean loadImage, ActionCallback callback, final boolean foil) {
this.gameCard = newGameCard;
this.callback = callback;
this.gameId = gameId;
@ -150,7 +146,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
if (!loadImage) return;
Util.threadPool.submit(new Runnable() {
public void run () {
public void run() {
try {
tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0;
BufferedImage srcImage = ImageCache.getImageOriginal(gameCard);
@ -158,9 +154,10 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
if (srcImage != null) {
hasImage = true;
setText(gameCard);
setImage(srcImage, srcImage);
setImage(srcImage);
setFoil(foil);
} else {
log.warn("image wasn't found, card=" + gameCard.getName() + ", set=" + gameCard.getExpansionSetCode() + ", cid=" + gameCard.getCardNumber());
//log.warn("image wasn't found, card=" + gameCard.getName() + ", set=" + gameCard.getExpansionSetCode() + ", cid=" + gameCard.getCardNumber());
}
} catch (Exception e) {
e.printStackTrace();
@ -179,50 +176,94 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
}
}
private void setImage (Image srcImage, Image srcImageBlurred) {
private void setImage(Image srcImage) {
synchronized (imagePanel) {
imagePanel.setImage(srcImage, srcImageBlurred);
imagePanel.setImage(srcImage);
repaint();
for (CardPanel cardPanel : imageLoadListeners) {
cardPanel.setImage(srcImage, srcImageBlurred);
cardPanel.repaint();
}
imageLoadListeners.clear();
}
layout();
}
public void setImage (final CardPanel panel) {
public void setImage(final CardPanel panel) {
synchronized (panel.imagePanel) {
if (panel.imagePanel.hasImage())
setImage(panel.imagePanel.srcImage, panel.imagePanel.srcImageBlurred);
else
panel.imageLoadListeners.add(this);
if (panel.imagePanel.hasImage()) {
setImage(panel.imagePanel.srcImage);
}
}
}
public void setScalingType (ScalingType scalingType) {
public boolean isFoil() {
return this.isFoil;
}
public void setFoil(boolean foil) {
this.isFoil = foil;
if (foil) {
/*BufferedImage source = BufferedImageBuilder.bufferImage(imagePanel.getSrcImage());
HueFilter filter = FilterFactory.getHueFilter();
filter.setHue(0.1sf);
BufferedImage dest = filter.filter(source, null);
imagePanel.setImage(dest);
imagePanel.repaint();*/
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
if (imagePanel.getSrcImage() == null) {
return;
}
BufferedImage source = BufferedImageBuilder.bufferImage(imagePanel.getSrcImage());
HueFilter filter = FilterFactory.getHueFilter();
float hue = 0.005f;
while (true) {
try {
Thread.sleep(DEFAULT_DELAY_PERIOD);
} catch (InterruptedException e) {
}
hue += 0.015F;
if (hue >= 1.0D) {
hue = 0.005F;
}
filter.setHue(hue);
final BufferedImage dest = filter.filter(source, null);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
imagePanel.setImage(dest);
imagePanel.repaint();
}
});
}
}
});
thread.setDaemon(false);
thread.start();
}
}
public void setScalingType(ScalingType scalingType) {
imagePanel.setScalingType(scalingType);
}
public void setDisplayEnabled (boolean displayEnabled) {
public void setDisplayEnabled(boolean displayEnabled) {
this.displayEnabled = displayEnabled;
}
public boolean isDisplayEnabled () {
public boolean isDisplayEnabled() {
return displayEnabled;
}
public void setAnimationPanel (boolean isAnimationPanel) {
public void setAnimationPanel(boolean isAnimationPanel) {
this.isAnimationPanel = isAnimationPanel;
}
public void setSelected (boolean isSelected) {
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
repaint();
}
public void setAttacking (boolean isAttacking) {
public void setAttacking(boolean isAttacking) {
//TODO:uncomment
//this.gameCard.setAttacking(isAttacking);
repaint();
@ -232,24 +273,24 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
return this.isSelected;
}
public void setShowCastingCost (boolean showCastingCost) {
public void setShowCastingCost(boolean showCastingCost) {
this.showCastingCost = showCastingCost;
}
public void paint (Graphics g) {
public void paint(Graphics g) {
if (!displayEnabled) return;
if (!isValid()) super.validate();
Graphics2D g2d = (Graphics2D)g;
Graphics2D g2d = (Graphics2D) g;
if (tappedAngle > 0) {
g2d = (Graphics2D)g2d.create();
g2d = (Graphics2D) g2d.create();
float edgeOffset = cardWidth / 2f;
g2d.rotate(tappedAngle, cardXOffset + edgeOffset, cardYOffset + cardHeight - edgeOffset);
}
super.paint(g2d);
}
protected void paintComponent (Graphics g) {
Graphics2D g2d = (Graphics2D)g;
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (alpha != 1.0f) {
@ -259,9 +300,9 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
//TODO:uncomment
if (!hasImage /*&& gameCard.getTableID() > 0*/) {
g2d.setColor(new Color(30,200,200,120));
g2d.setColor(new Color(30, 200, 200, 120));
} else {
g2d.setColor(new Color(0,0,0,200));
g2d.setColor(new Color(0, 0, 0, 200));
}
//for debug repainting
@ -270,8 +311,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
g2d.fillRoundRect(cardXOffset, cardYOffset, cardWidth, cardHeight, cornerSize, cornerSize);
if (isSelected) {
//g2d.setColor(new Color(0,250,0,200));
g2d.setColor(new Color(200,120,40,200));
g2d.fillRoundRect(cardXOffset+1, cardYOffset+1, cardWidth-2, cardHeight-2, cornerSize, cornerSize);
g2d.setColor(new Color(200, 120, 40, 200));
g2d.fillRoundRect(cardXOffset + 1, cardYOffset + 1, cardWidth - 2, cardHeight - 2, cornerSize, cornerSize);
}
//TODO:uncomment
@ -305,7 +346,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
*/
}
protected void paintChildren (Graphics g) {
protected void paintChildren(Graphics g) {
super.paintChildren(g);
if (showCastingCost && !isAnimationPanel && cardWidth < 200 && cardWidth > 60) {
@ -355,12 +396,12 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
imagePanel.setScalingType(ScalingType.bilinear);
}
public String toString () {
public String toString() {
return gameCard.toString();
}
@Override
public void setCardBounds (int x, int y, int width, int height) {
public void setCardBounds(int x, int y, int width, int height) {
cardWidth = width;
cardHeight = height;
int rotCenterX = Math.round(width / 2f);
@ -376,7 +417,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
setBounds(x + xOffset, y + yOffset, width, height);
}
public void repaint () {
public void repaint() {
Rectangle b = getBounds();
JRootPane rootPane = SwingUtilities.getRootPane(this);
if (rootPane == null) return;
@ -384,23 +425,23 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
rootPane.repaint(p.x, p.y, b.width, b.height);
}
public int getCardX () {
public int getCardX() {
return getX() + cardXOffset;
}
public int getCardY () {
public int getCardY() {
return getY() + cardYOffset;
}
public int getCardWidth () {
public int getCardWidth() {
return cardWidth;
}
public int getCardHeight () {
public int getCardHeight() {
return cardHeight;
}
public Point getCardLocation () {
public Point getCardLocation() {
Point p = getLocation();
p.x += cardXOffset;
p.y += cardYOffset;
@ -437,18 +478,20 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
public void updateImage() {
if (!hasImage) {
Util.threadPool.submit(new Runnable() {
throw new IllegalStateException("Not implemented");
//TODO:
/*Util.threadPool.submit(new Runnable() {
public void run () {
//TODO: BufferedImage srcImage = ImageCache.getImageOriginal(gameCard);
//BufferedImage srcImage = ImageCache.getImageOriginal(gameCard);
//BufferedImage srcImage = null;
//tappedAngle = isTapped() ? CardPanel.TAPPED_ANGLE : 0;
/*if (srcImage != null) {
if (srcImage != null) {
hasImage = true;
setText(gameCard);
setImage(srcImage, srcImage);
}*/
}
});
}
});*/
}
}
@ -460,7 +503,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
@Override
public boolean isTapped() {
if (isPermanent) {
return ((PermanentView)gameCard).isTapped();
return ((PermanentView) gameCard).isTapped();
}
return false;
}
@ -476,7 +519,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
@Override
public void update(CardView card) {
if (isPermanent) {
if (isTapped() != ((PermanentView)card).isTapped()) {
if (isTapped() != ((PermanentView) card).isTapped()) {
Animation.tapCardToggle(this, this);
}
}
@ -572,7 +615,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
}
@Override
public void mouseDragged(MouseEvent e) {}
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
@ -582,7 +626,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
@Override
public void mouseExited(MouseEvent e) {
if(getMousePosition(true) != null) return;
if (getMousePosition(true) != null) return;
if (popupShowing) {
synchronized (this) {
if (popupShowing) {
@ -605,7 +649,8 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
}
@Override
public void mouseReleased(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {
}
/**
* Prepares data to be sent to action callback on client side.
@ -625,17 +670,17 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
protected String getType(CardView card) {
StringBuilder sbType = new StringBuilder();
for (String superType: card.getSuperTypes()) {
for (String superType : card.getSuperTypes()) {
sbType.append(superType).append(" ");
}
for (mage.Constants.CardType cardType: card.getCardTypes()) {
for (mage.Constants.CardType cardType : card.getCardTypes()) {
sbType.append(cardType.toString()).append(" ");
}
if (card.getSubTypes().size() > 0) {
sbType.append("- ");
for (String subType: card.getSubTypes()) {
for (String subType : card.getSubTypes()) {
sbType.append(subType).append(" ");
}
}
@ -646,11 +691,10 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
protected String getText(String cardType, CardView card) {
StringBuilder sb = new StringBuilder();
if (card instanceof StackAbilityView || card instanceof AbilityView) {
for (String rule: card.getRules()) {
for (String rule : card.getRules()) {
sb.append("\n").append(rule);
}
}
else {
} else {
sb.append(card.getName());
if (card.getManaCost().size() > 0) {
sb.append("\n").append(card.getManaCost());
@ -661,11 +705,10 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
}
if (card.getCardTypes().contains(CardType.CREATURE)) {
sb.append("\n").append(card.getPower()).append("/").append(card.getToughness());
}
else if (card.getCardTypes().contains(CardType.PLANESWALKER)) {
} else if (card.getCardTypes().contains(CardType.PLANESWALKER)) {
sb.append("\n").append(card.getLoyalty());
}
for (String rule: card.getRules()) {
for (String rule : card.getRules()) {
sb.append("\n").append(rule);
}
if (card.getExpansionSetCode() != null && card.getExpansionSetCode().length() > 0) {
@ -681,7 +724,7 @@ public class CardPanel extends MagePermanent implements MouseListener, MouseMoti
@Override
public void update(PermanentView card) {
update((CardView)card);
update((CardView) card);
this.hasSickness = card.hasSummoningSickness();
}

View file

@ -27,11 +27,10 @@ public class ManaSymbols {
"BR", "G", "GU", "GW", "R", "RG", "RW", "S", "T", "U", "UB", "UR", "W", "WB", "WU", "X", "Y", "Z", "slash"};
for (String symbol : symbols) {
File file = new File(Constants.RESOURCE_PATH_MANA_LARGE + "/" + symbol + ".jpg");
BufferedImageBuilder builder = new BufferedImageBuilder();
Rectangle r = new Rectangle(11, 11);
try {
Image image = UI.getImageIcon(file.getAbsolutePath()).getImage();
BufferedImage resized = ImageCache.getResizedImage(builder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
BufferedImage resized = ImageCache.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
manaImages.put(symbol, resized);
} catch (Exception e) {}
file = new File(Constants.RESOURCE_PATH_MANA_MEDIUM + "/" + symbol + ".jpg");

View file

@ -11,7 +11,7 @@ import javax.swing.JPanel;
public class ScaledImagePanel extends JPanel {
private static final long serialVersionUID = -1523279873208605664L;
public volatile Image srcImage;
public volatile Image srcImageBlurred;
//public volatile Image srcImageBlurred;
private ScalingType scalingType = ScalingType.bilinear;
private boolean scaleLarger;
@ -23,9 +23,8 @@ public class ScaledImagePanel extends JPanel {
setOpaque(false);
}
public void setImage (Image srcImage, Image srcImageBlurred) {
public void setImage(Image srcImage) {
this.srcImage = srcImage;
this.srcImageBlurred = srcImageBlurred;
}
public void clearImage () {
@ -168,9 +167,10 @@ public class ScaledImagePanel extends JPanel {
}
private Image getSourceImage (ScalingInfo info) {
if (!blur || srcImageBlurred == null) return srcImage;
if (info.srcWidth / 2 < info.targetWidth || info.srcHeight / 2 < info.targetHeight) return srcImage;
return srcImageBlurred;
return srcImage;
//if (!blur || srcImageBlurred == null) return srcImage;
//if (info.srcWidth / 2 < info.targetWidth || info.srcHeight / 2 < info.targetHeight) return srcImage;
//return srcImageBlurred;
}
public Image getSrcImage() {

View file

@ -6,12 +6,7 @@ import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import javax.swing.JComponent;
import javax.swing.JDialog;
@ -92,7 +87,8 @@ public class CardPluginImpl implements CardPlugin {
@Override
public MagePermanent getMagePermanent(PermanentView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback) {
CardPanel cardPanel = new CardPanel(permanent, gameId, true, callback);
boolean foil = (new Random()).nextInt(5) == 0;
CardPanel cardPanel = new CardPanel(permanent, gameId, true, callback, foil);
cardPanel.setShowCastingCost(true);
cardPanel.setCardBounds(0, 0, dimension.frameWidth, dimension.frameHeight);
cardPanel.setShowCastingCost(true);
@ -101,10 +97,12 @@ public class CardPluginImpl implements CardPlugin {
@Override
public MagePermanent getMageCard(CardView permanent, CardDimensions dimension, UUID gameId, ActionCallback callback) {
CardPanel cardPanel = new CardPanel(permanent, gameId, true, callback);
boolean foil = (new Random()).nextInt(5) == 0;
CardPanel cardPanel = new CardPanel(permanent, gameId, true, callback, foil);
cardPanel.setShowCastingCost(true);
cardPanel.setCardBounds(0, 0, dimension.frameWidth, dimension.frameHeight);
cardPanel.setShowCastingCost(true);
return cardPanel;
}

View file

@ -5,15 +5,27 @@ import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
/**
* Utility class for creating BufferedImage object from Image instance.
*
* @author nantuko
*/
public class BufferedImageBuilder {
private static final int DEFAULT_IMAGE_TYPE = BufferedImage.TYPE_INT_RGB;
public BufferedImage bufferImage(Image image) {
/**
* Hide constructor
*/
private BufferedImageBuilder() {
}
public static BufferedImage bufferImage(Image image) {
return bufferImage(image, DEFAULT_IMAGE_TYPE);
}
public BufferedImage bufferImage(Image image, int type) {
public static BufferedImage bufferImage(Image image, int type) {
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
Graphics2D g = bufferedImage.createGraphics();
g.drawImage(image, null, null);

View file

@ -29,8 +29,7 @@ public class ImageManagerImpl implements ImageManager {
Image image = getImageFromResourceTransparent("/sickness.png", Color.WHITE, new Rectangle(296, 265));
Toolkit tk = Toolkit.getDefaultToolkit();
image = tk.createImage(new FilteredImageSource(image.getSource(), new CropImageFilter(0, 0, 200, 285)));
BufferedImageBuilder builder = new BufferedImageBuilder();
imageSickness = builder.bufferImage(image, BufferedImage.TYPE_INT_ARGB);
imageSickness = BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB);
}
return imageSickness;
}