diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 75c62ac6f7..9cf9cfae90 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -374,6 +374,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { ui.addComponent(MageComponents.CARD_INFO_PANE, cardInfoPane); ui.addComponent(MageComponents.POPUP_CONTAINER, popupContainer); + // preview panel normal JPanel cardPreviewContainer = new JPanel(); cardPreviewContainer.setOpaque(false); cardPreviewContainer.setLayout(null); @@ -390,6 +391,24 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { ui.addComponent(MageComponents.CARD_PREVIEW_CONTAINER, cardPreviewContainer); desktopPane.add(cardPreviewContainer, JLayeredPane.POPUP_LAYER); + + // preview panel rotated + JPanel cardPreviewContainerRotated = new JPanel(); + cardPreviewContainerRotated.setOpaque(false); + cardPreviewContainerRotated.setLayout(null); + bigCard = new BigCard(true); + bigCard.setSize(500, 350); + bigCard.setLocation(40, 40); + bigCard.setBackground(new Color(0, 0, 0, 0)); + cardPreviewContainerRotated.add(bigCard); + cardPreviewContainerRotated.setVisible(false); + cardPreviewContainerRotated.setBounds(0, 0, 500 + 80, 420 + 30); + + ui.addComponent(MageComponents.CARD_PREVIEW_PANE_ROTATED, bigCard); + ui.addComponent(MageComponents.CARD_PREVIEW_CONTAINER_ROTATED, cardPreviewContainerRotated); + + desktopPane.add(cardPreviewContainerRotated, JLayeredPane.POPUP_LAYER); + } private void setBackground() { diff --git a/Mage.Client/src/main/java/mage/client/cards/BigCard.java b/Mage.Client/src/main/java/mage/client/cards/BigCard.java index f4f60a4cf1..6265dc288a 100644 --- a/Mage.Client/src/main/java/mage/client/cards/BigCard.java +++ b/Mage.Client/src/main/java/mage/client/cards/BigCard.java @@ -34,20 +34,26 @@ package mage.client.cards; -import mage.client.plugins.impl.Plugins; -import mage.client.util.ImageHelper; -import org.jdesktop.swingx.JXPanel; - -import javax.swing.*; -import javax.swing.text.BadLocationException; -import javax.swing.text.StyledDocument; -import java.awt.*; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.util.List; import java.util.UUID; - -import static mage.constants.Constants.*; +import javax.swing.JComponent; +import javax.swing.text.BadLocationException; +import javax.swing.text.StyledDocument; +import static mage.client.constants.Constants.CONTENT_MAX_XOFFSET; +import static mage.client.constants.Constants.FRAME_MAX_HEIGHT; +import static mage.client.constants.Constants.FRAME_MAX_WIDTH; +import static mage.client.constants.Constants.TEXT_MAX_HEIGHT; +import static mage.client.constants.Constants.TEXT_MAX_WIDTH; +import static mage.client.constants.Constants.TEXT_MAX_YOFFSET; +import mage.client.plugins.impl.Plugins; +import mage.client.util.ImageHelper; import mage.constants.EnlargeMode; +import org.jdesktop.swingx.JXPanel; /** * Class for displaying big image of the card @@ -69,9 +75,13 @@ public class BigCard extends JComponent { protected EnlargeMode enlargeMode; public BigCard() { + this(false); + } + + public BigCard(boolean rotated) { initComponents(); if (!Plugins.getInstance().isCardPluginLoaded()) { - initBounds(); + initBounds(rotated); } setDoubleBuffered(true); setOpaque(true); @@ -79,16 +89,20 @@ public class BigCard extends JComponent { this.scrollPane.setVisible(false); } - private void initBounds() { + private void initBounds(boolean rotated) { oldWidth = this.getWidth(); - scrollPane.setBounds(this.getWidth()*1000/17777,this.getWidth()*1000/1100, - this.getWidth()*1000/1142,this.getWidth()*1000/2539); + if (rotated) { + scrollPane.setBounds(50, 50, 100, 100); + } else { + scrollPane.setBounds(this.getWidth()*1000/17777,this.getWidth()*1000/1100, + this.getWidth()*1000/1142,this.getWidth()*1000/2539); + } } public void clearUp() { } - + public void setCard(UUID cardId, EnlargeMode enlargeMode, Image image, List strings) { if (this.cardId == null || !enlargeMode.equals(this.enlargeMode) || !this.cardId.equals(cardId)) { if (this.panel != null) { @@ -141,7 +155,7 @@ public class BigCard extends JComponent { public void showTextComponent() { if (oldWidth != this.getWidth()) { - initBounds(); + initBounds(false); } this.scrollPane.setVisible(true); } diff --git a/Mage.Client/src/main/java/mage/client/components/MageComponents.java b/Mage.Client/src/main/java/mage/client/components/MageComponents.java index 13e5f15b3b..7add7ab6df 100644 --- a/Mage.Client/src/main/java/mage/client/components/MageComponents.java +++ b/Mage.Client/src/main/java/mage/client/components/MageComponents.java @@ -9,13 +9,16 @@ public enum MageComponents { CARD_INFO_PANE("cardInfoPane"), POPUP_CONTAINER("popupContainer"), CARD_PREVIEW_PANE("cardPreviewPane"), - CARD_PREVIEW_CONTAINER("cardPreviewContainer"); + CARD_PREVIEW_CONTAINER("cardPreviewContainer"), + CARD_PREVIEW_PANE_ROTATED("cardPreviewPaneRotated"), + CARD_PREVIEW_CONTAINER_ROTATED("cardPreviewContainer"); - private String name; + private final String name; MageComponents(String name) { this.name = name; } + @Override public String toString() { return this.name; } diff --git a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java index 69e8be9d08..84123e4d0b 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java +++ b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java @@ -64,7 +64,11 @@ public class MageActionCallback implements ActionCallback { private TransferData popupData; private JComponent cardInfoPane; private volatile boolean popupTextWindowOpen = false; - private volatile boolean enlargedImageWindowOpen = false; + enum EnlargedWindowState { + CLOSED, NORMAL, ROTATED + } + private volatile EnlargedWindowState enlargedWindowState = EnlargedWindowState.CLOSED; + //private volatile boolean enlargedImageWindowOpen = false; // shows the alternative card the normal card or the alternative card (copy source, other flip side, other transformed side) private volatile EnlargeMode enlargeMode; @@ -239,7 +243,7 @@ public class MageActionCallback implements ActionCallback { public void run() { ThreadUtils.sleep(300); - if (popupCard == null || !popupCard.equals(data.card) || session == null || !popupTextWindowOpen || enlargedImageWindowOpen) { + if (popupCard == null || !popupCard.equals(data.card) || session == null || !popupTextWindowOpen || !enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { return; } @@ -260,7 +264,7 @@ public class MageActionCallback implements ActionCallback { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - if (!popupTextWindowOpen || enlargedImageWindowOpen) { + if (!popupTextWindowOpen || !enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { return; } popupContainer.setVisible(true); @@ -301,7 +305,7 @@ public class MageActionCallback implements ActionCallback { } else { popupTextWindowOpen = true; } - if (enlargedImageWindowOpen) { + if (!enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { displayEnlargedCard(mageCard.getOriginal(), transferData); } } @@ -356,7 +360,7 @@ public class MageActionCallback implements ActionCallback { @Override public void mouseWheelMoved(MouseWheelEvent e, TransferData transferData) { int notches = e.getWheelRotation(); - if (enlargedImageWindowOpen) { + if (!enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { // same move direction will be ignored, opposite direction closes the enlarged window if (enlargeMode.equals(EnlargeMode.NORMAL)) { if (notches > 0) { @@ -384,7 +388,7 @@ public class MageActionCallback implements ActionCallback { * @param showAlternative defines if the original image (if it's a copied card) or the opposite side of a transformable card will be shown */ public void enlargeCard(EnlargeMode showAlternative) { - if (!enlargedImageWindowOpen) { + if (enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { this.enlargeMode = showAlternative; CardView cardView = null; if (popupData != null) { @@ -394,18 +398,25 @@ public class MageActionCallback implements ActionCallback { hidePopup(); } if (cardView != null) { - enlargedImageWindowOpen = true; + if (cardView.isToRotate()) { + enlargedWindowState = EnlargedWindowState.ROTATED; + } else { + enlargedWindowState = EnlargedWindowState.NORMAL; + } displayEnlargedCard(cardView, popupData); } } } public void hideEnlargedCard() { - if (enlargedImageWindowOpen) { - enlargedImageWindowOpen = false; + if (!enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { + enlargedWindowState = EnlargedWindowState.CLOSED; try { Component cardPreviewContainer = MageFrame.getUI().getComponent(MageComponents.CARD_PREVIEW_CONTAINER); cardPreviewContainer.setVisible(false); + cardPreviewContainer = MageFrame.getUI().getComponent(MageComponents.CARD_PREVIEW_CONTAINER_ROTATED); + cardPreviewContainer.setVisible(false); + } catch (InterruptedException e) { e.printStackTrace(); } @@ -422,14 +433,31 @@ public class MageActionCallback implements ActionCallback { return; } try { - if (!enlargedImageWindowOpen) { + if (enlargedWindowState.equals(EnlargedWindowState.CLOSED)) { return; } Component parentComponent = SwingUtilities.getRoot(transferData.component); Point parentPoint = parentComponent.getLocationOnScreen(); - final Component popupContainer = MageFrame.getUI().getComponent(MageComponents.CARD_PREVIEW_CONTAINER); - Component cardPreviewPane = MageFrame.getUI().getComponent(MageComponents.CARD_PREVIEW_PANE); + MageComponents mageComponentCardPreviewContainer; + MageComponents mageComponentCardPreviewPane; + if (cardView.isToRotate()) { + if(enlargedWindowState.equals(EnlargedWindowState.NORMAL)) { + hideEnlargedCard(); + enlargedWindowState = EnlargedWindowState.ROTATED; + } + mageComponentCardPreviewContainer = MageComponents.CARD_PREVIEW_CONTAINER_ROTATED; + mageComponentCardPreviewPane = MageComponents.CARD_PREVIEW_PANE_ROTATED; + } else { + if(enlargedWindowState.equals(EnlargedWindowState.ROTATED)) { + hideEnlargedCard(); + enlargedWindowState = EnlargedWindowState.NORMAL; + } + mageComponentCardPreviewContainer = MageComponents.CARD_PREVIEW_CONTAINER; + mageComponentCardPreviewPane = MageComponents.CARD_PREVIEW_PANE; + } + final Component popupContainer = MageFrame.getUI().getComponent(mageComponentCardPreviewContainer); + Component cardPreviewPane = MageFrame.getUI().getComponent(mageComponentCardPreviewPane); if (cardPreviewPane != null) { Point location = new Point((int) transferData.locationOnScreen.getX() + transferData.popupOffsetX - 40, (int) transferData.locationOnScreen.getY() + transferData.popupOffsetY - 40); location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, cardPreviewPane, parentComponent); @@ -477,7 +505,12 @@ public class MageActionCallback implements ActionCallback { private void displayCardInfo(MageCard mageCard, Image image, BigCard bigCard) { if (image != null && image instanceof BufferedImage) { // XXX: scaled to fit width - image = ImageHelper.getResizedImage((BufferedImage) image, bigCard.getWidth()); + if (mageCard.getOriginal().isToRotate() && bigCard.getWidth() > bigCard.getHeight()) { + image = ImageHelper.getResizedImage((BufferedImage) image, bigCard.getHeight()); + image = ImageHelper.rotate((BufferedImage) image, Math.toRadians(90)); + } else { + image = ImageHelper.getResizedImage((BufferedImage) image, bigCard.getWidth()); + } bigCard.setCard(mageCard.getOriginal().getId(), enlargeMode, image, mageCard.getOriginal().getRules()); // if it's an ability, show only the ability text as overlay if (mageCard.getOriginal().isAbility()) { diff --git a/Mage.Client/src/main/java/mage/client/util/ImageHelper.java b/Mage.Client/src/main/java/mage/client/util/ImageHelper.java index 3eeae4bb13..1d3311c7de 100644 --- a/Mage.Client/src/main/java/mage/client/util/ImageHelper.java +++ b/Mage.Client/src/main/java/mage/client/util/ImageHelper.java @@ -28,11 +28,15 @@ package mage.client.util; -import static mage.constants.Constants.*; - +import com.mortennobel.imagescaling.ResampleOp; import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.Image; +import java.awt.Rectangle; import java.awt.RenderingHints; +import java.awt.Transparency; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.awt.image.MemoryImageSource; @@ -41,28 +45,27 @@ import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.List; - import javax.imageio.ImageIO; - import mage.cards.CardDimensions; +import static mage.client.constants.Constants.FRAME_MAX_HEIGHT; +import static mage.client.constants.Constants.FRAME_MAX_WIDTH; +import static mage.client.constants.Constants.SYMBOL_MAX_SPACE; import mage.view.CardView; import org.mage.card.arcane.UI; -import com.mortennobel.imagescaling.ResampleOp; -import java.awt.Rectangle; - /** * * @author BetaSteward_at_googlemail.com */ public class ImageHelper { - protected static HashMap images = new HashMap(); - protected static HashMap backgrounds = new HashMap(); + protected static HashMap images = new HashMap<>(); + protected static HashMap backgrounds = new HashMap<>(); public static BufferedImage loadImage(String ref, int width, int height) { BufferedImage image = loadImage(ref); - if (image != null) + if (image != null) { return scaleImage(image, width, height); + } return null; } @@ -74,8 +77,9 @@ public class ImageHelper { */ public static BufferedImage loadImage(String ref, int height) { BufferedImage image = loadImage(ref); - if (image != null) + if (image != null) { return scaleImage(image, height); + } return null; } @@ -148,6 +152,24 @@ public class ImageHelper { } + public static BufferedImage rotate(BufferedImage image, double angle) { + double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle)); + int w = image.getWidth(), h = image.getHeight(); + int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin); + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gs = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gs.getDefaultConfiguration(); + + BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT); + Graphics2D g = result.createGraphics(); + g.translate((neww-w)/2, (newh-h)/2); + g.rotate(angle, w/2, h/2); + g.drawRenderedImage(image, null); + g.dispose(); + return result; + } + public static void drawCosts(List costs, Graphics2D g, int xOffset, int yOffset, ImageObserver o) { if (costs.size() > 0) { int costLeft = xOffset; @@ -176,6 +198,9 @@ public class ImageHelper { /** * Returns an image scaled to fit width * panel + * @param original + * @param width + * @return */ public static BufferedImage getResizedImage(BufferedImage original, int width) { if (width != original.getWidth()) { @@ -189,6 +214,9 @@ public class ImageHelper { /** * Returns an image scaled to the needed size + * @param original + * @param sizeNeed + * @return */ public static BufferedImage getResizedImage(BufferedImage original, Rectangle sizeNeed) { ResampleOp resampleOp = new ResampleOp(sizeNeed.width, sizeNeed.height); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java index 3a035aa3cf..76ca147112 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java @@ -337,10 +337,10 @@ public class ImageCache { if (card.getUsesVariousArt()) { key += "#usesVariousArt"; } - log.warn("getImage: " + key); + // log.warn("getImage: " + key); BufferedImage original = getImage(key); if (original == null) { - log.warn(key + " not found"); + log.debug(key + " not found"); return null; } diff --git a/Mage.Common/src/mage/view/CardView.java b/Mage.Common/src/mage/view/CardView.java index 9563425468..267e255925 100644 --- a/Mage.Common/src/mage/view/CardView.java +++ b/Mage.Common/src/mage/view/CardView.java @@ -108,6 +108,8 @@ public class CardView extends SimpleCardView { protected boolean controlledByOwner = true; + protected boolean rotate; + public CardView(Card card, UUID cardId) { this(card); this.id = cardId; @@ -125,9 +127,19 @@ public class CardView extends SimpleCardView { SplitCard splitCard = null; if (card.isSplitCard()) { splitCard = (SplitCard) card; + rotate = true; } else { - if (card instanceof Spell && ((Spell) card).getSpellAbility().getSpellAbilityType().equals(SpellAbilityType.SPLIT_FUSED)) { - splitCard = (SplitCard) ((Spell) card).getCard(); + if (card instanceof Spell) { + switch(((Spell) card).getSpellAbility().getSpellAbilityType()) { + case SPLIT_FUSED: + splitCard = (SplitCard) ((Spell) card).getCard(); + rotate = true; + break; + case SPLIT_LEFT: + case SPLIT_RIGHT: + rotate = true; + break; + } } } if (splitCard != null) { @@ -596,5 +608,9 @@ public class CardView extends SimpleCardView { public boolean isFlipCard() { return flipCard; } + + public boolean isToRotate() { + return rotate; + } } diff --git a/Mage/src/mage/cards/SplitCard.java b/Mage/src/mage/cards/SplitCard.java index 9aea6839f3..1716f41793 100644 --- a/Mage/src/mage/cards/SplitCard.java +++ b/Mage/src/mage/cards/SplitCard.java @@ -46,6 +46,7 @@ import mage.watchers.Watcher; /** * * @author LevelX2 + * @param */ public abstract class SplitCard> extends CardImpl {