diff --git a/Mage.Client/src/main/java/mage/client/cards/CardGrid.java b/Mage.Client/src/main/java/mage/client/cards/CardGrid.java index cf9503660f5..61680723b2f 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardGrid.java @@ -70,17 +70,24 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener, private Map cards = new HashMap(); private Dimension cardDimension; - public CardGrid() { + /** + * Max amount of cards in card grid for which card images will be drawn. + * Done so to solve issue with memory for big piles of cards. + */ + private static final int MAX_IMAGES = 250; + + public CardGrid() { initComponents(); setOpaque(false); } public void loadCards(CardsView showCards, SortBy sortBy, boolean piles, BigCard bigCard, UUID gameId) { + boolean drawImage = showCards.size() < MAX_IMAGES; this.bigCard = bigCard; this.gameId = gameId; for (CardView card: showCards.values()) { if (!cards.containsKey(card.getId())) { - addCard(card, bigCard, gameId); + addCard(card, bigCard, gameId, drawImage); } } for (Iterator> i = cards.entrySet().iterator(); i.hasNext();) { @@ -95,11 +102,11 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener, this.setVisible(true); } - private void addCard(CardView card, BigCard bigCard, UUID gameId) { + private void addCard(CardView card, BigCard bigCard, UUID gameId, boolean drawImage) { if (cardDimension == null) { cardDimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight); } - MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, true); + MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, drawImage); cards.put(card.getId(), cardImg); cardImg.addMouseListener(this); add(cardImg); diff --git a/Mage.Client/src/main/java/mage/client/cards/CardsList.java b/Mage.Client/src/main/java/mage/client/cards/CardsList.java index fc77a66c47c..68e70b8a067 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardsList.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardsList.java @@ -36,9 +36,9 @@ package mage.client.cards; import mage.Constants.CardType; import mage.cards.MageCard; -import mage.client.constants.Constants; import mage.client.constants.Constants.SortBy; import mage.client.deckeditor.table.TableModel; +import mage.client.deckeditor.table.UpdateCountsCallback; import mage.client.plugins.impl.Plugins; import mage.client.util.*; import mage.client.util.Event; @@ -98,8 +98,8 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar mainTable.setForeground(Color.white); DefaultTableCellRenderer myRenderer = (DefaultTableCellRenderer) mainTable.getDefaultRenderer(String.class); myRenderer.setBackground(new Color(0, 0, 0, 100)); - mainTable.getColumnModel().getColumn(0).setMaxWidth(0); - mainTable.getColumnModel().getColumn(0).setPreferredWidth(10); + mainTable.getColumnModel().getColumn(0).setMaxWidth(25); + mainTable.getColumnModel().getColumn(0).setPreferredWidth(25); mainTable.getColumnModel().getColumn(1).setPreferredWidth(110); mainTable.getColumnModel().getColumn(2).setPreferredWidth(90); mainTable.getColumnModel().getColumn(3).setPreferredWidth(50); @@ -130,6 +130,8 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar } } }); + + mainModel.setUpdateCountsCallback(new UpdateCountsCallback(lblCount, lblCreatureCount, lblLandCount)); } public ICardGrid getMainModel() { @@ -162,6 +164,8 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar int curRow = 0; int landCount = 0; int creatureCount = 0; + //FIXME: why we remove all cards? for performance it's better to merge changes + // as it is already done in ListView cardArea.removeAll(); if (cards != null && cards.size() > 0) { Rectangle rectangle = new Rectangle(Config.dimensions.frameWidth, Config.dimensions.frameHeight); @@ -271,7 +275,6 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar @Override public void loadCards(CardsView showCards, SortBy sortBy, boolean piles, BigCard bigCard, UUID gameId) { - //FIXME: why we remove all cards? for performance it's better to merge changes cards = showCards; this.bigCard = bigCard; this.gameId = gameId; @@ -420,8 +423,8 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar jToggleListView.setSelected(false); currentView = this; jScrollPane1.setViewportView(cardArea); - cbSortBy.setEnabled(false); - chkPiles.setEnabled(false); + cbSortBy.setEnabled(true); + chkPiles.setEnabled(true); //drawCards((SortBy) cbSortBy.getSelectedItem()); redrawCards(); }//GEN-LAST:event_jToggleCardViewActionPerformed @@ -474,4 +477,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar public void mouseExited(MouseEvent e) { } + public void setDisplayNoCopies(boolean value) { + mainModel.setDisplayNoCopies(value); + } } diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java index 6e3c7172c1d..5fb9a1402b5 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java @@ -149,10 +149,12 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene } }); cbExpansionSet.setModel(new DefaultComboBoxModel(l)); -// cbExpansionSet.insertItemAt("All sets", 0); + cbExpansionSet.insertItemAt("All sets", 0); cbExpansionSet.setSelectedIndex(0); initFilter(); - filter.getExpansionSetCode().add(((ExpansionSet)this.cbExpansionSet.getSelectedItem()).getCode()); + if (this.cbExpansionSet.getSelectedItem() instanceof ExpansionSet) { + filter.getExpansionSetCode().add(((ExpansionSet)this.cbExpansionSet.getSelectedItem()).getCode()); + } filterCards(); } @@ -692,8 +694,13 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene filter.getExpansionSetCode().clear(); if (cbExpansionSet.getSelectedItem() instanceof ExpansionSet) { filter.getExpansionSetCode().add(((ExpansionSet)this.cbExpansionSet.getSelectedItem()).getCode()); + filterCards(); + } else { + // auto switch for ListView for "All sets" (too many cards to load) + jToggleListView.doClick(); + jToggleListView.setSelected(true); } - filterCards(); + }//GEN-LAST:event_cbExpansionSetActionPerformed private void btnClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearActionPerformed diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java index 80068fa914c..50c31ebffcd 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java @@ -55,6 +55,8 @@ public class DeckArea extends javax.swing.JPanel { jSplitPane1.setOpaque(false); deckList.setOpaque(false); sideboardList.setOpaque(false); + deckList.setDisplayNoCopies(true); + sideboardList.setDisplayNoCopies(true); } public void showSideboard(boolean show) { diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index 3ae8a937e29..14220cfe1bb 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -173,6 +173,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { if (cardInfoPane instanceof CardInfoPane) { ((CardInfoPane)cardInfoPane).setCard(new CardView(card)); } + hidePopup(); } } else if (event.getEventName().equals("shift-double-click") && mode == DeckEditorMode.Constructed) { @@ -181,6 +182,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { if (cardInfoPane instanceof CardInfoPane) { ((CardInfoPane)cardInfoPane).setCard(new CardView(card)); } + hidePopup(); } refreshDeck(); } @@ -194,7 +196,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { public void event(Event event) { if (event.getEventName().equals("double-click")) { for (Card card: deck.getCards()) { - if (card.getId().equals((UUID)event.getSource())) { + if (card.getId().equals(event.getSource())) { deck.getCards().remove(card); if (mode == DeckEditorMode.Limited || mode == DeckEditorMode.Sideboard) { deck.getSideboard().add(card); @@ -203,16 +205,18 @@ public class DeckEditorPanel extends javax.swing.JPanel { break; } } + hidePopup(); refreshDeck(); } else if (event.getEventName().equals("shift-double-click") && mode == DeckEditorMode.Constructed) { for (Card card: deck.getCards()) { - if (card.getId().equals((UUID)event.getSource())) { + if (card.getId().equals(event.getSource())) { deck.getCards().remove(card); deck.getSideboard().add(card); break; } } + hidePopup(); refreshDeck(); } } @@ -223,16 +227,14 @@ public class DeckEditorPanel extends javax.swing.JPanel { @Override public void event(Event event) { if (event.getEventName().equals("double-click")) { - //boolean isListView = cardSelector.getCardsList() instanceof TableModel; for (Card card: deck.getSideboard()) { - if (card.getId().equals((UUID)event.getSource())) { + if (card.getId().equals(event.getSource())) { deck.getSideboard().remove(card); - //if (!isListView) { deck.getCards().add(card); - //} break; } } + hidePopup(); refreshDeck(); } } @@ -243,6 +245,10 @@ public class DeckEditorPanel extends javax.swing.JPanel { this.repaint(); } + private void hidePopup() { + Plugins.getInstance().getActionCallback().mouseExited(null, null); + } + public void hideDeckEditor() { Component c = this.getParent(); while (c != null && !(c instanceof DeckEditorPane)) { diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/table/TableModel.java b/Mage.Client/src/main/java/mage/client/deckeditor/table/TableModel.java index ad6ef2ab1b0..09159b41c55 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/table/TableModel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/table/TableModel.java @@ -28,6 +28,7 @@ package mage.client.deckeditor.table; +import mage.Constants; import mage.client.cards.BigCard; import mage.client.cards.CardEventSource; import mage.client.cards.ICardGrid; @@ -69,11 +70,14 @@ public class TableModel extends AbstractTableModel implements ICardGrid { protected BigCard bigCard; protected UUID gameId; private Map cards = new LinkedHashMap(); + private Map cardsNoCopies = new LinkedHashMap(); private List view = new ArrayList(); private Dimension cardDimension; - private String column[] = { "", "Name", "Cost", "Color", "Type", "Stats", - "Rarity", "Set" }; + private boolean displayNoCopies = false; + private UpdateCountsCallback updateCountsCallback; + + private String column[] = { "", "Name", "Cost", "Color", "Type", "Stats", "Rarity", "Set" }; private int recentSortedColumn; private boolean recentAscending; @@ -81,24 +85,69 @@ public class TableModel extends AbstractTableModel implements ICardGrid { public void loadCards(CardsView showCards, SortBy sortBy, boolean piles, BigCard bigCard, UUID gameId) { this.bigCard = bigCard; this.gameId = gameId; + int landCount = 0; + int creatureCount = 0; for (CardView card : showCards.values()) { if (!cards.containsKey(card.getId())) { addCard(card, bigCard, gameId); } + if (updateCountsCallback != null) { + if (card.getCardTypes().contains(Constants.CardType.LAND)) + landCount++; + if (card.getCardTypes().contains(Constants.CardType.CREATURE)) + creatureCount++; + } } - for (Iterator> i = cards.entrySet().iterator(); i - .hasNext();) { + // not easy logic for merge :) + for (Iterator> i = cards.entrySet().iterator(); i.hasNext();) { Entry entry = i.next(); if (!showCards.containsKey(entry.getKey())) { i.remove(); - for (CardView cv : view) { - if (cv.getId().equals(entry.getKey())) { - view.remove(cv); - break; + if (displayNoCopies) { + String key = entry.getValue().getName() + entry.getValue().getExpansionSetCode(); + if (cardsNoCopies.containsKey(key)) { + Integer count = cardsNoCopies.get(key); + count--; + if (count > 0) { + cardsNoCopies.put(key, count); + } else { + cardsNoCopies.remove(key); + } + for (int j = 0; j < view.size(); j++) { + CardView cv = view.get(j); + if (cv.getId().equals(entry.getKey())) { + if (count > 0) { + // replace by another card with the same name+setCode + String key1 = cv.getName()+cv.getExpansionSetCode(); + for (CardView cardView : cards.values()) { + String key2 = cardView.getName()+cardView.getExpansionSetCode(); + if ((key1).equals(key2)) { + view.set(j, cardView); + break; + } + } + } else { + view.remove(j); + } + break; + } + } + } + } else { + for (CardView cv : view) { + if (cv.getId().equals(entry.getKey())) { + view.remove(cv); + break; + } } } } } + + if (updateCountsCallback != null) { + updateCountsCallback.update(cards.size(), creatureCount, landCount); + } + sort(1, true); drawCards(sortBy, piles); } @@ -128,6 +177,11 @@ public class TableModel extends AbstractTableModel implements ICardGrid { CardView c = (CardView) obj; switch (column) { case 0: + if (displayNoCopies) { + String key = c.getName() + c.getExpansionSetCode(); + Integer count = cardsNoCopies.get(key); + return count != null ? count : ""; + } return ""; case 1: return c.getName(); @@ -163,7 +217,19 @@ public class TableModel extends AbstractTableModel implements ICardGrid { Config.dimensions.frameHeight); } cards.put(card.getId(), card); - view.add(card); + + if (displayNoCopies) { + String key = card.getName()+card.getExpansionSetCode(); + Integer count = 1; + if (cardsNoCopies.containsKey(key)) { + count = cardsNoCopies.get(key) + 1; + } else { + view.add(card); + } + cardsNoCopies.put(key, count); + } else { + view.add(card); + } } public void drawCards(SortBy sortBy, boolean piles) { @@ -285,4 +351,12 @@ public class TableModel extends AbstractTableModel implements ICardGrid { return true; } + + public void setDisplayNoCopies(boolean value) { + this.displayNoCopies = value; + } + + public void setUpdateCountsCallback(UpdateCountsCallback callback) { + this.updateCountsCallback = callback; + } } \ No newline at end of file diff --git a/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java b/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java index 6cf15aca4e3..b2e2ebfc78e 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java +++ b/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java @@ -13,6 +13,7 @@ import mage.cards.Card; import mage.cards.CardDimensions; import mage.cards.MageCard; import mage.cards.MagePermanent; +import mage.cards.action.ActionCallback; import mage.client.cards.BigCard; import mage.view.CardView; import mage.view.PermanentView; @@ -22,8 +23,8 @@ public interface MagePlugins { void shutdown(); void updateGamePanel(Map ui); JComponent updateTablePanel(Map ui); - MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean canBeFoil); - MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean canBeFoil); + MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage); + MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage); boolean isThemePluginLoaded(); boolean isCardPluginLoaded(); boolean isCounterPluginLoaded(); @@ -37,4 +38,5 @@ public interface MagePlugins { void onRemoveCard(MagePermanent card, int count); JComponent getCardInfoPane(); BufferedImage getOriginalImage(CardView card); + ActionCallback getActionCallback(); } diff --git a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java index 89986ce9206..4041e7f955d 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java +++ b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java @@ -1,18 +1,8 @@ package mage.client.plugins.impl; -import java.awt.*; -import java.awt.image.BufferedImage; -import java.io.File; -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import javax.swing.JComponent; - import mage.cards.MageCard; import mage.cards.MagePermanent; -import mage.cards.action.impl.EmptyCallback; +import mage.cards.action.ActionCallback; import mage.client.MageFrame; import mage.client.cards.BigCard; import mage.client.cards.Card; @@ -20,7 +10,6 @@ import mage.client.cards.Permanent; import mage.client.plugins.MagePlugins; import mage.client.plugins.adapters.MageActionCallback; import mage.client.util.Config; -import mage.client.util.DefaultActionCallback; import mage.constants.Constants; import mage.interfaces.PluginException; import mage.interfaces.plugin.CardPlugin; @@ -32,6 +21,15 @@ import net.xeoh.plugins.base.PluginManager; import net.xeoh.plugins.base.impl.PluginManagerFactory; import org.apache.log4j.Logger; +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + public class Plugins implements MagePlugins { @@ -42,8 +40,6 @@ public class Plugins implements MagePlugins { private ThemePlugin themePlugin = null; private CardPlugin cardPlugin = null; private CounterPlugin counterPlugin = null; - protected static DefaultActionCallback defaultCallback = DefaultActionCallback.getInstance(); - private static final EmptyCallback emptyCallback = new EmptyCallback(); private static final MageActionCallback mageActionCallback = new MageActionCallback(); public static MagePlugins getInstance() { @@ -79,22 +75,22 @@ public class Plugins implements MagePlugins { } @Override - public MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean canBeFoil) { + public MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage) { if (cardPlugin != null) { mageActionCallback.refreshSession(); mageActionCallback.setCardPreviewComponent(bigCard); - return cardPlugin.getMagePermanent(card, dimension, gameId, mageActionCallback, canBeFoil, !MageFrame.isLite()); + return cardPlugin.getMagePermanent(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage); } else { return new Permanent(card, bigCard, Config.dimensions, gameId); } } @Override - public MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean canBeFoil) { + public MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage) { if (cardPlugin != null) { mageActionCallback.refreshSession(); mageActionCallback.setCardPreviewComponent(bigCard); - return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, canBeFoil, !MageFrame.isLite()); + return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage); } else { return new Card(card, bigCard, Config.dimensions, gameId); } @@ -197,4 +193,7 @@ public class Plugins implements MagePlugins { return null; } + public ActionCallback getActionCallback() { + return mageActionCallback; + } }