* 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

@ -1,5 +1,6 @@
package mage.client;
import mage.MageException;
import mage.cards.action.ActionCallback;
import mage.cards.decks.Deck;
import mage.cards.repository.CardRepository;
@ -53,6 +54,7 @@ import net.java.truevfs.access.TConfig;
import net.java.truevfs.kernel.spec.FsAccessOption;
import org.apache.log4j.Logger;
import org.mage.card.arcane.ManaSymbols;
import org.mage.card.arcane.SvgUtils;
import org.mage.plugins.card.images.DownloadPicturesService;
import org.mage.plugins.card.info.CardInfoPaneImpl;
import org.mage.plugins.card.utils.CardImageUtils;
@ -81,6 +83,7 @@ import java.util.prefs.Preferences;
public class MageFrame extends javax.swing.JFrame implements MageClient {
private static final String TITLE_NAME = "XMage";
private static final Logger logger = Logger.getLogger(MageFrame.class);
private static final Logger LOGGER = Logger.getLogger(MageFrame.class);
private static final String LITE_MODE_ARG = "-lite";
@ -186,7 +189,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
/**
* Creates new form MageFrame
*/
public MageFrame() {
public MageFrame() throws MageException {
setWindowTitle();
EDTExceptionHandler.registerExceptionHandler();
@ -248,8 +251,12 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
if (RateCard.PRELOAD_CARD_RATINGS_ON_STARTUP) {
RateCard.bootstrapCardsAndRatings();
}
SvgUtils.checkSvgSupport();
ManaSymbols.loadImages();
Plugins.instance.loadPlugins();
if (!Plugins.instance.isCardPluginLoaded()) {
throw new MageException("can't load card plugin");
}
initComponents();
@ -1232,7 +1239,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
} else {
SwingUtilities.invokeLater(() -> userRequestDialog.showDialog(userRequestMessage));
}
}
public void showErrorDialog(final String title, final String message) {
@ -1241,7 +1247,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
} else {
SwingUtilities.invokeLater(() -> errorDialog.showDialog(title, message));
}
}
public void showCollectionViewer() {
@ -1329,7 +1334,12 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
splash.update();
}
}
instance = new MageFrame();
try {
instance = new MageFrame();
} catch (Throwable e) {
logger.fatal("Critical error on start up, app will be closed: " + e.getMessage(), e);
System.exit(1);
}
// debug menu
instance.separatorDebug.setVisible(debugMode);
@ -1348,7 +1358,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
instance.currentConnection.setPassword(startPassword);
}
instance.setVisible(true);
});
}

View file

@ -1,10 +1,3 @@
/*
* MagePane.java
*
* Created on 15-Dec-2009, 9:34:25 PM
*/
package mage.client;
import java.awt.*;

View file

@ -1,11 +1,3 @@
/*
* BigCard.java
*
* Created on Jan 18, 2010, 3:21:33 PM
*/
package mage.client.cards;
import java.awt.Dimension;

View file

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection component="Form" name="preferredSize" type="property"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new Dimension(dimension.frameWidth, dimension.frameHeight)" type="code"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-30,0,0,0,-88"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
<Property name="useNullLayout" type="boolean" value="true"/>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="horizontalScrollBarPolicy" type="int" value="31"/>
<Property name="focusable" type="boolean" value="false"/>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_allCodePost" type="java.lang.String" value="jScrollPane1.setBounds(new Rectangle(dimension.contentXOffset, dimension.textYOffset, dimension.textWidth, dimension.textHeight));"/>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout" value="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout$AbsoluteConstraintsDescription">
<AbsoluteConstraints x="20" y="110" width="130" height="100"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextPane" name="text">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Arial" size="9" style="0"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="4"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View file

