* GUI: new reworked GUI and card render engine, card icons and dozens of other fixes (see full list in related PR);

This commit is contained in:
Oleg Agafonov 2021-01-30 16:38:55 +04:00
parent df98cc3e62
commit a1da5ef437
304 changed files with 7266 additions and 5093 deletions

View file

@ -123,7 +123,7 @@ public class ColorPane extends JEditorPane {
tooltipCounter = 0;
}
if (tooltipCounter > 0) {
Point location = new Point(getLocationOnScreen().x - container.getWidth(), MouseInfo.getPointerInfo().getLocation().y);
Point location = new Point(this.getLocationOnScreen().x - container.getWidth(), MouseInfo.getPointerInfo().getLocation().y);
Component parentComponent = MageFrame.getInstance();
location = GuiDisplayUtil.keepComponentInsideParent(location, parentComponent.getLocationOnScreen(), container, parentComponent);
container.setLocation(location);

View file

@ -15,8 +15,8 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.*;
import mage.client.util.Command;
/**
@ -261,7 +261,7 @@ public class HoverButton extends JPanel implements MouseListener {
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
if (SwingUtilities.isLeftMouseButton(e)) {
if (isEnabled() && observer != null) {
observer.execute();
}

View file

@ -0,0 +1,306 @@
package mage.client.components;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.net.URL;
/**
* An <CODE>Icon</CODE> that scales its image to fill the component area, excluding any border or insets, optionally maintaining the image's
* aspect ratio by padding and centering the scaled image horizontally or vertically.
* <p>
* The class is a drop-in replacement for <CODE>ImageIcon</CODE>, except that the no-argument constructor is not supported.
* <p>
* As the size of the Icon is determined by the size of the component in which it is displayed, <CODE>StretchIcon</CODE> must only be used
* in conjunction with a component and layout that does not depend on the size of the component's Icon.
* <p>
* Source: https://stackoverflow.com/a/34514866/1276632
*
* @author Darryl
* @version 1.1 01/15/2016
*/
public class StretchIcon extends ImageIcon {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Determines whether the aspect ratio of the image is maintained. Set to <code>false</code> to allow th image to distort to fill the
* component.
*/
protected boolean proportionate = true;
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes.
*
* @param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* @see ImageIcon#ImageIcon(byte[])
*/
public StretchIcon(byte[] imageData) {
super(imageData);
}
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes with the specified behavior.
*
* @param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
* @see ImageIcon#ImageIcon(byte[])
*/
public StretchIcon(byte[] imageData, boolean proportionate) {
super(imageData);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes.
*
* @param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* @param description a brief textual description of the image
* @see ImageIcon#ImageIcon(byte[], String)
*/
public StretchIcon(byte[] imageData, String description) {
super(imageData, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes with the specified behavior.
*
* @param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* @param description a brief textual description of the image
* @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
* @see ImageIcon#ImageIcon(byte[])
* @see ImageIcon#ImageIcon(byte[], String)
*/
public StretchIcon(byte[] imageData, String description, boolean proportionate) {
super(imageData, description);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image.
*
* @param image the image
* @see ImageIcon#ImageIcon(Image)
*/
public StretchIcon(Image image) {
super(image);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image with the specified behavior.
*
* @param image the image
* @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
* @see ImageIcon#ImageIcon(Image)
*/
public StretchIcon(Image image, boolean proportionate) {
super(image);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image.
*
* @param image the image
* @param description a brief textual description of the image
* @see ImageIcon#ImageIcon(Image, String)
*/
public StretchIcon(Image image, String description) {
super(image, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image with the specified behavior.
*
* @param image the image
* @param description a brief textual description of the image
* @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
* @see ImageIcon#ImageIcon(Image, String)
*/
public StretchIcon(Image image, String description, boolean proportionate) {
super(image, description);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file.
*
* @param filename a String specifying a filename or path
* @see ImageIcon#ImageIcon(String)
*/
public StretchIcon(String filename) {
super(filename);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file with the specified behavior.
*
* @param filename a String specifying a filename or path
* @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
* @see ImageIcon#ImageIcon(String)
*/
public StretchIcon(String filename, boolean proportionate) {
super(filename);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file.
*
* @param filename a String specifying a filename or path
* @param description a brief textual description of the image
* @see ImageIcon#ImageIcon(String, String)
*/
public StretchIcon(String filename, String description) {
super(filename, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file with the specified behavior.
*
* @param filename a String specifying a filename or path
* @param description a brief textual description of the image
* @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
* @see ImageIcon#ImageIcon(Image, String)
*/
public StretchIcon(String filename, String description, boolean proportionate) {
super(filename, description);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL.
*
* @param location the URL for the image
* @see ImageIcon#ImageIcon(URL)
*/
public StretchIcon(URL location) {
super(location);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL with the specified behavior.
*
* @param location the URL for the image
* @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
* @see ImageIcon#ImageIcon(URL)
*/
public StretchIcon(URL location, boolean proportionate) {
super(location);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL.
*
* @param location the URL for the image
* @param description a brief textual description of the image
* @see ImageIcon#ImageIcon(URL, String)
*/
public StretchIcon(URL location, String description) {
super(location, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL with the specified behavior.
*
* @param location the URL for the image
* @param description a brief textual description of the image
* @param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
* @see ImageIcon#ImageIcon(URL, String)
*/
public StretchIcon(URL location, String description, boolean proportionate) {
super(location, description);
this.proportionate = proportionate;
}
/**
* Paints the icon. The image is reduced or magnified to fit the component to which it is painted.
* <p>
* If the proportion has not been specified, or has been specified as <code>true</code>, the aspect ratio of the image will be preserved
* by padding and centering the image horizontally or vertically. Otherwise the image may be distorted to fill the component it is
* painted to.
* <p>
* If this icon has no image observer,this method uses the <code>c</code> component as the observer.
*
* @param c the component to which the Icon is painted. This is used as the observer if this icon has no image observer
* @param g the graphics context
* @param x not used.
* @param y not used.
* @see ImageIcon#paintIcon(Component, Graphics, int, int)
*/
@Override
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
Image image = getImage();
if (image == null) {
return;
}
Insets insets = ((Container) c).getInsets();
x = insets.left;
y = insets.top;
int w = c.getWidth() - x - insets.right;
int h = c.getHeight() - y - insets.bottom;
if (proportionate) {
int iw = image.getWidth(c);
int ih = image.getHeight(c);
if ((iw * h) < (ih * w)) {
iw = (h * iw) / ih;
x += (w - iw) / 2;
w = iw;
} else {
ih = (w * ih) / iw;
y += (h - ih) / 2;
h = ih;
}
}
ImageObserver io = getImageObserver();
/*
* Added this code to generate nicer looking results when scaling. - bspkrs
* BEGIN CHANGES
*/
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, w, h, io == null ? c : io);
g2d.dispose();
/*
* END CHANGES
*/
g.drawImage(bi, x, y, w, h, io == null ? c : io);
}
/**
* Overridden to return 0. The size of this Icon is determined by the size of the component.
*
* @return 0
*/
@Override
public int getIconWidth() {
return 0;
}
/**
* Overridden to return 0. The size of this Icon is determined by the size of the component.
*
* @return 0
*/
@Override
public int getIconHeight() {
return 0;
}
}

View file

@ -158,7 +158,7 @@ public class AbilityPicker extends JXPanel implements MouseWheelListener {
rows.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
if (evt.getButton() == MouseEvent.BUTTON1) {
if (SwingUtilities.isLeftMouseButton(evt)) {
objectMouseClicked(evt);
}
}
@ -320,7 +320,6 @@ public class AbilityPicker extends JXPanel implements MouseWheelListener {
if (isSelected) {
label.setIcon(new ImageIcon(rightImageHovered));
label.setForeground(SELECTED_COLOR);
//label.setBorder(BorderFactory.createLineBorder(BORDER_COLOR));
label.setBorder(BorderFactory.createEmptyBorder());
} else {
label.setIcon(new ImageIcon(rightImage));

View file

@ -2,7 +2,6 @@ package mage.client.components.ext.dlg;
import mage.client.components.ext.MessageDialogType;
import mage.client.components.ext.dlg.impl.ChoiceDialog;
import mage.client.components.ext.dlg.impl.StackDialog;
import javax.swing.*;
import java.awt.*;
@ -10,15 +9,15 @@ import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
/**
* @author mw, noxx
* Game GUI: part of the old dialog system
*
* @author mw, noxx, JayDi85
*/
public class DialogContainer extends JPanel {
private static final int X_OFFSET = 30;
private static final int Y_OFFSET = 30;
private final BufferedImage shadow = null;
//private DialogManager.MTGDialogs dialogType;
//private DlgParams params;
private Color backgroundColor = new Color(0, 255, 255, 60);
private int alpha = 50;
@ -38,102 +37,61 @@ public class DialogContainer extends JPanel {
drawContainer = true;
switch (dialogType) {
case MESSAGE:
//backgroundColor = new Color(0, 255, 255, 60);
case MESSAGE: {
if (params.type == MessageDialogType.WARNING) {
backgroundColor = new Color(255, 0, 0, 90);
} else {
backgroundColor = new Color(0, 0, 0, 90);
}
alpha = 0;
//MessageDlg dlg = new MessageDlg(params);
//add(dlg);
//dlg.setLocation(X_OFFSET + 10, Y_OFFSET);
//dlg.updateSize(params.rect.width, params.rect.height);
break;
case STACK: {
//backgroundColor = new Color(0, 255, 255, 60);
backgroundColor = new Color(0, 0, 0, 50);
alpha = 0;
StackDialog dlg = new StackDialog(params);
add(dlg);
dlg.setLocation(X_OFFSET + 10, Y_OFFSET + 10);
//int width = Math.min(params.rect.width - 80, 600);
int width = params.rect.width;
int height = params.rect.height - 80;
dlg.updateSize(width, height);
break;
}
/*
else if (dialogType == DialogManager.MTGDialogs.COMBAT) {
backgroundColor = new Color(0, 0, 0, 60);
alpha = 0;
COMBAT dlg = new COMBAT(params);
add(dlg);
dlg.setLocation(X_OFFSET + 10, Y_OFFSET + 10);
dlg.updateSize(params.rect.width - 80, params.rect.height - 80);
}*/
case CHOICE: {
//backgroundColor = new Color(200, 200, 172, 120);
//backgroundColor = new Color(180, 150, 200, 120);
//backgroundColor = new Color(0, 255, 0, 60);
//backgroundColor = new Color(139, 46, 173, 20);
backgroundColor = new Color(0, 0, 0, 110);
//backgroundColor = new Color(139, 46, 173, 0);
alpha = 0;
ChoiceDialog dlg = new ChoiceDialog(params, "Choose");
add(dlg);
//GameManager.getManager().setCurrentChoiceDlg(dlg);
dlg.setLocation(X_OFFSET + 10, Y_OFFSET + 10);
dlg.updateSize(params.rect.width - 80, params.rect.height - 80);
break;
}
case GRAVEYARD: {
backgroundColor = new Color(0, 0, 0, 110);
alpha = 0;
ChoiceDialog dlg = new ChoiceDialog(params, "Graveyard");
add(dlg);
dlg.setLocation(X_OFFSET + 10, Y_OFFSET + 10);
dlg.updateSize(params.rect.width - 80, params.rect.height - 80);
break;
}
case EXILE: {
backgroundColor = new Color(250, 250, 250, 50);
alpha = 0;
ChoiceDialog dlg = new ChoiceDialog(params, "Exile");
add(dlg);
dlg.setLocation(X_OFFSET + 10, Y_OFFSET + 10);
dlg.updateSize(params.rect.width - 80, params.rect.height - 80);
break;
}
case EMBLEMS: {
backgroundColor = new Color(0, 0, 50, 110);
alpha = 0;
ChoiceDialog dlg = new ChoiceDialog(params, "Command Zone (Commander, Emblems and Planes)");
add(dlg);
dlg.setLocation(X_OFFSET + 10, Y_OFFSET + 10);
dlg.updateSize(params.rect.width - 80, params.rect.height - 80);
break;
}
}
}
public void cleanUp() {
for (Component component:this.getComponents()) {
for (Component component : this.getComponents()) {
if (component instanceof ChoiceDialog) {
((ChoiceDialog) component).cleanUp();
}

View file

@ -15,10 +15,11 @@ import java.util.Map;
import java.util.UUID;
/**
* Game GUI: part of the old dialog system, transparent dialog with cards list (example: exile button on player's panel)
*
* @author mw, noxx
*/
public class DialogManager extends JComponent implements MouseListener,
MouseMotionListener {
public class DialogManager extends JComponent implements MouseListener, MouseMotionListener {
private static final Map<UUID, DialogManager> dialogManagers = new HashMap<>();
@ -39,7 +40,7 @@ public class DialogManager extends JComponent implements MouseListener,
}
public enum MTGDialogs {
NONE, ABOUT, MESSAGE, STACK, ASSIGN_DAMAGE, MANA_CHOICE, CHOICE, EMBLEMS, GRAVEYARD, DialogContainer, COMBAT,
NONE, ABOUT, MESSAGE, ASSIGN_DAMAGE, MANA_CHOICE, CHOICE, EMBLEMS, GRAVEYARD, DialogContainer, COMBAT,
CHOOSE_DECK, CHOOSE_COMMON, REVEAL, EXILE
}
@ -107,75 +108,6 @@ public class DialogManager extends JComponent implements MouseListener,
this.screen_height = screen_height;
}
public void showStackDialog(CardsView cards, BigCard bigCard, FeedbackPanel feedbackPanel, UUID gameId) {
int w = (int) (screen_width * 0.7);
//int h = (int) (screen_height * 0.5);
int h = 360;
/*if (h < 200) {
h = 200;
}*/
if (w > 800) {
w = 800;
}
int height = getHeight();
int width = getWidth();
int x = ((width - w) / 2);
int y = ((height - h) / 2);
DlgParams params = new DlgParams();
params.rect = new Rectangle(x, y, w, h);
params.bigCard = bigCard;
params.gameId = gameId;
params.feedbackPanel = feedbackPanel;
params.setCards(cards);
dialogContainer = new DialogContainer(MTGDialogs.STACK, params);
dialogContainer.setVisible(true);
add(dialogContainer);
this.currentDialog = MTGDialogs.DialogContainer;
setDlgBounds(new Rectangle(x, y, w, h));
dialogContainer.showDialog(true);
setVisible(true);
}
public void showGraveyardDialog(CardsView cards, BigCard bigCard, UUID gameId) {
int w = 720;
int h = 550;
int height = getHeight();
int width = getWidth();
int x = ((width - w) / 2);
int y = ((height - h) / 2);
DlgParams params = new DlgParams();
params.rect = new Rectangle(x, y, w, h);
params.bigCard = bigCard;
params.gameId = gameId;
//params.feedbackPanel = feedbackPanel;
params.setCards(cards);
dialogContainer = new DialogContainer(MTGDialogs.GRAVEYARD, params);
dialogContainer.setVisible(true);
add(dialogContainer);
this.currentDialog = MTGDialogs.DialogContainer;
setDlgBounds(new Rectangle(x, y, w, h));
dialogContainer.showDialog(true);
setVisible(true);
}
public void showExileDialog(CardsView cards, BigCard bigCard, UUID gameId) {
int w = 720;
@ -317,7 +249,7 @@ public class DialogManager extends JComponent implements MouseListener,
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
if (SwingUtilities.isLeftMouseButton(e)) {
j = (JComponent) getComponentAt(e.getX(), e.getY());
if (j instanceof DialogContainer) {

View file

@ -8,33 +8,28 @@ import javax.swing.*;
import java.awt.*;
/**
* @author mw, noxx
* Game GUI: part of the old dialog system
*
* @author mw, noxx, JayDi85
*/
public abstract class IDialogPanel extends JXPanel {
private DlgParams params;
private final DlgParams params;
private Dimension cardDimension;
public DlgParams getDlgParams() {
return params;
}
public void setDlgParams(DlgParams params) {
this.params = params;
}
public IDialogPanel(DlgParams params) {
super();
this.params = params;
}
protected void updateSize(int newWidth, int newHeight) {
Rectangle r0 = getBounds();
r0.width = newWidth;
r0.height = newHeight;
setBounds(r0);
}
@ -42,7 +37,6 @@ public abstract class IDialogPanel extends JXPanel {
* Make inner component transparent.
*/
protected void makeTransparent() {
setOpaque(false);
for (int i = 0; i < getComponentCount(); i++) {
@ -50,13 +44,12 @@ public abstract class IDialogPanel extends JXPanel {
if (c instanceof AbstractButton && !(c instanceof JButton)) {
((AbstractButton) c).setContentAreaFilled(false);
} else if (c instanceof ImageButton) {
((AbstractButton) c).setContentAreaFilled(false);
((AbstractButton) c).setContentAreaFilled(false);
}
}
}
protected void makeTransparent(JLayeredPane jLayeredPane) {
setOpaque(false);
for (int i = 0; i < getComponentCount(); i++) {
@ -64,7 +57,7 @@ public abstract class IDialogPanel extends JXPanel {
if (c instanceof AbstractButton && !(c instanceof JButton)) {
((AbstractButton) c).setContentAreaFilled(false);
} else if (c instanceof ImageButton) {
((AbstractButton) c).setContentAreaFilled(false);
((AbstractButton) c).setContentAreaFilled(false);
}
}
}

View file

@ -1,6 +1,7 @@
package mage.client.components.ext.dlg.impl;
import mage.cards.MageCard;
import mage.abilities.icon.CardIconRenderSettings;
import mage.client.cards.BigCard;
import mage.client.components.HoverButton;
import mage.client.components.ext.ShadowLabel;
@ -15,7 +16,6 @@ import mage.client.util.SettingsManager;
import mage.client.util.audio.AudioManager;
import mage.view.CardView;
import mage.view.CardsView;
import org.mage.card.arcane.CardPanel;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
import javax.swing.*;
@ -24,7 +24,9 @@ import java.util.ArrayList;
import java.util.UUID;
/**
* @author mw, noxx
* Game GUI: transparent dialog with cards list (example: exile button on player's panel)
*
* @author mw, noxx, JayDi85
*/
public class ChoiceDialog extends IDialogPanel {
@ -74,25 +76,15 @@ public class ChoiceDialog extends IDialogPanel {
in_a_row = 5;
rows = 2;
/**
* Calculate max pages
*/
// calculate max pages
maxPages = cards.size() / (in_a_row * rows);
if (cards.size() % (in_a_row * rows) != 0) {
maxPages++;
}
/**
* Init
*/
initialize();
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
jTitle = new ShadowLabel(title, 14);
jTitle.setBounds(new Rectangle(5, 4, 500, 16));
@ -100,9 +92,7 @@ public class ChoiceDialog extends IDialogPanel {
this.setLayout(null);
/**
* Components
*/
// components
this.add(jTitle, null);
this.add(getJButtonOK(), null);
this.add(getJButtonPrevPage(), null);
@ -111,17 +101,14 @@ public class ChoiceDialog extends IDialogPanel {
this.add(getJButtonCancel(), null);
makeTransparent();
/**
* Manage cards
*/
///GameManager.getManager().resetChosenCards();
// cards
displayCards(params.getCards(), params.gameId, params.bigCard);
}
public void cleanUp() {
for (Component comp : this.getComponents()) {
if (comp instanceof CardPanel) {
((CardPanel) comp).cleanUp();
if (comp instanceof MageCard) {
((MageCard) comp).cleanUp();
this.remove(comp);
}
}
@ -163,10 +150,11 @@ public class ChoiceDialog extends IDialogPanel {
}
CardView card = cardList.get(i);
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, getCardDimension(), gameId, true, true, PreferencesDialog.getRenderMode(), true);
cardImg.setLocation(dx, dy + j * (height + 30));
add(cardImg);
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, new CardIconRenderSettings(), getCardDimension(), gameId, true, true, PreferencesDialog.getRenderMode(), true);
cardImg.setCardContainerRef(this);
cardImg.update(card);
cardImg.setCardBounds(dx, dy + j * (height + 30), width, height);
this.add(cardImg);
dx += (width + 20);
}

View file

@ -1,184 +0,0 @@
package mage.client.components.ext.dlg.impl;
import mage.cards.MageCard;
import mage.client.cards.BigCard;
import mage.client.components.HoverButton;
import mage.client.components.ext.dlg.DialogContainer;
import mage.client.components.ext.dlg.DialogManager;
import mage.client.components.ext.dlg.DlgParams;
import mage.client.components.ext.dlg.IDialogPanel;
import mage.client.dialog.PreferencesDialog;
import mage.client.game.FeedbackPanel;
import mage.client.plugins.impl.Plugins;
import mage.client.util.Command;
import mage.client.util.SettingsManager;
import mage.view.CardView;
import mage.view.CardsView;
import mage.view.StackAbilityView;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
import javax.swing.*;
import java.awt.*;
import java.util.UUID;
/**
* @author mw, noxx
*/
public class StackDialog extends IDialogPanel {
private static final long serialVersionUID = 1L;
private JLabel jTitle = null;
private JLabel jTitle2 = null;
private HoverButton jButtonAccept = null;
private HoverButton jButtonResponse = null;
private JLayeredPane jLayeredPane;
private final FeedbackPanel feedbackPanel;
private final UUID gameId;
private static class CustomLabel extends JLabel {
@Override
public void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2D.setColor(Color.black);
g2D.drawString(getText(), 1, 11);
g2D.setColor(Color.white);
g2D.drawString(getText(), 0, 10);
}
private static final long serialVersionUID = 1L;
}
/**
* This is the default constructor
*/
public StackDialog(DlgParams params) {
super(params);
this.feedbackPanel = params.feedbackPanel;
this.gameId = params.gameId;
initialize();
displayStack(params.getCards(), params.gameId, params.bigCard);
}
/**
* This method initializes this
*
* @return void
*/
private void initialize() {
int w = getDlgParams().rect.width;
int h = getDlgParams().rect.height;
jLayeredPane = new JLayeredPane();
add(jLayeredPane);
jLayeredPane.setSize(w, h);
jLayeredPane.setVisible(true);
jLayeredPane.setOpaque(false);
jTitle = new CustomLabel();
jTitle.setBounds(new Rectangle(5, 3, w, 16));
jTitle.setFont(new Font("Dialog", Font.BOLD, 14));
jTitle.setText("Current stack: ");
this.setLayout(null);
jLayeredPane.setLayout(null);
jLayeredPane.add(jTitle, null);
//jLayeredPane.add(jTitle2, null);
jLayeredPane.add(getJButtonAccept(), null);
jLayeredPane.add(getJButtonResponse(), null);
makeTransparent(jLayeredPane);
}
private void displayStack(CardsView cards, UUID gameId, BigCard bigCard) {
if (cards == null || cards.isEmpty()) {
return;
}
/**
* Display spells and theis targets above them
*/
int dx = (SettingsManager.instance.getCardSize().width + 15) * (cards.size() - 1);
int dy = 30;
for (CardView card : cards.values()) {
if (card instanceof StackAbilityView) {
// replace ability by original card
CardView tmp = ((StackAbilityView) card).getSourceCard();
tmp.overrideRules(card.getRules());
tmp.setChoosable(card.isChoosable());
tmp.setPlayable(card.isPlayable());
tmp.setPlayableAmount(card.getPlayableAmount());
tmp.setSelected(card.isSelected());
tmp.setIsAbility(true);
tmp.overrideTargets(card.getTargets());
tmp.overrideId(card.getId());
card = tmp;
}
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, getCardDimension(), gameId, true, true, PreferencesDialog.getRenderMode(), true);
//cardImg.setBorder(BorderFactory.createLineBorder(Color.red));
cardImg.setLocation(dx, dy);
jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 1);
dx -= (SettingsManager.instance.getCardSize().width + 15);
}
}
private HoverButton getJButtonAccept() {
if (jButtonAccept == null) {
jButtonAccept = new HoverButton("", ImageManagerImpl.instance.getDlgAcceptButtonImage(),
ImageManagerImpl.instance.getDlgActiveAcceptButtonImage(),
ImageManagerImpl.instance.getDlgAcceptButtonImage(),
new Rectangle(60, 60));
int w = getDlgParams().rect.width - 90;
int h = getDlgParams().rect.height - 90;
jButtonAccept.setBounds(new Rectangle(w / 2 - 80, h - 50, 60, 60));
//jButtonAccept.setBorder(BorderFactory.createLineBorder(Color.red));
jButtonAccept.setObserver(new Command() {
@Override
public void execute() {
DialogManager.getManager(gameId).fadeOut((DialogContainer) getParent());
//GameManager.getInputControl().getInput().selectButtonOK();
StackDialog.this.feedbackPanel.doClick();
}
private static final long serialVersionUID = 1L;
});
}
return jButtonAccept;
}
private HoverButton getJButtonResponse() {
if (jButtonResponse == null) {
jButtonResponse = new HoverButton("", ImageManagerImpl.instance.getDlgCancelButtonImage(),
ImageManagerImpl.instance.getDlgActiveCancelButtonImage(),
ImageManagerImpl.instance.getDlgCancelButtonImage(),
new Rectangle(60, 60));
int w = getDlgParams().rect.width - 90;
int h = getDlgParams().rect.height - 90;
jButtonResponse.setBounds(new Rectangle(w / 2 + 5, h - 48, 60, 60));
jButtonResponse.setObserver(new Command() {
@Override
public void execute() {
DialogManager.getManager(gameId).fadeOut((DialogContainer) getParent());
}
private static final long serialVersionUID = 1L;
});
}
return jButtonResponse;
}
}