@ -1,544 +0,0 @@
package mage.client.cards;
import mage.cards.CardDimensions;
import mage.cards.MagePermanent;
import mage.cards.Sets;
import mage.cards.TextPopup;
import mage.cards.action.ActionCallback;
import mage.client.MageFrame;
import mage.client.game.PlayAreaPanel;
import mage.client.util.ClientDefaultSettings;
import mage.client.util.DefaultActionCallback;
import mage.client.util.ImageHelper;
import mage.client.util.gui.ArrowBuilder;
import mage.constants.CardType;
import mage.constants.EnlargeMode;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.view.*;
import org.apache.log4j.Logger;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static mage.client.constants.Constants.*;
/**
* @author BetaSteward_at_googlemail.com
*/
@SuppressWarnings("serial")
public class Card extends MagePermanent implements MouseMotionListener, MouseListener, FocusListener, ComponentListener {
protected Point p;
protected final CardDimensions dimension;
protected final UUID gameId;
protected final BigCard bigCard;
protected CardView card;
protected Popup tooltipPopup;
protected boolean tooltipShowing;
protected final TextPopup tooltipText = new TextPopup();
protected BufferedImage background;
protected final BufferedImage image = new BufferedImage(FRAME_MAX_WIDTH, FRAME_MAX_HEIGHT, BufferedImage.TYPE_INT_RGB);
protected final BufferedImage small;
protected String backgroundName;
// if this is set, it's opened if the user right clicks on the card panel
private JPopupMenu popupMenu;
/**
* Creates new form Card
*
* @param card
* @param bigCard
* @param dimension
* @param gameId
*/
public Card(CardView card, BigCard bigCard, CardDimensions dimension, UUID gameId) {
this.dimension = dimension;
initComponents();
this.gameId = gameId;
this.card = card;
this.bigCard = bigCard;
small = new BufferedImage(ClientDefaultSettings.dimensions.getFrameWidth(), ClientDefaultSettings.dimensions.getFrameHeight(), BufferedImage.TYPE_INT_RGB);
backgroundName = getBackgroundName();
background = ImageHelper.getBackground(card, backgroundName);
StyledDocument doc = text.getStyledDocument();
Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
Style regular = doc.addStyle("regular", def);
StyleConstants.setFontFamily(def, "arial");
Style s = doc.addStyle("small", regular);
StyleConstants.setFontSize(s, 9);
//addMouseListener(this);
//text.addMouseListener(this);
//addFocusListener(this);
//addMouseMotionListener(this);
//text.addMouseMotionListener(this);
//addComponentListener(this);
}
public UUID getCardId() {
return card.getId();
}
@Override
public void update(PermanentView permanent) {
this.update((CardView) permanent);
}
@Override
public void update(CardView card) {
this.card = card;
Graphics2D gImage = image.createGraphics();
Graphics2D gSmall = small.createGraphics();
String cardType = getType(card);
String testBackgroundName = getBackgroundName();
if (!testBackgroundName.equals(backgroundName)) {
backgroundName = testBackgroundName;
background = ImageHelper.getBackground(card, backgroundName);
}
tooltipText.setText(getText(cardType));
gImage.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gImage.setColor(Color.BLACK);
gImage.drawImage(background, 0, 0, this);
if (!card.getManaCost().isEmpty()) {
ImageHelper.drawCosts(card.getManaCost(), gImage, FRAME_MAX_WIDTH - SYMBOL_MAX_XOFFSET, SYMBOL_MAX_YOFFSET, this);
}
gSmall.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gSmall.setColor(Color.BLACK);
gSmall.drawImage(ImageHelper.scaleImage(image, ClientDefaultSettings.dimensions.getFrameWidth(), ClientDefaultSettings.dimensions.getFrameHeight()), 0, 0, this);
gImage.setFont(new Font("Arial", Font.PLAIN, NAME_FONT_MAX_SIZE));
gImage.drawString(card.getName() + "TEST", CONTENT_MAX_XOFFSET, NAME_MAX_YOFFSET);
if (card.isCreature()) {
gImage.drawString(card.getPower() + '/' + card.getToughness(), POWBOX_TEXT_MAX_LEFT, POWBOX_TEXT_MAX_TOP);
} else if (card.isPlanesWalker()) {
gImage.drawString(card.getLoyalty(), POWBOX_TEXT_MAX_LEFT, POWBOX_TEXT_MAX_TOP);
}
if (!card.getCardTypes().isEmpty()) {
gImage.drawString(cardType, CONTENT_MAX_XOFFSET, TYPE_MAX_YOFFSET);
}
gImage.dispose();
gSmall.setFont(new Font("Arial", Font.PLAIN, ClientDefaultSettings.dimensions.getNameFontSize()));
gSmall.drawString(card.getName() + "TEST2", ClientDefaultSettings.dimensions.getContentXOffset(), ClientDefaultSettings.dimensions.getNameYOffset());
if (card.isCreature()) {
gSmall.drawString(card.getPower() + "/-/" + card.getToughness(), ClientDefaultSettings.dimensions.getPowBoxTextLeft(), ClientDefaultSettings.dimensions.getPowBoxTextTop());
} else if (card.isPlanesWalker()) {
gSmall.drawString(card.getLoyalty(), ClientDefaultSettings.dimensions.getPowBoxTextLeft(), ClientDefaultSettings.dimensions.getPowBoxTextTop());
}
if (!card.getCardTypes().isEmpty()) {
gSmall.drawString(cardType, ClientDefaultSettings.dimensions.getContentXOffset(), ClientDefaultSettings.dimensions.getTypeYOffset());
}
drawText();
gSmall.dispose();
}
@Override
public void updateArtImage() {
}
protected String getText(String cardType) {
StringBuilder sb = new StringBuilder();
if (card instanceof StackAbilityView || card instanceof AbilityView) {
for (String rule : getRules()) {
sb.append('\n').append(rule);
}
} else {
sb.append(card.getName());
if (!card.getManaCost().isEmpty()) {
sb.append('\n').append(card.getManaCost());
}
sb.append('\n').append(cardType);
if (card.getColor().hasColor()) {
sb.append('\n').append(card.getColor().toString());
}
if (card.isCreature()) {
sb.append('\n').append(card.getPower()).append('/').append(card.getToughness());
} else if (card.isPlanesWalker()) {
sb.append('\n').append(card.getLoyalty());
}
for (String rule : getRules()) {
sb.append('\n').append(rule);
}
if (card.getExpansionSetCode() != null && !card.getExpansionSetCode().isEmpty()) {
sb.append('\n').append(card.getCardNumber()).append(" - ");
sb.append(Sets.getInstance().get(card.getExpansionSetCode()).getName()).append(" - ");
sb.append(card.getRarity() == null ? "none" : card.getRarity().toString());
}
}
// sb.append("\n").append(card.getId());
return sb.toString();
}
private String getBackgroundName() {
if (card instanceof StackAbilityView || card instanceof AbilityView) {
return "effect";
}
StringBuilder sb = new StringBuilder();
if (card.isLand()) {
sb.append("land").append(card.getSuperTypes()).append(card.getSubTypes());
} else if (card.getCardTypes() != null && (card.isCreature() || card.isPlanesWalker())) {
sb.append("creature");
}
sb.append(card.getColor()).append(card.getRarity()).append(card.getExpansionSetCode());
return sb.toString();
}
protected void drawText() {
text.setText("");
StyledDocument doc = text.getStyledDocument();
try {
for (String rule : getRules()) {
doc.insertString(doc.getLength(), rule + '\n', doc.getStyle("small"));
}
} catch (BadLocationException e) {
}
text.setCaretPosition(0);
}
protected List<String> getRules() {
if (card.getCounters() != null) {
List<String> rules = new ArrayList<>(card.getRules());
for (CounterView counter : card.getCounters()) {
rules.add(counter.getCount() + " x " + counter.getName());
}
return rules;
} else {
return card.getRules();
}
}
protected String getType(CardView card) {
StringBuilder sbType = new StringBuilder();
for (SuperType superType : card.getSuperTypes()) {
sbType.append(superType).append(' ');
}
for (CardType cardType : card.getCardTypes()) {
sbType.append(cardType.toString()).append(' ');
}
if (!card.getSubTypes().isEmpty()) {
sbType.append("- ");
for (SubType subType : card.getSubTypes()) {
sbType.append(subType).append(' ');
}
}
return sbType.toString();
}
protected void drawDetailed(Graphics2D g) {
// Get the size of the card
int width = getWidth();
int height = getHeight();
g.setColor(Color.black);
g.drawRoundRect(0, 0, width, height, 4, 4);
g.setColor(Color.white);
g.setFont(new Font("Arial", Font.PLAIN, NAME_FONT_MAX_SIZE));
g.drawString(card.getName(), 0, 0);
Logger.getLogger(Card.class).info("Drawing");
}
/**
* 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.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
text = new javax.swing.JTextPane();
setMinimumSize(getPreferredSize());
setOpaque(false);
setPreferredSize(new Dimension(dimension.getFrameWidth(), dimension.getFrameHeight()));
setLayout(null);
jScrollPane1.setBorder(null);
jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jScrollPane1.setFocusable(false);
jScrollPane1.setOpaque(false);
text.setBorder(null);
text.setEditable(false);
text.setFont(new java.awt.Font("Arial", 0, 9));
text.setFocusable(false);
text.setOpaque(false);
jScrollPane1.setViewportView(text);
add(jScrollPane1);
jScrollPane1.setBounds(20, 110, 130, 100);
jScrollPane1.setBounds(new Rectangle(dimension.getContentXOffset(), dimension.getTextYOffset(), dimension.getTextWidth(), dimension.getTextHeight()));
}// </editor-fold>//GEN-END:initComponents
@Override
public void paintComponent(Graphics graphics) {
drawDetailed((Graphics2D) graphics);
/*
Graphics2D g2 = (Graphics2D) graphics;
g2.drawImage(small, 0, 0, this);
//Add a border, red if card currently has focus
if (isFocusOwner()) {
g2.setColor(Color.RED);
} else {
g2.setColor(Color.BLACK);
}
g2.drawRect(0, 0, Config.dimensions.frameWidth - 1, Config.dimensions.frameHeight - 1);
*/
}
@Override
public void mouseDragged(MouseEvent arg0) {
}
@Override
public void mouseMoved(MouseEvent arg0) {
// this.bigCard.showTextComponent();
this.bigCard.setCard(card.getId(), EnlargeMode.NORMAL, image, getRules(), false);
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
requestFocusInWindow();
DefaultActionCallback.instance.mouseClicked(gameId, card);
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
@Override
public void mouseEntered(MouseEvent arg0) {
if (!tooltipShowing) {
if (tooltipPopup != null) {
tooltipPopup.hide();
}
PopupFactory factory = PopupFactory.getSharedInstance();
tooltipPopup = factory.getPopup(this, tooltipText, (int) this.getLocationOnScreen().getX() + ClientDefaultSettings.dimensions.getFrameWidth(), (int) this.getLocationOnScreen().getY() + 40);
tooltipPopup.show();
//hack to get tooltipPopup to resize to fit text
tooltipPopup.hide();
tooltipPopup = factory.getPopup(this, tooltipText, (int) this.getLocationOnScreen().getX() + ClientDefaultSettings.dimensions.getFrameWidth(), (int) this.getLocationOnScreen().getY() + 40);
tooltipPopup.show();
tooltipShowing = true;
// Draw Arrows for targets
List<UUID> targets = card.getTargets();
if (targets != null) {
for (UUID uuid : targets) {
PlayAreaPanel playAreaPanel = MageFrame.getGamePlayers(gameId).get(uuid);
if (playAreaPanel != null) {
Point target = playAreaPanel.getLocationOnScreen();
Point me = this.getLocationOnScreen();
ArrowBuilder.getBuilder().addArrow(gameId, (int) me.getX() + 35, (int) me.getY(), (int) target.getX() + 40, (int) target.getY() - 40, Color.red, ArrowBuilder.Type.TARGET);
} else {
for (PlayAreaPanel pa : MageFrame.getGamePlayers(gameId).values()) {
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
if (permanent != null) {
Point target = permanent.getLocationOnScreen();
Point me = this.getLocationOnScreen();
ArrowBuilder.getBuilder().addArrow(gameId, (int) me.getX() + 35, (int) me.getY(), (int) target.getX() + 40, (int) target.getY() + 10, Color.red, ArrowBuilder.Type.TARGET);
}
}
}
}
}
}
}
@Override
public void mouseExited(MouseEvent arg0) {
if (getMousePosition(true) != null) {
return;
}
if (tooltipPopup != null) {
tooltipPopup.hide();
tooltipShowing = false;
ArrowBuilder.getBuilder().removeArrowsByType(gameId, ArrowBuilder.Type.TARGET);
ArrowBuilder.getBuilder().removeArrowsByType(gameId, ArrowBuilder.Type.PAIRED);
ArrowBuilder.getBuilder().removeArrowsByType(gameId, ArrowBuilder.Type.BANDED);
ArrowBuilder.getBuilder().removeArrowsByType(gameId, ArrowBuilder.Type.SOURCE);
ArrowBuilder.getBuilder().removeArrowsByType(gameId, ArrowBuilder.Type.ENCHANT_PLAYERS);
}
}
@Override
public void focusGained(FocusEvent arg0) {
this.repaint();
}
@Override
public void focusLost(FocusEvent arg0) {
if (tooltipPopup != null) {
tooltipPopup.hide();
}
this.repaint();
}
protected JScrollPane getText() {
return jScrollPane1;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JScrollPane jScrollPane1;
protected javax.swing.JTextPane text;
// End of variables declaration//GEN-END:variables
@Override
public void componentResized(ComponentEvent e) {
}
@Override
public void componentMoved(ComponentEvent e) {
}
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public void componentHidden(ComponentEvent e) {
if (tooltipPopup != null) {
tooltipPopup.hide();
}
}
@Override
public List<MagePermanent> getLinks() {
return null;
}
@Override
public boolean isTapped() {
return false;
}
@Override
public boolean isFlipped() {
return false;
}
@Override
public void onBeginAnimation() {
}
@Override
public void onEndAnimation() {
}
@Override
public void setAlpha(float transparency) {
}
@Override
public CardView getOriginal() {
return card;
}
@Override
public void setCardBounds(int x, int y, int width, int height) {
// do nothing
}
@Override
public Image getImage() {
return image;
}
@Override
public void setZone(String zone) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String getZone() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void updateCallback(ActionCallback callback, UUID gameId) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public PermanentView getOriginalPermanent() {
return null;
}
@Override
public float getAlpha() {
return 0;
}
@Override
public void toggleTransformed() {
}
@Override
public boolean isTransformed() {
return false;
}
@Override
public void showCardTitle() {
}
@Override
public void setSelected(boolean isSelected) {
}
@Override
public void setCardAreaRef(JPanel cardArea) {
}
@Override
public void setChoosable(boolean isChoosable) {
}
@Override
public void setCardCaptionTopOffset(int yOffsetPercent) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public JPopupMenu getPopupMenu() {
return popupMenu;
}
@Override
public void setPopupMenu(JPopupMenu popupMenu) {
this.popupMenu = popupMenu;
}
}

View file

@ -1,26 +1,35 @@
package mage.client.cards;
import mage.abilities.icon.CardIconOrder;
import mage.abilities.icon.CardIconPosition;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.ClientEventType;
import mage.client.util.Event;
import mage.client.util.GUISizeHelper;
import mage.client.util.Listener;
import mage.view.AbilityView;
import mage.view.CardView;
import mage.view.CardsView;
import mage.view.SimpleCardView;
import org.mage.card.arcane.CardPanel;
import mage.util.DebugUtil;
import mage.view.*;
import org.apache.log4j.Logger;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import java.util.UUID;
public class CardArea extends JPanel implements MouseListener {
/**
* Panel with cards list, can show cards in two modes:
* - cards one by one in the line;
* - stacked and multicolumns (if many cards);
*
* Uses in some dialogs like pile choose and cards choosing
*/
public class CardArea extends JPanel implements CardEventProducer {
private static final Logger logger = Logger.getLogger(CardArea.class);
protected final CardEventSource cardEventSource = new CardEventSource();
@ -38,7 +47,9 @@ public class CardArea extends JPanel implements MouseListener {
private Dimension customCardSize = null; // custom card size for tests
private boolean customNeedFullPermanentRender = false; // disable permanent render mode, see CardArea for more info
private int customXOffsetBetweenCardsOrColumns = 0;
private MouseListener customMouseListener = null;
private CardIconPosition customCardIconPosition = null;
private CardIconOrder customCardIconOrder = null;
private int customCardIconsMaxVisibleCount = 0;
/**
* Create the panel.
@ -51,12 +62,26 @@ public class CardArea extends JPanel implements MouseListener {
setGUISize();
cardArea = new JLayeredPane();
scrollPane.setViewportView(cardArea);
if (DebugUtil.GUI_GAME_DIALOGS_DRAW_CARDS_AREA_BORDER) {
this.setBorder(BorderFactory.createLineBorder(Color.yellow));
}
// ENABLE non card popup menu
// if you want process popup menu from card then use special event
cardArea.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.isPopupTrigger() || SwingUtilities.isRightMouseButton(e)) {
Plugins.instance.getActionCallback().popupMenuPanel(e, CardArea.this);
}
}
});
}
public void cleanUp() {
for (Component comp : cardArea.getComponents()) {
if (comp instanceof CardPanel) {
((CardPanel) comp).cleanUp();
if (comp instanceof MageCard) {
((MageCard) comp).cleanUp();
cardArea.remove(comp);
}
}
@ -65,7 +90,7 @@ public class CardArea extends JPanel implements MouseListener {
public void changeGUISize() {
setGUISize();
for (Component component : cardArea.getComponents()) {
if (component instanceof CardPanel) {
if (component instanceof MageCard) {
component.setBounds(0, 0, cardDimension.width, cardDimension.height);
}
}
@ -93,6 +118,8 @@ public class CardArea extends JPanel implements MouseListener {
newSize.width += 20;
newSize.height += 20;
this.setPreferredSize(newSize);
scrollPane.getHorizontalScrollBar().setUnitIncrement(GUISizeHelper.getCardsScrollbarUnitInc(cardDimension.width));
scrollPane.getVerticalScrollBar().setUnitIncrement(GUISizeHelper.getCardsScrollbarUnitInc(cardDimension.height));
}
public void loadCards(CardsView showCards, BigCard bigCard, UUID gameId) {
@ -107,7 +134,6 @@ public class CardArea extends JPanel implements MouseListener {
}
redraw();
fixDialogSize();
}
@ -157,10 +183,16 @@ public class CardArea extends JPanel implements MouseListener {
tmp.setAbility(card); // cross-reference, required for ability picker
card = tmp;
}
MageCard cardPanel = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, true, true,
CardIconRenderSettings customIconsRender = new CardIconRenderSettings()
.withDebugMode(true)
.withCustomPosition(customCardIconPosition)
.withCustomOrder(customCardIconOrder)
.withCustomMaxVisibleCount(customCardIconsMaxVisibleCount)
.withCustomIconSizePercent(30);
MageCard cardPanel = Plugins.instance.getMageCard(card, bigCard, customIconsRender, cardDimension, gameId, true, true,
customRenderMode != -1 ? customRenderMode : PreferencesDialog.getRenderMode(), customNeedFullPermanentRender);
cardPanel.setBounds(rectangle);
cardPanel.addMouseListener(customMouseListener != null ? customMouseListener : this);
cardPanel.setCardContainerRef(this);
cardPanel.update(card);
cardPanel.setCardBounds(rectangle.x, rectangle.y, cardDimension.width, cardDimension.height);
cardArea.add(cardPanel);
@ -238,59 +270,6 @@ public class CardArea extends JPanel implements MouseListener {
cardEventSource.clearListeners();
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
if (e.getClickCount() >= 1 && !e.isConsumed()) {
Object obj = e.getSource();
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0)) { // double clicks and repeated double clicks
e.consume();
if (obj instanceof Card) {
if (e.isAltDown()) {
cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK);
} else {
cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.DOUBLE_CLICK);
}
} else if (obj instanceof MageCard) {
if (e.isAltDown()) {
cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK);
} else {
cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.DOUBLE_CLICK);
}
}
}
if (obj instanceof MageCard) {
checkMenu(e, ((MageCard) obj).getOriginal());
} else {
checkMenu(e, null);
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (!e.isConsumed()) {
Object obj = e.getSource();
if (obj instanceof MageCard) {
checkMenu(e, ((MageCard) obj).getOriginal());
} else {
checkMenu(e, null);
}
} else {
cardEventSource.fireEvent(ClientEventType.ACTION_CONSUMED);
}
}
private void checkMenu(MouseEvent Me, SimpleCardView card) {
if (Me.isPopupTrigger()) {
Me.consume();
cardEventSource.fireEvent(card, Me.getComponent(), Me.getX(), Me.getY(), ClientEventType.SHOW_POP_UP_MENU);
}
}
public void setCustomRenderMode(int customRenderMode) {
this.customRenderMode = customRenderMode;
}
@ -307,16 +286,20 @@ public class CardArea extends JPanel implements MouseListener {
this.customXOffsetBetweenCardsOrColumns = customXOffsetBetweenCardsOrColumns;
}
public void setCustomMouseListener(MouseListener customMouseListener) {
this.customMouseListener = customMouseListener;
public void setCustomCardIconsPanelPosition(CardIconPosition panelPosition) {
this.customCardIconPosition = panelPosition;
}
public void setCustomCardIconsPanelOrder(CardIconOrder panelOrder) {
this.customCardIconOrder = panelOrder;
}
public void setCustomCardIconsMaxVisibleCount(int maxVisibleCount) {
this.customCardIconsMaxVisibleCount = maxVisibleCount;
}
@Override
public void mouseEntered(MouseEvent e) {
public CardEventSource getCardEventSource() {
return this.cardEventSource;
}
@Override
public void mouseExited(MouseEvent e) {
}
}

View file

@ -1,40 +1,53 @@
package mage.client.cards;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.client.MagePane;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.ClientDefaultSettings;
import mage.util.DebugUtil;
import mage.view.CardView;
import org.apache.log4j.Logger;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.*;
import java.util.ArrayList;
/**
* Created by StravantUser on 2016-09-22.
* Popup panel for dragging cards drawing
*
* @author StravantUser, JayDi85
*/
public class CardDraggerGlassPane implements MouseListener, MouseMotionListener {
public class CardDraggerGlassPane {
private static final Logger logger = Logger.getLogger(CardDraggerGlassPane.class);
private final DragCardSource source;
private Component dragComponent;
private JRootPane currentRoot;
private JComponent glassPane;
private DragCardTarget currentTarget;
private MageCard draggingCard; // original card that starting the dragging (full dragging cards keeps in currentCards)
private ArrayList<CardView> currentCards;
private MageCard dragView;
private DragCardTarget currentDragTarget;
private JComponent draggingGlassPane;
private MageCard draggingDrawView; // fake card for drawing on glass pane
// processing drag events (moving and the end)
private MouseListener draggingMouseListener;
private MouseMotionListener draggingMouseMotionListener;
private boolean isDragging;
private Dimension cardDimension;
// This should not be strictly needed, but for some reason I can't figure out getDeepestComponentAt and
// getComponentAt do not seem to work correctly for our setup if called on the root MageFrame.
private MagePane currentEventRootMagePane;
private MagePane eventRootPane; // example: deck editor pane
public CardDraggerGlassPane(DragCardSource source) {
this.source = source;
}
public void beginDrag(Component c, MouseEvent e) {
public void handleDragStart(MageCard card, MouseEvent cardEvent) {
// Start drag
if (isDragging) {
return;
@ -42,145 +55,153 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener
isDragging = true;
// Record what we are dragging on
dragComponent = c;
currentRoot = SwingUtilities.getRootPane(c);
draggingCard = card;
// Pane
glassPane = (JComponent) currentRoot.getGlassPane();
glassPane.setLayout(null);
glassPane.setOpaque(false);
glassPane.setVisible(true);
// Pane for dragging drawing (fake card)
JRootPane currentRoot = SwingUtilities.getRootPane(draggingCard);
draggingGlassPane = (JComponent) currentRoot.getGlassPane();
draggingGlassPane.setLayout(null);
draggingGlassPane.setOpaque(false);
draggingGlassPane.setVisible(true);
if (DebugUtil.GUI_DECK_EDITOR_DRAW_DRAGGING_PANE_BORDER) {
draggingGlassPane.setBorder(BorderFactory.createLineBorder(Color.MAGENTA));
}
// Get root mage pane to handle drag targeting in
Component rootMagePane = c;
Component rootMagePane = draggingCard;
while (rootMagePane != null && !(rootMagePane instanceof MagePane)) {
rootMagePane = rootMagePane.getParent();
}
if (rootMagePane == null) {
throw new RuntimeException("CardDraggerGlassPane::beginDrag not in a MagePane?");
} else {
currentEventRootMagePane = (MagePane) rootMagePane;
eventRootPane = (MagePane) rootMagePane;
}
// Hook up events
c.addMouseListener(this);
c.addMouseMotionListener(this);
// ENABLE drag moving and drag ending processing
if (this.draggingMouseMotionListener == null) {
this.draggingMouseMotionListener = new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
handleDragging(e);
}
};
}
if (this.draggingMouseListener == null) {
this.draggingMouseListener = new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
handleDragEnd(e);
}
};
}
draggingCard.addMouseMotionListener(this.draggingMouseMotionListener);
draggingCard.addMouseListener(this.draggingMouseListener);
// Event to local space
e = SwingUtilities.convertMouseEvent(c, e, glassPane);
MouseEvent glassEvent = SwingUtilities.convertMouseEvent(draggingCard.getMainPanel(), cardEvent, draggingGlassPane);
// Get the cards to drag
currentCards = new ArrayList<>(source.dragCardList());
// Make a view for the first one and add it to us
dragView = Plugins.instance.getMageCard(currentCards.get(0), null, new Dimension(100, 140), null, true, false, PreferencesDialog.getRenderMode(), true);
for (MouseListener l : dragView.getMouseListeners()) {
dragView.removeMouseListener(l);
// make a fake card to drawing (card's top left corner under the cursor)
Rectangle rectangle = new Rectangle(glassEvent.getX(), glassEvent.getY(), getCardDimension().width, getCardDimension().height);
draggingDrawView = Plugins.instance.getMageCard(currentCards.get(0), null, new CardIconRenderSettings(), getCardDimension(), null, true, false, PreferencesDialog.getRenderMode(), true);
draggingDrawView.setCardContainerRef(null); // no feedback events
draggingDrawView.update(currentCards.get(0));
draggingDrawView.setCardBounds(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
// disable mouse events from fake card
for (MouseListener l : draggingDrawView.getMouseListeners()) {
draggingDrawView.removeMouseListener(l);
}
for (MouseMotionListener l : dragView.getMouseMotionListeners()) {
dragView.removeMouseMotionListener(l);
for (MouseMotionListener l : draggingDrawView.getMouseMotionListeners()) {
draggingDrawView.removeMouseMotionListener(l);
}
dragView.setLocation(e.getX(), e.getY());
glassPane.add(dragView);
draggingGlassPane.add(draggingDrawView);
// Notify the sounce
source.dragCardBegin();
// Update the target
currentDragTarget = null;
updateCurrentTarget(SwingUtilities.convertMouseEvent(glassPane, e, currentEventRootMagePane), false);
currentTarget = null;
MouseEvent rootEvent = SwingUtilities.convertMouseEvent(draggingGlassPane, glassEvent, eventRootPane);
updateCurrentTarget(rootEvent, false);
}
// e is relative to currentRoot
private void updateCurrentTarget(MouseEvent e, boolean isEnding) {
Component mouseOver = SwingUtilities.getDeepestComponentAt(currentEventRootMagePane, e.getX(), e.getY());
private void handleDragging(MouseEvent e) {
// redraw fake card near the cursor
MouseEvent glassEvent = SwingUtilities.convertMouseEvent(draggingCard.getMainPanel(), e, draggingGlassPane);
draggingDrawView.setCardLocation(glassEvent.getX(), glassEvent.getY());
draggingDrawView.repaint();
// Convert the event into root coords and update target
MouseEvent rootEvent = SwingUtilities.convertMouseEvent(draggingCard.getMainPanel(), e, eventRootPane);
updateCurrentTarget(rootEvent, false);
}
private void handleDragEnd(MouseEvent e) {
// No longer dragging
isDragging = false;
// Remove custom listeners
draggingCard.removeMouseListener(this.draggingMouseListener);
draggingCard.removeMouseMotionListener(this.draggingMouseMotionListener);
// Convert the event into root coords
MouseEvent rootEvent = SwingUtilities.convertMouseEvent(draggingCard.getMainPanel(), e, eventRootPane);
// Remove the drag card
draggingGlassPane.remove(draggingDrawView);
draggingGlassPane.repaint();
// Let the drag source know
source.dragCardEnd(currentTarget);
// Update the target, and do the drop
updateCurrentTarget(rootEvent, true);
}
private void updateCurrentTarget(MouseEvent rootEvent, boolean isEnding) {
// event related to eventRootPane
Component mouseOver = SwingUtilities.getDeepestComponentAt(eventRootPane, rootEvent.getX(), rootEvent.getY());
while (mouseOver != null) {
if (mouseOver instanceof DragCardTarget) {
DragCardTarget target = (DragCardTarget) mouseOver;
MouseEvent targetEvent = SwingUtilities.convertMouseEvent(currentEventRootMagePane, e, mouseOver);
if (target != currentDragTarget) {
if (currentDragTarget != null) {
MouseEvent oldTargetEvent = SwingUtilities.convertMouseEvent(currentEventRootMagePane, e, (Component) currentDragTarget);
currentDragTarget.dragCardExit(oldTargetEvent);
MouseEvent targetEvent = SwingUtilities.convertMouseEvent(eventRootPane, rootEvent, mouseOver);
if (target != currentTarget) {
if (currentTarget != null) {
MouseEvent oldTargetEvent = SwingUtilities.convertMouseEvent(eventRootPane, rootEvent, (Component) currentTarget);
currentTarget.dragCardExit(oldTargetEvent);
}
currentDragTarget = target;
currentDragTarget.dragCardEnter(targetEvent);
currentTarget = target;
currentTarget.dragCardEnter(targetEvent);
}
if (isEnding) {
currentDragTarget.dragCardExit(targetEvent);
currentDragTarget.dragCardDrop(targetEvent, source, currentCards);
currentTarget.dragCardExit(targetEvent);
currentTarget.dragCardDrop(targetEvent, source, currentCards);
} else {
currentDragTarget.dragCardMove(targetEvent);
currentTarget.dragCardMove(targetEvent);
}
return;
}
mouseOver = mouseOver.getParent();
}
if (currentDragTarget != null) {
MouseEvent oldTargetEvent = SwingUtilities.convertMouseEvent(currentEventRootMagePane, e, (Component) currentDragTarget);
currentDragTarget.dragCardExit(oldTargetEvent);
if (currentTarget != null) {
MouseEvent oldTargetEvent = SwingUtilities.convertMouseEvent(eventRootPane, rootEvent, (Component) currentTarget);
currentTarget.dragCardExit(oldTargetEvent);
}
currentDragTarget = null;
currentTarget = null;
}
protected Dimension getCardDimension() {
if (cardDimension == null) {
cardDimension = new Dimension(ClientDefaultSettings.dimensions.getFrameWidth(), ClientDefaultSettings.dimensions.getFrameHeight());
}
return cardDimension;
}
public boolean isDragging() {
return isDragging;
}
/**
* Mouse released -> we are done the drag
*/
@Override
public void mouseReleased(MouseEvent e) {
// No longer dragging
isDragging = false;
// Remove listeners
dragComponent.removeMouseListener(this);
dragComponent.removeMouseMotionListener(this);
// Convert the event into root coords
e = SwingUtilities.convertMouseEvent(dragComponent, e, currentEventRootMagePane);
// Remove the drag card
glassPane.remove(dragView);
glassPane.repaint();
// Let the drag source know
source.dragCardEnd(currentDragTarget);
// Update the target, and do the drop
updateCurrentTarget(e, true);
}
@Override
public void mouseDragged(MouseEvent e) {
// Update the view
MouseEvent glassE = SwingUtilities.convertMouseEvent(dragComponent, e, glassPane);
dragView.setLocation(glassE.getX(), glassE.getY());
dragView.repaint();
// Convert the event into root coords and update target
e = SwingUtilities.convertMouseEvent(dragComponent, e, currentEventRootMagePane);
updateCurrentTarget(e, false);
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
}
}

View file

@ -0,0 +1,12 @@
package mage.client.cards;
/**
* Add it to components that will be generates card's events (example: panel with cards list)
*
* @author JayDi85
*/
public interface CardEventProducer {
CardEventSource getCardEventSource();
}

View file

@ -1,16 +1,15 @@
package mage.client.cards;
import mage.client.util.*;
import mage.client.util.Event;
import mage.client.util.*;
import mage.view.SimpleCardView;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.io.Serializable;
/**
*
* @author BetaSteward_at_googlemail.com
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class CardEventSource implements EventSource<Event>, Serializable {
@ -22,25 +21,41 @@ public class CardEventSource implements EventSource<Event>, Serializable {
dispatcher.addListener(listener);
}
public void fireEvent(SimpleCardView card, ClientEventType eventType, int number){
dispatcher.fireEvent(new Event(card, eventType, number));
}
public void fireEvent(ClientEventType eventType){
dispatcher.fireEvent(new Event(null, eventType));
}
public void fireEvent(SimpleCardView card, ClientEventType eventType){
dispatcher.fireEvent(new Event(card, eventType));
}
public void fireEvent(SimpleCardView card, Component component, int x, int y, ClientEventType message) {
dispatcher.fireEvent(new Event(card, message, x, y, component));
}
@Override
public void clearListeners() {
dispatcher.clearListeners();
}
public void fireEvent(SimpleCardView card, ClientEventType eventType, int number) {
fireEvent(new Event(card, eventType, number));
}
public void fireEvent(ClientEventType eventType) {
fireEvent(new Event(null, eventType));
}
public void fireEvent(SimpleCardView card, ClientEventType eventType) {
fireEvent(new Event(card, eventType));
}
public void fireEvent(SimpleCardView card, Component component, int x, int y, ClientEventType message) {
fireEvent(new Event(card, message, 0, x, y, component));
}
public void fireEvent(SimpleCardView card, ClientEventType eventType, MouseEvent e, boolean forceFakeAltDown) {
Event event;
if (e != null) {
// normal mouse event
event = new Event(card, eventType, 0, e.getX(), e.getY(), e.getComponent(), e, forceFakeAltDown);
} else {
// fake mouse event
event = new Event(card, eventType, 0, 0, 0, null, null, forceFakeAltDown);
}
fireEvent(event);
}
public void fireEvent(Event clientEvent) {
dispatcher.fireEvent(clientEvent);
}
}

View file

@ -1,43 +1,40 @@
/*
* CardGrid.java
*
* Created on 30-Mar-2010, 9:25:40 PM
*/
package mage.client.cards;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.client.deckeditor.SortSetting;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.ClientEventType;
import mage.client.util.Event;
import mage.client.util.GUISizeHelper;
import mage.client.util.Listener;
import mage.client.util.comparators.*;
import mage.constants.Rarity;
import mage.utils.CardColorUtil;
import mage.view.CardView;
import mage.view.CardsView;
import org.mage.card.arcane.CardPanel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
/**
* @author BetaSteward_at_googlemail.com
* Deck editor: grid mode for selected cards list (NOT a drafting, only for free edition and sideboarding)
* TODO: combine source code with CardsList.java
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class CardGrid extends javax.swing.JLayeredPane implements MouseListener, ICardGrid {
public class CardGrid extends javax.swing.JLayeredPane implements CardEventProducer, /* MouseListener,*/ ICardGrid {
protected final CardEventSource cardEventSource = new CardEventSource();
protected BigCard bigCard;
protected UUID gameId;
private final Map<UUID, MageCard> cards = new HashMap<>();
private Dimension cardDimension;
private final List<JLabel> countLabels = new ArrayList<>();
/**
* Max amount of cards in card grid for which card images will be drawn.
@ -102,101 +99,94 @@
}
private void addCard(CardView card, BigCard bigCard, UUID gameId, boolean drawImage) {
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, drawImage, true, PreferencesDialog.getRenderMode(), true);
cards.put(card.getId(), cardImg);
cardImg.addMouseListener(this);
add(cardImg);
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, new CardIconRenderSettings(), cardDimension, gameId, drawImage, true, PreferencesDialog.getRenderMode(), true);
cardImg.setCardContainerRef(this);
cardImg.update(card);
// card position calculated on parent call by drawCards
//cardImg.setCardBounds(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
cards.put(card.getId(), cardImg);
this.add(cardImg, (Integer) 10); // count label must be on layer 0 for background drawing
}
@Override
public void drawCards(SortSetting sortSetting) {
this.countLabels.forEach(this::remove);
this.countLabels.clear();
int maxWidth = this.getParent().getWidth();
int cardVerticalOffset = GUISizeHelper.editorCardOffsetSize;
int vertOffsetPerCardInStack = GUISizeHelper.editorCardVertOffsetInStack;
int numColumns = maxWidth / cardDimension.width;
int curColumn = 0;
int curRow = 0;
if (!cards.isEmpty()) {
Rectangle rectangle = new Rectangle(cardDimension.width, cardDimension.height);
List<MageCard> sortedCards = new ArrayList<>(cards.values());
List<CardView> sortedCards = cards.values().stream().map(MageCard::getOriginal).collect(Collectors.toList());
CardViewComparator comparator;
switch (sortSetting.getSortBy()) {
case NAME:
sortedCards.sort(new CardNameComparator());
comparator = new CardViewNameComparator();
break;
case CARD_TYPE:
sortedCards.sort(new CardTypeComparator());
comparator = new CardViewCardTypeComparator();
break;
case RARITY:
sortedCards.sort(new CardRarityComparator());
comparator = new CardViewRarityComparator();
break;
case COLOR:
sortedCards.sort(new CardColorComparator());
comparator = new CardViewColorComparator();
break;
case COLOR_IDENTITY:
sortedCards.sort(new CardColorDetailedIdentity());
comparator = new CardViewColorIdentityComparator();
break;
case CASTING_COST:
sortedCards.sort(new CardCostComparator());
comparator = new CardViewCostComparator();
break;
case UNSORTED:
comparator = new CardViewNoneComparator();
break;
case EDH_POWER_LEVEL:
comparator = new CardViewEDHPowerLevelComparator();
break;
default:
throw new IllegalArgumentException("Error, unknown sort settings in deck editor: " + sortSetting.getSortBy());
}
sortedCards.sort(new CardViewNameComparator());
sortedCards.sort(comparator);
MageCard lastCard = null;
for (MageCard cardImg : sortedCards) {
JLabel lastCountLabel = null;
for (CardView sortedCard : sortedCards) {
MageCard currentCard = this.cards.get(sortedCard.getId());
if (sortSetting.isPilesToggle()) {
if (lastCard == null) {
lastCard = cardImg;
lastCard = currentCard;
// new new count label
lastCountLabel = addNewCountLabel(curColumn);
}
switch (sortSetting.getSortBy()) {
case NAME:
if (!cardImg.getOriginal().getName().equals(lastCard.getOriginal().getName())) {
curColumn++;
curRow = 0;
}
break;
case CARD_TYPE:
if (!cardImg.getOriginal().getCardTypes().equals(lastCard.getOriginal().getCardTypes())) {
curColumn++;
curRow = 0;
}
break;
case RARITY:
if (cardImg.getOriginal().getRarity() != lastCard.getOriginal().getRarity()) {
curColumn++;
curRow = 0;
}
break;
case COLOR:
if (cardImg.getOriginal().getColor().compareTo(lastCard.getOriginal().getColor()) != 0) {
curColumn++;
curRow = 0;
}
break;
case COLOR_IDENTITY:
if (CardColorUtil.getColorIdentitySortValue(cardImg.getOriginal().getManaCost(), cardImg.getOriginal().getColor(), cardImg.getOriginal().getRules())
!= CardColorUtil.getColorIdentitySortValue(lastCard.getOriginal().getManaCost(), lastCard.getOriginal().getColor(), lastCard.getOriginal().getRules())) {
curColumn++;
curRow = 0;
}
break;
case CASTING_COST:
if (cardImg.getOriginal().getConvertedManaCost() != lastCard.getOriginal().getConvertedManaCost()) {
curColumn++;
curRow = 0;
}
break;
// create new column on different card sorting
if (comparator.compare(currentCard.getOriginal(), lastCard.getOriginal()) != 0) {
curColumn++;
curRow = 0;
// add new count label
lastCountLabel = addNewCountLabel(curColumn);
}
rectangle.setLocation(curColumn * cardDimension.width, curRow * cardVerticalOffset);
cardImg.setBounds(rectangle);
cardImg.setCardBounds(rectangle.x, rectangle.y, cardDimension.width, cardDimension.height);
moveToFront(cardImg);
// update last count label stats
String description = comparator.getCategoryName(currentCard.getOriginal());
DragCardGrid.updateCountLabel(lastCountLabel, curRow + 1, description);
rectangle.setLocation(curColumn * cardDimension.width, curRow * vertOffsetPerCardInStack + DragCardGrid.COUNT_LABEL_HEIGHT);
currentCard.setCardBounds(rectangle.x, rectangle.y, cardDimension.width, cardDimension.height);
moveToFront(currentCard);
curRow++;
lastCard = cardImg;
lastCard = currentCard;
} else {
rectangle.setLocation(curColumn * cardDimension.width, curRow * cardVerticalOffset);
cardImg.setBounds(rectangle);
cardImg.setCardBounds(rectangle.x, rectangle.y, cardDimension.width, cardDimension.height);
moveToFront(cardImg);
rectangle.setLocation(curColumn * cardDimension.width, curRow * vertOffsetPerCardInStack);
currentCard.setCardBounds(rectangle.x, rectangle.y, cardDimension.width, cardDimension.height);
moveToFront(currentCard);
curColumn++;
if (curColumn == numColumns) {
curColumn = 0;
@ -210,12 +200,20 @@
repaint();
}
private JLabel addNewCountLabel(int columnNumber) {
JLabel label = DragCardGrid.createCountLabel(null);
this.countLabels.add(label);
this.add(label, (Integer) 0); // draw on background
label.setLocation(columnNumber * cardDimension.width, 5);
label.setSize(cardDimension.width, DragCardGrid.COUNT_LABEL_HEIGHT);
label.setVisible(true);
return label;
}
private void clearCards() {
// remove possible mouse listeners, preventing gc
for (MageCard mageCard : cards.values()) {
if (mageCard instanceof CardPanel) {
((CardPanel) mageCard).cleanUp();
}
mageCard.cleanUp();
}
this.cards.clear();
removeAllCardImg();
@ -223,7 +221,7 @@
private void removeAllCardImg() {
for (Component comp : getComponents()) {
if (comp instanceof Card || comp instanceof MageCard) {
if (comp instanceof MageCard) {
remove(comp);
}
}
@ -231,15 +229,9 @@
private void removeCardImg(UUID cardId) {
for (Component comp : getComponents()) {
if (comp instanceof Card) {
if (((Card) comp).getCardId().equals(cardId)) {
remove(comp);
comp = null;
}
} else if (comp instanceof MageCard) {
if (comp instanceof MageCard) {
if (((MageCard) comp).getOriginal().getId().equals(cardId)) {
remove(comp);
comp = null;
}
}
}
@ -283,41 +275,11 @@
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
@Override
public void mouseClicked(MouseEvent e) {
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0) && !e.isConsumed()) { // double clicks and repeated double clicks
e.consume();
Object obj = e.getSource();
if (obj instanceof Card) {
if (e.isAltDown()) {
cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK);
} else {
cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.DOUBLE_CLICK);
}
} else if (obj instanceof MageCard) {
if (e.isAltDown()) {
cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK);
} else {
cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.DOUBLE_CLICK);
}
}
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
public CardEventSource getCardEventSource() {
return this.cardEventSource;
}
private void resizeArea() {
@ -350,7 +312,14 @@
}
}
class CardNameComparator implements Comparator<MageCard> {
/**
* Workaround to use CardViewComparator with card panels
*/
interface CardPanelComparator extends Comparator<MageCard> {
String getCategoryName(MageCard sample);
}
class CardPanelNameComparator implements Comparator<MageCard> {
@Override
public int compare(MageCard o1, MageCard o2) {
@ -359,7 +328,7 @@
}
class CardRarityComparator implements Comparator<MageCard> {
class CardPanelRarityComparator implements Comparator<MageCard> {
@Override
public int compare(MageCard o1, MageCard o2) {
@ -380,7 +349,7 @@
}
class CardCostComparator implements Comparator<MageCard> {
class CardPanelCostComparator implements Comparator<MageCard> {
@Override
public int compare(MageCard o1, MageCard o2) {
@ -394,7 +363,7 @@
}
class CardColorComparator implements Comparator<MageCard> {
class CardPanelColorComparator implements Comparator<MageCard> {
@Override
public int compare(MageCard o1, MageCard o2) {
@ -408,22 +377,20 @@
}
class CardColorDetailedIdentity implements Comparator<MageCard> {
class CardPanelColorIdentityComparator implements Comparator<MageCard> {
@Override
public int compare(MageCard o1, MageCard o2) {
int val = CardColorUtil.getColorIdentitySortValue(o1.getOriginal().getManaCost(), o1.getOriginal().getColor(), o1.getOriginal().getRules())
- CardColorUtil.getColorIdentitySortValue(o2.getOriginal().getManaCost(), o2.getOriginal().getColor(), o2.getOriginal().getRules());
int val = CardViewColorIdentityComparator.calcHash(o1.getOriginal()) - CardViewColorIdentityComparator.calcHash(o2.getOriginal());
if (val == 0) {
return o1.getOriginal().getName().compareTo(o2.getOriginal().getName());
} else {
return val;
}
}
}
class CardTypeComparator implements Comparator<MageCard> {
class CardPanelTypeComparator implements Comparator<MageCard> {
@Override
public int compare(MageCard o1, MageCard o2) {

View file

@ -0,0 +1,371 @@
package mage.client.cards;
import mage.abilities.icon.*;
import mage.abilities.icon.system.CombinedCountIcon;
import mage.client.components.StretchIcon;
import mage.client.dialog.PreferencesDialog;
import mage.client.util.GUISizeHelper;
import mage.util.DebugUtil;
import org.mage.card.arcane.CardRendererUtils;
import org.mage.card.arcane.ManaSymbols;
import org.mage.card.arcane.SvgUtils;
import org.mage.plugins.card.images.ImageCache;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* GUI panel to drawning icons (one of the card's side)
*
* @author JayDi85
*/
public class CardIconsPanel extends JPanel {
private static final CardIconPosition DEFAULT_POSITION = CardIconPosition.LEFT;
private static final CardIconOrder DEFAULT_ORDER = CardIconOrder.START;
private static final int DEFAULT_MAX_VISIBLE_COUNT = 5;
private static final int DEFAULT_ICON_SIZE_PERCENT = 30;
private static final int MINIMUM_ICON_SIZE = 32; // TODO: not working?
private static final int KEEP_ICON_IN_CARD_INSIDE_PERCENT = 70; // example: 66% - 2/3 keep inside and 1/3 keep outside
private static final int MAXIMUM_CARD_WIDTH_FOR_ICONS_SMALL_MODE = 100; // enable icons small mode for too small cards (combine ability icons to one);
private final CardIconPosition position;
private final CardIconOrder order;
private final int iconSizePercent; // icons size, related to card's width
private final List<CardIcon> icons;
private final int cellsMaxCount; // split card side to cells, can be 1, 3, 5, 7 (x left + 1x center + x right)
private final int cellsVisibleCount; // if it contains too much elements then replace it by combined element (example: cells x7, visible x3)
private final int cellsOffset; // how many cells must be offset from the start and the end. Example: 0 - nothing, 1 - 1x from left and 1x from right
private int iconsGap = 3; // gap between icons in the cells (aplies from left and right sides)
private int halfSize = 0; // offset for icons from the card's border
private Font font = null;
// auto-calced for small mode, see calcSizes
private int calcedCellsMaxCount = 1;
private int calcedCellsVisibleCount = 1;
private int calcedSizeSizePercent = 30;
private int calcedCellsOffset = 1;
private CardIconPosition calcedPosition;
private CardIconOrder calcedOrder;
public CardIconsPanel(CardIconRenderSettings render) {
this(render.getCustomPosition() != null ? render.getCustomPosition() : DEFAULT_POSITION,
render.getCustomOrder() != null ? render.getCustomOrder() : DEFAULT_ORDER,
render.getCustomMaxVisibleCount() > 0 ? render.getCustomMaxVisibleCount() : DEFAULT_MAX_VISIBLE_COUNT,
render.getCustomIconSizePercent() > 0 ? render.getCustomIconSizePercent() : DEFAULT_ICON_SIZE_PERCENT
);
}
public CardIconsPanel(CardIconPosition position, CardIconOrder order, int cellsVisibleCount, int iconSizePercent) {
this(position, order, cellsVisibleCount, iconSizePercent, new ArrayList<>(), new Rectangle(100, 100));
}
public CardIconsPanel(CardIconPosition position, CardIconOrder order, int cellsVisibleCount, int iconSizePercent, List<CardIcon> icons, Rectangle startingCardSize) {
super(null);
this.position = position != null ? position : DEFAULT_POSITION;
this.iconSizePercent = iconSizePercent;
this.icons = icons;
// corners have only one icon with center order
if (this.position.getMaxIconsAmount() == 1) {
this.order = CardIconOrder.START;
this.cellsOffset = 0;
this.cellsMaxCount = 1;
} else {
this.order = order != null ? order : DEFAULT_ORDER;
this.cellsOffset = 1;
this.cellsMaxCount = 7;
}
int maxIcons = Math.max(1, Math.min(this.cellsMaxCount, cellsVisibleCount)); // must be in [1..cells];
this.cellsVisibleCount = Math.min(maxIcons, this.position.getMaxIconsAmount());
this.setVisible(false);
this.setOpaque(false);
if (DebugUtil.GUI_CARD_ICONS_DRAW_PANEL_BORDER) {
this.setBorder(BorderFactory.createLineBorder(Color.red));
}
this.updateSizes(startingCardSize);
}
public void updateSizes(Rectangle cardSize) {
this.calcSizes(cardSize);
// panel uses GridLayout with gaps, grid is static size, so the sizes structure:
// [gap + icon + gap + icon + ... gap]
// corner icons must be same sizes as max possible on left/right (for a more beautiful look)
int panelFullSize = this.halfSize * 2 + cardSize.height;
int panelIconSize = (panelFullSize - (7 + 1) * this.iconsGap) / 7;
int cornerHalfSize = Math.min(panelIconSize, this.halfSize * 2) / 2; // real icons can be limited by height or width
// move panel to the inner (for a more beautiful look)
// 2/3 keep inside and 1/3 keep outside
// panels already centered by halfSize, so use "- this.halfSize"
int panelOffset = Math.round(this.halfSize * 2 * KEEP_ICON_IN_CARD_INSIDE_PERCENT / 100f) - this.halfSize;
Rectangle panelRect;
Point panelTranslate;
switch (this.calcedPosition) {
case TOP:
panelRect = new Rectangle(cardSize.x - this.halfSize, cardSize.y - this.halfSize, cardSize.width + this.halfSize * 2, this.halfSize * 2);
panelTranslate = new Point(0, panelOffset);
this.setLayout(new GridLayout(1, this.calcedCellsMaxCount, iconsGap, 0));
break;
case LEFT:
panelRect = new Rectangle(cardSize.x - this.halfSize, cardSize.y - this.halfSize, this.halfSize * 2, cardSize.height + this.halfSize * 2);
panelTranslate = new Point(panelOffset, 0);
this.setLayout(new GridLayout(this.calcedCellsMaxCount, 1, 0, iconsGap));
break;
case RIGHT:
panelRect = new Rectangle(cardSize.x + cardSize.width - this.halfSize, cardSize.y - this.halfSize, this.halfSize * 2, cardSize.height + this.halfSize * 2);
panelTranslate = new Point(-panelOffset, 0);
this.setLayout(new GridLayout(this.calcedCellsMaxCount, 1, 0, iconsGap));
break;
case BOTTOM:
panelRect = new Rectangle(cardSize.x - this.halfSize, cardSize.y + cardSize.height - this.halfSize, cardSize.width + this.halfSize * 2, this.halfSize * 2);
panelTranslate = new Point(0, -panelOffset);
this.setLayout(new GridLayout(1, this.calcedCellsMaxCount, iconsGap, 0));
break;
case CORNER_TOP_LEFT:
panelRect = new Rectangle(cardSize.x - cornerHalfSize, cardSize.y - cornerHalfSize, cornerHalfSize * 2, cornerHalfSize * 2);
panelTranslate = new Point(panelOffset, panelOffset);
this.setLayout(new GridLayout(1, 1, 0, 0));
break;
case CORNER_TOP_RIGHT:
panelRect = new Rectangle(cardSize.x + cardSize.width - cornerHalfSize, cardSize.y - cornerHalfSize, cornerHalfSize * 2, cornerHalfSize * 2);
panelTranslate = new Point(-panelOffset, panelOffset);
this.setLayout(new GridLayout(1, 1, 0, 0));
break;
case CORNER_BOTTOM_LEFT:
panelRect = new Rectangle(cardSize.x - cornerHalfSize, cardSize.y + cardSize.height - cornerHalfSize, cornerHalfSize * 2, cornerHalfSize * 2);
panelTranslate = new Point(panelOffset, -panelOffset);
this.setLayout(new GridLayout(1, 1, 0, 0));
break;
case CORNER_BOTTOM_RIGHT:
panelRect = new Rectangle(cardSize.x + cardSize.width - cornerHalfSize, cardSize.y + cardSize.height - cornerHalfSize, cornerHalfSize * 2, cornerHalfSize * 2);
panelTranslate = new Point(-panelOffset, -panelOffset);
this.setLayout(new GridLayout(1, 1, 0, 0));
break;
default:
throw new IllegalArgumentException("Card icons do not support position " + this.calcedPosition);
}
panelRect.translate(panelTranslate.x, panelTranslate.y);
this.setBounds(panelRect);
// reload icons for new size
this.updateIcons();
}
public void updateIcons() {
updateIcons(null);
}
public void updateIcons(List<CardIcon> newIcons) {
this.removeAll();
if (newIcons != null) {
this.icons.clear();
this.icons.addAll(newIcons);
}
// auto-hide panel on empty icons
if (this.icons.isEmpty()) {
this.setVisible(false);
return;
} else {
this.setVisible(true);
}
int actualMaxVisibleCount = Math.min(this.calcedCellsVisibleCount, this.calcedCellsMaxCount - this.calcedCellsOffset * 2); // preserve offset cells
List<Component> visibleComponents = new ArrayList<>();
List<Component> combinedComponents = new ArrayList<>();
List<Component> orderedComponents = new ArrayList<>();
// structure:
// * icons panel - control the icons size and offsets in card;
// * grid panel - control the icons order and position (put empty panel for empty space)
// * grid's cell - control one icon
// * label - stretched icon image that occupy all cell's space
Map<Component, CardIcon> cardLinks = new HashMap<>();
this.icons.stream()
.sorted(CardIconComparator.instance)
.forEach(icon -> {
Component iconComponent = createIconComponent(icon);
if (iconComponent != null) {
visibleComponents.add(iconComponent);
cardLinks.put(iconComponent, icon);
}
});
// OPTIMIZE visible components (if card contains too much icons then combine it in one "...")
if (visibleComponents.size() > actualMaxVisibleCount) {
while (visibleComponents.size() > actualMaxVisibleCount - 1) {
// combined must contains minimum 2 elements
combinedComponents.add(visibleComponents.remove(visibleComponents.size() - 1));
}
String combinedHint = combinedComponents
.stream()
.map(cardLinks::get)
.filter(Objects::nonNull)
.sorted(CardIconComparator.instance)
.map(CardIcon::getCombinedInfo)
.collect(Collectors.joining("<br>"));
CardIcon combinedIcon = new CombinedCountIcon(combinedComponents.size(), combinedHint);
Component combinedComponent = createIconComponent(combinedIcon);
if (combinedComponent != null) {
visibleComponents.add(combinedComponent);
}
}
// add offsets to the start of the list
if (this.calcedOrder == CardIconOrder.START || this.calcedOrder == CardIconOrder.END) {
for (int i = 0; i < this.calcedCellsOffset; i++) {
JPanel panel = new JPanel(null);
panel.setOpaque(false);
visibleComponents.add(0, panel);
}
}
// fill components list to max (grid can't put elements to cells, so must fill all)
while (visibleComponents.size() < this.calcedCellsMaxCount) {
JPanel panel = new JPanel(null);
panel.setOpaque(false);
visibleComponents.add(panel);
}
// ORDER visible components
// icons sort order example with CENTER order:
// 1: [1]
// 3: [2 1 3]
// 5: [4 2 1 3 5]
// 7: [6 4 2 1 3 5 7]
//
// icons sort order example with START order (END order is same but reversed):
// 1: [1]
// 3: [1 2 3]
// 5: [1 2 3 4 5]
// 7: [1 2 3 4 5 6 7]
if (this.calcedOrder == CardIconOrder.CENTER) {
// CENTER
if (this.calcedCellsMaxCount == 1) {
Arrays.asList(1).forEach(i -> orderedComponents.add(visibleComponents.get(i - 1)));
} else if (this.calcedCellsMaxCount == 3) {
Arrays.asList(2, 1, 3).forEach(i -> orderedComponents.add(visibleComponents.get(i - 1)));
} else if (this.calcedCellsMaxCount == 5) {
Arrays.asList(4, 2, 1, 3, 5).forEach(i -> orderedComponents.add(visibleComponents.get(i - 1)));
} else if (this.calcedCellsMaxCount == 7) {
Arrays.asList(6, 4, 2, 1, 3, 5, 7).forEach(i -> orderedComponents.add(visibleComponents.get(i - 1)));
} else {
throw new IllegalArgumentException("Card icons do not support max size as " + this.calcedCellsMaxCount);
}
} else if (this.calcedOrder == CardIconOrder.START) {
// START
orderedComponents.addAll(visibleComponents);
} else if (this.calcedOrder == CardIconOrder.END) {
// END
orderedComponents.addAll(visibleComponents);
Collections.reverse(orderedComponents);
} else {
throw new IllegalArgumentException("Card icons do not support order type " + this.calcedOrder);
}
// ADD real components to the grid
orderedComponents.forEach(this::add);
}
private Component createIconComponent(CardIcon icon) {
if (!SvgUtils.haveSvgSupport()) {
return null;
}
// direct call
//BufferedImage iconImage = ImageManagerImpl.instance.getCardIcon(icon.getIconType().getResourceName(), this.halfSize * 2);
// cached call
BufferedImage iconImageCached = ImageCache.getCardIconImage(icon.getIconType().getResourceName(), this.halfSize * 2);
if (iconImageCached != null && this.font != null) {
BufferedImage iconImageWithText = ImageManagerImpl.deepCopy(iconImageCached); // must copy cached value before modify
// text
JLabel label = new JLabel();
label.setToolTipText("<html>" + ManaSymbols.replaceSymbolsWithHTML(icon.getHint(), ManaSymbols.Type.CARD_ICON_HINT));
if (!icon.getText().isEmpty()) {
Graphics2D g2d = iconImageWithText.createGraphics();
g2d.setColor(PreferencesDialog.getCurrentTheme().getCardIconsTextColor());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle rect = CardRendererUtils.reduceRect(new Rectangle(0, 0, iconImageWithText.getWidth(), iconImageWithText.getHeight()), 0.8f);
CardRendererUtils.drawCenteredText(g2d, icon.getText(), rect, this.font, true);
g2d.dispose();
}
// the stretch icon can occupy all space (full grid's cell)
StretchIcon s = new StretchIcon(iconImageWithText, true);
label.setIcon(s);
label.setIconTextGap(0);
if (DebugUtil.GUI_CARD_ICONS_DRAW_ICON_BORDER) {
label.setBorder(BorderFactory.createLineBorder(Color.green));
}
return label;
}
return null;
}
private void calcSizes(Rectangle cardSize) {
// small mode takes 20% of card's sizes diff
boolean smallMode = false;
int maxW = GUISizeHelper.battlefieldCardMaxDimension.width;
int minW = GUISizeHelper.battlefieldCardMinDimension.width;
if (minW > maxW) {
// on wrong settings
maxW = GUISizeHelper.battlefieldCardMinDimension.width;
minW = GUISizeHelper.battlefieldCardMaxDimension.width;
}
// cardSize.width < 120 - disable small mode on too big cards
if (cardSize.width < MAXIMUM_CARD_WIDTH_FOR_ICONS_SMALL_MODE && (cardSize.width < minW + (maxW - minW) * 0.2f)) {
smallMode = true;
}
// auto-sizeable icons (smaller for small card, normal for big)
this.calcedSizeSizePercent = this.iconSizePercent;
if (smallMode) {
this.calcedSizeSizePercent = Math.round(this.calcedSizeSizePercent * 1.5f);
}
// auto-amount for icons (less for small, normal for big)
this.calcedCellsMaxCount = this.cellsMaxCount;
this.calcedCellsVisibleCount = this.cellsVisibleCount;
this.calcedCellsOffset = this.cellsOffset;
this.calcedPosition = this.position;
this.calcedOrder = this.order;
if (smallMode) {
this.calcedCellsMaxCount = Math.min(5, this.calcedCellsMaxCount);
this.calcedCellsVisibleCount = Math.min(1, this.calcedCellsVisibleCount);
this.calcedCellsOffset = Math.min(1, this.calcedCellsOffset);
// change order of multi-icons and ignore corners (make icons it centered)
if (this.calcedPosition.getMaxIconsAmount() > 1) {
this.calcedOrder = CardIconOrder.CENTER;
}
}
// REAL SIZES
// auto-sizeable gaps (use test render form to find best values)
this.iconsGap = Math.floorDiv(cardSize.width, 100) * 2;
// icons intersect the card like mtg arena
this.halfSize = Math.max(MINIMUM_ICON_SIZE / 2, Math.round(cardSize.width / 100.0f * this.calcedSizeSizePercent / 2.0f));
this.font = new Font("Arial", Font.PLAIN + Font.BOLD, Math.round(this.halfSize * 1.5f));
}
public int getHalfSize() {
return halfSize;
}
}

View file

@ -0,0 +1,35 @@
package mage.client.cards;
import mage.abilities.icon.CardIconOrder;
import mage.abilities.icon.CardIconPosition;
import mage.abilities.icon.CardIconRenderSettings;
/**
* GUI panel to drawning icons (one of the card's side)
*
* @author JayDi85
*/
public class CardIconsPanelFactory {
public static CardIconsPanel createAbilitiesPanel() {
return new CardIconsPanel(
CardIconPosition.LEFT,
CardIconOrder.CENTER,
5,
30
);
}
public static CardIconsPanel createPlayablePanel() {
return new CardIconsPanel(
CardIconPosition.CORNER_BOTTOM_LEFT,
CardIconOrder.CENTER,
1,
30
);
}
public static CardIconsPanel createDebugPanel(CardIconRenderSettings render) {
return new CardIconsPanel(render);
}
}

View file

@ -1,35 +1,39 @@
package mage.client.cards;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.adapters.MageActionCallback;
import mage.client.plugins.impl.Plugins;
import mage.client.util.CardsViewUtil;
import mage.client.util.ClientDefaultSettings;
import mage.client.util.GUISizeHelper;
import mage.constants.Zone;
import mage.util.DebugUtil;
import mage.view.*;
import org.apache.log4j.Logger;
import org.mage.card.arcane.CardPanel;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.util.*;
import java.util.Map.Entry;
/**
* @author BetaSteward_at_googlemail.com
* Panel for stack and hand zones
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class Cards extends javax.swing.JPanel {
private static final Logger LOGGER = Logger.getLogger(Cards.class);
private static final Logger logger = Logger.getLogger(Cards.class);
private static final Border EMPTY_BORDER = new EmptyBorder(0, 0, 0, 0);
private final Map<UUID, MageCard> cards = new LinkedHashMap<>();
private boolean dontDisplayTapped = false;
private static final int GAP_X = 5; // needed for marking cards with coloured fram (e.g. on hand)
private String zone;
private int minOffsetY = 0;
private Zone zone;
private int lastLoadedCardsCount = 0;
private final JScrollPane parentScrollPane;
/**
* Defines whether component should be visible whenever there is no objects
@ -43,23 +47,37 @@
* Creates new form Cards
*/
public Cards() {
this(false);
this(false, null);
}
public Cards(boolean skipAddingScrollPane) {
/**
*
* @param skipAddingScrollPane use parent scrolls instead own
* @param parentScrollPane
*/
public Cards(boolean skipAddingScrollPane, JScrollPane parentScrollPane) {
initComponents(skipAddingScrollPane);
setOpaque(false);
//cardArea.setOpaque(false);
setBackgroundColor(new Color(0, 0, 0, 100));
// scrollpane can be own or from parent
this.parentScrollPane = parentScrollPane;
if (!skipAddingScrollPane) {
jScrollPane1.setOpaque(false);
jScrollPane1.getViewport().setOpaque(false);
jScrollPane1.setBorder(EMPTY_BORDER);
}
if (Plugins.instance.isCardPluginLoaded()) {
cardArea.setLayout(null);
}
cardArea.setBorder(EMPTY_BORDER);
if (DebugUtil.GUI_GAME_DRAW_HAND_AND_STACK_BORDER) {
setBorder(BorderFactory.createLineBorder(Color.green));
cardArea.setBorder(BorderFactory.createLineBorder(Color.yellow));
}
setGUISize();
}
@ -81,6 +99,7 @@
if (jScrollPane1 != null) {
jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(GUISizeHelper.scrollBarSize, 0));
jScrollPane1.getHorizontalScrollBar().setPreferredSize(new Dimension(0, GUISizeHelper.scrollBarSize));
jScrollPane1.getHorizontalScrollBar().setUnitIncrement(GUISizeHelper.getCardsScrollbarUnitInc(getCardDimension().width));
}
}
@ -115,22 +134,30 @@
public boolean loadCards(CardsView cardsView, BigCard bigCard, UUID gameId, boolean revertOrder) {
boolean changed = false;
// auto-move scrollbars to the end of the list
boolean moveScrollbar;
if (zone == Zone.HAND) {
// hand moves on new cards only
moveScrollbar = lastLoadedCardsCount != 0 && cardsView.size() > lastLoadedCardsCount;
} else {
// stack moves on any changes (e.g. show current stack object)
moveScrollbar = cardsView.size() != lastLoadedCardsCount;
}
this.lastLoadedCardsCount = cardsView.size();
// remove objects no longer to display
changed = removeOutdatedCards(cardsView);
// Workaround for bug leaving display of objects on the stack (issue #213 https://github.com/magefree/mage/issues/213)
if (cardsView.isEmpty() && countCards() > 0) {
// problem happens with transformable cards
LOGGER.fatal("Card object on the cards panel was not removed");
logger.fatal("Card object on the cards panel was not removed");
for (Component comp : cardArea.getComponents()) {
if (comp instanceof Card) {
Card card = (Card) comp;
LOGGER.fatal("Card name:" + card.getName() + " type:" + card.getType(null));
} else if (comp instanceof MageCard) {
if (comp instanceof MageCard) {
MageCard mageCard = (MageCard) comp;
LOGGER.fatal("MageCard name:" + mageCard.getName() + " toolTiptext:" + mageCard.getToolTipText());
logger.fatal("MageCard name:" + mageCard.getName() + " toolTiptext:" + mageCard.getToolTipText());
} else {
LOGGER.fatal("Unknown object:" + comp.getName() + " className:" + comp.getClass().getName());
logger.fatal("Unknown object:" + comp.getName() + " className:" + comp.getClass().getName());
}
cardArea.remove(comp);
}
@ -158,8 +185,7 @@
CardView tmp = ((StackAbilityView) card).getSourceCard();
tmp.overrideRules(card.getRules());
tmp.setChoosable(card.isChoosable());
tmp.setPlayable(card.isPlayable());
tmp.setPlayableAmount(card.getPlayableAmount());
tmp.setPlayableStats(card.getPlayableStats().copy());
tmp.setSelected(card.isSelected());
tmp.setIsAbility(true);
tmp.overrideTargets(card.getTargets());
@ -188,11 +214,28 @@
this.revalidate();
this.repaint();
// auto-scroll (must use it at the end)
if (changed && moveScrollbar) {
SwingUtilities.invokeLater(() -> {
if (jScrollPane1 != null) {
jScrollPane1.getHorizontalScrollBar().setValue(jScrollPane1.getHorizontalScrollBar().getMaximum());
}
if (parentScrollPane != null) {
parentScrollPane.getHorizontalScrollBar().setValue(parentScrollPane.getHorizontalScrollBar().getMaximum());
}
});
}
return changed;
}
public void sizeCards(Dimension cardDimension) {
cardArea.setPreferredSize(new Dimension((int) ((cards.size()) * (cardDimension.getWidth() + GAP_X)) + 20, (int) (cardDimension.getHeight()) + 20));
cardArea.setPreferredSize(new Dimension(
(int) ((cards.size()) * (cardDimension.getWidth() + MageActionCallback.getHandOrStackBetweenGapX(zone)))
+ MageActionCallback.getHandOrStackMargins(zone).getWidth(),
(int) (cardDimension.getHeight())
+ MageActionCallback.getHandOrStackMargins(zone).getHeight()
));
cardArea.revalidate();
cardArea.repaint();
}
@ -211,7 +254,7 @@
public void setCardDimension(Dimension dimension) {
this.cardDimension = dimension;
for (Component component : cardArea.getComponents()) {
if (component instanceof CardPanel) {
if (component instanceof MageCard) {
component.setBounds(0, 0, dimension.width, dimension.height);
}
}
@ -219,49 +262,52 @@
}
private void addCard(CardView card, BigCard bigCard, UUID gameId) {
MageCard mageCard = Plugins.instance.getMageCard(card, bigCard, getCardDimension(), gameId, true, true, PreferencesDialog.getRenderMode(), true);
MageCard mageCard = Plugins.instance.getMageCard(card, bigCard, new CardIconRenderSettings(), getCardDimension(), gameId, true, true, PreferencesDialog.getRenderMode(), true);
mageCard.setCardContainerRef(cardArea);
mageCard.update(card);
if (zone != null) {
mageCard.setZone(zone);
}
cards.put(card.getId(), mageCard);
cardArea.add(mageCard);
definePosition(mageCard);
mageCard.setCardAreaRef(cardArea);
}
private void definePosition(MageCard card) {
int dx = 0;
for (Component comp : cardArea.getComponents()) {
if (!comp.equals(card)) {
dx = Math.max(dx, (int) comp.getLocation().getX());
private void definePosition(MageCard newCard) {
int dx = MageActionCallback.getHandOrStackMargins(zone).getLeft(); // starting position
// search last card's position
for (Component currentComp : cardArea.getComponents()) {
if (!currentComp.equals(newCard) && currentComp instanceof MageCard) {
MageCard currentCard = (MageCard) currentComp;
dx = Math.max(dx, currentCard.getCardLocation().getCardX());
}
}
dx += ((CardPanel) card).getCardWidth() + GAP_X;
card.setLocation(dx, (int) card.getLocation().getY());
// Y position sets here one time only (all sorting and drag manipulations works with X)
// add card to the end
dx += newCard.getCardLocation().getCardWidth() + MageActionCallback.getHandOrStackBetweenGapX(newCard.getZone());
newCard.setCardLocation(dx, MageActionCallback.getHandOrStackMargins(newCard.getZone()).getTop());
}
private boolean removeOutdatedCards(CardsView cardsView) {
boolean changed = false;
// links to components
cards.keySet().removeIf(id -> !cardsView.containsKey(id));
// components
for (Component comp : cardArea.getComponents()) {
UUID cardId = null;
if (comp instanceof Card) {
cardId = ((Card) comp).getCardId();
} else if (comp instanceof MageCard) {
cardId = ((MageCard) comp).getOriginal().getId();
if (comp instanceof MageCard) {
if (!cards.containsValue(comp)) {
cardArea.remove(comp);
changed = true;
}
} else {
LOGGER.error("Unknown card conponent in cards panel to remove: " + comp);
}
if (cardId == null || !cardsView.containsKey(cardId)) {
cardArea.remove(comp);
changed = true;
logger.error("Unknown card conponent in cards panel to remove: " + comp);
}
}
// links
cards.keySet().removeIf(id -> !cardsView.containsKey(id));
return changed;
}
@ -298,10 +344,6 @@
private javax.swing.JScrollPane jScrollPane1;
// End of variables declaration//GEN-END:variables
public void setDontDisplayTapped(boolean dontDisplayTapped) {
this.dontDisplayTapped = dontDisplayTapped;
}
public void setHScrollSpeed(int unitIncrement) {
if (jScrollPane1 != null) {
jScrollPane1.getHorizontalScrollBar().setUnitIncrement(unitIncrement);
@ -315,28 +357,29 @@
}
private void layoutCards() {
java.util.List<CardPanel> cardsToLayout = new ArrayList<>();
// get all the card panels
java.util.List<MageCard> cardsToLayout = new ArrayList<>();
for (Component component : cardArea.getComponents()) {
if (component instanceof CardPanel) {
cardsToLayout.add((CardPanel) component);
if (component instanceof MageCard) {
cardsToLayout.add((MageCard) component);
}
}
// WARNING, must be same sort code as MageActionCallback->sortLayout (if not then hand cards will be messed after drag)
// sort the cards
cardsToLayout.sort(Comparator.comparingInt(cp -> cp.getLocation().x));
// relocate the cards
int dx = 0;
for (Component component : cardsToLayout) {
component.setLocation(dx, Math.max(component.getLocation().y, minOffsetY));
dx += ((CardPanel) component).getCardWidth() + GAP_X;
cardsToLayout.sort(Comparator.comparingInt(cp -> cp.getCardLocation().getCardX()));
// relocate the cards (support only horizontal style: hand and stack panels)
// TODO: add shrinking of cards list for too big amount (cards will be overlapped, use MageActionCallback.HAND_CARDS_BETWEEN_GAP_X to control it)
int dx = MageActionCallback.getHandOrStackBetweenGapX(zone); // starting position
for (MageCard component : cardsToLayout) {
component.setCardLocation(dx, component.getCardLocation().getCardY());
dx += component.getCardLocation().getCardWidth() + MageActionCallback.getHandOrStackBetweenGapX(zone);
}
}
public void setZone(String zone) {
public void setZone(Zone zone) {
this.zone = zone;
}
public void setMinOffsetY(int minOffsetY) {
this.minOffsetY = minOffsetY;
}
}

View file

@ -1,12 +1,6 @@
/*
* CardsList.java
*
* Created on Dec 18, 2009, 10:40:12 AM
*/
package mage.client.cards;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.client.constants.Constants.DeckEditorMode;
import mage.client.constants.Constants.SortBy;
@ -17,11 +11,10 @@
import mage.client.plugins.impl.Plugins;
import mage.client.util.Event;
import mage.client.util.*;
import mage.client.util.comparators.*;
import mage.client.util.gui.TableSpinnerEditor;
import mage.view.CardView;
import mage.view.CardsView;
import mage.view.SimpleCardView;
import org.mage.card.arcane.CardPanel;
import org.mage.card.arcane.ManaSymbolsCellRenderer;
import javax.swing.*;
@ -37,12 +30,17 @@
import java.util.*;
/**
* @author BetaSteward_at_googlemail.com
* Deck editor: grid mode for drafting (NOT a normal deck editor or sideboarding)
* TODO: combine with CardGrid.java
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class CardsList extends javax.swing.JPanel implements MouseListener, ICardGrid {
public class CardsList extends javax.swing.JPanel implements ICardGrid, CardEventProducer {
protected final CardEventSource cardEventSource = new CardEventSource();
private Dimension cardDimension;
private final List<JLabel> countLabels = new ArrayList<>(); // count label code copy-pasted from CardGrid.java
private int rowHeight;
private CardsView cards;
private Map<UUID, MageCard> mageCards = new LinkedHashMap<>();
@ -53,6 +51,7 @@
private TableModel mainModel;
private JTable mainTable;
private ICardGrid currentView;
private boolean isLoading; // disable events from comboboxes while updating
/**
* Creates new form Cards
@ -78,8 +77,8 @@
cardArea.removeMouseListener(ml);
}
for (Component comp : cardArea.getComponents()) {
if (comp instanceof CardPanel) {
((CardPanel) comp).cleanUp();
if (comp instanceof MageCard) {
((MageCard) comp).cleanUp();
}
}
cardArea.removeAll();
@ -108,7 +107,7 @@
mainTable.setFont(GUISizeHelper.tableFont);
mainTable.setRowHeight(GUISizeHelper.getTableRowHeight());
cardDimension = GUISizeHelper.editorCardDimension;
rowHeight = GUISizeHelper.editorCardOffsetSize;
rowHeight = GUISizeHelper.editorCardVertOffsetInStack;
}
private void makeTransparent() {
@ -157,27 +156,38 @@
chkPiles.setEnabled(true);
}
cardArea.addMouseListener(this);
mainTable.setOpaque(false);
// ENABLE double clicks in table mode
mainTable.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// simulate mouse click on the card
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0) && !e.isConsumed()) { // double clicks and repeated double clicks
e.consume();
if (e.isAltDown()) {
handleAltDoubleClick();
} else {
handleDoubleClick();
}
handleTableDoubleClick(e); // TODO: replace on card's event source instead mouse listener
}
}
});
mainModel.setUpdateCountsCallback(new UpdateCountsCallback(lblCount, lblCreatureCount, lblLandCount, null, null, null, null));
// ENABLE popup menu for non card area
cardArea.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.isPopupTrigger() || SwingUtilities.isRightMouseButton(e)) {
cardEventSource.fireEvent(null, e.getComponent(), e.getX(), e.getY(), ClientEventType.CARD_POPUP_MENU);
}
}
});
}
// if you use the deck ediot to build a free deck, numbers can be set directly in deck and sideboard
@Override
public CardEventSource getCardEventSource() {
return cardEventSource;
}
// if you use the deck editor to build a free deck, numbers can be set directly in deck and sideboard
public void setDeckEditorMode(DeckEditorMode mode) {
if (mode == DeckEditorMode.FREE_BUILDING) {
// activate spinner for card number change
@ -197,24 +207,13 @@
}
}
public void handleDoubleClick() {
public void handleTableDoubleClick(MouseEvent e) {
if (mainTable.getSelectedRowCount() > 0) {
int[] n = mainTable.getSelectedRows();
List<Integer> indexes = asList(n);
Collections.reverse(indexes);
for (Integer index : indexes) {
mainModel.doubleClick(index);
}
}
}
public void handleAltDoubleClick() {
if (mainTable.getSelectedRowCount() > 0) {
int[] n = mainTable.getSelectedRows();
List<Integer> indexes = asList(n);
Collections.reverse(indexes);
for (Integer index : indexes) {
mainModel.altDoubleClick(index);
mainModel.doubleClick(index, e, false);
}
}
}
@ -240,8 +239,13 @@
this.bigCard = bigCard;
this.gameId = gameId;
cbSortBy.setSelectedItem(sortSetting.getSortBy());
chkPiles.setSelected(sortSetting.isPilesToggle());
isLoading = true;
try {
cbSortBy.setSelectedItem(sortSetting.getSortBy());
chkPiles.setSelected(sortSetting.isPilesToggle());
} finally {
isLoading = false;
}
currentView.loadCards(showCards, sortSetting, bigCard, gameId);
if (selectedRow >= 0) {
selectedRow = Math.min(selectedRow, mainTable.getRowCount() - 1);
@ -260,13 +264,18 @@
@Override
public void drawCards(SortSetting sortSetting) {
for (JLabel label : this.countLabels) {
cardArea.remove(label);
}
this.countLabels.clear();
int maxWidth = this.getParent().getWidth();
int numColumns = maxWidth / cardDimension.width;
int curColumn = 0;
int curRow = 0;
int maxRow = 0;
int maxColumn = 0;
Comparator<CardView> comparator = null;
CardViewComparator comparator = null;
Map<UUID, MageCard> oldMageCards = mageCards;
mageCards = new LinkedHashMap<>();
@ -308,25 +317,43 @@
case CASTING_COST:
comparator = new CardViewCostComparator();
break;
case UNSORTED:
comparator = new CardViewNoneComparator();
break;
case EDH_POWER_LEVEL:
comparator = new CardViewEDHPowerLevelComparator();
break;
default:
throw new IllegalArgumentException("Error, unknown sort settings in deck editor: " + sortSetting.getSortBy());
}
if (comparator != null) {
sortedCards.sort(new CardViewNameComparator());
sortedCards.sort(comparator);
}
sortedCards.sort(new CardViewNameComparator());
sortedCards.sort(comparator);
CardView lastCard = null;
JLabel lastCountLabel = null;
for (CardView card : sortedCards) {
if (sortSetting.isPilesToggle()) {
if (lastCard == null) {
lastCard = card;
// new new count label
lastCountLabel = addNewCountLabel(curColumn);
}
if (comparator != null) {
if (comparator.compare(card, lastCard) > 0) {
curColumn++;
maxRow = Math.max(maxRow, curRow);
curRow = 0;
}
// create new column on different card sorting
if (comparator.compare(card, lastCard) != 0) {
curColumn++;
maxRow = Math.max(maxRow, curRow);
curRow = 0;
// add new count label
lastCountLabel = addNewCountLabel(curColumn);
}
rectangle.setLocation(curColumn * cardDimension.width, curRow * rowHeight);
// update last count label stats
String description = comparator.getCategoryName(card);
DragCardGrid.updateCountLabel(lastCountLabel, curRow + 1, description);
rectangle.setLocation(curColumn * cardDimension.width, curRow * rowHeight + DragCardGrid.COUNT_LABEL_HEIGHT);
setCardBounds(mageCards.get(card.getId()), rectangle);
curRow++;
@ -353,6 +380,16 @@
this.setVisible(true);
}
private JLabel addNewCountLabel(int columnNumber) {
JLabel label = DragCardGrid.createCountLabel(null);
this.countLabels.add(label);
cardArea.add(label, (Integer) 0); // draw on background
label.setLocation(columnNumber * cardDimension.width, 5);
label.setSize(cardDimension.width, DragCardGrid.COUNT_LABEL_HEIGHT);
label.setVisible(true);
return label;
}
private void updateCounts() {
int landCount = 0;
int creatureCount = 0;
@ -389,15 +426,16 @@
}
private MageCard addCard(CardView card, BigCard bigCard, UUID gameId) {
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, true, true, PreferencesDialog.getRenderMode(), true);
cardArea.add(cardImg);
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, new CardIconRenderSettings(), cardDimension, gameId, true, true, PreferencesDialog.getRenderMode(), true);
cardImg.setCardContainerRef(this);
cardImg.update(card);
cardImg.addMouseListener(this);
// card position calculated on parent call by drawCards
//cardImg.setCardBounds(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
cardArea.add(cardImg, (Integer) 10); // count label must be on layer 0 for background drawing
return cardImg;
}
private void setCardBounds(MageCard card, Rectangle rectangle) {
card.setBounds(rectangle);
card.setCardBounds(rectangle.x, rectangle.y, cardDimension.width, cardDimension.height);
cardArea.moveToFront(card);
}
@ -605,13 +643,17 @@
}//GEN-LAST:event_jToggleListViewActionPerformed
private void cbSortByActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbSortByActionPerformed
sortSetting.setSortBy((SortBy) cbSortBy.getSelectedItem());
drawCards(sortSetting);
if (!isLoading) {
sortSetting.setSortBy((SortBy) cbSortBy.getSelectedItem());
drawCards(sortSetting);
}
}//GEN-LAST:event_cbSortByActionPerformed
private void chkPilesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkPilesActionPerformed
sortSetting.setPilesToggle(chkPiles.isSelected());
drawCards(sortSetting);
if (!isLoading) {
sortSetting.setPilesToggle(chkPiles.isSelected());
drawCards(sortSetting);
}
}//GEN-LAST:event_chkPilesActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
@ -628,64 +670,6 @@
private javax.swing.JPanel panelControl;
// End of variables declaration//GEN-END:variables
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
if (e.getClickCount() >= 1 && !e.isConsumed()) {
Object obj = e.getSource();
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0)) { // double clicks and repeated double clicks
e.consume();
if (obj instanceof Card) {
if (e.isAltDown()) {
cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK);
} else {
cardEventSource.fireEvent(((Card) obj).getOriginal(), ClientEventType.DOUBLE_CLICK);
}
} else if (obj instanceof MageCard) {
if (e.isAltDown()) {
cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.ALT_DOUBLE_CLICK);
} else {
cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.DOUBLE_CLICK);
}
}
}
if (obj instanceof MageCard) {
checkMenu(e, ((MageCard) obj).getOriginal());
} else {
checkMenu(e, null);
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (!e.isConsumed()) {
Object obj = e.getSource();
if (obj instanceof MageCard) {
checkMenu(e, ((MageCard) obj).getOriginal());
} else {
checkMenu(e, null);
}
}
}
private void checkMenu(MouseEvent Me, SimpleCardView card) {
if (Me.isPopupTrigger()) {
Me.consume();
cardEventSource.fireEvent(card, Me.getComponent(), Me.getX(), Me.getY(), ClientEventType.SHOW_POP_UP_MENU);
}
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
public void setDisplayNoCopies(boolean value) {
mainModel.setDisplayNoCopies(value);

View file

@ -1,18 +1,11 @@
/*
* DraftGrid.java
*
* Created on 7-Jan-2011, 6:23:39 PM
*/
package mage.client.cards;
import mage.cards.CardDimensions;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.CardViewRarityComparator;
import mage.client.util.comparators.CardViewRarityComparator;
import mage.client.util.ClientEventType;
import mage.client.util.Event;
import mage.client.util.Listener;
@ -23,15 +16,15 @@ import mage.view.CardsView;
import org.apache.log4j.Logger;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;
/**
* @author BetaSteward_at_googlemail.com
* Drafting: panel with the picks
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class DraftGrid extends javax.swing.JPanel implements MouseListener {
public class DraftGrid extends javax.swing.JPanel implements CardEventProducer {
private static final Logger logger = Logger.getLogger(DraftGrid.class);
@ -47,20 +40,44 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
initComponents();
markedCard = null;
emptyGrid = true;
// ENABLE picks and other actions
cardEventSource.addListener(new Listener<Event>() {
@Override
public void event(Event event) {
if (event.getEventType() == ClientEventType.CARD_DOUBLE_CLICK) {
logger.info("draft grid: catch double click");
CardView card = (CardView) event.getSource();
cardEventSource.fireEvent(card, ClientEventType.DRAFT_PICK_CARD);
hidePopup();
AudioManager.playOnDraftSelect();
} else if (event.getEventType() == ClientEventType.CARD_CLICK) {
logger.info("draft grid: catch single click");
CardView card = (CardView) event.getSource();
MageCard cardPanel = (MageCard) event.getComponent();
if (markedCard != null) {
markedCard.setSelected(false);
}
cardEventSource.fireEvent(card, ClientEventType.DRAFT_MARK_CARD);
markedCard = cardPanel;
markedCard.setSelected(true);
repaint();
}
}
});
}
public void clear() {
markedCard = null;
this.clearCardEventListeners();
for (Component comp : getComponents()) {
if (comp instanceof Card || comp instanceof MageCard) {
if (comp instanceof MageCard) {
this.remove(comp);
}
}
}
public void loadBooster(CardsView booster, BigCard bigCard) {
if (booster instanceof CardsView && booster.isEmpty()) {
if (booster != null && booster.isEmpty()) {
emptyGrid = true;
} else {
if (!emptyGrid) {
@ -103,13 +120,12 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
List<CardView> sortedCards = new ArrayList<>(booster.values());
sortedCards.sort(new CardViewRarityComparator());
for (CardView card : sortedCards) {
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, dimension, null, true, true, PreferencesDialog.getRenderMode(), true);
cardImg.addMouseListener(this);
add(cardImg);
MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, new CardIconRenderSettings(), dimension, null, true, true, PreferencesDialog.getRenderMode(), true);
cardImg.setCardContainerRef(this);
cardImg.update(card);
rectangle.setLocation(curColumn * (cardDimension.getFrameWidth() + offsetX) + offsetX, curRow * (rectangle.height + offsetY) + offsetY);
this.add(cardImg);
cardImg.setBounds(rectangle);
rectangle.setLocation(curColumn * (cardDimension.getFrameWidth() + offsetX) + offsetX, curRow * (rectangle.height + offsetY) + offsetY);
cardImg.setCardBounds(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
curColumn++;
if (curColumn == numColumns) {
@ -127,10 +143,6 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
cardEventSource.addListener(listener);
}
public void clearCardEventListeners() {
cardEventSource.clearListeners();
}
private void hidePopup() {
Plugins.instance.getActionCallback().mouseExited(null, null);
}
@ -158,54 +170,14 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
}// </editor-fold>//GEN-END:initComponents
@Override
public void mouseClicked(MouseEvent e) {
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0)) { // double clicks and repeated double clicks
if (e.getButton() == MouseEvent.BUTTON1) {
Object obj = e.getSource();
if (obj instanceof MageCard) {
this.cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.PICK_A_CARD);
this.hidePopup();
AudioManager.playOnDraftSelect();
}
}
}
}
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 || e.getButton() == MouseEvent.BUTTON3) { // left or right click
Object obj = e.getSource();
if (obj instanceof MageCard) {
if (this.markedCard != null) {
markedCard.setSelected(false);
}
this.cardEventSource.fireEvent(((MageCard) obj).getOriginal(), ClientEventType.MARK_A_CARD);
markedCard = ((MageCard) obj);
markedCard.setSelected(true);
repaint();
}
}
public CardEventSource getCardEventSource() {
return cardEventSource;
}
public boolean isEmptyGrid() {
return emptyGrid;
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables

View file

@ -1,6 +1,7 @@
package mage.client.cards;
import mage.cards.Card;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLayout;
@ -11,22 +12,23 @@ import mage.client.constants.Constants;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.*;
import mage.client.util.Event;
import mage.client.util.comparators.*;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.util.DebugUtil;
import mage.util.RandomUtil;
import mage.view.CardView;
import mage.view.CardsView;
import org.apache.log4j.Logger;
import org.mage.card.arcane.CardRenderer;
import org.mage.card.arcane.ManaSymbols;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.*;
import java.util.List;
import java.util.*;
import java.util.regex.Matcher;
@ -34,12 +36,16 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Created by StravantUser on 2016-09-20.
* @author StravantUser, JayDi85
*/
public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarget {
public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarget, CardEventProducer {
private static final Logger logger = Logger.getLogger(DragCardGrid.class);
private static final String DOUBLE_CLICK_MODE_INFO = "<html>Double click mode: <b>%s</b>";
private static final Logger LOGGER = Logger.getLogger(DragCardGrid.class);
private Constants.DeckEditorMode mode;
Listener<Event> cardListener;
MouseListener countLabelListener; // clicks on the count label
@Override
public Collection<CardView> dragCardList() {
@ -66,7 +72,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
if (card.isSelected()) {
stack.set(i, null);
removeCardView(card);
eventSource.fireEvent(card, ClientEventType.REMOVE_SPECIFIC_CARD);
eventSource.fireEvent(card, ClientEventType.DECK_REMOVE_SPECIFIC_CARD);
}
}
}
@ -88,6 +94,11 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
showDropPosition(e.getX(), e.getY());
}
@Override
public CardEventSource getCardEventSource() {
return this.eventSource;
}
private void showDropPosition(int x, int y) {
// Clamp to region
if (x < 0) {
@ -320,7 +331,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
for (CardView card : cards) {
card.setSelected(true);
addCardView(card, false);
eventSource.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD);
eventSource.fireEvent(card, ClientEventType.DECK_ADD_SPECIFIC_CARD);
}
layoutGrid();
repaintGrid();
@ -361,21 +372,33 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
creatureCountLabel.setVisible(false);
landCountLabel.setVisible(false);
cardSizeSliderLabel.setVisible(false);
mouseDoubleClickMode.setVisible(false);
} else {
creatureCountLabel.setVisible(true);
landCountLabel.setVisible(true);
cardSizeSliderLabel.setVisible(true);
mouseDoubleClickMode.setVisible(true);
}
updateCounts();
}
private void updateMouseDoubleClicksInfo(boolean isHotKeyPressed) {
boolean gameMode = isHotKeyPressed
|| mode != Constants.DeckEditorMode.FREE_BUILDING;
String oldText = mouseDoubleClickMode.getText();
String newText = String.format(DOUBLE_CLICK_MODE_INFO, gameMode ? "MOVE" : "DELETE");
if (!oldText.equals(newText)) {
mouseDoubleClickMode.setText(newText);
}
}
public void removeSelection() {
for (List<List<CardView>> gridRow : cardGrid) {
for (List<CardView> stack : gridRow) {
for (int i = 0; i < stack.size(); ++i) {
CardView card = stack.get(i);
if (card.isSelected()) {
eventSource.fireEvent(card, ClientEventType.REMOVE_SPECIFIC_CARD);
eventSource.fireEvent(card, ClientEventType.DECK_REMOVE_SPECIFIC_CARD);
stack.set(i, null);
removeCardView(card);
}
@ -406,13 +429,11 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
public void setDeckEditorMode(Constants.DeckEditorMode mode) {
this.mode = mode;
updateMouseDoubleClicksInfo(false);
}
public enum Sort {
NONE("No Sort", (o1, o2) -> {
// Always equal, sort into the first row
return 0;
}),
NONE("No Sort", new CardViewNoneComparator()),
CARD_TYPE("Card Type", new CardViewCardTypeComparator()),
CMC("Converted Mana Cost", new CardViewCostComparator()),
COLOR("Color", new CardViewColorComparator()),
@ -420,12 +441,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
RARITY("Rarity", new CardViewRarityComparator()),
EDH_POWER_LEVEL("EDH Power Level", new CardViewEDHPowerLevelComparator());
Sort(String text, Comparator<CardView> comparator) {
Sort(String text, CardViewComparator comparator) {
this.comparator = comparator;
this.text = text;
}
public Comparator<CardView> getComparator() {
public CardViewComparator getComparator() {
return comparator;
}
@ -433,7 +454,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
return text;
}
private final Comparator<CardView> comparator;
private final CardViewComparator comparator;
private final String text;
}
@ -537,7 +558,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
}
// Constants
public static final int COUNT_LABEL_HEIGHT = 20;
public static final int COUNT_LABEL_HEIGHT = 40; // can contains 1 or 2 lines
public static final int GRID_PADDING = 10;
private static final ImageIcon INSERT_ROW_ICON = new ImageIcon(DragCardGrid.class.getClassLoader().getResource("editor_insert_row.png"));
@ -547,7 +568,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
private final Map<UUID, MageCard> cardViews = new LinkedHashMap<>();
private final List<CardView> allCards = new ArrayList<>();
// Card listeners
// card listeners
private final CardEventSource eventSource = new CardEventSource();
// Last big card
@ -561,6 +582,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
JButton analyseButton;
JButton blingButton;
JButton oldVersionButton;
JLabel mouseDoubleClickMode;
// Popup for toolbar
final JPopupMenu filterPopup;
@ -696,7 +718,6 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
cardSizeSlider.setValue(size);
}
// Constructor
public DragCardGrid() {
// Make sure that the card grid is populated with at least one (empty) stack to begin with
cardGrid = new ArrayList<>();
@ -705,13 +726,55 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
setLayout(new BorderLayout());
setOpaque(false);
// Editting mode
// default game mode (real game mode will be set after all components init)
this.mode = Constants.DeckEditorMode.LIMITED_BUILDING;
// Content
cardContent = new JLayeredPane();
cardContent.setLayout(null);
cardContent.setOpaque(false);
// ENABLE MOUSE CLICKS (cards, menu)
this.cardListener = event -> {
switch(event.getEventType()) {
case CARD_POPUP_MENU:
if (event.getSource() != null) {
// menu for card
CardView card = (CardView) event.getSource();
MouseEvent me = event.getMouseEvent();
if (!card.isSelected()) {
selectCard(card);
}
showCardRightClickMenu(card, me);
}
break;
case CARD_CLICK:
if (event.getSource() != null) {
CardView card = (CardView) event.getSource();
MouseEvent me = event.getMouseEvent();
cardClicked(card, me);
}
break;
}
};
eventSource.addListener(this.cardListener);
// keyboard listener for ALT status update
// it requires GLOBAL listener
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventDispatcher(new KeyEventDispatcher() {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ALT) {
updateMouseDoubleClicksInfo(e.isAltDown());
}
return false;
}
});
// ENABLE MULTI-CARDS SELECTION
cardContent.addMouseListener(new MouseAdapter() {
private boolean isDragging = false;
@ -739,6 +802,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
updateSelectionDrag(e.getX(), e.getY());
}
});
cardScroll = new JScrollPane(cardContent,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
@ -757,6 +821,13 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
analyseButton = new JButton("M"); // "Mana" button
blingButton = new JButton("B"); // "Bling" button
oldVersionButton = new JButton("O"); // "Old version" button
mouseDoubleClickMode = new JLabel(DOUBLE_CLICK_MODE_INFO);
mouseDoubleClickMode.setToolTipText("<html>Mouse modes for double clicks:"
+ "<br> * &lt;Double Click&gt;: <b>DELETE</b> card from mainboard/sideboard (it works as <b>MOVE</b> in games);"
+ "<br> * &lt;ALT + Double Click&gt;: <b>MOVE</b> card between mainboard/sideboard (default for games);"
+ "<br> * Deck editor: use &lt;ALT + Double Click&gt; on cards list to add card to the sideboard instead mainboard."
);
updateMouseDoubleClicksInfo(false);
// Name and count label
deckNameAndCountLabel = new JLabel();
@ -782,6 +853,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
toolbarInner.add(analyseButton);
toolbarInner.add(blingButton);
toolbarInner.add(oldVersionButton);
toolbarInner.add(mouseDoubleClickMode);
toolbar.add(toolbarInner, BorderLayout.WEST);
JPanel sliderPanel = new JPanel(new GridBagLayout());
sliderPanel.setOpaque(false);
@ -809,12 +881,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
insertArrow = new JLabel();
insertArrow.setSize(20, 20);
insertArrow.setVisible(false);
cardContent.add(insertArrow, 1000);
cardContent.add(insertArrow, (Integer) 1000);
// Selection panel
selectionPanel = new SelectionBox();
selectionPanel.setVisible(false);
cardContent.add(selectionPanel, new Integer(1001));
cardContent.add(selectionPanel, (Integer) 1001);
// Load separate creatures setting
separateCreatures = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_DECK_EDITOR_LAST_SEPARATE_CREATURES, "false").equals("true");
@ -965,6 +1037,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
@Override
public void keyPressed(KeyEvent e) {
}
});
@ -975,17 +1048,14 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Analyse Mana (aka #blue pips, #islands, #white pips, #plains etc.)
analyseButton.setToolTipText("Mana Analyser! Counts coloured/colourless mana costs. Counts land types.");
analyseButton.addActionListener(evt -> analyseDeck());
// Bling button - aka Add in a premium 'JR', 'MBP', 'CS' etc card
blingButton.setToolTipText("Bling your deck! Select the original and added cards by selecting 'Multiples' in the selection options");
blingButton.addActionListener(evt -> blingDeck());
// Old version button - Switch cards to the oldest non-promo printing. In case of multiples in a set, take the lowest card number.
oldVersionButton.setToolTipText("Switch cards to the oldest non-promo printing");
oldVersionButton.addActionListener(evt -> oldVersionDeck());
// Filter popup
@ -1032,11 +1102,11 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
sortMenu.add(separateButton);
menu.add(sortMenu);
// Hook up to card content
// ENABLE popup menu on non card (e.g. show all or sorting)
cardContent.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
if (e.isPopupTrigger() || SwingUtilities.isRightMouseButton(e)) {
for (Sort s : sortMenuItems.keySet()) {
sortMenuItems.get(s).setSelected(cardSort == s);
}
@ -1170,8 +1240,6 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
--col2;
}
// avoids a null ref issue but only deals with symptom of problem. not sure how it gets to this state ever. see issue #3197
// if (selectionDragStartCards == null) return;
int curY = COUNT_LABEL_HEIGHT;
for (int rowIndex = 0; rowIndex < cardGrid.size(); ++rowIndex) {
int stackStartIndex;
@ -1638,7 +1706,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
if (acard.getName().equals(card.getName())) {
CardView pimpedCard = new CardView(acard);
addCardView(pimpedCard, false);
eventSource.fireEvent(pimpedCard, ClientEventType.ADD_SPECIFIC_CARD);
eventSource.fireEvent(pimpedCard, ClientEventType.DECK_ADD_SPECIFIC_CARD);
pimpedCards.put(pimpedCard, 1);
didModify = true;
}
@ -1679,9 +1747,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
if (oldestCardInfo != null) {
CardView oldestCardView = new CardView(oldestCardInfo.getMockCard());
this.removeCardView(card);
eventSource.fireEvent(card, ClientEventType.REMOVE_SPECIFIC_CARD);
eventSource.fireEvent(card, ClientEventType.DECK_REMOVE_SPECIFIC_CARD);
this.addCardView(oldestCardView, false);
eventSource.fireEvent(oldestCardView, ClientEventType.ADD_SPECIFIC_CARD);
eventSource.fireEvent(oldestCardView, ClientEventType.DECK_ADD_SPECIFIC_CARD);
newStack.add(oldestCardView);
} else {
newStack.add(card);
@ -1806,7 +1874,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
for (Map<String, List<CardView>> tracked : trackedCards.values()) {
for (List<CardView> orphans : tracked.values()) {
for (CardView orphan : orphans) {
LOGGER.info("Orphan when setting with layout: ");
logger.info("Orphan when setting with layout: ");
sortIntoGrid(orphan);
}
}
@ -1902,48 +1970,23 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
updateCounts();
// Create the card view
final MageCard cardPanel = Plugins.instance.getMageCard(card, lastBigCard, new Dimension(getCardWidth(), getCardHeight()), null, true, true, PreferencesDialog.getRenderMode(), true);
final MageCard cardPanel = Plugins.instance.getMageCard(card, lastBigCard, new CardIconRenderSettings(), new Dimension(getCardWidth(), getCardHeight()), null, true, true, PreferencesDialog.getRenderMode(), true);
cardPanel.setCardContainerRef(this);
cardPanel.update(card);
// cards bounds set in layoutGrid()
cardPanel.setCardCaptionTopOffset(0);
// Remove mouse wheel listeners so that scrolling works
// Scrolling works on all areas without cards or by using the scroll bar, that's enough
// for (MouseWheelListener l : cardPanel.getMouseWheelListeners()) {
// cardPanel.removeMouseWheelListener(l);
// }
// Add a click listener for selection / drag start
cardPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
// Select if not selected
if (!card.isSelected()) {
selectCard(card);
}
// Show menu
showCardRightClickMenu(card, e);
} else if (SwingUtilities.isLeftMouseButton(e)) {
if (e.getClickCount() == 1) {
cardClicked(card, e);
} else if (e.isAltDown()) {
eventSource.fireEvent(card, ClientEventType.ALT_DOUBLE_CLICK);
} else {
eventSource.fireEvent(card, ClientEventType.DOUBLE_CLICK);
}
}
}
});
// Add a motion listener to process drags
// ENABLE DRAG SUPPORT FOR CARDS
// TODO: rewrite mouseDragged in MageActionCallback, so it can support any drags, not hands only
cardPanel.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
if (!dragger.isDragging()) {
// If the card isn't already selected, make sure it is
if (!card.isSelected()) {
cardClicked(card, e);
selectCard(card);
}
dragger.beginDrag(cardPanel, e);
dragger.handleDragStart(cardPanel, e);
}
}
});
@ -1954,7 +1997,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
if (duplicated) {
sortIntoGrid(card);
eventSource.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD);
eventSource.fireEvent(card, ClientEventType.DECK_ADD_SPECIFIC_CARD);
// Update layout
layoutGrid();
repaintGrid();
@ -2059,9 +2102,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// No card in this column?
if (cardInColumn == null) {
// Error, should not have an empty column
LOGGER.error("Empty column! " + currentColumn);
logger.error("Empty column! " + currentColumn);
} else {
int res = cardSort.getComparator().compare(newCard, cardInColumn);
CardViewComparator cardComparator = cardSort.getComparator();
int res = cardComparator.compare(newCard, cardInColumn);
if (res <= 0) {
// Insert into this col, but if less, then we need to create a new col here first
if (res < 0) {
@ -2085,6 +2129,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
}
targetRow.get(targetRow.size() - 1).add(newCard);
}
// if it's a new deck then non creature cards can be added to second row, so fix empty rows here
trimGrid();
}
/**
@ -2191,16 +2238,35 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
stackCountLabels.add(new ArrayList<>());
}
if (stackCountLabels.get(rowIndex).size() <= colIndex) {
JLabel countLabel = new JLabel("", SwingConstants.CENTER);
countLabel.setForeground(Color.WHITE);
cardContent.add(countLabel, new Integer(0));
// add new count label for the column
// ENABLE cards auto-selection in the stack
if (this.countLabelListener == null) {
this.countLabelListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JLabel countLabel = (JLabel) e.getComponent();
List<CardView> cards = findCardStackByCountLabel(countLabel);
boolean selected = !cards.isEmpty() && cards.get(0).isSelected();
cards.forEach(card -> {
card.setSelected(!selected);
cardViews.get(card.getId()).update(card);
});
}
};
}
JLabel countLabel = DragCardGrid.createCountLabel(this.countLabelListener);
cardContent.add(countLabel, (Integer) 0);
stackCountLabels.get(rowIndex).add(countLabel);
}
JLabel countLabel = stackCountLabels.get(rowIndex).get(colIndex);
if (stack.isEmpty()) {
countLabel.setVisible(false);
} else {
countLabel.setText(String.valueOf(stack.size()));
String description = cardSort.getComparator().getCategoryName(stack.get(0));
DragCardGrid.updateCountLabel(countLabel, stack.size(), description);
countLabel.setLocation(GRID_PADDING + (cardWidth + GRID_PADDING) * colIndex, currentY - COUNT_LABEL_HEIGHT);
countLabel.setSize(cardWidth, COUNT_LABEL_HEIGHT);
countLabel.setVisible(true);
@ -2231,6 +2297,57 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
//cardContent.setSize(maxWidth, currentY - COUNT_LABEL_HEIGHT + GRID_PADDING);
}
public static JLabel createCountLabel(MouseListener mouseListener) {
JLabel countLabel = new JLabel("", JLabel.CENTER);
countLabel.setForeground(Color.WHITE); // TODO: add theme support
if (mouseListener != null) {
countLabel.addMouseListener(mouseListener);
}
return countLabel;
}
public static void updateCountLabel(JLabel countLabel, int amount, String description) {
// two modes:
// * small: one line with count
// * big: two lines with count and description
String descHtml = ManaSymbols.replaceSymbolsWithHTML(description, ManaSymbols.Type.TABLE);
boolean smallMode = description.isEmpty();
boolean supportCustomClicks = countLabel.getMouseListeners().length > 0
&& !(countLabel.getMouseListeners()[0] instanceof ToolTipManager); // ignore auto-added ToolTipManager for mouse over hints
// border: 1px solid black
// white-space: nowrap;
countLabel.setText("<html>"
+ "<div style='text-align: center;'>"
+ " <div>" + amount + "</div>"
+ (smallMode ? "" : " <div style=''>" + descHtml + "</div>")
+ "</div>"
+ "");
countLabel.setToolTipText("<html>"
+ amount + (smallMode ? "" : " - " + description)
+ (supportCustomClicks ? "<br>Click on the count label to select/unselect cards stack." : "")
);
countLabel.setVerticalAlignment(smallMode ? JLabel.CENTER : JLabel.TOP);
if (DebugUtil.GUI_DECK_EDITOR_DRAW_COUNT_LABEL_BORDER) {
countLabel.setBorder(BorderFactory.createLineBorder(Color.green));
}
}
private List<CardView> findCardStackByCountLabel(JLabel countLabel) {
for (int rowIndex = 0; rowIndex < cardGrid.size(); ++rowIndex) {
List<List<CardView>> gridRow = cardGrid.get(rowIndex);
for (int colIndex = 0; colIndex < gridRow.size(); ++colIndex) {
if (stackCountLabels.size() < rowIndex
|| stackCountLabels.get(rowIndex).size() < colIndex
|| !countLabel.equals(stackCountLabels.get(rowIndex).get(colIndex))) {
continue;
}
return gridRow.get(colIndex);
}
}
return new ArrayList<>();
}
private static void makeButtonPopup(final AbstractButton button, final JPopupMenu popup) {
button.addActionListener(e -> popup.show(button, 0, button.getHeight()));
}

View file

@ -5,10 +5,12 @@ import mage.view.CardView;
import java.util.Collection;
/**
* Created by StravantUser on 2016-09-22.
* @author StravantUser
*/
public interface DragCardSource {
Collection<CardView> dragCardList();
void dragCardBegin();
void dragCardEnd(DragCardTarget target);
}

View file

@ -6,11 +6,14 @@ import java.awt.event.MouseEvent;
import java.util.Collection;
/**
* Created by StravantUser on 2016-09-22.
* @author StravantUser
*/
public interface DragCardTarget {
void dragCardEnter(MouseEvent e);
void dragCardMove(MouseEvent e);
void dragCardExit(MouseEvent e);
void dragCardDrop(MouseEvent e, DragCardSource source, Collection<CardView> cards);
}

View file

@ -1,25 +1,29 @@
package mage.client.cards;
import java.util.UUID;
import mage.client.deckeditor.SortSetting;
import mage.client.util.Event;
import mage.client.util.Listener;
import mage.view.CardsView;
import java.util.UUID;
/**
* Interface for card container.
*
* @author nantuko
*
* @author nantuko
*/
public interface ICardGrid {
void clearCardEventListeners();
void addCardEventListener(Listener<Event> listener);
void drawCards(SortSetting sortSetting);
void loadCards(CardsView showCards, SortSetting sortSetting, BigCard bigCard, UUID gameId);
void loadCards(CardsView showCards, SortSetting sortSetting, BigCard bigCard, UUID gameId, boolean merge);
void refresh();
int cardsSize();
}

View file

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
<Property name="useNullLayout" type="boolean" value="true"/>
</Layout>
</Form>

View file

@ -1,263 +0,0 @@
/*
* Permanent.java
*
* Created on Dec 22, 2009, 3:25:49 PM
*/
package mage.client.cards;
import mage.cards.CardDimensions;
import mage.cards.MagePermanent;
import mage.cards.Sets;
import mage.client.util.ClientDefaultSettings;
import mage.client.util.TransformedImageCache;
import mage.view.CounterView;
import mage.view.PermanentView;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static mage.client.constants.Constants.DAMAGE_MAX_LEFT;
import static mage.client.constants.Constants.POWBOX_TEXT_MAX_TOP;
/**
* @author BetaSteward_at_googlemail.com
*/
public class Permanent extends Card {
protected PermanentView permanent;
protected final List<MagePermanent> links = new ArrayList<>();
protected boolean linked;
protected final BufferedImage tappedImage;
protected BufferedImage flippedImage;
/**
* Creates new form Permanent
*
* @param permanent
* @param bigCard
* @param dimensions
* @param gameId
*/
public Permanent(PermanentView permanent, BigCard bigCard, CardDimensions dimensions, UUID gameId) {
super(permanent, bigCard, dimensions, gameId);
this.setSize(this.getPreferredSize());
this.permanent = permanent;
tappedImage = new BufferedImage(ClientDefaultSettings.dimensions.getFrameHeight(), ClientDefaultSettings.dimensions.getFrameWidth(), BufferedImage.TYPE_INT_RGB);
}
public UUID getPermanentId() {
return permanent.getId();
}
@Override
public List<MagePermanent> getLinks() {
return links;
}
public boolean isLinked() {
return linked;
}
public void setLinked(boolean linked) {
this.linked = linked;
}
@Override
protected String getText(String cardType) {
StringBuilder sb = new StringBuilder();
sb.append(super.getText(cardType));
if (permanent.getOriginal() != null) {
sb.append("\n----- Originally -------\n");
sb.append(permanent.getOriginal().getName());
if (!permanent.getOriginal().getManaCost().isEmpty()) {
sb.append('\n').append(permanent.getOriginal().getManaCost());
}
sb.append('\n').append(getType(permanent.getOriginal()));
if (permanent.getOriginal().getColor().hasColor()) {
sb.append('\n').append(permanent.getOriginal().getColor().toString());
}
if (permanent.getOriginal().isCreature()) {
sb.append('\n').append(permanent.getOriginal().getPower()).append('/').append(permanent.getOriginal().getToughness());
} else if (permanent.getOriginal().isPlanesWalker()) {
sb.append('\n').append(permanent.getOriginal().getLoyalty());
}
for (String rule : getRules()) {
sb.append('\n').append(rule);
}
if (!permanent.getOriginal().getExpansionSetCode().isEmpty()) {
sb.append('\n').append(permanent.getCardNumber()).append(" - ");
sb.append('\n').append(Sets.getInstance().get(permanent.getOriginal().getExpansionSetCode()).getName()).append(" - ");
sb.append(permanent.getOriginal().getRarity() == null ? "none" : permanent.getOriginal().getRarity().toString());
}
// sb.append("\n").append(card.getId());
}
return sb.toString();
}
@Override
protected List<String> getRules() {
if (permanent.getCounters() != null) {
List<String> rules = new ArrayList<>(permanent.getRules());
for (CounterView counter : permanent.getCounters()) {
rules.add(counter.getCount() + " x " + counter.getName());
}
return rules;
} else {
return permanent.getRules();
}
}
@Override
public void mousePressed(MouseEvent e) {
p = e.getPoint();
e.consume();
}
@Override
public void mouseDragged(MouseEvent e) {
if (!linked) {
int dx = e.getX() - p.x;
int dy = e.getY() - p.y;
Rectangle r = this.getBounds();
r.x += dx;
r.y += dy;
if (r.x < 0) {
r.x = 0;
}
if (r.y < 0) {
r.y = 0;
}
this.setBounds(r);
this.repaint();
for (MagePermanent perm : links) {
r.x += 20;
r.y += 20;
perm.setBounds(r);
}
}
}
@Override
public void mouseClicked(MouseEvent arg0) {
super.mouseClicked(arg0);
}
@Override
public void paintComponent(Graphics graphics) {
Graphics2D g2 = (Graphics2D) graphics;
this.setSize(this.getPreferredSize());
if (permanent.isTapped()) {
this.getText().setVisible(false);
g2.drawImage(tappedImage, 0, 0, this);
} else {
this.getText().setVisible(true);
g2.drawImage(small, 0, 0, this);
}
//Add a border, red if card currently has focus
if (isFocusOwner()) {
g2.setColor(Color.RED);
} else {
g2.setColor(Color.BLACK);
}
if (permanent.isTapped()) {
g2.drawRect(0, 0, ClientDefaultSettings.dimensions.getFrameHeight() - 1, ClientDefaultSettings.dimensions.getFrameWidth() - 1);
} else {
g2.drawRect(0, 0, ClientDefaultSettings.dimensions.getFrameWidth() - 1, ClientDefaultSettings.dimensions.getFrameHeight() - 1);
}
}
protected void generateTappedImage() {
Graphics2D g = (Graphics2D) tappedImage.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(TransformedImageCache.getRotatedResizedImage(small, dimension.getFrameWidth(), dimension.getFrameHeight(), Math.toRadians(90.0)), 0, 0, this);
g.dispose();
}
@Override
public void update(PermanentView permanent) {
this.permanent = permanent;
super.update(permanent);
if (permanent.getDamage() > 0) {
Graphics2D g = image.createGraphics();
g.setColor(Color.RED);
g.drawString(Integer.toString(permanent.getDamage()), DAMAGE_MAX_LEFT, POWBOX_TEXT_MAX_TOP);
g.dispose();
}
generateTappedImage();
}
@Override
public Dimension getPreferredSize() {
if (permanent != null && permanent.isTapped()) {
return new Dimension(ClientDefaultSettings.dimensions.getFrameHeight(), ClientDefaultSettings.dimensions.getFrameWidth());
} else {
return new Dimension(ClientDefaultSettings.dimensions.getFrameWidth(), ClientDefaultSettings.dimensions.getFrameHeight());
}
}
@Override
public Dimension getMinimumSize() {
return this.getPreferredSize();
}
public boolean overlaps(Rectangle r1) {
return this.getBounds().intersects(r1);
}
@Override
public void mouseEntered(MouseEvent arg0) {
if (!tooltipShowing) {
if (tooltipPopup != null) {
tooltipPopup.hide();
}
PopupFactory factory = PopupFactory.getSharedInstance();
int x = (int) this.getLocationOnScreen().getX() + (permanent.isTapped() ? ClientDefaultSettings.dimensions.getFrameHeight() : ClientDefaultSettings.dimensions.getFrameWidth());
int y = (int) this.getLocationOnScreen().getY() + 40;
tooltipPopup = factory.getPopup(this, tooltipText, x, y);
tooltipPopup.show();
//hack to get tooltipPopup to resize to fit text
tooltipPopup.hide();
tooltipPopup = factory.getPopup(this, tooltipText, x, y);
tooltipPopup.show();
tooltipShowing = true;
}
}
@Override
public PermanentView getOriginalPermanent() {
return permanent;
}
/**
* 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.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(null);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}

View file

@ -1,6 +1,6 @@
package mage.client.combat;
import mage.cards.MagePermanent;
import mage.cards.MageCard;
import mage.client.MageFrame;
import mage.client.game.PlayAreaPanel;
import mage.client.util.SettingsManager;
@ -17,7 +17,7 @@ import java.util.Map;
import java.util.UUID;
/**
* @author noxx
* @author noxx, JayDi85
*/
public enum CombatManager {
@ -27,8 +27,8 @@ public enum CombatManager {
private final Map<UUID, Integer> combatBlockers = new HashMap<>();
private int globalBlockersCount; // we need global counter as there are several combat groups
private static Color ARROW_COLOR_ATTACKER = Color.red;
private static Color ARROW_COLOR_BLOCKED_ATTACKER = Color.gray;
private static final Color ARROW_COLOR_ATTACKER = Color.red;
private static final Color ARROW_COLOR_BLOCKED_ATTACKER = Color.gray;
private Point parentPoint;
@ -71,7 +71,7 @@ public enum CombatManager {
private void drawAttacker(CombatGroupView group, CardView attacker, UUID gameId) {
for (PlayAreaPanel pa2 : MageFrame.getGamePlayers(gameId).values()) {
MagePermanent attackerCard = pa2.getBattlefieldPanel().getPermanents().get(attacker.getId());
MageCard attackerCard = pa2.getBattlefieldPanel().getPermanentPanels().get(attacker.getId());
if (attackerCard != null) {
drawDefender(group, attackerCard, gameId);
drawBlockers(group, attackerCard, gameId);
@ -79,7 +79,7 @@ public enum CombatManager {
}
}
private void drawDefender(CombatGroupView group, MagePermanent attackerCard, UUID gameId) {
private void drawDefender(CombatGroupView group, MageCard attackerCard, UUID gameId) {
UUID defenderId = group.getDefenderId();
if (defenderId != null) {
// if attacker was blocked then use another arrow color
@ -90,17 +90,17 @@ public enum CombatManager {
// attack to player
Point target = p.getLocationOnScreen();
target.translate(-parentPoint.x, -parentPoint.y);
Point attackerPoint = attackerCard.getLocationOnScreen();
Point attackerPoint = attackerCard.getCardLocationOnScreen().getCardPoint();
attackerPoint.translate(-parentPoint.x, -parentPoint.y);
ArrowBuilder.getBuilder().addArrow(gameId, (int) attackerPoint.getX() + 45, (int) attackerPoint.getY() + 25, (int) target.getX() + 40, (int) target.getY() - 20, attackColor, ArrowBuilder.Type.COMBAT);
} else {
// attack to planeswalker
for (PlayAreaPanel pa : MageFrame.getGamePlayers(gameId).values()) {
MagePermanent permanent = pa.getBattlefieldPanel().getPermanents().get(defenderId);
MageCard permanent = pa.getBattlefieldPanel().getPermanentPanels().get(defenderId);
if (permanent != null) {
Point target = permanent.getLocationOnScreen();
Point target = permanent.getCardLocationOnScreen().getCardPoint();
target.translate(-parentPoint.x, -parentPoint.y);
Point attackerPoint = attackerCard.getLocationOnScreen();
Point attackerPoint = attackerCard.getCardLocationOnScreen().getCardPoint();
attackerPoint.translate(-parentPoint.x, -parentPoint.y);
ArrowBuilder.getBuilder().addArrow(gameId, (int) attackerPoint.getX() + 45, (int) attackerPoint.getY() + 25, (int) target.getX() + 40, (int) target.getY() + 10, attackColor, ArrowBuilder.Type.COMBAT);
}
@ -109,20 +109,20 @@ public enum CombatManager {
}
}
private void drawBlockers(CombatGroupView group, MagePermanent attackerCard, UUID gameId) {
private void drawBlockers(CombatGroupView group, MageCard attackerCard, UUID gameId) {
for (CardView blocker : group.getBlockers().values()) {
for (PlayAreaPanel pa : MageFrame.getGamePlayers(gameId).values()) {
MagePermanent blockerCard = pa.getBattlefieldPanel().getPermanents().get(blocker.getId());
MageCard blockerCard = pa.getBattlefieldPanel().getPermanentPanels().get(blocker.getId());
if (blockerCard != null) {
parentPoint = getParentPoint(blockerCard);
Point blockerPoint = blockerCard.getLocationOnScreen();
Point blockerPoint = blockerCard.getCardLocationOnScreen().getCardPoint();
blockerPoint.translate(-parentPoint.x, -parentPoint.y);
Point attackerPoint = attackerCard.getLocationOnScreen();
Point attackerPoint = attackerCard.getCardLocationOnScreen().getCardPoint();
attackerPoint.translate(-parentPoint.x, -parentPoint.y);
double yRateA = (attackerCard.getSize().height / SettingsManager.instance.getCardSize().height);
double xRateA = (attackerCard.getSize().width / SettingsManager.instance.getCardSize().width);
double yRateB = (blockerCard.getSize().height / SettingsManager.instance.getCardSize().height);
double xRateB = (blockerCard.getSize().width / SettingsManager.instance.getCardSize().width);
double yRateA = (attackerCard.getCardLocation().getCardHeight() / SettingsManager.instance.getCardSize().height);
double xRateA = (attackerCard.getCardLocation().getCardWidth() / SettingsManager.instance.getCardSize().width);
double yRateB = (blockerCard.getCardLocation().getCardHeight() / SettingsManager.instance.getCardSize().height);
double xRateB = (blockerCard.getCardLocation().getCardWidth() / SettingsManager.instance.getCardSize().width);
ArrowBuilder.getBuilder().addArrow(gameId, (int) blockerPoint.getX() + (int) (55 * xRateB), (int) blockerPoint.getY() + (int) (25 * xRateB),
(int) attackerPoint.getX() + (int) (70 * xRateA), (int) attackerPoint.getY() + (int) (25 * yRateA), Color.blue, ArrowBuilder.Type.COMBAT);
globalBlockersCount++;
@ -142,7 +142,7 @@ public enum CombatManager {
combatBlockers.put(gameId, count);
}
private Point getParentPoint(MagePermanent permanent) {
private Point getParentPoint(MageCard permanent) {
if (parentPoint == null) {
Component parentComponent = SwingUtilities.getRoot(permanent);
parentPoint = parentComponent.getLocationOnScreen();

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;
}
}

View file

@ -1,8 +1,3 @@
/*
* CardSelector.java
*
* Created on Feb 18, 2010, 2:49:03 PM
*/
package mage.client.deckeditor;
import mage.MageObject;
@ -1272,7 +1267,8 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
java.util.List<Integer> indexes = asList(n);
Collections.reverse(indexes);
for (Integer index : indexes) {
mainModel.doubleClick(index);
// normal double click emulation
mainModel.doubleClick(index, null, false);
}
//if (!mode.equals(Constants.DeckEditorMode.Constructed))
if (limited) {
@ -1287,7 +1283,8 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
java.util.List<Integer> indexes = asList(n);
Collections.reverse(indexes);
for (Integer index : indexes) {
mainModel.altDoubleClick(index);
// ALT double click emulation
mainModel.doubleClick(index, null, true);
}
//if (!mode.equals(Constants.DeckEditorMode.Constructed))
if (limited) {
@ -1537,7 +1534,7 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
private javax.swing.JToggleButton tbWhite;
// End of variables declaration//GEN-END:variables
private final mage.client.cards.CardGrid cardGrid;
private final mage.client.cards.CardGrid cardGrid; // grid for piles view mode (example: selected cards in drafting)
@Override
public void componentResized(ComponentEvent e) {

View file

@ -92,8 +92,8 @@ public class DeckArea extends javax.swing.JPanel {
// Add to hidden and move to sideboard
for (CardView card : cards) {
hiddenCards.add(card.getId());
maindeckVirtualEvent.fireEvent(card, ClientEventType.REMOVE_SPECIFIC_CARD);
sideboardVirtualEvent.fireEvent(card, ClientEventType.ADD_SPECIFIC_CARD);
maindeckVirtualEvent.fireEvent(card, ClientEventType.DECK_REMOVE_SPECIFIC_CARD);
sideboardVirtualEvent.fireEvent(card, ClientEventType.DECK_ADD_SPECIFIC_CARD);
}
loadDeck(lastDeck, lastBigCard);
}

View file

@ -304,77 +304,92 @@ public class DeckEditorPanel extends javax.swing.JPanel {
private void init() {
//this.cardSelector.setVisible(true);
this.panelLeft.setVisible(true);
// TOP AREA: ENABLE ADDING/REMOVING BY DOUBLE CLICKS
for (ICardGrid component : this.cardSelector.getCardGridComponents()) {
component.clearCardEventListeners();
//component.clearCardEventListeners();
component.addCardEventListener((Listener<Event>) event -> {
switch (event.getEventType()) {
case DOUBLE_CLICK:
moveSelectorCardToDeck(event);
break;
case ALT_DOUBLE_CLICK:
if (mode == DeckEditorMode.FREE_BUILDING) {
moveSelectorCardToSideboard(event);
} else {
// because in match mode selector is used as sideboard the card goes to deck also for shift click
case CARD_DOUBLE_CLICK: {
boolean gameMode = mode != DeckEditorMode.FREE_BUILDING;
if (gameMode) {
// in game mode selector is used as sideboard, so the card must goes to deck all the time
moveSelectorCardToDeck(event);
} else {
// edit mode
if (event.isMouseAltDown()) {
moveSelectorCardToSideboard(event);
} else {
moveSelectorCardToDeck(event);
}
}
break;
case REMOVE_MAIN:
}
case DECK_REMOVE_SELECTION_MAIN: {
DeckEditorPanel.this.deckArea.getDeckList().removeSelection();
break;
case REMOVE_SIDEBOARD:
}
case DECK_REMOVE_SELECTION_SIDEBOARD: {
DeckEditorPanel.this.deckArea.getSideboardList().removeSelection();
break;
}
}
refreshDeck();
});
}
this.deckArea.clearDeckEventListeners();
// BOTTOM AREA: ENABLE ADDING/REMOVING CARDS in MAINBOARD
// do not clear event listener - DragCardGrid already have own listeners for cards
//this.deckArea.clearDeckEventListeners();
this.deckArea.addDeckEventListener(
// card manipulation events
// warning, do not use drag or single click events here, it's already processing by DragCardGrid
(Listener<Event>) event -> {
if (mode == DeckEditorMode.FREE_BUILDING) {
switch (event.getEventType()) {
case DOUBLE_CLICK: {
case CARD_DOUBLE_CLICK: {
SimpleCardView cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getCards()) {
if (card.getId().equals(cardView.getId())) {
deck.getCards().remove(card);
break;
}
}
hidePopup();
refreshDeck();
break;
}
case ALT_DOUBLE_CLICK: {
SimpleCardView cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getCards()) {
if (card.getId().equals(cardView.getId())) {
deck.getCards().remove(card);
deck.getSideboard().add(card);
break;
}
Card card = deck.findCard(cardView.getId());
if (card == null) {
return;
}
if (event.isMouseAltDown()) {
// ALT + double click: MOVE card from one deck to another
deck.getCards().remove(card);
deck.getSideboard().add(card);
} else {
// double click: DELETE card from deck
deck.getCards().remove(card);
}
hidePopup();
refreshDeck();
break;
}
case SET_NUMBER: {
setCardNumberToCardsList(event, deck.getCards());
break;
}
case REMOVE_SPECIFIC_CARD: {
case DECK_REMOVE_SPECIFIC_CARD: {
SimpleCardView cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getCards()) {
if (card.getId().equals(cardView.getId())) {
deck.getCards().remove(card);
storeTemporaryCard(card);
break;
}
Card card = deck.findCard(cardView.getId());
if (card == null) {
return;
}
deck.getCards().remove(card);
storeTemporaryCard(card);
break;
}
case ADD_SPECIFIC_CARD: {
case DECK_ADD_SPECIFIC_CARD: {
SimpleCardView cardView = (CardView) event.getSource();
deck.getCards().add(retrieveTemporaryCard(cardView));
break;
@ -383,33 +398,36 @@ public class DeckEditorPanel extends javax.swing.JPanel {
} else {
// constructing phase or sideboarding during match -> card goes always to sideboard
switch (event.getEventType()) {
case DOUBLE_CLICK:
case ALT_DOUBLE_CLICK: {
case CARD_DOUBLE_CLICK: {
SimpleCardView cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getCards()) {
if (card.getId().equals(cardView.getId())) {
deck.getCards().remove(card);
deck.getSideboard().add(card);
cardSelector.loadSideboard(new ArrayList<>(deck.getSideboard()), this.bigCard);
break;
}
Card card = deck.findCard(cardView.getId());
if (card == null) {
return;
}
deck.getCards().remove(card);
deck.getSideboard().add(card);
cardSelector.loadSideboard(new ArrayList<>(deck.getSideboard()), this.bigCard);
hidePopup();
refreshDeck();
break;
}
case REMOVE_SPECIFIC_CARD: {
case DECK_REMOVE_SPECIFIC_CARD: {
SimpleCardView cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getCards()) {
if (card.getId().equals(cardView.getId())) {
deck.getCards().remove(card);
storeTemporaryCard(card);
break;
}
Card card = deck.findCard(cardView.getId());
if (card == null) {
return;
}
deck.getCards().remove(card);
storeTemporaryCard(card);
break;
}
case ADD_SPECIFIC_CARD: {
case DECK_ADD_SPECIFIC_CARD: {
SimpleCardView cardView = (CardView) event.getSource();
deck.getCards().add(retrieveTemporaryCard(cardView));
break;
@ -417,95 +435,104 @@ public class DeckEditorPanel extends javax.swing.JPanel {
}
}
});
this.deckArea.clearSideboardEventListeners();
// BOTTOM AREA: ENABLE ADDING/REMOVING CARDS in SIDEBOARD
// do not clear event listener - DragCardGrid already have own listeners for cards
//this.deckArea.clearSideboardEventListeners();
this.deckArea.addSideboardEventListener(
// card manipulation events
(Listener<Event>) event -> {
if (mode == DeckEditorMode.FREE_BUILDING) {
// normal edit mode
// DECK EDITOR MODE
switch (event.getEventType()) {
case DOUBLE_CLICK:
// remove card from sideboard (don't add it to deck)
case CARD_DOUBLE_CLICK: {
SimpleCardView cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getSideboard()) {
if (card.getId().equals(cardView.getId())) {
deck.getSideboard().remove(card);
break;
}
}
hidePopup();
refreshDeck();
break;
case ALT_DOUBLE_CLICK:
// remove card from sideboard
cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getSideboard()) {
if (card.getId().equals(cardView.getId())) {
deck.getSideboard().remove(card);
deck.getCards().add(card);
break;
}
Card card = deck.findSideboardCard(cardView.getId());
if (card == null) {
return;
}
if (event.isMouseAltDown()) {
// ALT + double click: MOVE card from one deck to another
deck.getSideboard().remove(card);
deck.getCards().add(card);
} else {
// double click: DELETE card from deck
deck.getSideboard().remove(card);
}
hidePopup();
refreshDeck();
break;
}
case SET_NUMBER: {
setCardNumberToCardsList(event, deck.getSideboard());
break;
}
case REMOVE_SPECIFIC_CARD: {
cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getSideboard()) {
if (card.getId().equals(cardView.getId())) {
deck.getSideboard().remove(card);
storeTemporaryCard(card);
break;
}
case DECK_REMOVE_SPECIFIC_CARD: {
SimpleCardView cardView = (SimpleCardView) event.getSource();
Card card = deck.findSideboardCard(cardView.getId());
if (card == null) {
return;
}
deck.getSideboard().remove(card);
storeTemporaryCard(card);
break;
}
case ADD_SPECIFIC_CARD: {
cardView = (CardView) event.getSource();
case DECK_ADD_SPECIFIC_CARD: {
SimpleCardView cardView = (CardView) event.getSource();
deck.getSideboard().add(retrieveTemporaryCard(cardView));
break;
}
}
} else {
// construct phase or sideboarding during match
// GAME MODE
// constructing phase or sideboarding during match -> card goes always to main board
switch (event.getEventType()) {
case REMOVE_SPECIFIC_CARD: {
case DECK_REMOVE_SPECIFIC_CARD: {
SimpleCardView cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getSideboard()) {
if (card.getId().equals(cardView.getId())) {
deck.getSideboard().remove(card);
storeTemporaryCard(card);
break;
}
Card card = deck.findSideboardCard(cardView.getId());
if (card == null) {
return;
}
deck.getSideboard().remove(card);
storeTemporaryCard(card);
break;
}
case ADD_SPECIFIC_CARD: {
case DECK_ADD_SPECIFIC_CARD: {
SimpleCardView cardView = (CardView) event.getSource();
deck.getSideboard().add(retrieveTemporaryCard(cardView));
break;
}
case DOUBLE_CLICK:
case ALT_DOUBLE_CLICK:
case CARD_DOUBLE_CLICK: {
// in games you can't delete cards, only moves from one deck to another
SimpleCardView cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getSideboard()) {
if (card.getId().equals(cardView.getId())) {
deck.getSideboard().remove(card);
deck.getCards().add(card);
break;
}
Card card = deck.findSideboardCard(cardView.getId());
if (card == null) {
return;
}
deck.getSideboard().remove(card);
deck.getCards().add(card);
hidePopup();
refreshDeck();
break;
}
}
}
});
refreshDeck(true);
// auto-import dropped files from OS
if (mode == DeckEditorMode.FREE_BUILDING) {
setDropTarget(new DropTarget(this, new DnDDeckTargetListener() {
@ -562,26 +589,32 @@ public class DeckEditorPanel extends javax.swing.JPanel {
private void moveSelectorCardToDeck(Event event) {
SimpleCardView cardView = (SimpleCardView) event.getSource();
CardInfo cardInfo = CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber());
Card card = null;
if (mode == DeckEditorMode.SIDEBOARDING || mode == DeckEditorMode.LIMITED_BUILDING) {
for (Object o : deck.getSideboard()) {
card = (Card) o;
if (card.getId().equals(cardView.getId())) {
boolean gameMode = mode != DeckEditorMode.FREE_BUILDING;
if (gameMode) {
// game: use existing real cards
for (Card sideCard : deck.getSideboard()) {
if (sideCard.getId().equals(cardView.getId())) {
card = sideCard;
break;
}
}
} else {
// editor: create mock card
CardInfo cardInfo = CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber());
card = cardInfo != null ? cardInfo.getMockCard() : null;
}
if (card != null) {
deck.getCards().add(card);
if (mode == DeckEditorMode.SIDEBOARDING || mode == DeckEditorMode.LIMITED_BUILDING) {
if (gameMode) {
// game: move card from another board
deck.getSideboard().remove(card);
cardSelector.removeCard(card.getId());
cardSelector.setCardCount(deck.getSideboard().size());
cardSelector.refresh();
}
// card hint update
if (cardInfoPane instanceof CardInfoPane) {
((CardInfoPane) cardInfoPane).setCard(new CardView(card), null);
}
@ -590,12 +623,19 @@ public class DeckEditorPanel extends javax.swing.JPanel {
}
private void moveSelectorCardToSideboard(Event event) {
boolean gameMode = mode != DeckEditorMode.FREE_BUILDING;
if (gameMode) {
throw new IllegalArgumentException("ERROR, you can move card to sideboard from selector in game mode.");
}
SimpleCardView cardView = (SimpleCardView) event.getSource();
CardInfo cardInfo = CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber());
Card card = cardInfo != null ? cardInfo.getMockCard() : null;
if (card != null) {
deck.getSideboard().add(card);
}
// card hint update
if (cardInfoPane instanceof CardInfoPane) {
((CardInfoPane) cardInfoPane).setCard(new CardView(card), null);
}

View file

@ -14,6 +14,8 @@ import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
/**
* App GUI: deck export window, uses in deck editor
*
* @author JayDi85
*/
public class DeckExportClipboardDialog extends MageDialog {

View file

@ -13,6 +13,8 @@ import java.io.IOException;
import java.util.Optional;
/**
* App GUI: deck import window, uses in deck editor
*
* @author JayDi85
*/
public class DeckImportClipboardDialog extends MageDialog {

View file

@ -1,5 +1,6 @@
package mage.client.deckeditor.collection.viewer;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.*;
import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo;
@ -45,17 +46,17 @@ import static java.lang.Math.min;
import static org.mage.plugins.card.images.DownloadPicturesService.getTokenCardUrls;
/**
* Mage book with cards and page flipping.
* Card viewer (mage book) with cards and page flipping
*
* @author nantuko
* @author nantuko, JayDi85
*/
public class MageBook extends JComponent {
private static final long serialVersionUID = 1L;
public static final String LAYOUT_3X3 = "small";
public static final String LAYOUT_4X4 = "big";
private static final int CARD_CAPTION_OFFSET_Y = 8; // apply offset to see card names with mana icons at the same time
public MageBook(BigCard bigCard) {
super();
@ -71,7 +72,6 @@ public class MageBook extends JComponent {
setSize(conf.WIDTH, conf.HEIGHT);
setPreferredSize(new Dimension(conf.WIDTH, conf.HEIGHT));
setMinimumSize(new Dimension(conf.WIDTH, conf.HEIGHT));
//setBorder(BorderFactory.createLineBorder(Color.green));
jPanelLeft = getImagePanel(LEFT_PANEL_IMAGE_PATH, ImagePanelStyle.TILED);
jPanelLeft.setPreferredSize(new Dimension(LEFT_RIGHT_PAGES_WIDTH, 0));
@ -87,7 +87,6 @@ public class MageBook extends JComponent {
Image image = ImageHelper.loadImage(LEFT_PAGE_BUTTON_IMAGE_PATH);
pageLeft = new HoverButton(null, image, image, image, new Rectangle(64, 64));
//pageLeft.setBorder(BorderFactory.createLineBorder(new Color(180, 50, 0), 3, true)); //debug
pageLeft.setBounds(0, 0, 64, 64);
pageLeft.setVisible(false);
pageLeft.setObserver(() -> {
@ -124,7 +123,6 @@ public class MageBook extends JComponent {
// Top Panel (left page + (caption / stats) + right page
jPanelTop = new JPanel();
jPanelTop.setLayout(new BorderLayout());
// jPanelTop.setBorder(BorderFactory.createLineBorder(new Color(180, 50, 150), 3, true)); // debug
jPanelTop.setPreferredSize(new Dimension(captionHeight, captionHeight));
jPanelCenter.add(jPanelTop, BorderLayout.NORTH);
@ -144,7 +142,6 @@ public class MageBook extends JComponent {
// set's caption
setCaption = new JLabel();
setCaption.setHorizontalAlignment(SwingConstants.CENTER);
//setCaption.setBorder(BorderFactory.createLineBorder(new Color(180, 50, 150), 3, true)); // debug
setCaption.setFont(jLayeredPane.getFont().deriveFont(25f));
setCaption.setText("EMPTY CAPTION");
jPanelCaption.add(setCaption, BorderLayout.NORTH);
@ -152,7 +149,6 @@ public class MageBook extends JComponent {
// set's info
setInfo = new JLabel();
setInfo.setHorizontalAlignment(SwingConstants.CENTER);
//setCaption.setBorder(BorderFactory.createLineBorder(new Color(180, 50, 150), 3, true)); // debug
setInfo.setFont(jLayeredPane.getFont().deriveFont(17f));
setInfo.setText("EMPTY STATS");
jPanelCaption.add(setInfo, BorderLayout.SOUTH);
@ -245,7 +241,6 @@ public class MageBook extends JComponent {
for (int i = 0; i < min(conf.CARDS_PER_PAGE / 2, size); i++) {
Card card = cards.get(i).getMockCard();
addCard(new CardView(card), bigCard, null, rectangle);
rectangle = CardPosition.translatePosition(i, rectangle, conf);
}
@ -407,30 +402,29 @@ public class MageBook extends JComponent {
if (cardDimension == null) {
cardDimension = new Dimension(ClientDefaultSettings.dimensions.getFrameWidth(), ClientDefaultSettings.dimensions.getFrameHeight());
}
final MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, cardDimension, gameId, true, true, PreferencesDialog.getRenderMode(), true);
cardImg.setBounds(rectangle);
jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10);
final MageCard cardImg = Plugins.instance.getMageCard(card, bigCard, new CardIconRenderSettings(), cardDimension, gameId, true, true, PreferencesDialog.getRenderMode(), true);
cardImg.setCardContainerRef(jLayeredPane);
cardImg.update(card);
cardImg.setCardBounds(rectangle.x, rectangle.y, cardDimensions.getFrameWidth(), cardDimensions.getFrameHeight());
jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10);
cardImg.setCardCaptionTopOffset(8); // card caption below real card caption to see full name even with mana icons
// card caption must be below real card caption to see full name even with mana icons
cardImg.setCardCaptionTopOffset(CARD_CAPTION_OFFSET_Y);
// card number label
JLabel cardNumber = new JLabel();
int dy = -5; // image panel have empty space in bottom (bug?), need to move label up
cardNumber.setBounds(rectangle.x, rectangle.y + cardImg.getHeight() + dy, cardDimensions.getFrameWidth(), 20);
cardNumber.setBounds(rectangle.x, rectangle.y + cardImg.getCardLocation().getCardHeight() + dy, cardDimensions.getFrameWidth(), 20);
cardNumber.setHorizontalAlignment(SwingConstants.CENTER);
//cardNumber.setBorder(BorderFactory.createLineBorder(new Color(180, 50, 150), 3, true));
cardNumber.setFont(jLayeredPane.getFont().deriveFont(jLayeredPane.getFont().getStyle() | Font.BOLD));
cardNumber.setText(card.getCardNumber());
jLayeredPane.add(cardNumber);
// draft rating label (
// draft rating label
JLabel draftRating = new JLabel();
dy = -5 * 2 + cardNumber.getHeight(); // under card number
draftRating.setBounds(rectangle.x, rectangle.y + cardImg.getHeight() + dy, cardDimensions.getFrameWidth(), 20);
draftRating.setBounds(rectangle.x, rectangle.y + cardImg.getCardLocation().getCardHeight() + dy, cardDimensions.getFrameWidth(), 20);
draftRating.setHorizontalAlignment(SwingConstants.CENTER);
//draftRating.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 150), 3, true));
draftRating.setFont(jLayeredPane.getFont().deriveFont(jLayeredPane.getFont().getStyle() | Font.BOLD));
if (card.getOriginalCard() != null) {
draftRating.setText("draft rating: " + RateCard.rateCard(card.getOriginalCard(), null));
@ -448,8 +442,8 @@ public class MageBook extends JComponent {
newToken.removeSummoningSickness();
PermanentView theToken = new PermanentView(newToken, null, null, null);
theToken.setInViewerOnly(true);
final MageCard cardImg = Plugins.instance.getMagePermanent(theToken, bigCard, cardDimension, gameId, true, PreferencesDialog.getRenderMode(), true);
cardImg.setBounds(rectangle);
final MageCard cardImg = Plugins.instance.getMagePermanent(theToken, bigCard, new CardIconRenderSettings(), cardDimension, gameId, true, PreferencesDialog.getRenderMode(), true);
cardImg.setCardContainerRef(jLayeredPane);
jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10);
cardImg.update(theToken);
cardImg.setCardBounds(rectangle.x, rectangle.y, cardDimensions.getFrameWidth(), cardDimensions.getFrameHeight());

View file

@ -1,10 +1,11 @@
package mage.client.deckeditor.collection.viewer;
import javax.swing.*;
import mage.cards.repository.CardScanner;
import mage.client.plugins.impl.Plugins;
import org.mage.card.arcane.ManaSymbols;
import org.mage.card.arcane.SvgUtils;
import javax.swing.*;
/**
* @author nantuko
@ -12,6 +13,7 @@ import org.mage.card.arcane.ManaSymbols;
public class TestMageBook extends JFrame {
public static void main(String[] args) {
Plugins.instance.loadPlugins();
SvgUtils.checkSvgSupport();
ManaSymbols.loadImages();
CardScanner.scan();
JFrame frame = new TestMageBook();

View file

@ -1,45 +1,18 @@
/* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.client.deckeditor.table;
import mage.cards.MageCard;
import mage.client.util.comparators.CardViewComparator;
import mage.game.draft.RateCard;
import mage.view.CardView;
import org.apache.log4j.Logger;
import java.util.Comparator;
/**
* {@link MageCard} comparator. Used to sort cards in Deck Editor Table View
* pane.
*
* @author nantuko
*/
public class MageCardComparator implements Comparator<CardView> {
public class MageCardComparator implements CardViewComparator {
private static final Logger logger = Logger.getLogger(MageCardComparator.class);
@ -122,5 +95,10 @@ public class MageCardComparator implements Comparator<CardView> {
} else {
return bCom.compareTo(aCom);
}
}// compare()
}
@Override
public String getCategoryName(CardView sample) {
return "";
}
}

View file

@ -293,22 +293,17 @@ public class TableModel extends AbstractTableModel implements ICardGrid {
cardEventSource.fireEvent(card, ClientEventType.SET_NUMBER, number);
}
public void doubleClick(int index) {
public void doubleClick(int index, MouseEvent e, boolean forceFakeAltDown) {
CardView card = view.get(index);
cardEventSource.fireEvent(card, ClientEventType.DOUBLE_CLICK);
}
public void altDoubleClick(int index) {
CardView card = view.get(index);
cardEventSource.fireEvent(card, ClientEventType.ALT_DOUBLE_CLICK);
cardEventSource.fireEvent(card, ClientEventType.CARD_DOUBLE_CLICK, e, forceFakeAltDown);
}
public void removeFromMainEvent(int index) {
cardEventSource.fireEvent(ClientEventType.REMOVE_MAIN);
cardEventSource.fireEvent(ClientEventType.DECK_REMOVE_SELECTION_MAIN);
}
public void removeFromSideEvent(int index) {
cardEventSource.fireEvent(ClientEventType.REMOVE_SIDEBOARD);
cardEventSource.fireEvent(ClientEventType.DECK_REMOVE_SELECTION_SIDEBOARD);
}
public void addListeners(final JTable table) {

View file

@ -7,6 +7,8 @@ import javax.swing.*;
import java.awt.event.KeyEvent;
/**
* App GUI: about window
*
* @author JayDi85
*/
public class AboutDialog extends MageDialog {
@ -14,7 +16,7 @@ public class AboutDialog extends MageDialog {
private static String devsList = "BetaSteward, Noxx, Eugen.Rivniy, North, LevelX2, "
+ "Jeff, Plopman, dustinconrad, emerald000, fireshoes, lunaskyrise, "
+ "mnapoleon, jgod, LoneFox, drmDev, spjspj, TheElk801, L_J, JayDi85, "
+ "jmharmon, Ketsuban, hitch17";
+ "jmharmon, Ketsuban, hitch17, weirddan455";
public AboutDialog() {
initComponents();

View file

@ -22,6 +22,8 @@ import java.util.SortedSet;
import java.util.TreeSet;
/**
* App GUI: adding new lands to the deck, uses in deck editor and drafting
*
* @author BetaSteward_at_googlemail.com
*/
public class AddLandDialog extends MageDialog {

View file

@ -1,6 +1,8 @@
package mage.client.dialog;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyVetoException;
import java.util.EnumSet;
import java.util.LinkedHashSet;
@ -9,6 +11,8 @@ import java.util.UUID;
import javax.swing.*;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.plaf.basic.BasicInternalFrameUI;
import mage.client.cards.BigCard;
import mage.client.util.GUISizeHelper;
import mage.client.util.ImageHelper;
@ -23,6 +27,8 @@ import org.apache.log4j.Logger;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
/**
* Game GUI: popup windows with title like reveal, graveyard
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class CardInfoWindowDialog extends MageDialog {
@ -44,6 +50,22 @@ public class CardInfoWindowDialog extends MageDialog {
this.positioned = false;
initComponents();
// ENABLE a minimizing window on double clicks
BasicInternalFrameUI ui = (BasicInternalFrameUI) this.getUI();
ui.getNorthPane().addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if ((e.getClickCount() & 1) == 0 && (e.getClickCount() > 0) && !e.isConsumed()) { // double clicks and repeated double clicks
e.consume();
try {
CardInfoWindowDialog.this.setIcon(!CardInfoWindowDialog.this.isIcon());
} catch (PropertyVetoException exp) {
// ignore read only
}
}
}
});
this.setModal(false);
switch (this.showType) {
case LOOKED_AT:
@ -62,7 +84,7 @@ public class CardInfoWindowDialog extends MageDialog {
this.setFrameIcon(new ImageIcon(ImageHelper.getImageFromResources("/info/grave.png")));
this.setClosable(true);
this.setDefaultCloseOperation(HIDE_ON_CLOSE);
addInternalFrameListener(new InternalFrameAdapter() {
this.addInternalFrameListener(new InternalFrameAdapter() {
@Override
public void internalFrameClosing(InternalFrameEvent e) {
CardInfoWindowDialog.this.hideDialog();

View file

@ -28,6 +28,8 @@ import java.util.concurrent.TimeoutException;
import static mage.client.dialog.PreferencesDialog.*;
/**
* App GUI: connection windows
*
* @author BetaSteward_at_googlemail.com
*/
public class ConnectDialog extends MageDialog {

View file

@ -12,6 +12,8 @@ import java.util.HashMap;
import java.util.Map;
/**
* App GUI: download card images window
*
* @author JayDi85
*/
public class DownloadImagesDialog extends MageDialog {

View file

@ -1,15 +1,7 @@
/*
* ErrorDialog.java
*
* Created on Dec 23, 2009, 11:01:32 AM
*/
package mage.client.dialog;
/**
* Game GUI: error dialog
*
* @author BetaSteward_at_googlemail.com
*/

View file

@ -1,10 +1,3 @@
/*
* GameEndDialog.java
*
* Created on Jul 31, 2013, 9:41:00 AM
*/
package mage.client.dialog;
import mage.client.MageFrame;
@ -27,6 +20,8 @@
import java.util.Calendar;
/**
* Game GUI: end game window
*
* @author LevelX2
*/
public class GameEndDialog extends MageDialog {

View file

@ -11,6 +11,8 @@ import javax.swing.*;
import java.util.UUID;
/**
* App GUI: join to the new game window
*
* @author BetaSteward_at_googlemail.com
*/
public class JoinTableDialog extends MageDialog {

View file

@ -27,6 +27,8 @@ import java.util.List;
import java.util.UUID;
/**
* App GUI: create new GAME
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class NewTableDialog extends MageDialog {

View file

@ -34,6 +34,8 @@ import java.util.*;
import java.util.stream.Collectors;
/**
* App GUI: create new TOURNEY
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class NewTournamentDialog extends MageDialog {

View file

@ -13,8 +13,9 @@ import java.util.*;
import java.util.List;
/**
* @author JayDi85
* @author Salco
* App GUI: fast search in the combobox, uses in deck editor (sets choosing)
*
* @author Salco, JayDi85
*/
public class PickCheckBoxDialog extends MageDialog {

View file

@ -11,6 +11,8 @@ import mage.client.MageFrame;
import mage.client.util.gui.MageDialogState;
/**
* Game GUI: choosing one of the list's item
*
* @author JayDi85
*/
public class PickChoiceDialog extends MageDialog {

View file

@ -7,6 +7,8 @@ import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/**
* Game GUI: choose number
*
* @author BetaSteward_at_googlemail.com
*/
public class PickNumberDialog extends MageDialog {

View file

@ -1,5 +1,6 @@
package mage.client.dialog;
import mage.cards.MageCard;
import mage.client.MageFrame;
import mage.client.cards.BigCard;
import mage.client.cards.CardArea;
@ -11,7 +12,9 @@ import java.awt.*;
import java.util.UUID;
/**
* @author BetaSteward_at_googlemail.com
* Game GUI: pile choosing (select a 1 pile from a 2 piles)
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class PickPileDialog extends MageDialog {
@ -19,6 +22,7 @@ public class PickPileDialog extends MageDialog {
private final CardArea pile2;
private boolean pickedPile1 = false;
private boolean pickedOK = false;
/**
* Create the frame.
@ -51,20 +55,22 @@ public class PickPileDialog extends MageDialog {
public void cleanUp() {
for (Component comp : pile1.getComponents()) {
if (comp instanceof CardPanel) {
((CardPanel) comp).cleanUp();
if (comp instanceof MageCard) {
((MageCard) comp).cleanUp();
pile1.remove(comp);
}
}
for (Component comp : pile2.getComponents()) {
if (comp instanceof CardPanel) {
((CardPanel) comp).cleanUp();
if (comp instanceof MageCard) {
((MageCard) comp).cleanUp();
pile2.remove(comp);
}
}
}
public void loadCards(String name, CardsView pile1, CardsView pile2, BigCard bigCard, UUID gameId) {
this.pickedOK = false;
this.pickedPile1 = false;
this.title = name;
this.pile1.loadCardsNarrow(pile1, bigCard, gameId);
this.pile2.loadCardsNarrow(pile2, bigCard, gameId);
@ -81,23 +87,25 @@ public class PickPileDialog extends MageDialog {
}
this.makeWindowCentered();
this.revalidate(); // TODO: remove?
this.repaint(); // TODO: remove?
this.setVisible(true);
}
private void btnPile1ActionPerformed(java.awt.event.ActionEvent evt) {
pickedPile1 = true;
pickedOK = true;
this.hideDialog();
}
private void btnPile2ActionPerformed(java.awt.event.ActionEvent evt) {
pickedPile1 = false;
pickedOK = true;
this.hideDialog();
}
public boolean isPickedPile1() {
return this.pickedPile1;
}
public boolean isPickedOK() {
return this.pickedOK;
}
}

View file

@ -2056,7 +2056,7 @@
<Property name="paintLabels" type="boolean" value="true"/>
<Property name="paintTicks" type="boolean" value="true"/>
<Property name="snapToTicks" type="boolean" value="true"/>
<Property name="toolTipText" type="java.lang.String" value="&lt;HTML&gt;The maximum size of permanents on the battlefield"/>
<Property name="toolTipText" type="java.lang.String" value="&lt;HTML&gt;The minimum size of permanents on the battlefield"/>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
<EtchetBorder/>

View file

@ -323,11 +323,22 @@ public class PreferencesDialog extends javax.swing.JDialog {
if (currentTheme == null) {
currentTheme = ThemeType.valueByName(getCachedValue(KEY_THEME, "Default"));
logger.info("Using GUI theme: " + currentTheme.getName());
currentTheme.reload();
}
return currentTheme;
}
/**
* Set and reload current theme. App need restart to apply all new settings.
*
* @param newTheme
*/
public static void setCurrentTheme(ThemeType newTheme) {
currentTheme = newTheme;
currentTheme.reload();
}
private final JFileChooser fc = new JFileChooser();
{
@ -656,7 +667,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
showFullImagePath.setSelected(true);
showFullImagePath.setToolTipText("Show the path Xmage is expecting for this card's image (only displays if missing)");
showFullImagePath.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
showFullImagePath.setLabel("Display image path for missing images");
showFullImagePath.setText("Display image path for missing images");
showFullImagePath.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
showFullImagePathActionPerformed(evt);
@ -1149,7 +1160,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
sliderCardSizeMinBattlefield.setPaintLabels(true);
sliderCardSizeMinBattlefield.setPaintTicks(true);
sliderCardSizeMinBattlefield.setSnapToTicks(true);
sliderCardSizeMinBattlefield.setToolTipText("<HTML>The maximum size of permanents on the battlefield");
sliderCardSizeMinBattlefield.setToolTipText("<HTML>The minimum size of permanents on the battlefield");
sliderCardSizeMinBattlefield.setBorder(javax.swing.BorderFactory.createEtchedBorder());
sliderCardSizeMinBattlefield.setMinimumSize(new java.awt.Dimension(150, 40));
gridBagConstraints = new java.awt.GridBagConstraints();
@ -2766,7 +2777,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
tabsPanel.addTab("Themes", tabThemes);
saveButton.setLabel("Save");
saveButton.setText("Save");
saveButton.setMaximumSize(new java.awt.Dimension(100, 30));
saveButton.setMinimumSize(new java.awt.Dimension(100, 30));
saveButton.setPreferredSize(new java.awt.Dimension(100, 30));
@ -2777,7 +2788,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
}
});
exitButton.setLabel("Exit");
exitButton.setText("Exit");
exitButton.setMaximumSize(new java.awt.Dimension(100, 30));
exitButton.setMinimumSize(new java.awt.Dimension(100, 30));
exitButton.setPreferredSize(new java.awt.Dimension(100, 30));

View file

@ -1,75 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="lblQuestion" alignment="0" pref="207" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="btnYes" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="btnNo" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="lblQuestion" pref="39" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="btnNo" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="btnYes" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lblQuestion">
<Properties>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="question"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnNo">
<Properties>
<Property name="text" type="java.lang.String" value="No"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnNoActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="btnYes">
<Properties>
<Property name="text" type="java.lang.String" value="Yes"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnYesActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

View file

@ -1,103 +0,0 @@
/*
* QuestionDialog.java
*
* Created on Dec 23, 2009, 11:01:32 AM
*/
package mage.client.dialog;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class QuestionDialog extends MageDialog {
private boolean answer;
/** Creates new form QuestionDialog */
public QuestionDialog() {
initComponents();
}
public void showDialog(String question) {
this.lblQuestion.setText(question);
this.setModal(true);
this.setVisible(true);
}
public boolean getAnswer() {
return answer;
}
/** 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.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
lblQuestion = new javax.swing.JLabel();
btnNo = new javax.swing.JButton();
btnYes = new javax.swing.JButton();
lblQuestion.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblQuestion.setText("question");
btnNo.setText("No");
btnNo.addActionListener(evt -> btnNoActionPerformed(evt));
btnYes.setText("Yes");
btnYes.addActionListener(evt -> btnYesActionPerformed(evt));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(lblQuestion, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 207, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(btnYes)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnNo)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(lblQuestion, javax.swing.GroupLayout.DEFAULT_SIZE, 35, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnNo)
.addComponent(btnYes))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void btnYesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnYesActionPerformed
this.answer = true;
this.hideDialog();
}//GEN-LAST:event_btnYesActionPerformed
private void btnNoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNoActionPerformed
this.answer = false;
this.hideDialog();
}//GEN-LAST:event_btnNoActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnNo;
private javax.swing.JButton btnYes;
private javax.swing.JLabel lblQuestion;
// End of variables declaration//GEN-END:variables
}

View file

@ -13,6 +13,10 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* App GUI: register new user on the server
*
*/
public class RegisterUserDialog extends MageDialog {
private static final Logger logger = Logger.getLogger(ConnectDialog.class);

View file

@ -13,6 +13,10 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* App GUI: reset password on the server
*
*/
public class ResetPasswordDialog extends MageDialog {
private static final Logger logger = Logger.getLogger(ResetPasswordDialog.class);

View file

@ -1,12 +1,6 @@
/*
* ShowCardsDialog.java
*
* Created on 3-Feb-2010, 8:59:11 PM
*/
package mage.client.dialog;
import mage.cards.MageCard;
import mage.client.MageFrame;
import mage.client.cards.BigCard;
import mage.client.cards.CardArea;
@ -25,6 +19,8 @@
import java.util.UUID;
/**
* Game GUI: choose target card from the cards list (example: exile and choose card to cast)
*
* @author BetaSteward_at_googlemail.com
*/
public class ShowCardsDialog extends MageDialog {
@ -48,8 +44,8 @@
public void cleanUp() {
cardArea.cleanUp();
for (Component comp : cardArea.getComponents()) {
if (comp instanceof CardPanel) {
((CardPanel) comp).cleanUp();
if (comp instanceof MageCard) {
((MageCard) comp).cleanUp();
cardArea.remove(comp);
}
}

View file

@ -1,10 +1,3 @@
/*
* TableWaitingDialog.java
*
* Created on Dec 16, 2009, 10:27:44 AM
*/
package mage.client.dialog;
import java.awt.Dimension;
@ -40,6 +33,8 @@ import static mage.client.dialog.PreferencesDialog.KEY_TABLE_WAITING_COLUMNS_WID
import static mage.client.dialog.PreferencesDialog.KEY_TABLES_DIVIDER_LOCATION_4;
/**
* App GUI: waiting other players before join to a table
*
* @author BetaSteward_at_googlemail.com
*/
public class TableWaitingDialog extends MageDialog {

View file

@ -19,14 +19,15 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="panelCardIcons" alignment="1" max="32767" attributes="0"/>
<Component id="cardsPanel" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="748" max="32767" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="buttonCancel" min="-2" pref="100" max="-2" attributes="0"/>
</Group>
<Component id="cardsPanel" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="buttonReloadCards" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
@ -34,9 +35,13 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="comboRenderMode" min="-2" pref="131" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="labelTheme" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="comboTheme" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="labelSize" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="sliderSize" min="-2" max="-2" attributes="0"/>
<Component id="sliderSize" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="checkBoxGenerateManyCards" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
@ -56,12 +61,16 @@
<Component id="labelRenderMode" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="comboRenderMode" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelSize" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="comboTheme" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelTheme" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="sliderSize" min="-2" max="-2" attributes="0"/>
<Component id="checkBoxGenerateManyCards" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="cardsPanel" pref="421" max="32767" attributes="0"/>
<Component id="panelCardIcons" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cardsPanel" pref="401" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="buttonCancel" min="-2" pref="30" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
@ -127,5 +136,146 @@
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="checkBoxGenerateManyCardsItemStateChanged"/>
</Events>
</Component>
<Container class="javax.swing.JPanel" name="panelCardIcons">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="labelCardIconsPosition" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="comboCardIconsPosition" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="labelCardIconsOrder" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="comboCardIconsOrder" min="-2" pref="80" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="labelCardIconsMaxVisible" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="spinnerCardIconsMaxVisible" min="-2" pref="50" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="labelCardIconsAdditionalAmount" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="spinnerCardIconsAdditionalAmount" min="-2" pref="50" max="-2" attributes="0"/>
<EmptySpace pref="188" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="comboCardIconsPosition" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelCardIconsPosition" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelCardIconsMaxVisible" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="spinnerCardIconsMaxVisible" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelCardIconsAdditionalAmount" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="spinnerCardIconsAdditionalAmount" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelCardIconsOrder" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="comboCardIconsOrder" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="labelCardIconsPosition">
<Properties>
<Property name="text" type="java.lang.String" value="Card icons position:"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="comboCardIconsPosition">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="8">
<StringItem index="0" value="TOP"/>
<StringItem index="1" value="LEFT"/>
<StringItem index="2" value="RIGHT"/>
<StringItem index="3" value="BOTTOM"/>
<StringItem index="4" value="CORNER_TOP_LEFT"/>
<StringItem index="5" value="CORNER_TOP_RIGHT"/>
<StringItem index="6" value="CORNER_BOTTOM_LEFT"/>
<StringItem index="7" value="CORNER_BOTTOM_RIGHT"/>
</StringArray>
</Property>
<Property name="selectedIndex" type="int" value="1"/>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="comboCardIconsPositionItemStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="labelCardIconsMaxVisible">
<Properties>
<Property name="text" type="java.lang.String" value="Max visible:"/>
</Properties>
</Component>
<Component class="javax.swing.JSpinner" name="spinnerCardIconsMaxVisible">
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spinnerCardIconsMaxVisibleStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="spinnerCardIconsMaxVisible.setValue(3);"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="labelCardIconsAdditionalAmount">
<Properties>
<Property name="text" type="java.lang.String" value="Add additional icons:"/>
</Properties>
</Component>
<Component class="javax.swing.JSpinner" name="spinnerCardIconsAdditionalAmount">
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="spinnerCardIconsAdditionalAmountStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="spinnerCardIconsAdditionalAmount.setValue(10);&#xd;&#xa;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="labelCardIconsOrder">
<Properties>
<Property name="text" type="java.lang.String" value="Order:"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="comboCardIconsOrder">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="3">
<StringItem index="0" value="START"/>
<StringItem index="1" value="CENTER"/>
<StringItem index="2" value="END"/>
</StringArray>
</Property>
<Property name="selectedIndex" type="int" value="2"/>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="comboCardIconsOrderItemStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="labelTheme">
<Properties>
<Property name="text" type="java.lang.String" value="Theme:"/>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="comboTheme">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="1">
<StringItem index="0" value="loading..."/>
</StringArray>
</Property>
<Property name="toolTipText" type="java.lang.String" value="WARNING, selected theme will be applied to full app, not render dialog only"/>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="comboThemeItemStateChanged"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Form>

View file

@ -1,9 +1,12 @@
package mage.client.dialog;
import mage.cards.Card;
import mage.cards.CardGraphicInfo;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.icon.CardIconImpl;
import mage.abilities.icon.CardIconType;
import mage.abilities.icon.CardIconOrder;
import mage.abilities.icon.CardIconPosition;
import mage.cards.*;
import mage.cards.decks.Deck;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
@ -11,9 +14,14 @@ import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository;
import mage.client.MageFrame;
import mage.client.cards.BigCard;
import mage.client.themes.ThemeType;
import mage.client.util.ClientEventType;
import mage.client.util.Event;
import mage.client.util.GUISizeHelper;
import mage.client.util.Listener;
import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.GameImpl;
import mage.game.command.Emblem;
@ -21,9 +29,11 @@ import mage.game.command.Plane;
import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan;
import mage.game.mulligan.MulliganType;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
import mage.players.Player;
import mage.players.StubPlayer;
import mage.util.RandomUtil;
import mage.view.*;
import org.apache.log4j.Logger;
import org.mage.card.arcane.CardPanel;
@ -31,21 +41,20 @@ import org.mage.card.arcane.CardPanel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.*;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* App GUI: debug only, testing card renders and manipulations
*
* @author JayDi85
*/
public class TestCardRenderDialog extends MageDialog {
private static final Logger logger = Logger.getLogger(TestCardRenderDialog.class);
float cardSizeMod = 1.0f;
private Game game = null;
Listener<Event> cardListener = null;
public TestCardRenderDialog() {
initComponents();
@ -54,6 +63,24 @@ public class TestCardRenderDialog extends MageDialog {
public void showDialog() {
this.setModal(false);
getRootPane().setDefaultButton(buttonCancel);
// init render mode
this.comboRenderMode.setSelectedIndex(PreferencesDialog.getRenderMode());
// init themes list
this.comboTheme.setModel(new DefaultComboBoxModel(ThemeType.values()));
this.comboTheme.setSelectedItem(PreferencesDialog.getCurrentTheme());
// debug logs to show current component
/*
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
public void eventDispatched(AWTEvent e) {
logger.info("component: " + e.getSource());
}
}, AWTEvent.MOUSE_EVENT_MASK);
*/
// render cards
reloadCards();
// windows settings
@ -75,12 +102,15 @@ public class TestCardRenderDialog extends MageDialog {
this.removeDialog();
}
private PermanentView createPermanentCard(Game game, UUID controllerId, String code, String cardNumber, int power, int toughness, int damage, boolean tapped) {
private PermanentView createPermanentCard(Game game, UUID controllerId, String code, String cardNumber, int power, int toughness, int damage, boolean tapped, List<Ability> extraAbilities) {
CardInfo cardInfo = CardRepository.instance.findCard(code, cardNumber);
ExpansionInfo setInfo = ExpansionRepository.instance.getSetByCode(code);
CardSetInfo testSet = new CardSetInfo(cardInfo.getName(), setInfo.getCode(), cardNumber, cardInfo.getRarity(),
new CardGraphicInfo(cardInfo.getFrameStyle(), cardInfo.usesVariousArt()));
Card card = CardImpl.createCard(cardInfo.getClassName(), testSet);
if (extraAbilities != null) {
extraAbilities.forEach(ability -> card.addAbility(ability));
}
Set<Card> cardsList = new HashSet<>();
cardsList.add(card);
@ -154,59 +184,86 @@ public class TestCardRenderDialog extends MageDialog {
}
private void reloadCards() {
// apply selected theme (warning, it will be applied for all app, so can be bugged in other dialogs - but it's ok for debug)
PreferencesDialog.setCurrentTheme((ThemeType) comboTheme.getSelectedItem());
cardsPanel.cleanUp();
cardsPanel.setCustomRenderMode(comboRenderMode.getSelectedIndex());
cardsPanel.setCustomNeedFullPermanentRender(false); // to fix cropped/position bugged with PermanentView (CardArean do not support it as normal, see CardArea for info)
cardsPanel.setCustomNeedFullPermanentRender(true); // enable full battlefield render mode (it was bugged in test dialog so was disabled in old days, not it works fine)
cardsPanel.setCustomCardSize(new Dimension(getCardWidth(), getCardHeight()));
cardsPanel.setCustomXOffsetBetweenCardsOrColumns(10);
cardsPanel.changeGUISize(); // reload new settings
cardsPanel.setCustomCardIconsPanelPosition(CardIconPosition.fromString((String) comboCardIconsPosition.getSelectedItem()));
cardsPanel.setCustomCardIconsPanelOrder(CardIconOrder.fromString((String) comboCardIconsOrder.getSelectedItem()));
cardsPanel.setCustomCardIconsMaxVisibleCount((Integer) spinnerCardIconsMaxVisible.getValue());
int needAdditionalIcons = Math.min(99, Math.max(0, (Integer) spinnerCardIconsAdditionalAmount.getValue()));
// create custom mouse listener
cardsPanel.setCustomMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
cardsPanel.mouseClicked(e); // default
// reload new settings
cardsPanel.changeGUISize();
// make cards chooseable or not
if (e.getSource() instanceof CardPanel) {
CardPanel panel = (CardPanel) e.getSource();
panel.setChoosable(!panel.isChoosable());
cardsPanel.redraw();
// sample popup menus
JMenuItem item;
JPopupMenu popupCardMenu = new JPopupMenu();
item = new JMenuItem("Card menu 1");
popupCardMenu.add(item);
item = new JMenuItem("Card menu 2");
popupCardMenu.add(item);
item = new JMenuItem("Card menu 3");
popupCardMenu.add(item);
//
JPopupMenu popupPanelMenu = new JPopupMenu();
item = new JMenuItem("Panel menu 1");
popupPanelMenu.add(item);
item = new JMenuItem("Panel menu 2");
popupPanelMenu.add(item);
item = new JMenuItem("Panel menu 3");
popupPanelMenu.add(item);
// init card listener for clicks, menu and other events
if (this.cardListener == null) {
this.cardListener = event -> {
switch(event.getEventType()) {
case CARD_CLICK:
case CARD_DOUBLE_CLICK:
handleCardClick(event);
break;
case CARD_POPUP_MENU:
if (event.getSource() != null) {
// card
handlePopupMenu(event, popupCardMenu);
} else {
// panel
handlePopupMenu(event, popupPanelMenu);
}
break;
}
}
};
cardsPanel.addCardEventListener(this.cardListener);
}
@Override
public void mousePressed(MouseEvent e) {
cardsPanel.mousePressed(e); // default
}
@Override
public void mouseReleased(MouseEvent e) {
cardsPanel.mouseReleased(e); // default
}
@Override
public void mouseEntered(MouseEvent e) {
cardsPanel.mouseEntered(e); // default
}
@Override
public void mouseExited(MouseEvent e) {
cardsPanel.mouseExited(e); // default
}
});
Game game = new TestGame(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20);
game = new TestGame(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20);
Deck deck = new Deck();
Player playerYou = new StubPlayer("player1", RangeOfInfluence.ALL);
game.addPlayer(playerYou, deck);
Player playerOpponent = new StubPlayer("player2", RangeOfInfluence.ALL);
game.addPlayer(playerOpponent, deck);
List<Ability> additionalIcons = Collections.singletonList(new SimpleStaticAbility(Zone.ALL, null));
for (int i = 0; i < needAdditionalIcons; i++) {
String text = "";
if (RandomUtil.nextBoolean()) {
if (RandomUtil.nextBoolean()) {
text = "75";
} else {
text = "8";
}
}
additionalIcons.get(0).addIcon(new CardIconImpl(CardIconType.PLAYABLE_COUNT, "test icon " + i + 1, text));
}
List<CardView> cardViews = new ArrayList<>();
/* // test morphed
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "263", 0, 0, 0, false)); // mountain
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "185", 0, 0, 0, true)); // Judith, the Scourge Diva
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "263", 0, 0, 0, false, null)); // mountain
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "185", 0, 0, 0, true, null)); // Judith, the Scourge Diva
cardViews.add(createHandCard(game, playerYou.getId(), "DIS", "153")); // Odds // Ends (split card)
cardViews.add(createHandCard(game, playerYou.getId(), "ELD", "38")); // Animating Faerie (adventure card)
cardViews.add(createFaceDownCard(game, playerOpponent.getId(), "ELD", "38", false, false, false)); // face down
@ -215,22 +272,30 @@ public class TestCardRenderDialog extends MageDialog {
//*/
/* //test emblems
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "78", 125, 89, 0, false)); // Noxious Groodion
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "14", 3, 5, 2, false)); // Knight of Sorrows
cardViews.add(createPermanentCard(game, playerYou.getId(), "DKA", "140", 5, 2, 2, false)); // Huntmaster of the Fells, transforms
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "221", 0, 0, 0, false)); // Bedeck // Bedazzle
cardViews.add(createPermanentCard(game, playerYou.getId(), "XLN", "234", 0, 0, 0, false)); // Conqueror's Galleon
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "78", 125, 89, 0, false, null)); // Noxious Groodion
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "14", 3, 5, 2, false, null)); // Knight of Sorrows
cardViews.add(createPermanentCard(game, playerYou.getId(), "DKA", "140", 5, 2, 2, false, null)); // Huntmaster of the Fells, transforms
cardViews.add(createPermanentCard(game, playerYou.getId(), "RNA", "221", 0, 0, 0, false, null)); // Bedeck // Bedazzle
cardViews.add(createPermanentCard(game, playerYou.getId(), "XLN", "234", 0, 0, 0, false, null)); // Conqueror's Galleon
cardViews.add(createEmblem(new AjaniAdversaryOfTyrantsEmblem())); // Emblem Ajani
cardViews.add(createPlane(new AkoumPlane())); // Plane - Akoum
//*/
//* //test split, transform and mdf in hands
/* //test split, transform and mdf in hands
cardViews.add(createHandCard(game, playerYou.getId(), "SOI", "97")); // Accursed Witch
cardViews.add(createHandCard(game, playerYou.getId(), "UMA", "225")); // Fire // Ice
cardViews.add(createHandCard(game, playerYou.getId(), "ELD", "14")); // Giant Killer
cardViews.add(createHandCard(game, playerYou.getId(), "ZNR", "134")); // Akoum Warrior
//*/
//* //test card icons
cardViews.add(createHandCard(game, playerYou.getId(), "POR", "169")); // Grizzly Bears
cardViews.add(createHandCard(game, playerYou.getId(), "DKA", "140")); // Huntmaster of the Fells, transforms
cardViews.add(createPermanentCard(game, playerYou.getId(), "MB1", "401", 1, 1, 0, false, additionalIcons)); // Hinterland Drake
cardViews.add(createPermanentCard(game, playerYou.getId(), "MB1", "1441", 1, 1, 0, true, additionalIcons)); // Kathari Remnant
//*/
// duplicate cards
if (checkBoxGenerateManyCards.isSelected()) {
while (cardViews.size() < 30) {
@ -248,6 +313,39 @@ public class TestCardRenderDialog extends MageDialog {
cardsPanel.loadCards(view, big, game.getId());
}
private void handleCardClick(Event event) {
MageCard panel = (MageCard) event.getComponent();
if (event.getEventType() == ClientEventType.CARD_DOUBLE_CLICK) {
// card tap
if (panel.getMainPanel() instanceof CardPanel) {
CardPanel main = (CardPanel) panel.getMainPanel();
if (main.getGameCard() instanceof PermanentView) {
// new settings must be as a new copy -- it would activate the animations
PermanentView oldPermanent = (PermanentView) main.getGameCard();
PermanentView newPermament = new PermanentView(
(Permanent) oldPermanent.getOriginalCard(),
game.getCard(oldPermanent.getOriginalCard().getId()),
UUID.randomUUID(),
game
);
newPermament.overrideTapped(!oldPermanent.isTapped());
main.update(newPermament);
}
}
} else {
// card choose
panel.setChoosable(!panel.isChoosable());
}
cardsPanel.redraw();
}
private void handlePopupMenu(Event event, JPopupMenu popupMenu) {
//Point p = event.getComponent().getLocationOnScreen();
Point p = MouseInfo.getPointerInfo().getLocation();
popupMenu.show(this, 0, 0); // use relative coords
popupMenu.setLocation(p); // use screen coords
}
private int getCardWidth() {
if (GUISizeHelper.editorCardDimension == null) {
return 200;
@ -277,6 +375,17 @@ public class TestCardRenderDialog extends MageDialog {
sliderSize = new javax.swing.JSlider();
labelSize = new javax.swing.JLabel();
checkBoxGenerateManyCards = new javax.swing.JCheckBox();
panelCardIcons = new javax.swing.JPanel();
labelCardIconsPosition = new javax.swing.JLabel();
comboCardIconsPosition = new javax.swing.JComboBox<>();
labelCardIconsMaxVisible = new javax.swing.JLabel();
spinnerCardIconsMaxVisible = new javax.swing.JSpinner();
labelCardIconsAdditionalAmount = new javax.swing.JLabel();
spinnerCardIconsAdditionalAmount = new javax.swing.JSpinner();
labelCardIconsOrder = new javax.swing.JLabel();
comboCardIconsOrder = new javax.swing.JComboBox<>();
labelTheme = new javax.swing.JLabel();
comboTheme = new javax.swing.JComboBox<>();
buttonCancel.setText("Close");
buttonCancel.addActionListener(new java.awt.event.ActionListener() {
@ -294,7 +403,7 @@ public class TestCardRenderDialog extends MageDialog {
labelRenderMode.setText("Render mode:");
comboRenderMode.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"MTGO", "Image"}));
comboRenderMode.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "MTGO", "Image" }));
comboRenderMode.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
comboRenderModeItemStateChanged(evt);
@ -316,49 +425,141 @@ public class TestCardRenderDialog extends MageDialog {
}
});
labelCardIconsPosition.setText("Card icons position:");
comboCardIconsPosition.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "TOP", "LEFT", "RIGHT", "BOTTOM", "CORNER_TOP_LEFT", "CORNER_TOP_RIGHT", "CORNER_BOTTOM_LEFT", "CORNER_BOTTOM_RIGHT" }));
comboCardIconsPosition.setSelectedIndex(1);
comboCardIconsPosition.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
comboCardIconsPositionItemStateChanged(evt);
}
});
labelCardIconsMaxVisible.setText("Max visible:");
spinnerCardIconsMaxVisible.setValue(3);
spinnerCardIconsMaxVisible.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
spinnerCardIconsMaxVisibleStateChanged(evt);
}
});
labelCardIconsAdditionalAmount.setText("Add additional icons:");
spinnerCardIconsAdditionalAmount.setValue(10);
spinnerCardIconsAdditionalAmount.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
spinnerCardIconsAdditionalAmountStateChanged(evt);
}
});
labelCardIconsOrder.setText("Order:");
comboCardIconsOrder.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "START", "CENTER", "END" }));
comboCardIconsOrder.setSelectedIndex(2);
comboCardIconsOrder.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
comboCardIconsOrderItemStateChanged(evt);
}
});
javax.swing.GroupLayout panelCardIconsLayout = new javax.swing.GroupLayout(panelCardIcons);
panelCardIcons.setLayout(panelCardIconsLayout);
panelCardIconsLayout.setHorizontalGroup(
panelCardIconsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelCardIconsLayout.createSequentialGroup()
.addComponent(labelCardIconsPosition)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(comboCardIconsPosition, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelCardIconsOrder)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(comboCardIconsOrder, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelCardIconsMaxVisible)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spinnerCardIconsMaxVisible, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelCardIconsAdditionalAmount)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(spinnerCardIconsAdditionalAmount, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(188, Short.MAX_VALUE))
);
panelCardIconsLayout.setVerticalGroup(
panelCardIconsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelCardIconsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(comboCardIconsPosition, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(labelCardIconsPosition)
.addComponent(labelCardIconsMaxVisible)
.addComponent(spinnerCardIconsMaxVisible, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(labelCardIconsAdditionalAmount)
.addComponent(spinnerCardIconsAdditionalAmount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(labelCardIconsOrder)
.addComponent(comboCardIconsOrder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
);
labelTheme.setText("Theme:");
comboTheme.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "loading..." }));
comboTheme.setToolTipText("WARNING, selected theme will be applied to full app, not render dialog only");
comboTheme.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
comboThemeItemStateChanged(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 748, Short.MAX_VALUE)
.addComponent(buttonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(cardsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(buttonReloadCards)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelRenderMode)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(comboRenderMode, javax.swing.GroupLayout.PREFERRED_SIZE, 131, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelSize)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sliderSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(checkBoxGenerateManyCards)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panelCardIcons, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(cardsPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(buttonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(buttonReloadCards)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelRenderMode)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(comboRenderMode, javax.swing.GroupLayout.PREFERRED_SIZE, 131, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelTheme)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(comboTheme, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(labelSize)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sliderSize, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(checkBoxGenerateManyCards)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(buttonReloadCards)
.addComponent(labelRenderMode)
.addComponent(comboRenderMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(labelSize))
.addComponent(sliderSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(checkBoxGenerateManyCards))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cardsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 421, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(buttonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(buttonReloadCards)
.addComponent(labelRenderMode)
.addComponent(comboRenderMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(labelSize)
.addComponent(comboTheme, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(labelTheme))
.addComponent(sliderSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(checkBoxGenerateManyCards))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(panelCardIcons, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cardsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 401, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(buttonCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pack();
@ -373,7 +574,10 @@ public class TestCardRenderDialog extends MageDialog {
}//GEN-LAST:event_buttonReloadCardsActionPerformed
private void comboRenderModeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboRenderModeItemStateChanged
reloadCards();
// render modes are loading on show dialog, so must ignore change event on startup
if (this.isVisible()) {
reloadCards();
}
}//GEN-LAST:event_comboRenderModeItemStateChanged
private void sliderSizeStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sliderSizeStateChanged
@ -389,15 +593,49 @@ public class TestCardRenderDialog extends MageDialog {
reloadCards();
}//GEN-LAST:event_checkBoxGenerateManyCardsItemStateChanged
private void comboCardIconsPositionItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboCardIconsPositionItemStateChanged
reloadCards();
}//GEN-LAST:event_comboCardIconsPositionItemStateChanged
private void spinnerCardIconsMaxVisibleStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerCardIconsMaxVisibleStateChanged
reloadCards();
}//GEN-LAST:event_spinnerCardIconsMaxVisibleStateChanged
private void spinnerCardIconsAdditionalAmountStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_spinnerCardIconsAdditionalAmountStateChanged
reloadCards();
}//GEN-LAST:event_spinnerCardIconsAdditionalAmountStateChanged
private void comboCardIconsOrderItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboCardIconsOrderItemStateChanged
reloadCards();
}//GEN-LAST:event_comboCardIconsOrderItemStateChanged
private void comboThemeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboThemeItemStateChanged
// themes list are loading on show dialog, so must ignore change event on startup
if (this.isVisible()) {
reloadCards();
}
}//GEN-LAST:event_comboThemeItemStateChanged
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton buttonCancel;
private javax.swing.JButton buttonReloadCards;
private mage.client.cards.CardArea cardsPanel;
private javax.swing.JCheckBox checkBoxGenerateManyCards;
private javax.swing.JComboBox<String> comboCardIconsOrder;
private javax.swing.JComboBox<String> comboCardIconsPosition;
private javax.swing.JComboBox<String> comboRenderMode;
private javax.swing.JComboBox<String> comboTheme;
private javax.swing.JLabel labelCardIconsAdditionalAmount;
private javax.swing.JLabel labelCardIconsMaxVisible;
private javax.swing.JLabel labelCardIconsOrder;
private javax.swing.JLabel labelCardIconsPosition;
private javax.swing.JLabel labelRenderMode;
private javax.swing.JLabel labelSize;
private javax.swing.JLabel labelTheme;
private javax.swing.JPanel panelCardIcons;
private javax.swing.JSlider sliderSize;
private javax.swing.JSpinner spinnerCardIconsAdditionalAmount;
private javax.swing.JSpinner spinnerCardIconsMaxVisible;
// End of variables declaration//GEN-END:variables
}

View file

@ -7,6 +7,8 @@ import javax.swing.*;
import java.awt.event.KeyEvent;
/**
* App GUI: debug only, testing dialogs system
*
* @author JayDi85
*/
public class TestModalDialog extends MageDialog {

View file

@ -7,6 +7,8 @@ import java.awt.*;
import java.awt.event.KeyEvent;
/**
* App GUI: debug only, sample dialog for testing dialogs system
*
* @author JayDi85
*/
public class TestModalSampleDialog extends MageDialog {

View file

@ -10,6 +10,8 @@ import javax.swing.plaf.basic.BasicInternalFrameUI;
import java.awt.*;
/**
* App GUI: confirm some actions from the user (example: close the app)
*
* @author BetaSteward_at_googlemail.com
*/
public class UserRequestDialog extends MageDialog {

View file

@ -28,6 +28,8 @@ import java.util.Scanner;
import java.util.concurrent.TimeUnit;
/**
* App GUI: show latest xmage news from the web page
*
* @author JayDi85
*/
public class WhatsNewDialog extends MageDialog {

View file

@ -1,10 +1,3 @@
/*
* DraftPane.java
*
* Created on Jan 7, 2011, 2:11:44 PM
*/
package mage.client.draft;
import java.awt.Component;
@ -16,6 +9,7 @@ import mage.client.MagePane;
import mage.client.plugins.impl.Plugins;
/**
* Game GUI: draft panel with scrolls
*
* @author BetaSteward_at_googlemail.com
*/

View file

@ -1,10 +1,3 @@
/*
* DraftPanel.java
*
* Created on Jan 7, 2011, 2:15:48 PM
*/
package mage.client.draft;
import mage.cards.repository.CardInfo;
@ -21,10 +14,12 @@
import mage.client.util.gui.BufferedImageBuilder;
import mage.constants.PlayerAction;
import mage.view.*;
import org.apache.log4j.Logger;
import javax.swing.Timer;
import javax.swing.*;
import java.awt.*;
import java.awt.dnd.DragSourceEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
@ -35,10 +30,14 @@
import java.util.*;
/**
* @author BetaSteward_at_googlemail.com
* Game GUI: draft panel for drafting game mode only
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class DraftPanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(DraftPanel.class);
private UUID draftId;
private Timer countdown;
private int timeout;
@ -73,6 +72,9 @@
private static final CardsView EMPTY_VIEW = new CardsView();
private Listener<Event> selectedCardsListener = null;
private Listener<Event> pickingCardsListener = null;
/**
* Creates new form DraftPanel
*/
@ -247,47 +249,52 @@
// upper area that shows the picks
loadCardsToPickedCardsArea(draftPickView.getPicks());
this.draftPicks.clearCardEventListeners();
this.draftPicks.addCardEventListener((Listener<Event>) event -> {
if (event.getEventType() == ClientEventType.SHOW_POP_UP_MENU) {
if (event.getSource() != null) {
// Popup Menu Card
cardIdPopupMenu = ((SimpleCardView) event.getSource()).getId();
popupMenuCardPanel.show(event.getComponent(), event.getxPos(), event.getyPos());
} else {
// Popup Menu area
popupMenuPickedArea.show(event.getComponent(), event.getxPos(), event.getyPos());
}
// ENABLE clicks on selected/picked cards
if (this.selectedCardsListener == null) {
this.selectedCardsListener = event -> {
if (event.getEventType() == ClientEventType.CARD_POPUP_MENU) {
if (event.getSource() != null) {
// Popup Menu Card
cardIdPopupMenu = ((SimpleCardView) event.getSource()).getId();
popupMenuCardPanel.show(event.getComponent(), event.getxPos(), event.getyPos());
} else {
// Popup Menu area
popupMenuPickedArea.show(event.getComponent(), event.getxPos(), event.getyPos());
}
}
);
};
this.draftPicks.addCardEventListener(this.selectedCardsListener);
}
// lower area that shows the booster
draftBooster.loadBooster(CardsViewUtil.convertSimple(draftPickView.getBooster()), bigCard);
this.draftBooster.clearCardEventListeners();
this.draftBooster.addCardEventListener(
(Listener<Event>) event -> {
if (event.getEventType() == ClientEventType.PICK_A_CARD) {
SimpleCardView source = (SimpleCardView) event.getSource();
DraftPickView view = SessionHandler.sendCardPick(draftId, source.getId(), cardsHidden);
if (view != null) {
loadCardsToPickedCardsArea(view.getPicks());
draftBooster.loadBooster(EMPTY_VIEW, bigCard);
Plugins.instance.getActionCallback().hideOpenComponents();
setMessage("Waiting for other players");
}
}
if (event.getEventType() == ClientEventType.MARK_A_CARD) {
SimpleCardView source = (SimpleCardView) event.getSource();
SessionHandler.sendCardMark(draftId, source.getId());
this.draftBooster.loadBooster(CardsViewUtil.convertSimple(draftPickView.getBooster()), bigCard);
if (this.pickingCardsListener == null) {
this.pickingCardsListener = event -> {
if (event.getEventType() == ClientEventType.DRAFT_PICK_CARD) {
logger.info("draft panel: catch pick card");
SimpleCardView source = (SimpleCardView) event.getSource();
DraftPickView view = SessionHandler.sendCardPick(draftId, source.getId(), cardsHidden);
if (view != null) {
loadCardsToPickedCardsArea(view.getPicks());
draftBooster.loadBooster(EMPTY_VIEW, bigCard);
Plugins.instance.getActionCallback().hideOpenComponents();
setMessage("Waiting for other players");
}
} else if (event.getEventType() == ClientEventType.DRAFT_MARK_CARD) {
logger.info("draft panel: catch mark card");
SimpleCardView source = (SimpleCardView) event.getSource();
SessionHandler.sendCardMark(draftId, source.getId());
}
);
};
this.draftBooster.addCardEventListener(this.pickingCardsListener);
}
setMessage("Pick a card");
if (!AppUtil.isAppActive()) {
MageTray.instance.displayMessage("Pick the next card.");
MageTray.instance.blink();
}
countdown.stop();
this.timeout = draftPickView.getTimeout();
setTimeout(timeout);

View file

@ -1,22 +1,31 @@
package mage.client.game;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.cards.MagePermanent;
import mage.client.MageFrame;
import mage.client.cards.BigCard;
import mage.client.cards.Permanent;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.ClientDefaultSettings;
import mage.client.util.GUISizeHelper;
import mage.client.util.audio.AudioManager;
import mage.client.util.layout.CardLayoutStrategy;
import mage.client.util.layout.impl.OldCardLayoutStrategy;
import mage.client.util.layout.impl.CardLayoutStrategyImpl;
import mage.interfaces.callback.ClientCallback;
import mage.interfaces.callback.ClientCallbackMethod;
import mage.util.DebugUtil;
import mage.view.CounterView;
import mage.view.PermanentView;
import org.apache.log4j.Logger;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.List;
@ -24,11 +33,23 @@ import java.util.*;
import java.util.Map.Entry;
/**
* @author BetaSteward_at_googlemail.com
* Game GUI: battlefield panel (cards panel + scrollbars)
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class BattlefieldPanel extends javax.swing.JLayeredPane {
private final Map<UUID, MagePermanent> permanents = new LinkedHashMap<>();
private static final Logger logger = Logger.getLogger(BattlefieldPanel.class);
private static final int GAME_REDRAW_TIMEOUT_MS = 300; // timeout before game goes to redraw on scrollbars change
// WARNING, permanents contains top level PANELS (cards), use getMainPanel for real MagePermanent (permanents)
// Source code logic and naming here:
// * MageCard card - top layer panel (example: permanent + icons layer + another layer);
// * MagePermanent permanent - original card panel with all data, but without additional panels like icons;
// * Only MagePermanent allows for panels here, so getMainPanel() must return MagePermanent all the time
private final Map<UUID, MageCard> permanents = new LinkedHashMap<>();
private UUID gameId;
private BigCard bigCard;
private final Map<String, JComponent> uiComponentsList = new HashMap<>();
@ -36,10 +57,11 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
protected Map<UUID, PermanentView> battlefield;
private Dimension cardDimension;
private JLayeredPane jPanel;
private JScrollPane jScrollPane;
private JLayeredPane jPanel; // cards
private JScrollPane jScrollPane; // scrollbars
private final CardLayoutStrategy layoutStrategy = new CardLayoutStrategyImpl();
private final CardLayoutStrategy layoutStrategy = new OldCardLayoutStrategy();
private javax.swing.Timer gameUpdateTimer; // timer for custom GUI re-drawing (example: update attack arrows)
//private static int iCounter = 0;
private boolean addedPermanent;
@ -57,6 +79,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
uiComponentsList.put("battlefieldPanel", this);
initComponents();
uiComponentsList.put("jPanel", jPanel);
uiComponentsList.put("scrollPane", this.jScrollPane);
setGUISize();
addComponentListener(new ComponentAdapter() {
@ -65,6 +88,12 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
updateSize();
}
});
gameUpdateTimer = new Timer(GAME_REDRAW_TIMEOUT_MS, evt -> SwingUtilities.invokeLater(() -> {
gameUpdateTimer.stop();
ClientCallback updateMessage = new ClientCallback(ClientCallbackMethod.GAME_REDRAW_GUI, gameId);
MageFrame.getInstance().processCallback(updateMessage);
}));
}
public void updateSize() {
@ -78,13 +107,16 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
}
public void cleanUp() {
gameUpdateTimer.stop();
for (Component c : this.jPanel.getComponents()) {
if (c instanceof Permanent || c instanceof MagePermanent) {
this.jPanel.remove(c);
if (c instanceof MageCard) {
if (((MageCard) c).getMainPanel() instanceof MagePermanent) {
this.jPanel.remove(c);
}
}
}
permanents.clear();
// Plugins.getInstance().sortPermanents(uiComponentsList, permanents.values());
this.bigCard = null;
}
@ -96,6 +128,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
private void setGUISize() {
jScrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(GUISizeHelper.scrollBarSize, 0));
jScrollPane.getHorizontalScrollBar().setPreferredSize(new Dimension(0, GUISizeHelper.scrollBarSize));
// scrollbars speed changes on layout (depends on cards amount)
cardDimension = GUISizeHelper.battlefieldCardMaxDimension;
}
@ -108,6 +141,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
}
public void update(Map<UUID, PermanentView> battlefield) {
gameUpdateTimer.stop();
boolean changed = false;
List<PermanentView> permanentsToAdd = new ArrayList<>();
@ -115,14 +149,15 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
if (!permanent.isPhasedIn()) {
continue;
}
MagePermanent oldMagePermanent = permanents.get(permanent.getId());
MageCard oldFound = permanents.get(permanent.getId());
MagePermanent oldMagePermanent = oldFound == null ? null : (MagePermanent) oldFound.getMainPanel();
if (oldMagePermanent == null) {
permanentsToAdd.add(permanent);
changed = true;
} else {
if (!changed) {
changed = oldMagePermanent.getOriginalPermanent().isCreature() != permanent.isCreature();
// Check if there was a chnage in the permanets that are the permanent attached to
// Check if there was a change in the permanets that are the permanent attached to
if (!changed) {
int attachments = permanent.getAttachments() == null ? 0 : permanent.getAttachments().size();
int attachmentsBefore = oldMagePermanent.getLinks().size();
@ -130,7 +165,8 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
changed = true;
} else if (attachments > 0) {
Set<UUID> attachmentIds = new HashSet<>(permanent.getAttachments());
for (MagePermanent magePermanent : oldMagePermanent.getLinks()) {
for (MageCard mageCard : oldMagePermanent.getLinks()) {
MagePermanent magePermanent = (MagePermanent) mageCard.getMainPanel();
if (!attachmentIds.contains(magePermanent.getOriginalPermanent().getId())) {
// that means that the amount of attachments is the same
// but they are different:
@ -161,7 +197,6 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
changed = true;
}
}
}
oldMagePermanent.update(permanent);
}
@ -184,8 +219,8 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
removedCreature = false;
for (Iterator<Entry<UUID, MagePermanent>> iterator = permanents.entrySet().iterator(); iterator.hasNext(); ) {
Entry<UUID, MagePermanent> entry = iterator.next();
for (Iterator<Entry<UUID, MageCard>> iterator = permanents.entrySet().iterator(); iterator.hasNext(); ) {
Entry<UUID, MageCard> entry = iterator.next();
if (!battlefield.containsKey(entry.getKey()) || !battlefield.get(entry.getKey()).isPhasedIn()) {
removePermanent(entry.getKey(), 1);
iterator.remove();
@ -221,28 +256,17 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
if (cardDimension == null) {
cardDimension = new Dimension(ClientDefaultSettings.dimensions.getFrameWidth(), ClientDefaultSettings.dimensions.getFrameHeight());
}
final MagePermanent perm = Plugins.instance.getMagePermanent(permanent, bigCard, cardDimension, gameId, true, PreferencesDialog.getRenderMode(), true);
final MageCard perm = Plugins.instance.getMagePermanent(permanent, bigCard, new CardIconRenderSettings(), cardDimension, gameId, true, PreferencesDialog.getRenderMode(), true);
perm.setCardContainerRef(jPanel);
perm.update(permanent);
// cards sizes changes in parent call by sortLayout
//perm.setCardBounds
permanents.put(permanent.getId(), perm);
BattlefieldPanel.this.jPanel.add(perm, 10);
//this.jPanel.add(perm);
if (!Plugins.instance.isCardPluginLoaded()) {
moveToFront(perm);
perm.update(permanent);
} else {
moveToFront(jPanel);
Plugins.instance.onAddCard(perm, 1);
/*Thread t = new Thread(new Runnable() {
@Override
public void run() {
Plugins.getInstance().onAddCard(perm, count);
}
});
synchronized (this) {
threads.add(t);
}*/
}
this.jPanel.add(perm, (Integer) 10);
moveToFront(jPanel);
Plugins.instance.onAddCard(perm, 1);
if (permanent.isArtifact()) {
addedArtifact = true;
@ -254,24 +278,22 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
}
private void removePermanent(UUID permanentId, final int count) {
for (Component c : this.jPanel.getComponents()) {
final Component comp = c;
if (comp instanceof Permanent) {
if (((Permanent) comp).getPermanentId().equals(permanentId)) {
comp.setVisible(false);
this.jPanel.remove(comp);
}
} else if (comp instanceof MagePermanent) {
if (((MagePermanent) comp).getOriginal().getId().equals(permanentId)) {
Thread t = new Thread(() -> {
Plugins.instance.onRemoveCard((MagePermanent) comp, count);
comp.setVisible(false);
BattlefieldPanel.this.jPanel.remove(comp);
});
t.start();
}
if (((MagePermanent) comp).getOriginal().isCreature()) {
removedCreature = true;
for (Component comp : this.jPanel.getComponents()) {
if (comp instanceof MageCard) {
MageCard mageCard = (MageCard) comp;
if (mageCard.getMainPanel() instanceof MagePermanent) {
MagePermanent magePermanent = (MagePermanent) mageCard.getMainPanel();
if (magePermanent.getOriginal().getId().equals(permanentId)) {
Thread t = new Thread(() -> {
Plugins.instance.onRemoveCard(mageCard, count);
mageCard.setVisible(false);
this.jPanel.remove(mageCard);
});
t.start();
}
if (magePermanent.getOriginal().isCreature()) {
removedCreature = true;
}
}
}
}
@ -282,7 +304,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
return false;
}
public Map<UUID, MagePermanent> getPermanents() {
public Map<UUID, MageCard> getPermanentPanels() {
return permanents;
}
@ -293,12 +315,26 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
jPanel.setLayout(null);
jPanel.setOpaque(false);
jScrollPane = new JScrollPane(jPanel);
if (DebugUtil.GUI_GAME_DRAW_BATTLEFIELD_BORDER) {
jPanel.setBorder(BorderFactory.createLineBorder(Color.MAGENTA));
jScrollPane.setBorder(BorderFactory.createLineBorder(Color.green));
}
Border empty = new EmptyBorder(0, 0, 0, 0);
jScrollPane.setBorder(empty);
jScrollPane.setViewportBorder(empty);
jScrollPane.setOpaque(false);
jScrollPane.getViewport().setOpaque(false);
jScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
if (gameUpdateTimer.isRunning()) {
gameUpdateTimer.restart();
} else {
gameUpdateTimer.start();
}
}
});
this.add(jScrollPane);
}

View file

@ -67,7 +67,8 @@ public class FeedbackPanel extends javax.swing.JPanel {
int messageId, boolean gameNeedUserFeedback, TurnPhase gameTurnPhase) {
synchronized (this) {
if (messageId < this.lastMessageId) {
LOGGER.warn("ignoring message from later source: " + messageId + ", text=" + message);
// if too many warning messages here then look at GAME_REDRAW_GUI event logic
LOGGER.warn("catch un-synced message from later source (possible reason: connection or performance problems): " + messageId + ", text=" + message);
return;
}
this.lastMessageId = messageId;
@ -76,7 +77,6 @@ public class FeedbackPanel extends javax.swing.JPanel {
this.helper.setOriginalId(null); // reference to the feedback causing ability
String lblText = addAdditionalText(message, options);
this.helper.setTextArea(lblText);
//this.lblMessage.setText(lblText);
this.mode = mode;
switch (this.mode) {
@ -167,6 +167,12 @@ public class FeedbackPanel extends javax.swing.JPanel {
}
private void handleOptions(Map<String, Serializable> options) {
// clear already opened dialog (second request)
if (connectedDialog != null) {
connectedDialog.removeDialog();
connectedDialog = null;
}
if (options != null) {
if (options.containsKey("UI.left.btn.text")) {
String text = (String) options.get("UI.left.btn.text");

View file

@ -2,6 +2,7 @@ package mage.client.game;
import mage.client.components.KeyboundButton;
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.function.Consumer;
@ -32,7 +33,7 @@ public class FirstButtonMousePressedAction extends MouseAdapter {
KeyboundButton button = (KeyboundButton) e.getSource();
button.setTint(false);
}
if (e.getButton() == MouseEvent.BUTTON1 && inside) {
if (SwingUtilities.isLeftMouseButton(e) && inside) {
callback.accept(e);
}
}

View file

@ -1,10 +1,3 @@
/*
* GamePane.java
*
* Created on Dec 17, 2009, 9:34:10 AM
*/
package mage.client.game;
import java.awt.AWTEvent;
@ -14,6 +7,7 @@ import javax.swing.*;
import mage.client.MagePane;
/**
* Game GUI: game panel with scrollbars
*
* @author BetaSteward_at_googlemail.com
*/

View file

@ -1,6 +1,7 @@
package mage.client.game;
import mage.cards.Card;
import mage.cards.MageCard;
import mage.cards.action.ActionCallback;
import mage.choices.Choice;
import mage.client.MageFrame;
@ -25,9 +26,9 @@ import mage.client.util.gui.ArrowBuilder;
import mage.client.util.gui.MageDialogState;
import mage.constants.*;
import mage.game.events.PlayerQueryEvent;
import mage.players.PlayableObjectsList;
import mage.view.*;
import org.apache.log4j.Logger;
import org.mage.card.arcane.CardPanel;
import org.mage.plugins.card.utils.impl.ImageManagerImpl;
import javax.swing.*;
@ -52,6 +53,8 @@ import static mage.client.dialog.PreferencesDialog.*;
import static mage.constants.PlayerAction.*;
/**
* Game GUI: main game panel with all controls
*
* @author BetaSteward_at_googlemail.com, nantuko8, JayDi85
*/
public final class GamePanel extends javax.swing.JPanel {
@ -59,7 +62,6 @@ public final class GamePanel extends javax.swing.JPanel {
private static final Logger logger = Logger.getLogger(GamePanel.class);
private static final String YOUR_HAND = "Your hand";
private static final int X_PHASE_WIDTH = 55;
private static final int STACK_MIN_CARDS_OFFSET_Y = 7; // TODO: Size bui GUISize value
private static final String CMD_AUTO_ORDER_FIRST = "cmdAutoOrderFirst";
private static final String CMD_AUTO_ORDER_LAST = "cmdAutoOrderLast";
@ -77,8 +79,8 @@ public final class GamePanel extends javax.swing.JPanel {
private final Map<String, CardInfoWindowDialog> graveyardWindows = new HashMap<>();
private final Map<String, CardInfoWindowDialog> companion = new HashMap<>();
private final Map<String, CardsView> graveyards = new HashMap<>();
private final ArrayList<ShowCardsDialog> pickTarget = new ArrayList<>();
private final ArrayList<PickPileDialog> pickPile = new ArrayList<>();
private UUID gameId;
private UUID playerId; // playerId of the player
GamePane gamePane;
@ -114,6 +116,17 @@ public final class GamePanel extends javax.swing.JPanel {
// popup menu for triggered abilities order
private JPopupMenu popupMenuTriggerOrder;
// keep game data for updates/re-draws
// warning, it keeps updates from GAME_UPDATE events only and ignore another events with GameView
static class LastGameData {
GameView game;
boolean showPlayable;
Map<String, Serializable> options;
Set<UUID> targets;
}
private final LastGameData lastGameData = new LastGameData();
public GamePanel() {
initComponents = true;
initComponents();
@ -123,8 +136,6 @@ public final class GamePanel extends javax.swing.JPanel {
this.feedbackPanel.setConnectedChatPanel(this.userChatPanel);
this.stackObjects.setMinOffsetY(STACK_MIN_CARDS_OFFSET_Y);
// Override layout (I can't edit generated code)
this.setLayout(new BorderLayout());
final JLayeredPane jLayeredBackgroundPane = new JLayeredPane();
@ -161,6 +172,7 @@ public final class GamePanel extends javax.swing.JPanel {
}
});
// Resize the width of the stack area if the size of the play area is changed
ComponentAdapter componentAdapterPlayField = new ComponentAdapter() {
@Override
@ -179,7 +191,6 @@ public final class GamePanel extends javax.swing.JPanel {
resizeTimer.stop();
setGUISize();
feedbackPanel.changeGUISize();
}));
pnlHelperHandButtonsStackArea.addComponentListener(componentAdapterPlayField);
@ -247,10 +258,10 @@ public final class GamePanel extends javax.swing.JPanel {
companionDialog.cleanUp();
companionDialog.removeDialog();
}
for (ShowCardsDialog pickTargetDialog : pickTarget) {
pickTargetDialog.cleanUp();
pickTargetDialog.removeDialog();
}
clearPickTargetDialogs();
clearPickPileDialogs();
Plugins.instance.getActionCallback().hideOpenComponents();
try {
Component popupContainer = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER);
@ -262,6 +273,23 @@ public final class GamePanel extends javax.swing.JPanel {
this.bigCard = null;
}
private void clearPickTargetDialogs() {
for (ShowCardsDialog pickTargetDialog : this.pickTarget) {
pickTargetDialog.cleanUp();
pickTargetDialog.removeDialog();
}
this.pickTarget.clear();
}
private void clearPickPileDialogs() {
for (PickPileDialog pickPileDialog : this.pickPile) {
pickPileDialog.cleanUp();
pickPileDialog.removeDialog();
}
this.pickPile.clear();
}
public void changeGUISize() {
initComponents = true;
setGUISize();
@ -290,6 +318,9 @@ public final class GamePanel extends javax.swing.JPanel {
for (ShowCardsDialog showCardsDialog : pickTarget) {
showCardsDialog.changeGUISize();
}
for (PickPileDialog pickPileDialog : pickPile) {
pickPileDialog.changeGUISize();
}
this.revalidate();
this.repaint();
@ -300,21 +331,28 @@ public final class GamePanel extends javax.swing.JPanel {
jSplitPane0.setDividerSize(GUISizeHelper.dividerBarSize);
jSplitPane1.setDividerSize(GUISizeHelper.dividerBarSize);
jSplitPane2.setDividerSize(GUISizeHelper.dividerBarSize);
stackObjects.setCardDimension(GUISizeHelper.handCardDimension);
txtSpellsCast.setFont(new Font(GUISizeHelper.gameDialogAreaFont.getFontName(), Font.BOLD, GUISizeHelper.gameDialogAreaFont.getSize()));
txtHoldPriority.setFont(new Font(GUISizeHelper.gameDialogAreaFont.getFontName(), Font.BOLD, GUISizeHelper.gameDialogAreaFont.getSize()));
GUISizeHelper.changePopupMenuFont(popupMenuTriggerOrder);
// hand + stack panels
// the stack takes up a portion of the possible space (GUISizeHelper.stackWidth)
int newStackWidth = pnlHelperHandButtonsStackArea.getWidth() * GUISizeHelper.stackWidth / 100;
if (newStackWidth < 410) {
newStackWidth = 410;
}
Dimension newDimension = new Dimension(pnlHelperHandButtonsStackArea.getWidth() - newStackWidth, GUISizeHelper.handCardDimension.height + GUISizeHelper.scrollBarSize);
newStackWidth = Math.max(410, newStackWidth);
Dimension newDimension = new Dimension(
pnlHelperHandButtonsStackArea.getWidth() - newStackWidth,
MageActionCallback.getHandOrStackMargins(Zone.HAND).getHeight() + GUISizeHelper.handCardDimension.height + GUISizeHelper.scrollBarSize
);
handContainer.setPreferredSize(newDimension);
handContainer.setMaximumSize(newDimension);
newDimension = new Dimension(newStackWidth, STACK_MIN_CARDS_OFFSET_Y + GUISizeHelper.handCardDimension.height + GUISizeHelper.scrollBarSize);
newDimension = new Dimension(
newStackWidth,
MageActionCallback.getHandOrStackMargins(Zone.STACK).getHeight() + GUISizeHelper.handCardDimension.height + GUISizeHelper.scrollBarSize
);
stackObjects.setCardDimension(GUISizeHelper.handCardDimension);
stackObjects.setPreferredSize(newDimension);
stackObjects.setMinimumSize(newDimension);
stackObjects.setMaximumSize(newDimension);
@ -633,24 +671,27 @@ public final class GamePanel extends javax.swing.JPanel {
}
public synchronized void updateGame(GameView game, boolean showPlayable, Map<String, Serializable> options, Set<UUID> targets) {
keepLastGameData(game, showPlayable, options, targets);
prepareSelectableView();
updateGame();
}
prepareSelectableView(game, showPlayable, options, targets);
if (playerId == null && game.getWatchedHands() == null) {
public synchronized void updateGame() {
if (playerId == null && lastGameData.game.getWatchedHands() == null) {
this.handContainer.setVisible(false);
} else {
this.handContainer.setVisible(true);
handCards.clear();
if (game.getWatchedHands() != null) {
for (Map.Entry<String, SimpleCardsView> hand : game.getWatchedHands().entrySet()) {
if (lastGameData.game.getWatchedHands() != null) {
for (Map.Entry<String, SimpleCardsView> hand : lastGameData.game.getWatchedHands().entrySet()) {
handCards.put(hand.getKey(), CardsViewUtil.convertSimple(hand.getValue(), loadedCards));
}
}
if (playerId != null) {
handCards.put(YOUR_HAND, game.getHand());
handCards.put(YOUR_HAND, lastGameData.game.getHand());
// Get opponents hand cards if available (only possible for players)
if (game.getOpponentHands() != null) {
for (Map.Entry<String, SimpleCardsView> hand : game.getOpponentHands().entrySet()) {
if (lastGameData.game.getOpponentHands() != null) {
for (Map.Entry<String, SimpleCardsView> hand : lastGameData.game.getOpponentHands().entrySet()) {
handCards.put(hand.getKey(), CardsViewUtil.convertSimple(hand.getValue(), loadedCards));
}
}
@ -669,7 +710,7 @@ public final class GamePanel extends javax.swing.JPanel {
if (playerId != null) {
// set visible only if we have any other hand visible than ours
btnSwitchHands.setVisible(handCards.size() > 1);
boolean change = (handCardsOfOpponentAvailable != (game.getOpponentHands() != null));
boolean change = (handCardsOfOpponentAvailable != (lastGameData.game.getOpponentHands() != null));
if (change) {
handCardsOfOpponentAvailable = !handCardsOfOpponentAvailable;
if (handCardsOfOpponentAvailable) {
@ -683,45 +724,45 @@ public final class GamePanel extends javax.swing.JPanel {
}
}
if (game.getPhase() != null) {
this.txtPhase.setText(game.getPhase().toString());
if (lastGameData.game.getPhase() != null) {
this.txtPhase.setText(lastGameData.game.getPhase().toString());
} else {
this.txtPhase.setText("");
}
if (game.getStep() != null) {
updatePhases(game.getStep());
this.txtStep.setText(game.getStep().toString());
if (lastGameData.game.getStep() != null) {
updatePhases(lastGameData.game.getStep());
this.txtStep.setText(lastGameData.game.getStep().toString());
} else {
logger.debug("Step is empty");
this.txtStep.setText("");
}
if (game.getSpellsCastCurrentTurn() > 0 && PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_SHOW_STORM_COUNTER, "true").equals("true")) {
if (lastGameData.game.getSpellsCastCurrentTurn() > 0 && PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_SHOW_STORM_COUNTER, "true").equals("true")) {
this.txtSpellsCast.setVisible(true);
this.txtSpellsCast.setText(' ' + Integer.toString(game.getSpellsCastCurrentTurn()) + ' ');
this.txtSpellsCast.setText(' ' + Integer.toString(lastGameData.game.getSpellsCastCurrentTurn()) + ' ');
} else {
this.txtSpellsCast.setVisible(false);
}
this.txtActivePlayer.setText(game.getActivePlayerName());
this.txtPriority.setText(game.getPriorityPlayerName());
this.txtTurn.setText(Integer.toString(game.getTurn()));
this.txtActivePlayer.setText(lastGameData.game.getActivePlayerName());
this.txtPriority.setText(lastGameData.game.getPriorityPlayerName());
this.txtTurn.setText(Integer.toString(lastGameData.game.getTurn()));
List<UUID> possibleAttackers = new ArrayList<>();
if (options != null && options.containsKey(Constants.Option.POSSIBLE_ATTACKERS)) {
if (options.get(Constants.Option.POSSIBLE_ATTACKERS) instanceof List) {
possibleAttackers.addAll((List) options.get(Constants.Option.POSSIBLE_ATTACKERS));
if (lastGameData.options != null && lastGameData.options.containsKey(Constants.Option.POSSIBLE_ATTACKERS)) {
if (lastGameData.options.get(Constants.Option.POSSIBLE_ATTACKERS) instanceof List) {
possibleAttackers.addAll((List) lastGameData.options.get(Constants.Option.POSSIBLE_ATTACKERS));
}
}
List<UUID> possibleBlockers = new ArrayList<>();
if (options != null && options.containsKey(Constants.Option.POSSIBLE_BLOCKERS)) {
if (options.get(Constants.Option.POSSIBLE_BLOCKERS) instanceof List) {
possibleBlockers.addAll((List) options.get(Constants.Option.POSSIBLE_BLOCKERS));
if (lastGameData.options != null && lastGameData.options.containsKey(Constants.Option.POSSIBLE_BLOCKERS)) {
if (lastGameData.options.get(Constants.Option.POSSIBLE_BLOCKERS) instanceof List) {
possibleBlockers.addAll((List) lastGameData.options.get(Constants.Option.POSSIBLE_BLOCKERS));
}
}
for (PlayerView player : game.getPlayers()) {
for (PlayerView player : lastGameData.game.getPlayers()) {
if (players.containsKey(player.getPlayerId())) {
if (!possibleAttackers.isEmpty()) {
for (UUID permanentId : possibleAttackers) {
@ -737,7 +778,7 @@ public final class GamePanel extends javax.swing.JPanel {
}
}
}
players.get(player.getPlayerId()).update(game, player, targets);
players.get(player.getPlayerId()).update(lastGameData.game, player, lastGameData.targets);
if (player.getPlayerId().equals(playerId)) {
skipButtons.updateFromPlayer(player);
}
@ -778,7 +819,7 @@ public final class GamePanel extends javax.swing.JPanel {
sb.append("Playing: ");
}
boolean first = true;
for (PlayerView player : game.getPlayers()) {
for (PlayerView player : lastGameData.game.getPlayers()) {
if (first) {
first = false;
} else {
@ -790,10 +831,10 @@ public final class GamePanel extends javax.swing.JPanel {
gamePane.setTitle(sb.toString());
}
GameManager.instance.setStackSize(game.getStack().size());
displayStack(game, bigCard, feedbackPanel, gameId);
GameManager.instance.setStackSize(lastGameData.game.getStack().size());
displayStack(lastGameData.game, bigCard, feedbackPanel, gameId);
for (ExileView exile : game.getExile()) {
for (ExileView exile : lastGameData.game.getExile()) {
if (!exiles.containsKey(exile.getId())) {
CardInfoWindowDialog newExile = new CardInfoWindowDialog(ShowType.EXILE, exile.getName());
exiles.put(exile.getId(), newExile);
@ -803,16 +844,16 @@ public final class GamePanel extends javax.swing.JPanel {
exiles.get(exile.getId()).loadCards(exile, bigCard, gameId);
}
showRevealed(game);
showLookedAt(game);
showCompanion(game);
if (!game.getCombat().isEmpty()) {
CombatManager.instance.showCombat(game.getCombat(), gameId);
showRevealed(lastGameData.game);
showLookedAt(lastGameData.game);
showCompanion(lastGameData.game);
if (!lastGameData.game.getCombat().isEmpty()) {
CombatManager.instance.showCombat(lastGameData.game.getCombat(), gameId);
} else {
CombatManager.instance.hideCombat(gameId);
}
for (PlayerView player : game.getPlayers()) {
for (PlayerView player : lastGameData.game.getPlayers()) {
if (player.hasLeft() && !playersWhoLeft.get(player.getPlayerId())) {
PlayAreaPanel playerLeftPanel = players.get(player.getPlayerId());
playersWhoLeft.put(player.getPlayerId(), true);
@ -1230,34 +1271,43 @@ public final class GamePanel extends javax.swing.JPanel {
this.feedbackPanel.getFeedback(FeedbackMode.QUESTION, question, false, options, messageId, true, gameView.getPhase());
}
private void prepareSelectableView(GameView gameView, boolean showPlayable, Map<String, Serializable> options, Set<UUID> targets) {
// make cards/perm selectable/chooseable/playable
// playable must be used for ask dialog only (priority and mana pay)
private void keepLastGameData(GameView game, boolean showPlayable, Map<String, Serializable> options, Set<UUID> targets) {
lastGameData.game = game;
lastGameData.showPlayable = showPlayable;
lastGameData.options = options;
lastGameData.targets = targets;
}
private void prepareSelectableView() {
// make cards/perm selectable/chooseable/playable update game data updates
if (lastGameData.game == null) {
return;
}
Zone needZone = Zone.ALL;
if (options != null && options.containsKey("targetZone")) {
needZone = (Zone) options.get("targetZone");
if (lastGameData.options != null && lastGameData.options.containsKey("targetZone")) {
needZone = (Zone) lastGameData.options.get("targetZone");
}
List<UUID> needChoosen;
if (options != null && options.containsKey("chosen")) {
needChoosen = (List<UUID>) options.get("chosen");
if (lastGameData.options != null && lastGameData.options.containsKey("chosen")) {
needChoosen = (List<UUID>) lastGameData.options.get("chosen");
} else {
needChoosen = new ArrayList<>();
}
Set<UUID> needSelectable;
if (targets != null) {
needSelectable = targets;
if (lastGameData.targets != null) {
needSelectable = lastGameData.targets;
} else {
needSelectable = new HashSet<>();
}
Map<UUID, Integer> needPlayable;
if (showPlayable && gameView.getCanPlayObjects() != null) {
needPlayable = gameView.getCanPlayObjects();
PlayableObjectsList needPlayable;
if (lastGameData.showPlayable && lastGameData.game.getCanPlayObjects() != null) {
needPlayable = lastGameData.game.getCanPlayObjects();
} else {
needPlayable = new HashMap<>();
needPlayable = new PlayableObjectsList();
}
if (needChoosen.isEmpty() && needSelectable.isEmpty() && needPlayable.isEmpty()) {
@ -1266,23 +1316,22 @@ public final class GamePanel extends javax.swing.JPanel {
// hand
if (needZone == Zone.HAND || needZone == Zone.ALL) {
for (CardView card : gameView.getHand().values()) {
for (CardView card : lastGameData.game.getHand().values()) {
if (needSelectable.contains(card.getId())) {
card.setChoosable(true);
}
if (needChoosen.contains(card.getId())) {
card.setSelected(true);
}
if (needPlayable.containsKey(card.getId())) {
card.setPlayable(true);
card.setPlayableAmount(needPlayable.get(card.getId()));
if (needPlayable.containsObject(card.getId())) {
card.setPlayableStats(needPlayable.getStats(card.getId()));
}
}
}
// stack
if (needZone == Zone.STACK || needZone == Zone.ALL) {
for (Map.Entry<UUID, CardView> card : gameView.getStack().entrySet()) {
for (Map.Entry<UUID, CardView> card : lastGameData.game.getStack().entrySet()) {
if (needSelectable.contains(card.getKey())) {
card.getValue().setChoosable(true);
}
@ -1290,16 +1339,15 @@ public final class GamePanel extends javax.swing.JPanel {
card.getValue().setSelected(true);
}
// users can activate abilities of the spell on the stack (example: Lightning Storm);
if (needPlayable.containsKey(card.getKey())) {
card.getValue().setPlayable(true);
card.getValue().setPlayableAmount(needPlayable.get(card.getKey()));
if (needPlayable.containsObject(card.getKey())) {
card.getValue().setPlayableStats(needPlayable.getStats(card.getKey()));
}
}
}
// battlefield
if (needZone == Zone.BATTLEFIELD || needZone == Zone.ALL) {
for (PlayerView player : gameView.getPlayers()) {
for (PlayerView player : lastGameData.game.getPlayers()) {
for (Map.Entry<UUID, PermanentView> perm : player.getBattlefield().entrySet()) {
if (needSelectable.contains(perm.getKey())) {
perm.getValue().setChoosable(true);
@ -1307,9 +1355,8 @@ public final class GamePanel extends javax.swing.JPanel {
if (needChoosen.contains(perm.getKey())) {
perm.getValue().setSelected(true);
}
if (needPlayable.containsKey(perm.getKey())) {
perm.getValue().setPlayable(true);
perm.getValue().setPlayableAmount(needPlayable.get(perm.getKey()));
if (needPlayable.containsObject(perm.getKey())) {
perm.getValue().setPlayableStats(needPlayable.getStats(perm.getKey()));
}
}
}
@ -1317,7 +1364,7 @@ public final class GamePanel extends javax.swing.JPanel {
// graveyard
if (needZone == Zone.GRAVEYARD || needZone == Zone.ALL) {
for (PlayerView player : gameView.getPlayers()) {
for (PlayerView player : lastGameData.game.getPlayers()) {
for (Map.Entry<UUID, CardView> card : player.getGraveyard().entrySet()) {
if (needSelectable.contains(card.getKey())) {
card.getValue().setChoosable(true);
@ -1325,17 +1372,31 @@ public final class GamePanel extends javax.swing.JPanel {
if (needChoosen.contains(card.getKey())) {
card.getValue().setSelected(true);
}
if (needPlayable.containsKey(card.getKey())) {
card.getValue().setPlayable(true);
card.getValue().setPlayableAmount(needPlayable.get(card.getKey()));
if (needPlayable.containsObject(card.getKey())) {
card.getValue().setPlayableStats(needPlayable.getStats(card.getKey()));
}
}
}
}
// exile
if (needZone == Zone.HAND || needZone == Zone.ALL) {
for (ExileView exile : gameView.getExile()) {
if (needZone == Zone.EXILED || needZone == Zone.ALL) {
// exile from player panel
for (PlayerView player : lastGameData.game.getPlayers()) {
for (CardView card : player.getExile().values()) {
if (needSelectable.contains(card.getId())) {
card.setChoosable(true);
}
if (needChoosen.contains(card.getId())) {
card.setSelected(true);
}
if (needPlayable.containsObject(card.getId())) {
card.setPlayableStats(needPlayable.getStats(card.getId()));
}
}
}
// exile from windows
for (ExileView exile : lastGameData.game.getExile()) {
for (Map.Entry<UUID, CardView> card : exile.entrySet()) {
if (needSelectable.contains(card.getKey())) {
card.getValue().setChoosable(true);
@ -1343,9 +1404,8 @@ public final class GamePanel extends javax.swing.JPanel {
if (needChoosen.contains(card.getKey())) {
card.getValue().setSelected(true);
}
if (needPlayable.containsKey(card.getKey())) {
card.getValue().setPlayable(true);
card.getValue().setPlayableAmount(needPlayable.get(card.getKey()));
if (needPlayable.containsObject(card.getKey())) {
card.getValue().setPlayableStats(needPlayable.getStats(card.getKey()));
}
}
}
@ -1353,7 +1413,7 @@ public final class GamePanel extends javax.swing.JPanel {
// command
if (needZone == Zone.COMMAND || needZone == Zone.ALL) {
for (PlayerView player : gameView.getPlayers()) {
for (PlayerView player : lastGameData.game.getPlayers()) {
for (CommandObjectView com : player.getCommandObjectList()) {
if (needSelectable.contains(com.getId())) {
com.setChoosable(true);
@ -1361,16 +1421,15 @@ public final class GamePanel extends javax.swing.JPanel {
if (needChoosen.contains(com.getId())) {
com.setSelected(true);
}
if (needPlayable.containsKey(com.getId())) {
com.setPlayable(true);
com.setPlayableAmount(needPlayable.get(com.getId()));
if (needPlayable.containsObject(com.getId())) {
com.setPlayableStats(needPlayable.getStats(com.getId()));
}
}
}
}
// revealed
for (RevealedView rev : gameView.getRevealed()) {
for (RevealedView rev : lastGameData.game.getRevealed()) {
for (Map.Entry<UUID, CardView> card : rev.getCards().entrySet()) {
if (needSelectable.contains(card.getKey())) {
card.getValue().setChoosable(true);
@ -1378,15 +1437,14 @@ public final class GamePanel extends javax.swing.JPanel {
if (needChoosen.contains(card.getKey())) {
card.getValue().setSelected(true);
}
if (needPlayable.containsKey(card.getKey())) {
card.getValue().setPlayable(true);
card.getValue().setPlayableAmount(needPlayable.get(card.getKey()));
if (needPlayable.containsObject(card.getKey())) {
card.getValue().setPlayableStats(needPlayable.getStats(card.getKey()));
}
}
}
// companion
for (RevealedView rev : gameView.getCompanion()) {
for (RevealedView rev : lastGameData.game.getCompanion()) {
for (Map.Entry<UUID, CardView> card : rev.getCards().entrySet()) {
if (needSelectable.contains(card.getKey())) {
card.getValue().setChoosable(true);
@ -1394,19 +1452,17 @@ public final class GamePanel extends javax.swing.JPanel {
if (needChoosen.contains(card.getKey())) {
card.getValue().setSelected(true);
}
if (needPlayable.containsKey(card.getKey())) {
card.getValue().setPlayable(true);
card.getValue().setPlayableAmount(needPlayable.get(card.getKey()));
if (needPlayable.containsObject(card.getKey())) {
card.getValue().setPlayableStats(needPlayable.getStats(card.getKey()));
}
}
}
// looked at
for (LookedAtView look : gameView.getLookedAt()) {
for (LookedAtView look : lastGameData.game.getLookedAt()) {
for (Map.Entry<UUID, SimpleCardView> card : look.getCards().entrySet()) {
if (needPlayable.containsKey(card.getKey())) {
card.getValue().setPlayable(true);
card.getValue().setPlayableAmount(needPlayable.get(card.getKey()));
if (needPlayable.containsObject(card.getKey())) {
card.getValue().setPlayableStats(needPlayable.getStats(card.getKey()));
}
}
}
@ -1417,14 +1473,14 @@ public final class GamePanel extends javax.swing.JPanel {
* the pick triggered ability)
*
* @param message
* @param cardView
* @param cardsView
* @param gameView
* @param targets
* @param required
* @param options
* @param messageId
*/
public void pickTarget(String message, CardsView cardView, GameView gameView, Set<UUID> targets, boolean required, Map<String, Serializable> options, int messageId) {
public void pickTarget(String message, CardsView cardsView, GameView gameView, Set<UUID> targets, boolean required, Map<String, Serializable> options, int messageId) {
PopUpMenuType popupMenuType = null;
if (options != null) {
if (options.containsKey("queryType")) {
@ -1446,13 +1502,15 @@ public final class GamePanel extends javax.swing.JPanel {
Map<String, Serializable> options0 = options == null ? new HashMap<>() : options;
ShowCardsDialog dialog = null;
if (cardView != null && !cardView.isEmpty()) {
dialog = showCards(message, cardView, required, options0, popupMenuType);
if (cardsView != null && !cardsView.isEmpty()) {
// clear old dialogs before the new
clearPickTargetDialogs();
dialog = showCards(message, cardsView, required, options0, popupMenuType);
options0.put("dialog", dialog);
}
this.feedbackPanel.getFeedback(required ? FeedbackMode.INFORM : FeedbackMode.CANCEL, message, gameView.getSpecial(), options0, messageId, true, gameView.getPhase());
if (dialog != null) {
this.pickTarget.add(dialog); // TODO: 01.01.2018, JayDi85: why feedbackPanel saved to pickTarget list? Need to research
this.pickTarget.add(dialog);
}
}
@ -1581,9 +1639,17 @@ public final class GamePanel extends javax.swing.JPanel {
public void pickPile(String message, CardsView pile1, CardsView pile2) {
hideAll();
// remove old dialogs before the new
clearPickPileDialogs();
PickPileDialog pickPileDialog = new PickPileDialog();
this.pickPile.add(pickPileDialog);
pickPileDialog.loadCards(message, pile1, pile2, bigCard, gameId);
SessionHandler.sendPlayerBoolean(gameId, pickPileDialog.isPickedPile1());
if (pickPileDialog.isPickedOK()) {
SessionHandler.sendPlayerBoolean(gameId, pickPileDialog.isPickedPile1());
}
pickPileDialog.cleanUp();
pickPileDialog.removeDialog();
}
@ -2453,7 +2519,7 @@ public final class GamePanel extends javax.swing.JPanel {
}
private void mouseClickPhaseBar(MouseEvent evt) {
if (evt.getButton() == MouseEvent.BUTTON1) { // Left button
if (SwingUtilities.isLeftMouseButton(evt)) {
PreferencesDialog.main(new String[]{PreferencesDialog.OPEN_PHASES_TAB});
// TODO: add event handler on preferences closed and refresh game data from server
}
@ -2542,18 +2608,15 @@ public final class GamePanel extends javax.swing.JPanel {
// Event listener for the ShowCardsDialog
private Listener<Event> getShowCardsEventListener(final ShowCardsDialog dialog) {
return event -> {
if (event.getEventType() == ClientEventType.SHOW_POP_UP_MENU) {
if (event.getComponent() != null && event.getComponent() instanceof CardPanel) {
JPopupMenu menu = ((CardPanel) event.getComponent()).getPopupMenu();
if (event.getEventType() == ClientEventType.CARD_POPUP_MENU) {
if (event.getComponent() != null && event.getComponent() instanceof MageCard) {
JPopupMenu menu = ((MageCard) event.getComponent()).getPopupMenu();
if (menu != null) {
cardViewPopupMenu = ((CardView) event.getSource());
menu.show(event.getComponent(), event.getxPos(), event.getyPos());
}
}
}
if (event.getEventType() == ClientEventType.ACTION_CONSUMED) {
dialog.removeDialog();
}
};
}
@ -2594,9 +2657,14 @@ public final class GamePanel extends javax.swing.JPanel {
default:
break;
}
// TODO: 2021-01-23 why it here? Can be removed?
for (ShowCardsDialog dialog : pickTarget) {
dialog.removeDialog();
}
for (PickPileDialog dialog : pickPile) {
dialog.removeDialog();
}
}
private void initPopupMenuTriggerOrder() {

View file

@ -12,22 +12,19 @@ import mage.view.CardsView;
public class HandPanel extends JPanel {
private static final int HAND_MIN_CARDS_OFFSET_Y = -10;
public HandPanel() {
initComponents();
changeGUISize();
}
public void initComponents() {
hand = new mage.client.cards.Cards(true);
hand.setMinOffsetY(HAND_MIN_CARDS_OFFSET_Y);
hand.setCardDimension(GUISizeHelper.handCardDimension);
jPanel = new JPanel();
jScrollPane1 = new JScrollPane(jPanel);
jScrollPane1.getViewport().setBackground(new Color(0, 0, 0, 0));
hand = new mage.client.cards.Cards(true, jScrollPane1);
hand.setCardDimension(GUISizeHelper.handCardDimension);
jPanel.setLayout(new GridBagLayout()); // centers hand
jPanel.setBackground(new Color(0, 0, 0, 0));
jPanel.add(hand);
@ -49,7 +46,7 @@ public class HandPanel extends JPanel {
hand.setBackgroundColor(new Color(0, 0, 0, 0));
hand.setVisibleIfEmpty(false);
hand.setBorder(EMPTY_BORDER);
hand.setZone(Zone.HAND.toString());
hand.setZone(Zone.HAND);
}
public void cleanUp() {
@ -63,6 +60,7 @@ public class HandPanel extends JPanel {
private void setGUISize() {
jScrollPane1.getVerticalScrollBar().setPreferredSize(new Dimension(GUISizeHelper.scrollBarSize, 0));
jScrollPane1.getHorizontalScrollBar().setPreferredSize(new Dimension(0, GUISizeHelper.scrollBarSize));
jScrollPane1.getHorizontalScrollBar().setUnitIncrement(GUISizeHelper.getCardsScrollbarUnitInc(GUISizeHelper.handCardDimension.width));
hand.setCardDimension(GUISizeHelper.handCardDimension);
hand.changeGUISize();
}

View file

@ -186,13 +186,13 @@ public class HelperPanel extends JPanel {
MouseListener checkPopupAdapter = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent me) {
checkPopupMenu(me);
public void mousePressed(MouseEvent e) {
checkPopupMenu(e);
}
@Override
public void mouseReleased(MouseEvent me) {
checkPopupMenu(me);
public void mouseReleased(MouseEvent e) {
checkPopupMenu(e);
}
};
@ -230,26 +230,26 @@ public class HelperPanel extends JPanel {
dialogTextArea.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent me) {
public void mouseEntered(MouseEvent e) {
ToolTipManager.sharedInstance().setDismissDelay(100 * 1000);
UIManager.put("info", Color.DARK_GRAY);
}
@Override
public void mouseExited(MouseEvent me) {
public void mouseExited(MouseEvent e) {
ToolTipManager.sharedInstance().setDismissDelay(Constants.TOOLTIPS_DELAY_MS);
UIManager.put("info", tooltipBackground);
}
});
}
private void checkPopupMenu(MouseEvent me) {
if (me.isPopupTrigger()
private void checkPopupMenu(MouseEvent e) {
if (e.isPopupTrigger()
&& originalId != null) { // only Yes/No requests from abilities can be automated
JButton source = (JButton) me.getSource();
JButton source = (JButton) e.getSource();
if (source.getActionCommand().startsWith(QUESTION.toString())) {
showPopupMenu(me.getComponent(), source.getActionCommand());
me.consume();
showPopupMenu(e.getComponent(), source.getActionCommand());
e.consume();
}
}
}

View file

@ -1,11 +1,3 @@
/*
* ManaPool.java
*
* Created on Dec 22, 2009, 9:52:00 AM
*/
package mage.client.game;
import mage.view.ManaPoolView;

View file

@ -421,19 +421,19 @@ public class PlayAreaPanel extends javax.swing.JPanel {
battlefieldPanel.getMainPanel().addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent Me) {
this.checkMenu(Me);
public void mouseReleased(MouseEvent e) {
this.checkMenu(e);
}
// neccessary for linux and mac systems
@Override
public void mousePressed(MouseEvent Me) {
this.checkMenu(Me);
public void mousePressed(MouseEvent e) {
this.checkMenu(e);
}
private void checkMenu(MouseEvent Me) {
if (Me.isPopupTrigger() && playingMode) {
popupMenu.show(Me.getComponent(), Me.getX(), Me.getY());
private void checkMenu(MouseEvent e) {
if (e.isPopupTrigger() && playingMode) {
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
@ -474,19 +474,19 @@ public class PlayAreaPanel extends javax.swing.JPanel {
battlefieldPanel.getMainPanel().addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent Me) {
this.checkMenu(Me);
public void mouseReleased(MouseEvent e) {
this.checkMenu(e);
}
// neccessary for linux and mac systems
@Override
public void mousePressed(MouseEvent Me) {
this.checkMenu(Me);
public void mousePressed(MouseEvent e) {
this.checkMenu(e);
}
private void checkMenu(MouseEvent Me) {
if (Me.isPopupTrigger() && playingMode) {
popupMenu.show(Me.getComponent(), Me.getX(), Me.getY());
private void checkMenu(MouseEvent e) {
if (e.isPopupTrigger() && playingMode) {
popupMenu.show(e.getComponent(), e.getX(), e.getY());
}
}
});

View file

@ -36,7 +36,7 @@ import java.util.*;
import static mage.constants.Constants.*;
/**
* Enhanced player pane.
* Game GUI: player panel with avatar and icons
*
* @author nantuko, JayDi85
*/
@ -150,7 +150,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
// can play
if (gameView.getCanPlayObjects() != null && !gameView.getCanPlayObjects().isEmpty()) {
for (CardView card : cards) {
if (gameView.getCanPlayObjects().containsKey(card.getId())) {
if (gameView.getCanPlayObjects().containsObject(card.getId())) {
return true;
}
}
@ -247,7 +247,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
Color commandColor = Color.BLACK;
for (CommandObjectView com : player.getCommandObjectList()) {
if (game != null && game.getCanPlayObjects() != null && game.getCanPlayObjects().containsKey(com.getId())) {
if (game != null && game.getCanPlayObjects() != null && game.getCanPlayObjects().containsObject(com.getId())) {
commandColor = activeValueColor;
break;
}
@ -545,7 +545,6 @@ public class PlayerPanelExt extends javax.swing.JPanel {
cheat.addActionListener(e -> btnCheatActionPerformed(e));
zonesPanel = new JPanel();
//zonesPanel.setBorder(BorderFactory.createLineBorder(Color.red));
zonesPanel.setPreferredSize(new Dimension(100, 60));
zonesPanel.setSize(100, 60);
zonesPanel.setLayout(null);

View file

@ -1,7 +1,7 @@
package mage.client.plugins;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.cards.MagePermanent;
import mage.cards.action.ActionCallback;
import mage.client.cards.BigCard;
import mage.view.CardView;
@ -23,9 +23,9 @@ public interface MagePlugins {
JComponent updateTablePanel(Map<String, JComponent> ui);
MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, int renderMode, boolean needFullPermanentRender);
MageCard getMagePermanent(PermanentView card, BigCard bigCard, CardIconRenderSettings cardIconRenderSettings, Dimension dimension, UUID gameId, boolean loadImage, int renderMode, boolean needFullPermanentRender);
MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable, int renderMode, boolean needFullPermanentRender);
MageCard getMageCard(CardView card, BigCard bigCard, CardIconRenderSettings cardIconRenderSettings, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable, int renderMode, boolean needFullPermanentRender);
boolean isThemePluginLoaded();
@ -33,7 +33,7 @@ public interface MagePlugins {
boolean isCounterPluginLoaded();
int sortPermanents(Map<String, JComponent> ui, Map<UUID, MagePermanent> permanents, boolean topRow);
int sortPermanents(Map<String, JComponent> ui, Map<UUID, MageCard> cards, boolean topRow);
void downloadSymbols();
@ -41,9 +41,9 @@ public interface MagePlugins {
void addGamesPlayed();
void onAddCard(MagePermanent card, int count);
void onAddCard(MageCard card, int count);
void onRemoveCard(MagePermanent card, int count);
void onRemoveCard(MageCard card, int count);
JComponent getCardInfoPane();

View file

@ -1,28 +1,31 @@
package mage.client.plugins.adapters;
import mage.cards.MageCard;
import mage.cards.MageCardSpace;
import mage.cards.action.ActionCallback;
import mage.cards.action.TransferData;
import mage.client.MageFrame;
import mage.client.MagePane;
import mage.client.SessionHandler;
import mage.client.cards.BigCard;
import mage.client.cards.CardEventProducer;
import mage.client.components.MageComponents;
import mage.client.dialog.PreferencesDialog;
import mage.client.game.GamePane;
import mage.client.plugins.impl.Plugins;
import mage.client.util.ClientEventType;
import mage.client.util.DefaultActionCallback;
import mage.client.util.gui.ArrowBuilder;
import mage.client.util.gui.ArrowUtil;
import mage.client.util.gui.GuiDisplayUtil;
import mage.components.CardInfoPane;
import mage.constants.EnlargeMode;
import mage.constants.Zone;
import mage.utils.ThreadUtils;
import mage.view.CardView;
import mage.view.PermanentView;
import org.apache.log4j.Logger;
import org.jdesktop.swingx.JXPanel;
import org.mage.card.arcane.CardPanel;
import org.mage.plugins.card.images.ImageCache;
import javax.swing.*;
@ -41,14 +44,26 @@ import java.util.concurrent.TimeUnit;
* Class that handles the callbacks from the card panels to mage to display big
* card images from the cards the mouse hovers on. Also handles tooltip text
* window.
* <p>
* Only ONE action callback possible for the app
* <p>
* If you want to process card events in your component then use CardEventProducer, see example with mouseClicked here
*
* @author Nantuko, noxx
* @author Nantuko, noxx, JayDi85
*/
public class MageActionCallback implements ActionCallback {
private static final Logger LOGGER = Logger.getLogger(ActionCallback.class);
public static final int GAP_X = 5;
public static final double COMPARE_GAP_X = 30;
private static final Logger logger = Logger.getLogger(ActionCallback.class);
// hand and stack panel sizes (without scrolls)
public static final int HAND_CARDS_BETWEEN_GAP_X = 5; // space between cards in hand // TODO: make it gui's sizeable
public static final int STACK_CARDS_BETWEEN_GAP_X = 5; // space between cards in hand // TODO: make it gui's sizeable
public static final MageCardSpace HAND_CARDS_MARGINS = new MageCardSpace(10, 10, 5, 5); // no needs bottom space for scrolls, it's already calced in parent panel
public static final MageCardSpace STACK_CARDS_MARGINS = new MageCardSpace(10, 10, 5, 5);
// effect of moving the cards apart while dragging another card above it
// higher value -> the effect will appear earlier (depends on the card size)
public static final int HAND_CARDS_COMPARE_GAP_X = 30;
public static final int GO_DOWN_ON_DRAG_Y_OFFSET = 0;
public static final int GO_UP_ON_DRAG_Y_OFFSET = 0;
@ -56,7 +71,6 @@ public class MageActionCallback implements ActionCallback {
public static final int MIN_X_OFFSET_REQUIRED = 20;
private Popup tooltipPopup;
private JPopupMenu jPopupMenu;
private BigCard bigCard;
private CardView tooltipCard;
@ -66,7 +80,6 @@ public class MageActionCallback implements ActionCallback {
private int tooltipDelay;
enum EnlargedWindowState {
CLOSED, NORMAL, ROTATED
}
@ -79,12 +92,12 @@ public class MageActionCallback implements ActionCallback {
private static final ScheduledExecutorService timeoutExecutor = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> hideTimeout;
private CardPanel prevCardPanel;
private MageCard prevCardPanel;
private boolean startedDragging;
private boolean isDragging;
private boolean isDragging; // TODO: remove drag hand code to the hand panels
private Point initialCardPos;
private Point initialMousePos;
private final Set<CardPanel> cardPanels = new HashSet<>();
private final Set<MageCard> draggingCards = new HashSet<>();
public MageActionCallback() {
enlargeMode = EnlargeMode.NORMAL;
@ -101,44 +114,57 @@ public class MageActionCallback implements ActionCallback {
}
@Override
public void mouseClicked(MouseEvent e, TransferData data) {
public void mouseClicked(MouseEvent e, TransferData data, boolean doubleClick) {
// send mouse clicked event to the card's area and other cards list components for processing
if (e.isConsumed()) {
return;
}
if (data.getComponent().getCardContainer() instanceof CardEventProducer) {
ClientEventType clickType = doubleClick ? ClientEventType.CARD_DOUBLE_CLICK : ClientEventType.CARD_CLICK;
CardEventProducer cardContainer = (CardEventProducer) data.getComponent().getCardContainer();
mage.client.util.Event clientEvent = new mage.client.util.Event(
data.getComponent().getOriginal(), clickType,
0, e.getX(), e.getY(), data.getComponent(), e, false
);
cardContainer.getCardEventSource().fireEvent(clientEvent);
}
}
@Override
public void mouseEntered(MouseEvent e, final TransferData data) {
this.popupData = data;
handleOverNewView(data);
handleMouseMoveOverNewCard(data);
}
private void showTooltipPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
if (data.getComponent() != null) {
tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300);
if (tooltipDelay == 0) {
return;
}
private void startCardHintPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
MageCard cardPanel = data.getComponent().getTopPanelRef();
tooltipDelay = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300);
if (tooltipDelay == 0) {
return;
}
if (cardInfoPane == null) {
PopupFactory factory = PopupFactory.getSharedInstance();
// create new popup
if (data.getLocationOnScreen() == null) {
if (data.getComponent() == null) {
return;
}
data.setLocationOnScreen(data.getComponent().getLocationOnScreen());
data.setLocationOnScreen(cardPanel.getCardLocationOnScreen().getCardPoint());
}
PopupFactory factory = PopupFactory.getSharedInstance();
data.getPopupText().updateText();
tooltipPopup = factory.getPopup(data.getComponent(), data.getPopupText(), (int) data.getLocationOnScreen().getX() + data.getPopupOffsetX(), (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() + 40);
tooltipPopup = factory.getPopup(cardPanel, data.getPopupText(), (int) data.getLocationOnScreen().getX() + data.getPopupOffsetX(), (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() + 40);
tooltipPopup.show();
// hack to get popup to resize to fit text
tooltipPopup.hide();
tooltipPopup = factory.getPopup(data.getComponent(), data.getPopupText(), (int) data.getLocationOnScreen().getX() + data.getPopupOffsetX(), (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() + 40);
tooltipPopup = factory.getPopup(cardPanel, data.getPopupText(), (int) data.getLocationOnScreen().getX() + data.getPopupOffsetX(), (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() + 40);
tooltipPopup.show();
} else {
sumbitShowPopupTask(data, parentComponent, parentPoint);
showCardHintPopup(data, parentComponent, parentPoint);
}
}
private void sumbitShowPopupTask(final TransferData data, final Component parentComponent, final Point parentPoint) {
private void showCardHintPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
MageCard cardPanel = data.getComponent().getTopPanelRef();
ThreadUtils.threadPool2.submit(new Runnable() {
@Override
public void run() {
@ -158,7 +184,7 @@ public class MageActionCallback implements ActionCallback {
((CardInfoPane) popupInfo).setCard(data.getCard(), popupContainer);
showPopup(popupContainer, popupInfo);
} catch (InterruptedException e) {
LOGGER.error("Can't show card tooltip", e);
logger.error("Can't show card tooltip", e);
Thread.currentThread().interrupt();
}
}
@ -171,7 +197,7 @@ public class MageActionCallback implements ActionCallback {
}
if (data.getLocationOnScreen() == null) {
data.setLocationOnScreen(data.getComponent().getLocationOnScreen());
data.setLocationOnScreen(cardPanel.getCardLocationOnScreen().getCardPoint());
}
Point location = new Point((int) data.getLocationOnScreen().getX() + data.getPopupOffsetX() - 40, (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() - 40);
@ -188,7 +214,8 @@ public class MageActionCallback implements ActionCallback {
@Override
public void mousePressed(MouseEvent e, TransferData data) {
data.getComponent().requestFocusInWindow();
MageCard cardPanel = data.getComponent().getTopPanelRef();
cardPanel.requestFocusInWindow();
// for some reason sometime mouseRelease happens before numerous Mouse_Dragged events
// that results in not finished dragging
@ -197,83 +224,88 @@ public class MageActionCallback implements ActionCallback {
isDragging = false;
startedDragging = false;
prevCardPanel = null;
cardPanels.clear();
draggingCards.clear();
Point mouse = new Point(e.getX(), e.getY());
SwingUtilities.convertPointToScreen(mouse, data.getComponent());
initialMousePos = new Point((int) mouse.getX(), (int) mouse.getY());
initialCardPos = data.getComponent().getLocation();
initialCardPos = cardPanel.getCardLocation().getCardPoint();
// Closes popup & enlarged view if a card/Permanent is selected
hideTooltipPopup();
}
@Override
public void mouseReleased(MouseEvent e, TransferData transferData) {
CardPanel card = ((CardPanel) transferData.getComponent());
if (e.isPopupTrigger() /*&& card.getPopupMenu() != null*/) {
public void mouseReleased(MouseEvent e, TransferData data) {
MageCard cardPanel = data.getComponent().getTopPanelRef();
if (e.isPopupTrigger()) {
hideTooltipPopup();
} else if (card.getZone() != null && card.getZone().equalsIgnoreCase("hand")) {
} else if (cardPanel.getZone() == Zone.HAND) {
// drag end
int maxXOffset = 0;
if (isDragging) {
Point mouse = new Point(e.getX(), e.getY());
SwingUtilities.convertPointToScreen(mouse, transferData.getComponent());
SwingUtilities.convertPointToScreen(mouse, data.getComponent());
maxXOffset = Math.abs((int) (mouse.getX() - initialMousePos.x));
}
clearDragging(card);
clearDragging(cardPanel);
this.startedDragging = false;
if (maxXOffset < MIN_X_OFFSET_REQUIRED) { // we need this for protection from small card movements
transferData.getComponent().requestFocusInWindow();
DefaultActionCallback.instance.mouseClicked(transferData.getGameId(), transferData.getCard());
// default click simulation // TODO: replace to normal clicked events (change dialogs)
cardPanel.requestFocusInWindow();
DefaultActionCallback.instance.mouseClicked(data.getGameId(), data.getCard());
// Closes popup & enlarged view if a card/Permanent is selected
hideTooltipPopup();
}
e.consume();
} else {
transferData.getComponent().requestFocusInWindow();
DefaultActionCallback.instance.mouseClicked(transferData.getGameId(), transferData.getCard());
// default click simulation
cardPanel.requestFocusInWindow();
DefaultActionCallback.instance.mouseClicked(data.getGameId(), data.getCard());
// Closes popup & enlarged view if a card/Permanent is selected
hideTooltipPopup();
e.consume();
}
}
private void clearDragging(CardPanel card) {
if (this.startedDragging && prevCardPanel != null && card != null) {
for (Component component : card.getCardArea().getComponents()) {
if (component instanceof CardPanel) {
if (cardPanels.contains(component)) {
component.setLocation(component.getLocation().x, component.getLocation().y - GO_DOWN_ON_DRAG_Y_OFFSET);
private void clearDragging(MageCard clearCard) {
if (this.startedDragging && prevCardPanel != null && clearCard != null) {
// distribute cards between cards container and a drag container
for (Component comp : clearCard.getCardContainer().getComponents()) {
if (comp instanceof MageCard) {
MageCard realCard = (MageCard) comp;
if (draggingCards.contains(realCard)) {
realCard.setCardLocation(realCard.getCardLocation().getCardX(), realCard.getCardLocation().getCardY() - GO_DOWN_ON_DRAG_Y_OFFSET);
}
}
}
card.setLocation(card.getLocation().x, card.getLocation().y + GO_UP_ON_DRAG_Y_OFFSET);
sort(card, card.getCardArea(), true);
cardPanels.clear();
clearCard.setCardLocation(clearCard.getCardLocation().getCardX(), clearCard.getCardLocation().getCardY() + GO_UP_ON_DRAG_Y_OFFSET);
sortHandCards(clearCard, clearCard.getCardContainer(), true);
draggingCards.clear();
}
prevCardPanel = null;
}
@Override
public void mouseMoved(MouseEvent e, TransferData transferData) {
public void mouseMoved(MouseEvent e, TransferData data) {
if (!Plugins.instance.isCardPluginLoaded()) {
return;
}
if (!popupData.getCard().equals(transferData.getCard())) {
this.popupData = transferData;
handleOverNewView(transferData);
if (!popupData.getCard().equals(data.getCard())) {
this.popupData = data;
handleMouseMoveOverNewCard(data);
}
if (bigCard == null) {
return;
}
handlePopup(transferData);
updateCardHints(data);
}
@Override
public void mouseDragged(MouseEvent e, TransferData transferData) {
CardPanel cardPanel = ((CardPanel) transferData.getComponent());
if (cardPanel.getZone() == null || !cardPanel.getZone().equalsIgnoreCase("hand")) {
public void mouseDragged(MouseEvent e, TransferData data) {
// start the dragging
MageCard cardPanel = data.getComponent().getTopPanelRef();
if (cardPanel.getZone() != Zone.HAND) {
// drag'n'drop is allowed for HAND zone only
return;
}
@ -283,18 +315,19 @@ public class MageActionCallback implements ActionCallback {
}
isDragging = true;
prevCardPanel = cardPanel;
Point cardPanelLocationOld = cardPanel.getLocation();
Point cardPanelLocationOld = cardPanel.getCardLocation().getCardPoint();
Point mouse = new Point(e.getX(), e.getY());
SwingUtilities.convertPointToScreen(mouse, transferData.getComponent());
int xOffset = cardPanel.getXOffset(cardPanel.getCardWidth());
int newX = Math.max(initialCardPos.x + (int) (mouse.getX() - initialMousePos.x) - xOffset, 0);
SwingUtilities.convertPointToScreen(mouse, data.getComponent());
int xOffset = 0; // starting position
int newX = Math.max(initialCardPos.x + (int) (mouse.getX() - initialMousePos.x) - xOffset, 0); // TODO: fix
cardPanel.setCardBounds(
newX,
cardPanelLocationOld.y + cardPanel.getCardYOffset(),
cardPanel.getCardWidth(),
cardPanel.getCardHeight());
cardPanel.getCardArea().setComponentZOrder(cardPanel, 0);
sort(cardPanel, cardPanel.getCardArea(), false);
cardPanelLocationOld.y,
cardPanel.getCardLocation().getCardWidth(),
cardPanel.getCardLocation().getCardHeight());
cardPanel.getCardContainer().setComponentZOrder(cardPanel, 0);
sortHandCards(cardPanel, cardPanel.getCardContainer(), false);
if (!this.startedDragging) {
this.startedDragging = true;
@ -308,55 +341,106 @@ public class MageActionCallback implements ActionCallback {
} else {
hideAll(null);
}
///clearDragging((CardPanel)data.component);
///clearDragging((MageCard)data.component);
}
private void sort(CardPanel card, JPanel container, boolean sortSource) {
java.util.List<CardPanel> cards = new ArrayList<>();
for (Component component : container.getComponents()) {
if (component instanceof CardPanel) {
if (!component.equals(card)) {
if (!cardPanels.contains(component)) {
component.setLocation(component.getLocation().x, component.getLocation().y + GO_DOWN_ON_DRAG_Y_OFFSET);
@Override
public void popupMenuCard(MouseEvent e, TransferData data) {
// send popup menu request over card
if (e.isConsumed()) {
return;
}
e.consume();
if (data.getComponent().getCardContainer() instanceof CardEventProducer) {
CardEventProducer area = (CardEventProducer) data.getComponent().getCardContainer();
mage.client.util.Event clientEvent = new mage.client.util.Event(
data.getComponent().getOriginal(), ClientEventType.CARD_POPUP_MENU,
0, e.getX(), e.getY(), data.getComponent(), e, false
);
area.getCardEventSource().fireEvent(clientEvent);
}
}
@Override
public void popupMenuPanel(MouseEvent e, Component sourceComponent) {
// over non card component
if (e.isConsumed()) {
return;
}
e.consume();
if (sourceComponent instanceof CardEventProducer) {
CardEventProducer area = (CardEventProducer) sourceComponent;
// card param must be empty
mage.client.util.Event clientEvent = new mage.client.util.Event(
null, ClientEventType.CARD_POPUP_MENU,
0, e.getX(), e.getY(), e.getComponent(), e, false
);
area.getCardEventSource().fireEvent(clientEvent);
}
}
private void sortHandCards(MageCard card, Container container, boolean sortSource) {
java.util.List<MageCard> cards = new ArrayList<>();
// distribute cards between cards container and a drag container
for (Component comp : container.getComponents()) {
if (comp instanceof MageCard) {
MageCard realCard = (MageCard) comp;
if (!realCard.equals(card)) {
if (!draggingCards.contains(realCard)) {
realCard.setCardLocation(realCard.getCardLocation().getCardX(), realCard.getCardLocation().getCardY() + GO_DOWN_ON_DRAG_Y_OFFSET);
}
cardPanels.add((CardPanel) component);
draggingCards.add(realCard);
} else if (!startedDragging) {
component.setLocation(component.getLocation().x, component.getLocation().y - GO_UP_ON_DRAG_Y_OFFSET);
realCard.setCardLocation(realCard.getCardLocation().getCardX(), realCard.getCardLocation().getCardY() - GO_DOWN_ON_DRAG_Y_OFFSET);
}
cards.add((CardPanel) component);
cards.add(realCard);
}
}
sortLayout(cards, card, sortSource);
sortAndAnimateDraggingHandCards(cards, card, sortSource);
}
private void sortLayout(List<CardPanel> cards, CardPanel source, boolean includeSource) {
source.getLocation().x -= COMPARE_GAP_X; // this creates nice effect
private void sortAndAnimateDraggingHandCards(List<MageCard> cards, MageCard source, boolean includeSource) {
// special offset, allows to switch with first card
source.setCardLocation(source.getCardLocation().getCardX() - HAND_CARDS_COMPARE_GAP_X, source.getCardLocation().getCardY());
cards.sort(Comparator.comparingInt(cp -> cp.getLocation().x));
// sorting card components, so the effect above will be applied too
cards.sort(Comparator.comparingInt(cp -> cp.getCardLocation().getCardX()));
int dx = 0;
// WARNING, must be same sort code as Cards->layoutCards (if not then hand cards will be messed after drag)
int dx = MageActionCallback.getHandOrStackMargins(source.getZone()).getLeft(); // starting position
boolean createdGapForSource = false;
for (Component component : cards) {
for (MageCard component : cards) {
// use real component locations, not a card's
if (!includeSource) {
// create special hole between cards to put dragging card into it
if (!component.equals(source)) {
component.setLocation(dx, component.getLocation().y);
dx += ((CardPanel) component).getCardWidth() + GAP_X;
component.setCardLocation(dx, component.getCardLocation().getCardY());
dx += component.getCardLocation().getCardWidth() + MageActionCallback.getHandOrStackBetweenGapX(source.getZone());
// once dx is bigger than source's x position
// we need to create a gap for the source card
// but only once
if (!createdGapForSource && (dx + COMPARE_GAP_X) > source.getLocation().x) {
if (!createdGapForSource && (dx + HAND_CARDS_COMPARE_GAP_X) > source.getCardLocation().getCardX()) {
createdGapForSource = true;
dx += ((CardPanel) component).getCardWidth() + GAP_X;
int gapOffset = component.getCardLocation().getCardWidth() + MageActionCallback.getHandOrStackBetweenGapX(source.getZone());
dx += gapOffset;
// workaround to apply gap on the first card (if you drag over first card)
if (cards.get(0).equals(source) && cards.size() > 1 && cards.get(1).equals(component)) {
component.setCardLocation(component.getCardLocation().getCardX() + gapOffset, component.getCardLocation().getCardY());
}
}
}
} else {
component.setLocation(dx, component.getLocation().y);
dx += ((CardPanel) component).getCardWidth() + GAP_X;
component.setCardLocation(dx, component.getCardLocation().getCardY());
dx += component.getCardLocation().getCardWidth() + MageActionCallback.getHandOrStackBetweenGapX(source.getZone());
}
}
}
private void handleOverNewView(TransferData data) {
private void handleMouseMoveOverNewCard(TransferData data) {
MageCard cardPanel = data.getComponent().getTopPanelRef();
// Prevent to show tooltips from panes not in front
MagePane topPane = MageFrame.getTopMost(null);
if (topPane instanceof GamePane) {
@ -367,11 +451,11 @@ public class MageActionCallback implements ActionCallback {
hideTooltipPopup();
cancelTimeout();
Component parentComponent = SwingUtilities.getRoot(data.getComponent());
Component parentComponent = SwingUtilities.getRoot(cardPanel);
Point parentPoint = parentComponent.getLocationOnScreen();
if (data.getLocationOnScreen() == null) {
data.setLocationOnScreen(data.getComponent().getLocationOnScreen());
data.setLocationOnScreen(cardPanel.getCardLocationOnScreen().getCardPoint());
}
ArrowUtil.drawArrowsForTargets(data, parentPoint);
@ -381,22 +465,23 @@ public class MageActionCallback implements ActionCallback {
ArrowUtil.drawArrowsForEnchantPlayers(data, parentPoint);
tooltipCard = data.getCard();
showTooltipPopup(data, parentComponent, parentPoint);
startCardHintPopup(data, parentComponent, parentPoint);
}
private void handlePopup(TransferData transferData) {
MageCard mageCard = (MageCard) transferData.getComponent();
private void updateCardHints(TransferData data) {
MageCard cardPanel = data.getComponent().getTopPanelRef();
if (!popupTextWindowOpen
|| !Objects.equals(mageCard.getOriginal().getId(), bigCard.getCardId())) {
|| !Objects.equals(cardPanel.getOriginal().getId(), bigCard.getCardId())) {
if (bigCard.getWidth() > 0) {
synchronized (MageActionCallback.class) {
if (!popupTextWindowOpen || !Objects.equals(mageCard.getOriginal().getId(), bigCard.getCardId())) {
if (!popupTextWindowOpen || !Objects.equals(cardPanel.getOriginal().getId(), bigCard.getCardId())) {
if (!popupTextWindowOpen) {
bigCard.resetCardId();
}
popupTextWindowOpen = true;
Image image = mageCard.getImage();
displayCardInfo(mageCard, image, bigCard);
Image image = cardPanel.getImage();
displayCardInfo(cardPanel, image, bigCard);
}
}
} else {
@ -404,7 +489,7 @@ public class MageActionCallback implements ActionCallback {
}
if (enlargedWindowState != EnlargedWindowState.CLOSED) {
cancelTimeout();
displayEnlargedCard(mageCard.getOriginal(), transferData);
displayEnlargedCard(cardPanel.getOriginal(), data);
}
}
}
@ -419,9 +504,6 @@ public class MageActionCallback implements ActionCallback {
if (tooltipPopup != null) {
tooltipPopup.hide();
}
if (jPopupMenu != null) {
jPopupMenu.setVisible(false);
}
try {
if (SessionHandler.getSession() == null) {
return;
@ -429,7 +511,7 @@ public class MageActionCallback implements ActionCallback {
Component popupContainer = MageFrame.getUI().getComponent(MageComponents.POPUP_CONTAINER);
popupContainer.setVisible(false);
} catch (InterruptedException e) {
LOGGER.error("Can't hide card tooltip", e);
logger.error("Can't hide card tooltip", e);
Thread.currentThread().interrupt();
}
}
@ -456,22 +538,22 @@ public class MageActionCallback implements ActionCallback {
}
@Override
public void mouseWheelMoved(MouseWheelEvent e, TransferData transferData) {
public void mouseWheelMoved(MouseWheelEvent e, TransferData data) {
int notches = e.getWheelRotation();
if (enlargedWindowState != EnlargedWindowState.CLOSED) {
// same move direction will be ignored, opposite direction closes the enlarged window
if (enlargeredViewOpened != null && new Date().getTime() - enlargeredViewOpened.getTime() > 1000) {
// if the opening is back more than 1 seconds close anyway
hideEnlargedCard();
handleOverNewView(transferData);
handleMouseMoveOverNewCard(data);
} else if (enlargeMode == EnlargeMode.NORMAL) {
if (notches > 0) {
hideEnlargedCard();
handleOverNewView(transferData);
handleMouseMoveOverNewCard(data);
}
} else if (notches < 0) {
hideEnlargedCard();
handleOverNewView(transferData);
handleMouseMoveOverNewCard(data);
}
return;
}
@ -526,11 +608,13 @@ public class MageActionCallback implements ActionCallback {
}
} catch (InterruptedException e) {
LOGGER.warn("Can't hide enlarged card", e);
logger.warn("Can't hide enlarged card", e);
}
}
private void displayEnlargedCard(final CardView cardView, final TransferData transferData) {
private void displayEnlargedCard(final CardView cardView, final TransferData data) {
MageCard cardPanel = data.getComponent().getTopPanelRef();
ThreadUtils.threadPool3.submit(() -> {
if (cardView == null) {
return;
@ -539,7 +623,7 @@ public class MageActionCallback implements ActionCallback {
if (enlargedWindowState == EnlargedWindowState.CLOSED) {
return;
}
MageComponents mageComponentCardPreviewContainer;
MageComponents mageComponentCardPreviewPane;
if (cardView.isToRotate()) {
@ -559,17 +643,16 @@ public class MageActionCallback implements ActionCallback {
}
final Component popupContainer = MageFrame.getUI().getComponent(mageComponentCardPreviewContainer);
Component cardPreviewPane = MageFrame.getUI().getComponent(mageComponentCardPreviewPane);
Component parentComponent = SwingUtilities.getRoot(transferData.getComponent());
Component parentComponent = SwingUtilities.getRoot(cardPanel);
if (cardPreviewPane != null && parentComponent != null) {
Point parentPoint = parentComponent.getLocationOnScreen();
transferData.setLocationOnScreen(transferData.getComponent().getLocationOnScreen());
Point location = new Point((int) transferData.getLocationOnScreen().getX() + transferData.getPopupOffsetX() - 40, (int) transferData.getLocationOnScreen().getY() + transferData.getPopupOffsetY() - 40);
data.setLocationOnScreen(cardPanel.getCardLocationOnScreen().getCardPoint());
Point location = new Point((int) data.getLocationOnScreen().getX() + data.getPopupOffsetX() - 40, (int) data.getLocationOnScreen().getY() + data.getPopupOffsetY() - 40);
location = GuiDisplayUtil.keepComponentInsideParent(location, parentPoint, cardPreviewPane, parentComponent);
location.translate(-parentPoint.x, -parentPoint.y);
popupContainer.setLocation(location);
popupContainer.setVisible(true);
MageCard mageCard = (MageCard) transferData.getComponent();
Image image = null;
switch (enlargeMode) {
case COPY:
@ -593,17 +676,17 @@ public class MageActionCallback implements ActionCallback {
break;
}
if (image == null) {
image = mageCard.getImage();
image = cardPanel.getImage();
}
// shows the card in the popup Container
displayCardInfo(mageCard, image, (BigCard) cardPreviewPane);
displayCardInfo(cardPanel, image, (BigCard) cardPreviewPane);
} else {
LOGGER.warn("No Card preview Pane in Mage Frame defined. Card: " + cardView.getName());
logger.warn("No Card preview Pane in Mage Frame defined. Card: " + cardView.getName());
}
} catch (Exception e) {
LOGGER.warn("Problem dring display of enlarged card", e);
logger.warn("Problem dring display of enlarged card", e);
}
});
}
@ -641,4 +724,20 @@ public class MageActionCallback implements ActionCallback {
hideTimeout.cancel(false);
}
}
public static MageCardSpace getHandOrStackMargins(Zone zone) {
if (zone == Zone.HAND) {
return HAND_CARDS_MARGINS;
} else {
return STACK_CARDS_MARGINS;
}
}
public static int getHandOrStackBetweenGapX(Zone zone) {
if (zone == Zone.HAND) {
return HAND_CARDS_BETWEEN_GAP_X;
} else {
return STACK_CARDS_BETWEEN_GAP_X;
}
}
}

View file

@ -1,16 +1,13 @@
package mage.client.plugins.impl;
import mage.abilities.icon.CardIconRenderSettings;
import mage.cards.MageCard;
import mage.cards.MagePermanent;
import mage.cards.action.ActionCallback;
import mage.client.MageFrame;
import mage.client.cards.BigCard;
import mage.client.cards.Card;
import mage.client.cards.Permanent;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.MagePlugins;
import mage.client.plugins.adapters.MageActionCallback;
import mage.client.util.ClientDefaultSettings;
import mage.interfaces.PluginException;
import mage.interfaces.plugin.CardPlugin;
import mage.interfaces.plugin.CounterPlugin;
@ -21,6 +18,7 @@ import net.xeoh.plugins.base.PluginManager;
import net.xeoh.plugins.base.impl.PluginManagerFactory;
import net.xeoh.plugins.base.util.uri.ClassURI;
import org.apache.log4j.Logger;
import org.mage.card.arcane.MageLayer;
import org.mage.plugins.card.CardPluginImpl;
import org.mage.plugins.theme.ThemePluginImpl;
@ -42,7 +40,7 @@ public enum Plugins implements MagePlugins {
private static PluginManager pm;
private ThemePlugin themePlugin = null;
private CardPlugin cardPlugin = null;
private CardPlugin cardPlugin = null; // required by game
private CounterPlugin counterPlugin = null;
private static final MageActionCallback mageActionCallback = new MageActionCallback();
private final Map<String, String> sortingOptions = new HashMap<>();
@ -93,27 +91,39 @@ public enum Plugins implements MagePlugins {
}
@Override
public MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, int renderMode, boolean needFullPermanentRender) {
public MageCard getMagePermanent(PermanentView card, BigCard bigCard, CardIconRenderSettings cardIconRenderSettings, Dimension dimension, UUID gameId, boolean loadImage, int renderMode, boolean needFullPermanentRender) {
MageCard mageCard;
if (cardPlugin != null) {
mageActionCallback.refreshSession();
mageActionCallback.setCardPreviewComponent(bigCard);
return cardPlugin.getMagePermanent(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage, renderMode, needFullPermanentRender);
mageCard = cardPlugin.getMagePermanent(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage, renderMode, needFullPermanentRender);
} else {
return new Permanent(card, bigCard, ClientDefaultSettings.dimensions, gameId);
throw new IllegalArgumentException("Card's plugin must be loaded");
}
return createLayeredCard(mageCard, dimension, cardIconRenderSettings);
}
@Override
public MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable, int renderMode, boolean needFullPermanentRender) {
public MageCard getMageCard(CardView card, BigCard bigCard, CardIconRenderSettings cardIconRenderSettings, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable, int renderMode, boolean needFullPermanentRender) {
// Card icons panels must be put outside of the card like MTG Arena.
// So for compatibility purposes: keep free space for icons and change card dimention
MageCard mageCard;
if (cardPlugin != null) {
if (previewable) {
mageActionCallback.refreshSession();
mageActionCallback.setCardPreviewComponent(bigCard);
}
return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage, renderMode, needFullPermanentRender);
mageCard = cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage, renderMode, needFullPermanentRender);
} else {
return new Card(card, bigCard, ClientDefaultSettings.dimensions, gameId);
throw new IllegalArgumentException("Card's plugin must be loaded");
}
return createLayeredCard(mageCard, dimension, cardIconRenderSettings);
}
private MageCard createLayeredCard(MageCard mageCard, Dimension dimension, CardIconRenderSettings cardIconRenderSettings) {
MageLayer mageLayer = new MageLayer(mageCard, cardIconRenderSettings);
mageLayer.setCardBounds(0, 0, dimension.width, dimension.height); // default size
return mageLayer;
}
@Override
@ -122,9 +132,9 @@ public enum Plugins implements MagePlugins {
}
@Override
public int sortPermanents(Map<String, JComponent> ui, Map<UUID, MagePermanent> permanents, boolean topRow) {
public int sortPermanents(Map<String, JComponent> ui, Map<UUID, MageCard> cards, boolean topRow) {
if (this.cardPlugin != null) {
return this.cardPlugin.sortPermanents(ui, permanents, PreferencesDialog.getCachedValue("nonLandPermanentsInOnePile", "false").equals("true"), topRow);
return this.cardPlugin.sortPermanents(ui, cards, PreferencesDialog.getCachedValue("nonLandPermanentsInOnePile", "false").equals("true"), topRow);
}
return -1;
}
@ -176,14 +186,14 @@ public enum Plugins implements MagePlugins {
}
@Override
public void onAddCard(MagePermanent card, int count) {
public void onAddCard(MageCard card, int count) {
if (this.cardPlugin != null) {
this.cardPlugin.onAddCard(card, count);
}
}
@Override
public void onRemoveCard(MagePermanent card, int count) {
public void onRemoveCard(MageCard card, int count) {
if (this.cardPlugin != null) {
this.cardPlugin.onRemoveCard(card, count);
}

View file

@ -49,31 +49,41 @@ public class CallbackClientImpl implements CallbackClient {
try {
logger.debug(callback.getMessageId() + " -- " + callback.getMethod());
switch (callback.getMethod()) {
case START_GAME: {
TableClientMessage message = (TableClientMessage) callback.getData();
GameManager.instance.setCurrentPlayerUUID(message.getPlayerId());
gameStarted(message.getGameId(), message.getPlayerId());
break;
}
case START_TOURNAMENT: {
TableClientMessage message = (TableClientMessage) callback.getData();
tournamentStarted(message.getGameId(), message.getPlayerId());
break;
}
case START_DRAFT: {
TableClientMessage message = (TableClientMessage) callback.getData();
draftStarted(message.getGameId(), message.getPlayerId());
break;
}
case REPLAY_GAME:
case REPLAY_GAME: {
replayGame(callback.getObjectId());
break;
case SHOW_TOURNAMENT:
}
case SHOW_TOURNAMENT: {
showTournament(callback.getObjectId());
break;
case WATCHGAME:
}
case WATCHGAME: {
watchGame(callback.getObjectId());
break;
}
case CHATMESSAGE: {
ChatMessage message = (ChatMessage) callback.getData();
// Drop messages from ignored users
@ -117,7 +127,8 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case SERVER_MESSAGE:
case SERVER_MESSAGE: {
if (callback.getData() != null) {
ChatMessage message = (ChatMessage) callback.getData();
if (message.getColor() == ChatMessage.MessageColor.RED) {
@ -127,11 +138,14 @@ public class CallbackClientImpl implements CallbackClient {
}
}
break;
}
case JOINED_TABLE: {
TableClientMessage message = (TableClientMessage) callback.getData();
joinedTable(message.getRoomId(), message.getTableId(), message.getFlag());
break;
}
case REPLAY_INIT: {
GamePanel panel = MageFrame.getGame(callback.getObjectId());
if (panel != null) {
@ -139,6 +153,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case REPLAY_DONE: {
GamePanel panel = MageFrame.getGame(callback.getObjectId());
if (panel != null) {
@ -146,6 +161,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case REPLAY_UPDATE: {
GamePanel panel = MageFrame.getGame(callback.getObjectId());
if (panel != null) {
@ -153,6 +169,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_INIT: {
GamePanel panel = MageFrame.getGame(callback.getObjectId());
if (panel != null) {
@ -161,6 +178,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_OVER: {
GamePanel panel = MageFrame.getGame(callback.getObjectId());
if (panel != null) {
@ -175,9 +193,12 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_ERROR:
case GAME_ERROR: {
frame.showErrorDialog("Game Error", (String) callback.getData());
break;
}
case GAME_ASK: {
GameClientMessage message = (GameClientMessage) callback.getData();
GamePanel panel = MageFrame.getGame(callback.getObjectId());
@ -187,6 +208,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_TARGET: // e.g. Pick triggered ability
{
GameClientMessage message = (GameClientMessage) callback.getData();
@ -199,6 +221,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_SELECT: {
GameClientMessage message = (GameClientMessage) callback.getData();
@ -209,6 +232,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_CHOOSE_ABILITY: {
GamePanel panel = MageFrame.getGame(callback.getObjectId());
if (panel != null) {
@ -217,6 +241,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_CHOOSE_PILE: {
GameClientMessage message = (GameClientMessage) callback.getData();
GamePanel panel = MageFrame.getGame(callback.getObjectId());
@ -226,6 +251,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_CHOOSE_CHOICE: {
GameClientMessage message = (GameClientMessage) callback.getData();
@ -237,6 +263,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_PLAY_MANA: {
GameClientMessage message = (GameClientMessage) callback.getData();
GamePanel panel = MageFrame.getGame(callback.getObjectId());
@ -246,6 +273,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_PLAY_XMANA: {
GameClientMessage message = (GameClientMessage) callback.getData();
@ -256,6 +284,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_GET_AMOUNT: {
GameClientMessage message = (GameClientMessage) callback.getData();
@ -267,6 +296,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case GAME_UPDATE: {
GamePanel panel = MageFrame.getGame(callback.getObjectId());
@ -277,17 +307,31 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case END_GAME_INFO:
MageFrame.getInstance().showGameEndDialog((GameEndView) callback.getData());
case GAME_REDRAW_GUI: {
// re-draw game's gui elements like attack arrows
// uses for client side only (example: update after scrollbars support)
GamePanel panel = MageFrame.getGame(callback.getObjectId());
if (panel != null) {
panel.updateGame();
}
break;
case SHOW_USERMESSAGE:
}
case END_GAME_INFO: {
MageFrame.getInstance().showGameEndDialog((GameEndView) callback.getData());
break;
}
case SHOW_USERMESSAGE: {
List<String> messageData = (List<String>) callback.getData();
if (messageData.size() == 2) {
JOptionPane.showMessageDialog(null, messageData.get(1), messageData.get(0), JOptionPane.WARNING_MESSAGE);
}
break;
case GAME_INFORM:
}
case GAME_INFORM: {
if (callback.getMessageId() > gameInformMessageId) {
{
GameClientMessage message = (GameClientMessage) callback.getData();
@ -297,13 +341,14 @@ public class CallbackClientImpl implements CallbackClient {
panel.inform(message.getMessage(), message.getGameView(), callback.getMessageId());
}
}
// no longer needed because phase skip handling on server side now
// no longer needed because phase skip handling on server side now
} else {
logger.warn(new StringBuilder("message out of sequence - ignoring").append("MessageId = ").append(callback.getMessageId()).append(" method = ").append(callback.getMethod()));
//logger.warn("message out of sequence - ignoring");
}
gameInformMessageId = messageId;
break;
}
case GAME_INFORM_PERSONAL: {
GameClientMessage message = (GameClientMessage) callback.getData();
GamePanel panel = MageFrame.getGame(callback.getObjectId());
@ -313,6 +358,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case SIDEBOARD: {
TableClientMessage message = (TableClientMessage) callback.getData();
DeckView deckView = message.getDeck();
@ -324,6 +370,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case VIEW_LIMITED_DECK: {
TableClientMessage message = (TableClientMessage) callback.getData();
DeckView deckView = message.getDeck();
@ -331,6 +378,7 @@ public class CallbackClientImpl implements CallbackClient {
viewLimitedDeck(deck, message.getTableId(), message.getTime());
break;
}
case CONSTRUCT: {
TableClientMessage message = (TableClientMessage) callback.getData();
DeckView deckView = message.getDeck();
@ -338,9 +386,13 @@ public class CallbackClientImpl implements CallbackClient {
construct(deck, message.getTableId(), message.getTime());
break;
}
case DRAFT_OVER:
case DRAFT_OVER: {
MageFrame.removeDraft(callback.getObjectId());
break;
}
case DRAFT_INIT:
case DRAFT_PICK: {
DraftClientMessage message = (DraftClientMessage) callback.getData();
DraftPanel panel = MageFrame.getDraft(callback.getObjectId());
@ -349,6 +401,7 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case DRAFT_UPDATE: {
DraftPanel panel = MageFrame.getDraft(callback.getObjectId());
DraftClientMessage message = (DraftClientMessage) callback.getData();
@ -357,23 +410,25 @@ public class CallbackClientImpl implements CallbackClient {
}
break;
}
case DRAFT_INIT: {
DraftClientMessage message = (DraftClientMessage) callback.getData();
DraftPanel panel = MageFrame.getDraft(callback.getObjectId());
if (panel != null) {
panel.loadBooster(message.getDraftPickView());
}
case TOURNAMENT_INIT: {
break;
}
case TOURNAMENT_INIT:
break;
case USER_REQUEST_DIALOG:
case USER_REQUEST_DIALOG: {
frame.showUserRequestDialog((UserRequestMessage) callback.getData());
break;
default:
}
default: {
break;
}
}
// sync message for server side events only
if (!callback.getMethod().isClientSideMessage()) {
messageId = callback.getMessageId();
}
messageId = callback.getMessageId();
} catch (Exception ex) {
handleException(ex);
}
@ -551,6 +606,10 @@ public class CallbackClientImpl implements CallbackClient {
private void handleException(Exception ex) {
logger.fatal("Client error\n", ex);
frame.showError("Error: " + ex.getMessage());
String errorMessage = ex.getMessage();
if (errorMessage == null || errorMessage.isEmpty() || errorMessage.equals("Null")) {
errorMessage = ex.getClass().getSimpleName() + " - look server logs for more details";
}
frame.showError("Server's error: " + errorMessage);
}
}

View file

@ -1,11 +1,3 @@
/*
* TablePlayerPanel.java
*
* Created on 9-May-2010, 11:43:03 AM
*/
package mage.client.table;
import mage.cards.decks.importer.DeckImporter;

View file

@ -1,11 +1,3 @@
/*
* TournamentPlayerPanel.java
*
* Created on Jan 28, 2011, 1:50:29 PM
*/
package mage.client.table;
import mage.cards.decks.DeckCardLists;

View file

@ -1,7 +1,13 @@
package mage.client.themes;
import mage.abilities.hint.HintUtils;
import org.mage.card.arcane.SvgUtils;
import java.awt.*;
/**
* @author 18ths, JayDi85
*/
public enum ThemeType {
// https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/_nimbusDefaults.html
DEFAULT("Default",
@ -21,7 +27,11 @@ public enum ThemeType {
null, // mageToolbar
new Color(200, 200, 180, 200), // playerPanel_inactiveBackgroundColor
new Color(200, 255, 200, 200), // playerPanel_activeBackgroundColor
new Color(131, 94, 83, 200) // playerPanel_deadBackgroundColor
new Color(131, 94, 83, 200), // playerPanel_deadBackgroundColor
// card icons
new Color(169, 176, 190),
Color.black,
new Color(51, 98, 140)
),
GREY("Grey",
"grey-theme/",
@ -40,7 +50,11 @@ public enum ThemeType {
null, // mageToolbar
new Color(172, 172, 172, 200), // playerPanel_inactiveBackgroundColor
new Color(180, 234, 180, 200), // playerPanel_activeBackgroundColor
new Color(99, 99, 99, 200) // playerPanel_deadBackgroundColor
new Color(99, 99, 99, 200), // playerPanel_deadBackgroundColor
// card icons
new Color(158, 158, 158),
Color.black,
Color.black
),
SUNSET_VAPORWAVE("Vaporwave Sunset",
"16bit-theme/",
@ -59,6 +73,10 @@ public enum ThemeType {
new Color(192, 166, 232),
new Color(243, 233, 164),
new Color(204, 236, 201),
new Color(106, 0, 255),
// card icons
new Color(246, 136, 158),
Color.black,
new Color(106, 0, 255)
),
COFFEE("Coffee",
@ -78,7 +96,11 @@ public enum ThemeType {
new Color(219, 193, 172), // mageToolbar
new Color(219, 193, 172),
new Color(204, 236, 201),
new Color(99, 72, 50, 255)
new Color(99, 72, 50, 255),
// card icons
new Color(219, 193, 172),
Color.black,
new Color(97, 27, 0)
),
ISLAND("Island",
"island-theme/",
@ -97,7 +119,11 @@ public enum ThemeType {
new Color(172, 195, 219), // mageToolbar
new Color(172, 195, 219),
new Color(204, 236, 201),
new Color(50, 68, 99, 255)
new Color(50, 68, 99, 255),
// card icons
new Color(172, 197, 219),
Color.black,
new Color(0, 78, 97)
);
private final String name;
@ -118,6 +144,10 @@ public enum ThemeType {
private final Color playerPanel_inactiveBackgroundColor;
private final Color playerPanel_activeBackgroundColor;
private final Color playerPanel_deadBackgroundColor;
// card icons settings (example: flying icon)
private final Color cardIconsFillColor;
private final Color cardIconsStrokeColor;
private final Color cardIconsTextColor;
ThemeType(String name,
String path,
@ -136,7 +166,10 @@ public enum ThemeType {
Color mageToolbar,
Color playerPanel_inactiveBackgroundColor,
Color playerPanel_activeBackgroundColor,
Color playerPanel_deadBackgroundColor
Color playerPanel_deadBackgroundColor,
Color cardIconsFillColor,
Color cardIconsStrokeColor,
Color cardIconsTextColor
) {
this.name = name;
this.path = path;
@ -156,6 +189,9 @@ public enum ThemeType {
this.playerPanel_activeBackgroundColor = playerPanel_activeBackgroundColor;
this.playerPanel_deadBackgroundColor = playerPanel_deadBackgroundColor;
this.playerPanel_inactiveBackgroundColor = playerPanel_inactiveBackgroundColor;
this.cardIconsFillColor = cardIconsFillColor;
this.cardIconsStrokeColor = cardIconsStrokeColor;
this.cardIconsTextColor = cardIconsTextColor;
}
@Override
@ -267,4 +303,46 @@ public enum ThemeType {
return getBackgroundPath();
}
}
public Color getCardIconsFillColor() {
return this.cardIconsFillColor;
}
public Color getCardIconsStrokeColor() {
return cardIconsStrokeColor;
}
public Color getCardIconsTextColor() {
return cardIconsTextColor;
}
public String getCardIconsResourcePath(String resourceName) {
return "/card/icons/" + resourceName;
}
public String getCardIconsCssFile() {
return "card-icons-svg-settings.css";
}
public String getCardIconsCssSettings() {
String fillColorVal = HintUtils.colorToHtml(this.getCardIconsFillColor());
String strokeColorVal = HintUtils.colorToHtml(this.getCardIconsStrokeColor());
return String.format(""
+ "fill: %s;"
+ "stroke: %s;"
+ "stroke-width: 0.5;" // px
+ "stroke-opacity: 0.7;", // 1 = 100%
fillColorVal,
strokeColorVal
);
}
/**
* Prepare theme settings and files before using. Call it on app loading or after theme changed
*/
public void reload() {
// reload card icons css file (run it all the time, even on svg unsupport mode)
SvgUtils.prepareCss(this.getCardIconsCssFile(), this.getCardIconsCssSettings(), true);
}
}

View file

@ -1,10 +1,3 @@
/*
* TournamentPane.java
*
* Created on 22-Jan-2011, 11:41:47 PM
*/
package mage.client.tournament;
import java.util.UUID;

View file

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JInternalFrameFormInfo">
<Properties>
<Property name="resizable" type="boolean" value="true"/>
<Property name="title" type="java.lang.String" value="Combat"/>
<Property name="normalBounds" type="java.awt.Rectangle" editor="org.netbeans.beaninfo.editors.RectangleEditor">
<Rectangle value="[400, 200, 410, 307]"/>
</Property>
<Property name="visible" type="boolean" value="true"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,2,11,0,0,0,-33"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
<BorderConstraints direction="Center"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="combatArea">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View file

@ -1,127 +0,0 @@
/*
* COMBAT.java
*
* Created on Feb 10, 2010, 3:35:02 PM
*/
//package mage.client.dialog;
package mage.client.unusedFiles;
import mage.client.cards.BigCard;
import mage.view.CombatGroupView;
import javax.swing.*;
import java.awt.*;
import java.beans.PropertyVetoException;
import java.util.List;
import java.util.UUID;
import mage.client.dialog.MageDialog;
import org.apache.log4j.Logger;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class CombatDialog extends MageDialog {
private static final Logger logger = Logger.getLogger(CombatDialog.class);
private UUID gameId;
private BigCard bigCard;
private int lastX = 500;
private int lastY = 300;
/** Creates new form COMBAT */
public CombatDialog() {
JPanel contentPane = new JPanel() {
private static final long serialVersionUID = -8283955788355547309L;
@Override
public void paintComponent(Graphics g) {
g.setColor(new Color(50, 50, 50, 100));
g.fillRect(0, 0, getWidth(), getHeight());
}
};
setContentPane(contentPane);
initComponents();
this.setModal(false);
combatArea.setOpaque(false);
jScrollPane1.setOpaque(false);
jScrollPane1.getViewport().setOpaque(false);
getRootPane().setOpaque(false);
//setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE);
}
public void init(UUID gameId, BigCard bigCard) {
this.gameId = gameId;
this.bigCard = bigCard;
}
public void showDialog(List<CombatGroupView> combat) {
combatArea.removeAll();
for (CombatGroupView group: combat) {
CombatGroup combatGroup = new CombatGroup();
combatGroup.init(gameId, bigCard);
combatGroup.update(group);
combatGroup.setVisible(true);
combatArea.add(combatGroup);
combatGroup.revalidate();
}
try {
this.setSelected(true);
} catch (PropertyVetoException ex) {
logger.error(null, ex);
}
pack();
this.revalidate();
this.repaint();
if (!this.isVisible()) {
this.setVisible(true);
this.setLocation(lastX, lastY);
}
}
@Override
public void hideDialog() {
this.lastX = this.getX();
this.lastY = this.getY();
super.hideDialog();
}
/** 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.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
combatArea = new javax.swing.JPanel();
setResizable(true);
setTitle("Combat");
setNormalBounds(new java.awt.Rectangle(400, 200, 410, 307));
setVisible(true);
getContentPane().setLayout(new java.awt.BorderLayout());
jScrollPane1.setViewportView(combatArea);
getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);
pack();
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel combatArea;
private javax.swing.JScrollPane jScrollPane1;
// End of variables declaration//GEN-END:variables
}

View file

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lblDefender" alignment="0" pref="69" max="32767" attributes="0"/>
<Component id="blockers" alignment="0" min="-2" max="-2" attributes="2"/>
<Component id="attackers" alignment="0" min="-2" max="-2" attributes="2"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="lblDefender" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="blockers" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="attackers" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="mage.client.cards.Cards" name="blockers">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new java.awt.Dimension(Config.dimensions.frameWidth + 8, Config.dimensions.frameHeight + 25)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="mage.client.cards.Cards" name="attackers">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="new java.awt.Dimension(Config.dimensions.frameWidth + 8, Config.dimensions.frameHeight + 25)" type="code"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblDefender">
<Properties>
<Property name="horizontalAlignment" type="int" value="0"/>
<Property name="text" type="java.lang.String" value="Defender"/>
</Properties>
</Component>
</SubComponents>
</Form>

View file

@ -1,96 +0,0 @@
/*
* CombatGroup.java
*
* Created on Feb 10, 2010, 3:36:55 PM
*/
package mage.client.unusedFiles;
//package mage.client.game;
import java.util.UUID;
import mage.client.cards.BigCard;
import mage.client.util.ClientDefaultSettings;
import mage.client.util.GUISizeHelper;
import mage.view.CombatGroupView;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class CombatGroup extends javax.swing.JPanel {
private UUID gameId;
private BigCard bigCard;
/**
* Creates new form CombatGroup
*/
public CombatGroup() {
initComponents();
attackers.setDontDisplayTapped(true);
}
public void init(UUID gameId, BigCard bigCard) {
this.gameId = gameId;
this.bigCard = bigCard;
}
public void update(CombatGroupView combatGroup) {
this.lblDefender.setText(combatGroup.getDefenderName());
attackers.setCardDimension(GUISizeHelper.otherZonesCardDimension);
this.attackers.loadCards(combatGroup.getAttackers(), bigCard, gameId, true);
blockers.setCardDimension(GUISizeHelper.otherZonesCardDimension);
this.blockers.loadCards(combatGroup.getBlockers(), bigCard, gameId, true);
this.attackers.setVisible(true);
this.blockers.setVisible(true);
}
/**
* 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.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
blockers = new mage.client.cards.Cards();
attackers = new mage.client.cards.Cards();
lblDefender = new javax.swing.JLabel();
blockers.setPreferredSize(new java.awt.Dimension(ClientDefaultSettings.dimensions.getFrameWidth() + 8, ClientDefaultSettings.dimensions.getFrameHeight() + 25));
attackers.setPreferredSize(new java.awt.Dimension(ClientDefaultSettings.dimensions.getFrameWidth() + 8, ClientDefaultSettings.dimensions.getFrameHeight() + 25));
lblDefender.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblDefender.setText("Defender");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblDefender, javax.swing.GroupLayout.DEFAULT_SIZE, 69, Short.MAX_VALUE)
.addComponent(blockers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(attackers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(lblDefender)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(blockers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(attackers, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private mage.client.cards.Cards attackers;
private mage.client.cards.Cards blockers;
private javax.swing.JLabel lblDefender;
// End of variables declaration//GEN-END:variables
}

View file

@ -1,57 +0,0 @@
package mage.client.unusedFiles;
//package mage.client.thread;
import java.awt.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class DelayedViewerThread extends Thread {
private static final DelayedViewerThread instance = new DelayedViewerThread();
public static DelayedViewerThread getInstance() {
return instance;
}
private final Map<Component, Long> delayedViewers;
protected DelayedViewerThread() {
delayedViewers = new HashMap<>();
start();
}
public synchronized void show(Component component, long delay) {
delayedViewers.put(component, System.currentTimeMillis() + delay);
notifyAll();
}
public synchronized void hide(Component component) {
delayedViewers.remove(component);
component.setVisible(false);
}
@Override
public synchronized void run() {
while (true) {
try {
if (delayedViewers.isEmpty()) {
wait();
}
final long time = System.currentTimeMillis();
for (Iterator<Component> it = delayedViewers.keySet().iterator(); it.hasNext();) {
Component component = it.next();
final long delayedTime = delayedViewers.get(component);
if (delayedTime <= time) {
component.setVisible(true);
it.remove();
}
}
wait(100);
} catch (final InterruptedException ex) {
System.out.println("Interrupted : " + ex.getMessage());
}
}
}
}

View file

@ -1,156 +0,0 @@
<?xml version="1.1" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="name" type="java.lang.String" value="Form" noResource="true"/>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lblLife" alignment="1" pref="42" max="32767" attributes="1"/>
<Component id="lblGrave" alignment="0" pref="42" max="32767" attributes="0"/>
<Component id="lblHand" alignment="0" pref="42" max="32767" attributes="0"/>
<Component id="lblLibrary" alignment="0" pref="42" max="32767" attributes="1"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="txtLife" alignment="1" pref="48" max="32767" attributes="2"/>
<Component id="txtLibrary" alignment="1" pref="48" max="32767" attributes="2"/>
<Component id="txtHand" alignment="1" pref="48" max="32767" attributes="2"/>
<Component id="btnGrave" alignment="1" pref="48" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Component id="btnPlayerName" alignment="0" pref="116" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="btnPlayerName" min="-2" pref="26" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="txtLife" min="-2" pref="14" max="-2" attributes="1"/>
<Component id="lblLife" alignment="1" min="-2" pref="14" max="-2" attributes="1"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="txtLibrary" min="-2" pref="14" max="-2" attributes="1"/>
<Component id="lblLibrary" alignment="1" max="32767" attributes="1"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="txtHand" pref="14" max="32767" attributes="1"/>
<Component id="lblHand" min="-2" max="-2" attributes="1"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="lblGrave" min="-2" max="-2" attributes="1"/>
<Component id="btnGrave" min="-2" pref="18" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="btnPlayerName">
<Properties>
<Property name="text" type="java.lang.String" value="Player Name" noResource="true"/>
<Property name="name" type="java.lang.String" value="btnPlayerName" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnPlayerNameActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lblLife">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtLife"/>
</Property>
<Property name="text" type="java.lang.String" value="Life:" noResource="true"/>
<Property name="name" type="java.lang.String" value="lblLife" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblLibrary">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtLibrary"/>
</Property>
<Property name="text" type="java.lang.String" value="Library:" noResource="true"/>
<Property name="name" type="java.lang.String" value="lblLibrary" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblHand">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="txtHand"/>
</Property>
<Property name="text" type="java.lang.String" value="Hand:" noResource="true"/>
<Property name="name" type="java.lang.String" value="lblHand" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="txtLife">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
<LineBorder/>
</Border>
</Property>
<Property name="name" type="java.lang.String" value="txtLife" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="txtLibrary">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
<LineBorder/>
</Border>
</Property>
<Property name="name" type="java.lang.String" value="txtLibrary" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="txtHand">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
<LineBorder/>
</Border>
</Property>
<Property name="name" type="java.lang.String" value="txtHand" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lblGrave">
<Properties>
<Property name="labelFor" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="btnGrave"/>
</Property>
<Property name="text" type="java.lang.String" value="Grave:" noResource="true"/>
<Property name="name" type="java.lang.String" value="lblGrave" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="btnGrave">
<Properties>
<Property name="name" type="java.lang.String" value="btnGrave" noResource="true"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnGraveActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>

View file

@ -1,181 +0,0 @@
/*
* PlayerPanel.java
*
* Created on Nov 18, 2009, 3:01:31 PM
*/
package mage.client.unusedFiles;
//package mage.client.game;
import java.awt.Color;
import java.util.UUID;
import mage.client.SessionHandler;
import mage.client.cards.BigCard;
import mage.client.dialog.ShowCardsDialog;
import mage.view.PlayerView;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class PlayerPanel extends javax.swing.JPanel {
private UUID playerId;
private UUID gameId;
private PlayerView player;
private ShowCardsDialog graveyard;
private BigCard bigCard;
/**
* Creates new form PlayerPanel
*/
public PlayerPanel() {
initComponents();
}
public void init(UUID gameId, UUID playerId, BigCard bigCard) {
this.gameId = gameId;
this.playerId = playerId;
this.bigCard = bigCard;
}
public void update(PlayerView player) {
this.player = player;
this.txtLife.setText(Integer.toString(player.getLife()));
this.txtHand.setText(Integer.toString(player.getHandCount()));
this.txtLibrary.setText(Integer.toString(player.getLibraryCount()));
this.btnGrave.setText(Integer.toString(player.getGraveyard().size()));
this.btnPlayerName.setText(player.getName());
if (player.isActive()) {
this.btnPlayerName.setBackground(Color.DARK_GRAY);
} else if (player.hasLeft()) {
this.btnPlayerName.setBackground(Color.RED);
} else {
this.btnPlayerName.setBackground(Color.LIGHT_GRAY);
}
}
/**
* 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.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
btnPlayerName = new javax.swing.JButton();
lblLife = new javax.swing.JLabel();
lblLibrary = new javax.swing.JLabel();
lblHand = new javax.swing.JLabel();
txtLife = new javax.swing.JLabel();
txtLibrary = new javax.swing.JLabel();
txtHand = new javax.swing.JLabel();
lblGrave = new javax.swing.JLabel();
btnGrave = new javax.swing.JButton();
setName("Form"); // NOI18N
btnPlayerName.setText("Player Name"); // NOI18N
btnPlayerName.setName("btnPlayerName"); // NOI18N
btnPlayerName.addActionListener(evt -> btnPlayerNameActionPerformed(evt));
lblLife.setLabelFor(txtLife);
lblLife.setText("Life:"); // NOI18N
lblLife.setName("lblLife"); // NOI18N
lblLibrary.setLabelFor(txtLibrary);
lblLibrary.setText("Library:"); // NOI18N
lblLibrary.setName("lblLibrary"); // NOI18N
lblHand.setLabelFor(txtHand);
lblHand.setText("Hand:"); // NOI18N
lblHand.setName("lblHand"); // NOI18N
txtLife.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
txtLife.setName("txtLife"); // NOI18N
txtLibrary.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
txtLibrary.setName("txtLibrary"); // NOI18N
txtHand.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
txtHand.setName("txtHand"); // NOI18N
lblGrave.setLabelFor(btnGrave);
lblGrave.setText("Grave:"); // NOI18N
lblGrave.setName("lblGrave"); // NOI18N
btnGrave.setName("btnGrave"); // NOI18N
btnGrave.addActionListener(evt -> btnGraveActionPerformed(evt));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblLife, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 42, Short.MAX_VALUE)
.addComponent(lblGrave, javax.swing.GroupLayout.DEFAULT_SIZE, 42, Short.MAX_VALUE)
.addComponent(lblHand, javax.swing.GroupLayout.DEFAULT_SIZE, 42, Short.MAX_VALUE)
.addComponent(lblLibrary, javax.swing.GroupLayout.DEFAULT_SIZE, 42, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(txtLife, javax.swing.GroupLayout.DEFAULT_SIZE, 48, Short.MAX_VALUE)
.addComponent(txtLibrary, javax.swing.GroupLayout.DEFAULT_SIZE, 48, Short.MAX_VALUE)
.addComponent(txtHand, javax.swing.GroupLayout.DEFAULT_SIZE, 48, Short.MAX_VALUE)
.addComponent(btnGrave, javax.swing.GroupLayout.DEFAULT_SIZE, 48, Short.MAX_VALUE))
.addContainerGap())
.addComponent(btnPlayerName, javax.swing.GroupLayout.DEFAULT_SIZE, 116, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(btnPlayerName, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(txtLife, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblLife, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(txtLibrary, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblLibrary, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(txtHand, javax.swing.GroupLayout.DEFAULT_SIZE, 14, Short.MAX_VALUE)
.addComponent(lblHand))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(lblGrave)
.addComponent(btnGrave, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void btnPlayerNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPlayerNameActionPerformed
SessionHandler.sendPlayerUUID(gameId, playerId);
}//GEN-LAST:event_btnPlayerNameActionPerformed
private void btnGraveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGraveActionPerformed
if (graveyard == null) {
graveyard = new ShowCardsDialog();
}
graveyard.loadCards(player.getName() + " graveyard", player.getGraveyard(), bigCard, gameId, false, null, null, null);
}//GEN-LAST:event_btnGraveActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnGrave;
private javax.swing.JButton btnPlayerName;
private javax.swing.JLabel lblGrave;
private javax.swing.JLabel lblHand;
private javax.swing.JLabel lblLibrary;
private javax.swing.JLabel lblLife;
private javax.swing.JLabel txtHand;
private javax.swing.JLabel txtLibrary;
private javax.swing.JLabel txtLife;
// End of variables declaration//GEN-END:variables
}

View file

@ -1,22 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.client.util;
import java.util.Comparator;
import mage.view.CardView;
/**
*
* @author LevelX2
*/
public class CardViewCardTypeComparator implements Comparator<CardView> {
@Override
public int compare(CardView o1, CardView o2) {
return o1.getCardTypes().toString().compareTo(o2.getCardTypes().toString());
}
}

View file

@ -1,19 +0,0 @@
package mage.client.util;
import java.util.Comparator;
import mage.view.CardView;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class CardViewColorComparator implements Comparator<CardView> {
@Override
public int compare(CardView o1, CardView o2) {
return o1.getColor().compareTo(o2.getColor());
}
}

View file

@ -1,19 +0,0 @@
package mage.client.util;
import java.util.Comparator;
import mage.utils.CardColorUtil;
import mage.view.CardView;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class CardViewColorIdentityComparator implements Comparator<CardView> {
@Override
public int compare(CardView o1, CardView o2) {
return CardColorUtil.getColorIdentitySortValue(o1.getManaCost(), o1.getColor(), o1.getRules())
- CardColorUtil.getColorIdentitySortValue(o2.getManaCost(), o2.getColor(), o2.getRules());
}
}

View file

@ -1,19 +0,0 @@
package mage.client.util;
import java.util.Comparator;
import mage.view.CardView;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class CardViewNameComparator implements Comparator<CardView> {
@Override
public int compare(CardView o1, CardView o2) {
return o1.getName().compareTo(o2.getName());
}
}

View file

@ -1,20 +1,22 @@
package mage.client.util;
/**
* @author JayDi85
*/
public enum ClientEventType {
CARD_CLICK,
CARD_DOUBLE_CLICK,
CARD_POPUP_MENU, // right click on windows // TODO: split into two events: CARD_ and PANEL_
//
SET_NUMBER,
ACTION_CONSUMED,
DOUBLE_CLICK,
ALT_DOUBLE_CLICK,
REMOVE_MAIN,
REMOVE_SIDEBOARD,
SHOW_POP_UP_MENU,
REMOVE_SPECIFIC_CARD,
ADD_SPECIFIC_CARD,
PICK_A_CARD,
MARK_A_CARD,
//
DECK_REMOVE_SELECTION_MAIN,
DECK_REMOVE_SELECTION_SIDEBOARD,
DECK_REMOVE_SPECIFIC_CARD,
DECK_ADD_SPECIFIC_CARD,
//
DRAFT_PICK_CARD,
DRAFT_MARK_CARD,
//
PLAYER_TYPE_CHANGED
}

Some files were not shown because too many files have changed in this diff Show more