Added the four finalists from You Make the Cube.

This commit is contained in:
fireshoes 2016-10-17 23:44:14 -05:00
parent c045204622
commit b733f911f7

View file

@ -1,32 +1,83 @@
package mage.client.cards; package mage.client.cards;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import mage.cards.MageCard; import mage.cards.MageCard;
import mage.cards.decks.DeckCardInfo; import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLayout; import mage.cards.decks.DeckCardLayout;
import mage.client.MageFrame;
import mage.client.constants.Constants;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins; import mage.client.plugins.impl.Plugins;
import mage.client.util.*; import mage.client.util.CardViewCardTypeComparator;
import mage.client.util.CardViewColorComparator;
import mage.client.util.CardViewColorIdentityComparator;
import mage.client.util.CardViewCostComparator;
import mage.client.util.CardViewNameComparator;
import mage.client.util.CardViewRarityComparator;
import mage.client.util.Event; import mage.client.util.Event;
import mage.client.util.GUISizeHelper;
import mage.client.util.Listener;
import mage.constants.CardType; import mage.constants.CardType;
import mage.view.CardView; import mage.view.CardView;
import mage.view.CardsView; import mage.view.CardsView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.card.arcane.CardRenderer; import org.mage.card.arcane.CardRenderer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/** /**
* Created by StravantUser on 2016-09-20. * Created by StravantUser on 2016-09-20.
*/ */
public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarget { public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarget {
private static Logger LOGGER = Logger.getLogger(DragCardGrid.class);
private final static Logger LOGGER = Logger.getLogger(DragCardGrid.class);
private Constants.DeckEditorMode mode;
@Override @Override
public Collection<CardView> dragCardList() { public Collection<CardView> dragCardList() {
@ -234,7 +285,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
ArrayList<ArrayList<CardView>> newRow = new ArrayList<>(); ArrayList<ArrayList<CardView>> newRow = new ArrayList<>();
if (!cardGrid.isEmpty()) { if (!cardGrid.isEmpty()) {
for (int colIndex = 0; colIndex < cardGrid.get(0).size(); ++colIndex) { for (int colIndex = 0; colIndex < cardGrid.get(0).size(); ++colIndex) {
newRow.add(new ArrayList<CardView>()); newRow.add(new ArrayList<>());
} }
} }
cardGrid.add(newRow); cardGrid.add(newRow);
@ -243,7 +294,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Insert the new column to add to // Insert the new column to add to
for (int i = 0; i < cardGrid.size(); ++i) { for (int i = 0; i < cardGrid.size(); ++i) {
cardGrid.get(i).add(col, new ArrayList<CardView>()); cardGrid.get(i).add(col, new ArrayList<>());
} }
// Add the cards // Add the cards
@ -279,7 +330,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
ArrayList<ArrayList<CardView>> newRow = new ArrayList<>(); ArrayList<ArrayList<CardView>> newRow = new ArrayList<>();
if (!cardGrid.isEmpty()) { if (!cardGrid.isEmpty()) {
for (int colIndex = 0; colIndex < cardGrid.get(0).size(); ++colIndex) { for (int colIndex = 0; colIndex < cardGrid.get(0).size(); ++colIndex) {
newRow.add(new ArrayList<CardView>()); newRow.add(new ArrayList<>());
} }
} }
cardGrid.add(newRow); cardGrid.add(newRow);
@ -289,7 +340,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Add a new col if needed // Add a new col if needed
if (col >= cardGrid.get(0).size()) { if (col >= cardGrid.get(0).size()) {
for (int i = 0; i < cardGrid.size(); ++i) { for (int i = 0; i < cardGrid.size(); ++i) {
cardGrid.get(i).add(new ArrayList<CardView>()); cardGrid.get(i).add(new ArrayList<>());
} }
} }
@ -314,7 +365,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Add new cards to grid // Add new cards to grid
for (CardView card : cards) { for (CardView card : cards) {
card.setSelected(true); card.setSelected(true);
addCardView(card); addCardView(card, false);
eventSource.addSpecificCard(card, "add-specific-card"); eventSource.addSpecificCard(card, "add-specific-card");
} }
layoutGrid(); layoutGrid();
@ -399,6 +450,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
return new DeckCardLayout(info, saveSettings().toString()); return new DeckCardLayout(info, saveSettings().toString());
} }
public void setDeckEditorMode(Constants.DeckEditorMode mode) {
this.mode = mode;
}
public enum Sort { public enum Sort {
NONE("No Sort", new Comparator<CardView>() { NONE("No Sort", new Comparator<CardView>() {
@Override @Override
@ -407,8 +462,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
return 0; return 0;
} }
}), }),
CARD_TYPE("Card Type", new CardViewCardTypeComparator()),
CMC("Converted Mana Cost", new CardViewCostComparator()), CMC("Converted Mana Cost", new CardViewCostComparator()),
COLOR("Color", new CardViewColorComparator()), COLOR("Color", new CardViewColorComparator()),
COLOR_IDENTITY("Color Identity", new CardViewColorIdentityComparator()),
RARITY("Rarity", new CardViewRarityComparator()); RARITY("Rarity", new CardViewRarityComparator());
Sort(String text, Comparator<CardView> comparator) { Sort(String text, Comparator<CardView> comparator) {
@ -419,25 +476,29 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
public Comparator<CardView> getComparator() { public Comparator<CardView> getComparator() {
return comparator; return comparator;
} }
public String getText() { public String getText() {
return text; return text;
} }
private Comparator<CardView> comparator; private final Comparator<CardView> comparator;
private String text; private final String text;
} }
private abstract class CardTypeCounter { private abstract class CardTypeCounter {
protected abstract boolean is(CardView card); protected abstract boolean is(CardView card);
int get() { int get() {
return count; return count;
} }
void add(CardView card) { void add(CardView card) {
if (is(card)) { if (is(card)) {
++count; ++count;
} }
} }
void remove(CardView card) { void remove(CardView card) {
if (is(card)) { if (is(card)) {
--count; --count;
@ -459,12 +520,65 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
return card.getCardTypes().contains(CardType.LAND); return card.getCardTypes().contains(CardType.LAND);
} }
}; };
private CardTypeCounter[] allCounters = {creatureCounter, landCounter};
private CardTypeCounter artifactCounter = new CardTypeCounter() {
@Override
protected boolean is(CardView card) {
return card.getCardTypes().contains(CardType.ARTIFACT);
}
};
private CardTypeCounter enchantmentCounter = new CardTypeCounter() {
@Override
protected boolean is(CardView card) {
return card.getCardTypes().contains(CardType.ENCHANTMENT);
}
};
private CardTypeCounter instantCounter = new CardTypeCounter() {
@Override
protected boolean is(CardView card) {
return card.getCardTypes().contains(CardType.INSTANT);
}
};
private CardTypeCounter sorceryCounter = new CardTypeCounter() {
@Override
protected boolean is(CardView card) {
return card.getCardTypes().contains(CardType.SORCERY);
}
};
private CardTypeCounter planeswalkerCounter = new CardTypeCounter() {
@Override
protected boolean is(CardView card) {
return card.getCardTypes().contains(CardType.PLANESWALKER);
}
};
private final CardTypeCounter tribalCounter = new CardTypeCounter() {
@Override
protected boolean is(CardView card) {
return card.getCardTypes().contains(CardType.TRIBAL);
}
};
private final CardTypeCounter[] allCounters = {
creatureCounter,
landCounter,
artifactCounter,
enchantmentCounter,
instantCounter,
sorceryCounter,
planeswalkerCounter,
sorceryCounter,
tribalCounter
};
// Listener // Listener
public interface DragCardGridListener { public interface DragCardGridListener {
void cardsSelected(); void cardsSelected();
void hideCards(Collection<CardView> card); void hideCards(Collection<CardView> card);
void duplicateCards(Collection<CardView> cards);
void showAll(); void showAll();
}; };
@ -472,15 +586,15 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
public static int COUNT_LABEL_HEIGHT = 20; public static int COUNT_LABEL_HEIGHT = 20;
public static int GRID_PADDING = 10; public static int GRID_PADDING = 10;
private static ImageIcon INSERT_ROW_ICON = new ImageIcon(DragCardGrid.class.getClassLoader().getResource("editor_insert_row.png")); private final static ImageIcon INSERT_ROW_ICON = new ImageIcon(DragCardGrid.class.getClassLoader().getResource("editor_insert_row.png"));
private static ImageIcon INSERT_COL_ICON = new ImageIcon(DragCardGrid.class.getClassLoader().getResource("editor_insert_col.png")); private final static ImageIcon INSERT_COL_ICON = new ImageIcon(DragCardGrid.class.getClassLoader().getResource("editor_insert_col.png"));
// All of the current card views // All of the current card views
private Map<UUID, MageCard> cardViews = new LinkedHashMap<>(); private final Map<UUID, MageCard> cardViews = new LinkedHashMap<>();
private ArrayList<CardView> allCards = new ArrayList<>(); private final ArrayList<CardView> allCards = new ArrayList<>();
// Card listeners // Card listeners
private CardEventSource eventSource = new CardEventSource(); private final CardEventSource eventSource = new CardEventSource();
// Last big card // Last big card
BigCard lastBigCard = null; BigCard lastBigCard = null;
@ -489,17 +603,23 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
JButton sortButton; JButton sortButton;
JButton filterButton; JButton filterButton;
JButton visibilityButton; JButton visibilityButton;
JButton selectByButton;
JButton analyseButton;
// Popup for toolbar // Popup for toolbar
JPopupMenu filterPopup; JPopupMenu filterPopup;
JPopupMenu selectByTypePopup;
JPopupMenu sortPopup; JPopupMenu sortPopup;
JPopupMenu selectByPopup;
JCheckBox separateCreaturesCb; JCheckBox separateCreaturesCb;
JTextField searchByTextField;
JSlider cardSizeSlider; JSlider cardSizeSlider;
JLabel cardSizeSliderLabel; JLabel cardSizeSliderLabel;
Map<Sort, AbstractButton> sortButtons = new HashMap<>(); Map<Sort, AbstractButton> sortButtons = new HashMap<>();
HashMap<CardType, AbstractButton> selectByTypeButtons = new HashMap<>();
JLabel deckNameAndCountLabel; JLabel deckNameAndCountLabel;
JLabel landCountLabel; JLabel landCountLabel;
@ -525,7 +645,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
Role role = Role.MAINDECK; Role role = Role.MAINDECK;
// Dragging // Dragging
private CardDraggerGlassPane dragger = new CardDraggerGlassPane(this); private final CardDraggerGlassPane dragger = new CardDraggerGlassPane(this);
// The grid of cards // The grid of cards
// The outermost array contains multiple rows of stacks of cards // The outermost array contains multiple rows of stacks of cards
@ -533,8 +653,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// The innermost array represents a single vertical stack of cards // The innermost array represents a single vertical stack of cards
private ArrayList<ArrayList<ArrayList<CardView>>> cardGrid; private ArrayList<ArrayList<ArrayList<CardView>>> cardGrid;
private ArrayList<Integer> maxStackSize = new ArrayList<>(); private ArrayList<Integer> maxStackSize = new ArrayList<>();
private ArrayList<ArrayList<JLabel>> stackCountLabels = new ArrayList<>(); private final ArrayList<ArrayList<JLabel>> stackCountLabels = new ArrayList<>();
private Sort cardSort = Sort.CMC; private Sort cardSort = Sort.CMC;
private final ArrayList<CardType> selectByTypeSelected = new ArrayList<>();
private boolean separateCreatures = true; private boolean separateCreatures = true;
public enum Role { public enum Role {
@ -553,17 +674,28 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} }
public static class Settings { public static class Settings {
public Sort sort; public Sort sort;
public boolean separateCreatures; public boolean separateCreatures;
public int cardSize;
private static Pattern parser = Pattern.compile("\\(([^,]*),([^)]*)\\)"); private final static Pattern parser = Pattern.compile("\\(([^,]*),([^,]*),([^)]*)\\)");
public static Settings parse(String str) { public static Settings parse(String str) {
Matcher m = parser.matcher(str); Matcher m = parser.matcher(str);
if (m.find()) { if (m.find()) {
Settings s = new Settings(); Settings s = new Settings();
if (m.groupCount() > 0) {
s.sort = Sort.valueOf(m.group(1)); s.sort = Sort.valueOf(m.group(1));
}
if (m.groupCount() > 1) {
s.separateCreatures = Boolean.valueOf(m.group(2)); s.separateCreatures = Boolean.valueOf(m.group(2));
}
if (m.groupCount() > 2) {
s.cardSize = Integer.valueOf(m.group(3));
} else {
s.cardSize = 50;
}
return s; return s;
} else { } else {
return null; return null;
@ -572,7 +704,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
@Override @Override
public String toString() { public String toString() {
return "(" + sort.toString() + "," + Boolean.toString(separateCreatures) + ")"; return "(" + sort.toString() + "," + Boolean.toString(separateCreatures) + "," + Integer.toString(cardSize) + ")";
} }
} }
@ -580,6 +712,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
Settings s = new Settings(); Settings s = new Settings();
s.sort = cardSort; s.sort = cardSort;
s.separateCreatures = separateCreatures; s.separateCreatures = separateCreatures;
s.cardSize = cardSizeSlider.getValue();
return s; return s;
} }
@ -587,6 +720,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
if (s != null) { if (s != null) {
setSort(s.sort); setSort(s.sort);
setSeparateCreatures(s.separateCreatures); setSeparateCreatures(s.separateCreatures);
setCardSize(s.cardSize);
resort(); resort();
} }
} }
@ -601,6 +735,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
sortButtons.get(s).setSelected(true); sortButtons.get(s).setSelected(true);
} }
public void setCardSize(int size) {
cardSizeSlider.setValue(size);
}
// Constructor // Constructor
public DragCardGrid() { public DragCardGrid() {
// Make sure that the card grid is populated with at least one (empty) stack to begin with // Make sure that the card grid is populated with at least one (empty) stack to begin with
@ -610,10 +748,15 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
setLayout(new BorderLayout()); setLayout(new BorderLayout());
setOpaque(false); setOpaque(false);
// Editting mode
this.mode = Constants.DeckEditorMode.LIMITED_BUILDING;
// Toolbar // Toolbar
sortButton = new JButton("Sort"); sortButton = new JButton("Sort");
filterButton = new JButton("Filter"); filterButton = new JButton("Filter");
visibilityButton = new JButton("Visibility"); visibilityButton = new JButton("Visibility");
selectByButton = new JButton("Select By");
analyseButton = new JButton("Mana");
// Name and count label // Name and count label
deckNameAndCountLabel = new JLabel(); deckNameAndCountLabel = new JLabel();
@ -635,6 +778,8 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
toolbarInner.add(sortButton); toolbarInner.add(sortButton);
toolbarInner.add(filterButton); toolbarInner.add(filterButton);
toolbarInner.add(visibilityButton); toolbarInner.add(visibilityButton);
toolbarInner.add(selectByButton);
toolbarInner.add(analyseButton);
toolbar.add(toolbarInner, BorderLayout.WEST); toolbar.add(toolbarInner, BorderLayout.WEST);
JPanel sliderPanel = new JPanel(new GridBagLayout()); JPanel sliderPanel = new JPanel(new GridBagLayout());
sliderPanel.setOpaque(false); sliderPanel.setOpaque(false);
@ -664,6 +809,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
cardContent.setOpaque(false); cardContent.setOpaque(false);
cardContent.addMouseListener(new MouseAdapter() { cardContent.addMouseListener(new MouseAdapter() {
private boolean isDragging = false; private boolean isDragging = false;
@Override @Override
public void mousePressed(MouseEvent e) { public void mousePressed(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) { if (SwingUtilities.isLeftMouseButton(e)) {
@ -672,6 +818,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
updateSelectionDrag(e.getX(), e.getY()); updateSelectionDrag(e.getX(), e.getY());
} }
} }
@Override @Override
public void mouseReleased(MouseEvent e) { public void mouseReleased(MouseEvent e) {
if (isDragging) { if (isDragging) {
@ -710,8 +857,11 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Load separate creatures setting // Load separate creatures setting
separateCreatures = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_DECK_EDITOR_LAST_SEPARATE_CREATURES, "false").equals("true"); separateCreatures = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_DECK_EDITOR_LAST_SEPARATE_CREATURES, "false").equals("true");
try {
cardSort = Sort.valueOf(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_DECK_EDITOR_LAST_SORT, Sort.NONE.toString())); cardSort = Sort.valueOf(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_DECK_EDITOR_LAST_SORT, Sort.NONE.toString()));
} catch (IllegalArgumentException ex) {
cardSort = Sort.NONE;
}
// Sort popup // Sort popup
{ {
sortPopup = new JPopupMenu(); sortPopup = new JPopupMenu();
@ -721,7 +871,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
sortMode.setLayout(new GridLayout(Sort.values().length, 1, 0, 2)); sortMode.setLayout(new GridLayout(Sort.values().length, 1, 0, 2));
sortMode.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Sort by...")); sortMode.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Sort by..."));
GridBagConstraints sortModeC = new GridBagConstraints(); GridBagConstraints sortModeC = new GridBagConstraints();
sortModeC.gridx = 0; sortModeC.gridy = 0; sortModeC.gridwidth = 1; sortModeC.gridheight = 1; sortModeC.gridx = 0;
sortModeC.gridy = 0;
sortModeC.gridwidth = 1;
sortModeC.gridheight = 1;
sortModeC.fill = GridBagConstraints.HORIZONTAL; sortModeC.fill = GridBagConstraints.HORIZONTAL;
sortPopup.add(sortMode, sortModeC); sortPopup.add(sortMode, sortModeC);
@ -745,7 +898,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
sortOptions.setLayout(new BoxLayout(sortOptions, BoxLayout.Y_AXIS)); sortOptions.setLayout(new BoxLayout(sortOptions, BoxLayout.Y_AXIS));
sortOptions.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Sort options")); sortOptions.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Sort options"));
GridBagConstraints sortOptionsC = new GridBagConstraints(); GridBagConstraints sortOptionsC = new GridBagConstraints();
sortOptionsC.gridx = 0; sortOptionsC.gridy = 1; sortOptionsC.gridwidth = 1; sortOptionsC.gridheight = 1; sortOptionsC.gridx = 0;
sortOptionsC.gridy = 1;
sortOptionsC.gridwidth = 1;
sortOptionsC.gridheight = 1;
sortPopup.add(sortOptions, sortOptionsC); sortPopup.add(sortOptions, sortOptionsC);
separateCreaturesCb = new JCheckBox(); separateCreaturesCb = new JCheckBox();
@ -757,7 +913,6 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
resort(); resort();
}); });
sortOptions.add(separateCreaturesCb); sortOptions.add(separateCreaturesCb);
sortPopup.pack(); sortPopup.pack();
makeButtonPopup(sortButton, sortPopup); makeButtonPopup(sortButton, sortPopup);
@ -780,11 +935,80 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
}); });
} }
// selectBy.. popup
{
selectByPopup = new JPopupMenu();
selectByPopup.setLayout(new GridBagLayout());
JPanel selectByTypeMode = new JPanel();
selectByTypeMode.setLayout(new GridLayout(CardType.values().length, 1, 0, 2));
selectByTypeMode.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Select by Type"));
GridBagConstraints selectByTypeModeC = new GridBagConstraints();
selectByTypeModeC.gridx = 0;
selectByTypeModeC.gridy = 0;
selectByTypeModeC.gridwidth = 1;
selectByTypeModeC.gridheight = 1;
selectByTypeModeC.fill = GridBagConstraints.HORIZONTAL;
selectByPopup.add(selectByTypeMode, selectByTypeModeC);
ButtonGroup selectByTypeModeGroup = new ButtonGroup();
for (final CardType cardType : CardType.values()) {
JToggleButton button = new JToggleButton(cardType.toString());
selectByTypeButtons.put(cardType, button);
selectByTypeMode.add(button);
selectByTypeModeGroup.add(button);
button.addActionListener(e -> {
//selectByTypeSelected.add(cardType);
button.setSelected(!button.isSelected());
reselectBy();
});
}
JPanel selectBySearchPanel = new JPanel();
selectBySearchPanel.setPreferredSize(new Dimension(150, 60));
selectBySearchPanel.setLayout(new GridLayout(1, 1));
selectBySearchPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Search:"));
GridBagConstraints selectBySearchPanelC = new GridBagConstraints();
selectBySearchPanelC.gridx = 0;
selectBySearchPanelC.gridy = 1;
selectBySearchPanelC.gridwidth = 1;
selectBySearchPanelC.gridheight = 1;
selectBySearchPanelC.fill = GridBagConstraints.HORIZONTAL;
selectBySearchPanelC.fill = GridBagConstraints.VERTICAL;
searchByTextField = new JTextField();
searchByTextField.setToolTipText("Searches for card names, types, rarity, casting cost and rules text. NB: Mana symbols are written like {W},{U},{C} etc");
searchByTextField.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
reselectBy();
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
});
selectBySearchPanel.add(searchByTextField);
selectByPopup.add(selectBySearchPanel, selectBySearchPanelC);
makeButtonPopup(selectByButton, selectByPopup);
}
// Analyse Mana (aka #blue pips, #islands, #white pips, #plains etc.)
analyseButton.setToolTipText("Counts coloured/colourless mana costs. Counts land types.");
analyseButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
analyseDeck();
}
});
// Filter popup // Filter popup
filterPopup = new JPopupMenu(); filterPopup = new JPopupMenu();
filterPopup.setPreferredSize(new Dimension(300, 300)); filterPopup.setPreferredSize(new Dimension(300, 300));
makeButtonPopup(filterButton, filterPopup); makeButtonPopup(filterButton, filterPopup);
filterButton.setVisible(false); filterButton.setVisible(false);
// Right click in card area // Right click in card area
@ -864,6 +1088,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} }
} }
private void duplicateSelection() {
Collection<CardView> toDuplicate = dragCardList();
for (DragCardGridListener l : listeners) {
l.duplicateCards(toDuplicate);
}
}
private void showAll() { private void showAll() {
for (DragCardGridListener l : listeners) { for (DragCardGridListener l : listeners) {
l.showAll(); l.showAll();
@ -946,14 +1176,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
card.setSelected(true); card.setSelected(true);
view.update(card); view.update(card);
} }
} else { } else if (card.isSelected()) {
if (card.isSelected()) {
card.setSelected(false); card.setSelected(false);
view.update(card); view.update(card);
} }
} }
} }
}
curY += cardTopHeight * (maxStackSize.get(rowIndex) - 1) + cardHeight + COUNT_LABEL_HEIGHT; curY += cardTopHeight * (maxStackSize.get(rowIndex) - 1) + cardHeight + COUNT_LABEL_HEIGHT;
} }
} }
@ -989,6 +1217,218 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
repaint(); repaint();
} }
public void reselectBy() {
// Deselect everything
deselectAll();
boolean useText = false;
String searchStr = "";
if (searchByTextField.getText().length() >= 3) {
useText = true;
searchStr = searchByTextField.getText().toLowerCase();
}
for (CardType cardType : selectByTypeButtons.keySet()) {
AbstractButton button = selectByTypeButtons.get(cardType);
if (button != null) {
if (button.isSelected()) {
for (ArrayList<ArrayList<CardView>> gridRow : cardGrid) {
for (ArrayList<CardView> stack : gridRow) {
for (CardView card : stack) {
boolean s = card.isSelected() | card.getCardTypes().contains(cardType);
card.setSelected(s);
cardViews.get(card.getId()).update(card);
}
}
}
}
}
}
if (useText) {
for (ArrayList<ArrayList<CardView>> gridRow : cardGrid) {
for (ArrayList<CardView> stack : gridRow) {
for (CardView card : stack) {
boolean s = card.isSelected();
// Name
if (!s) {
s |= card.getName().toLowerCase().contains(searchStr);
}
// Sub & Super Types
if (!s) {
for (String str : card.getSuperTypes()) {
s |= str.toLowerCase().contains(searchStr);
}
for (String str : card.getSubTypes()) {
s |= str.toLowerCase().contains(searchStr);
}
}
// Rarity
if (!s) {
s |= card.getRarity().toString().toLowerCase().contains(searchStr);
}
// Type line
if (!s) {
String t = "";
for (CardType type : card.getCardTypes()) {
t += " " + type.toString();
}
s |= t.toLowerCase().contains(searchStr);
}
// Casting cost
if (!s) {
String mc = "";
for (String m : card.getManaCost()) {
mc += m;
}
s |= mc.toLowerCase().contains(searchStr);
}
// Rules
if (!s) {
for (String str : card.getRules()) {
s |= str.toLowerCase().contains(searchStr);
}
}
card.setSelected(s);
cardViews.get(card.getId()).update(card);
}
}
}
}
// And finally rerender
layoutGrid();
repaint();
}
private static final Pattern pattern = Pattern.compile(".*Add(.*)(\\{[WUBRGXC]\\})(.*)to your mana pool");
public void analyseDeck() {
HashMap<String, Integer> qtys = new HashMap<>();
HashMap<String, Integer> pips = new HashMap<>();
HashMap<String, Integer> sourcePips = new HashMap<>();
HashMap<String, Integer> manaCounts = new HashMap<>();
pips.put("#w}", 0);
pips.put("#u}", 0);
pips.put("#b}", 0);
pips.put("#r}", 0);
pips.put("#g}", 0);
pips.put("#c}", 0);
qtys.put("plains", 0);
qtys.put("island", 0);
qtys.put("swamp", 0);
qtys.put("mountain", 0);
qtys.put("forest", 0);
qtys.put("basic", 0);
qtys.put("wastes", 0);
manaCounts = new HashMap<>();
for (ArrayList<ArrayList<CardView>> gridRow : cardGrid) {
for (ArrayList<CardView> stack : gridRow) {
for (CardView card : stack) {
// Type line
String t = "";
for (CardType type : card.getCardTypes()) {
t += " " + type.toString();
}
// Sub & Super Types
for (String str : card.getSuperTypes()) {
t += " " + str.toLowerCase();
}
for (String str : card.getSubTypes()) {
t += " " + str.toLowerCase();
}
for (String qty : qtys.keySet()) {
int value = qtys.get(qty);
if (t.toLowerCase().contains(qty)) {
qtys.put(qty, ++value);
}
// Rules
for (String str : card.getRules()) {
if (str.toLowerCase().contains(qty)) {
qtys.put(qty, ++value);
}
}
}
// Wastes (special case)
if (card.getName().equals("Wastes")) {
int value = qtys.get("wastes");
qtys.put("wastes", ++value);
}
// Mana Cost
String mc = "";
for (String m : card.getManaCost()) {
mc += m;
}
mc = mc.replaceAll("\\{([WUBRG]).([WUBRG])\\}", "{$1}{$2}");
mc = mc.replaceAll("\\{", "#");
mc = mc.toLowerCase();
for (String pip : pips.keySet()) {
int value = pips.get(pip);
while (mc.toLowerCase().contains(pip)) {
pips.put(pip, ++value);
mc = mc.replaceFirst(pip, "");
}
}
// Adding mana
for (String str : card.getRules()) {
Matcher m = pattern.matcher(str);
// ".*Add(.*)(\\{[WUBRGXC]\\})(.*)to your mana pool"
while (m.find()) {
System.out.println("0=" + m.group(0) + ",,,1=" + m.group(1) + ",,,2=" + m.group(2) + ",,,3=" + m.group(3));
str = "Add" + m.group(1) + m.group(3) + "to your mana pool";
System.out.println("Found " + m.group(2) + " in " + card.getName());
int num = 1;
if (manaCounts.get(m.group(2)) != null) {
num = manaCounts.get(m.group(2));
num++;
}
manaCounts.put(m.group(2), num);
m = pattern.matcher(str);
}
}
}
}
}
String finalInfo = "Found the following quantity of mana costs, mana sources and land types:<br><font size=-1><ul>";
for (String qty : qtys.keySet()) {
int value = qtys.get(qty);
if (value > 0) {
finalInfo += "<li>" + qty + " = " + value;
}
}
for (String source : sourcePips.keySet()) {
int value = sourcePips.get(source);
if (value > 0) {
finalInfo += "<li>" + "Mana source " + source + " = " + value;
}
}
for (String pip : pips.keySet()) {
int value = pips.get(pip);
if (value > 0) {
finalInfo += "<li>" + pip.toUpperCase() + " mana pip/s = " + value;
}
}
for (String mana : manaCounts.keySet()) {
int value = manaCounts.get(mana);
if (value > 0) {
finalInfo += "<li>" + mana.toUpperCase() + " mana sources = " + value;
}
}
finalInfo = finalInfo.replaceAll("#", "\\{");
finalInfo += "</ul>";
MageFrame.getInstance().showMessage(finalInfo);
}
// Update the contents of the card grid // Update the contents of the card grid
public void setCards(CardsView cardsView, DeckCardLayout layout, BigCard bigCard) { public void setCards(CardsView cardsView, DeckCardLayout layout, BigCard bigCard) {
if (bigCard != null) { if (bigCard != null) {
@ -1025,7 +1465,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
for (CardView newCard : cardsView.values()) { for (CardView newCard : cardsView.values()) {
if (!cardViews.containsKey(newCard.getId())) { if (!cardViews.containsKey(newCard.getId())) {
// Is a new card // Is a new card
addCardView(newCard); addCardView(newCard, false);
// Put it into the appropirate place in the grid given the current sort // Put it into the appropirate place in the grid given the current sort
sortIntoGrid(newCard); sortIntoGrid(newCard);
@ -1048,7 +1488,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
for (CardView newCard : cardsView.values()) { for (CardView newCard : cardsView.values()) {
if (!cardViews.containsKey(newCard.getId())) { if (!cardViews.containsKey(newCard.getId())) {
// Add the new card // Add the new card
addCardView(newCard); addCardView(newCard, false);
// Add the new card to tracking // Add the new card to tracking
Map<String, ArrayList<CardView>> forSetCode; Map<String, ArrayList<CardView>> forSetCode;
@ -1081,8 +1521,8 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
gridRow.add(gridStack); gridRow.add(gridStack);
for (DeckCardInfo info : stack) { for (DeckCardInfo info : stack) {
if (trackedCards.containsKey(info.getSetCode()) && trackedCards.get(info.getSetCode()).containsKey(info.getCardNum())) { if (trackedCards.containsKey(info.getSetCode()) && trackedCards.get(info.getSetCode()).containsKey(info.getCardNum())) {
ArrayList<CardView> candidates = ArrayList<CardView> candidates
trackedCards.get(info.getSetCode()).get(info.getCardNum()); = trackedCards.get(info.getSetCode()).get(info.getCardNum());
if (candidates.size() > 0) { if (candidates.size() > 0) {
gridStack.add(candidates.remove(0)); gridStack.add(candidates.remove(0));
thisMaxStackSize = Math.max(thisMaxStackSize, gridStack.size()); thisMaxStackSize = Math.max(thisMaxStackSize, gridStack.size());
@ -1117,10 +1557,48 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} }
} }
private int getCount(CardType cardType) {
if (null != cardType) {
switch (cardType) {
case CREATURE:
return creatureCounter.get();
case LAND:
return landCounter.get();
case ARTIFACT:
return artifactCounter.get();
case ENCHANTMENT:
return enchantmentCounter.get();
case INSTANT:
return instantCounter.get();
case PLANESWALKER:
return planeswalkerCounter.get();
case SORCERY:
return sorceryCounter.get();
case TRIBAL:
return tribalCounter.get();
default:
break;
}
}
return 0;
}
private void updateCounts() { private void updateCounts() {
deckNameAndCountLabel.setText(role.getName() + " - " + allCards.size()); deckNameAndCountLabel.setText(role.getName() + " - " + allCards.size());
creatureCountLabel.setText("" + creatureCounter.get()); creatureCountLabel.setText("" + creatureCounter.get());
landCountLabel.setText("" + landCounter.get()); landCountLabel.setText("" + landCounter.get());
for (CardType cardType : selectByTypeButtons.keySet()) {
AbstractButton button = selectByTypeButtons.get(cardType);
String text = cardType.toString();
int numCards = getCount(cardType);
if (numCards > 0) {
button.setForeground(Color.BLACK);
text = text + " - " + numCards;
} else {
button.setForeground(new Color(100, 100, 100));
}
button.setText(text);
}
} }
private void showCardRightClickMenu(@SuppressWarnings("unused") final CardView card, MouseEvent e) { private void showCardRightClickMenu(@SuppressWarnings("unused") final CardView card, MouseEvent e) {
@ -1128,10 +1606,17 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
JMenuItem hide = new JMenuItem("Hide"); JMenuItem hide = new JMenuItem("Hide");
hide.addActionListener(e2 -> hideSelection()); hide.addActionListener(e2 -> hideSelection());
menu.add(hide); menu.add(hide);
// Show 'Duplicate Selection' for FREE_BUILDING
if (this.mode == Constants.DeckEditorMode.FREE_BUILDING) {
JMenuItem duplicateSelection = new JMenuItem("Duplicate Selection");
duplicateSelection.addActionListener(e2 -> duplicateSelection());
menu.add(duplicateSelection);
}
menu.show(e.getComponent(), e.getX(), e.getY()); menu.show(e.getComponent(), e.getX(), e.getY());
} }
private void addCardView(final CardView card) { public void addCardView(final CardView card, boolean duplicated) {
allCards.add(card); allCards.add(card);
// Update counts // Update counts
@ -1146,10 +1631,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
cardPanel.setTextOffset(0); cardPanel.setTextOffset(0);
// Remove mouse wheel listeners so that scrolling works // Remove mouse wheel listeners so that scrolling works
for (MouseWheelListener l : cardPanel.getMouseWheelListeners()) { // Scrolling works on all areas without cards or by using the scroll bar, that's enough
cardPanel.removeMouseWheelListener(l); // for (MouseWheelListener l : cardPanel.getMouseWheelListeners()) {
} // cardPanel.removeMouseWheelListener(l);
// }
// Add a click listener for selection / drag start // Add a click listener for selection / drag start
cardPanel.addMouseListener(new MouseAdapter() { cardPanel.addMouseListener(new MouseAdapter() {
@Override @Override
@ -1164,15 +1649,13 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} else if (SwingUtilities.isLeftMouseButton(e)) { } else if (SwingUtilities.isLeftMouseButton(e)) {
if (e.getClickCount() == 1) { if (e.getClickCount() == 1) {
cardClicked(card, e); cardClicked(card, e);
} else { } else if (e.isAltDown()) {
if (e.isAltDown()) {
eventSource.altDoubleClick(card, "alt-double-click"); eventSource.altDoubleClick(card, "alt-double-click");
} else { } else {
eventSource.doubleClick(card, "double-click"); eventSource.doubleClick(card, "double-click");
} }
} }
} }
}
}); });
// Add a motion listener to process drags // Add a motion listener to process drags
@ -1192,9 +1675,19 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// And add it // And add it
cardContent.add(cardPanel); cardContent.add(cardPanel);
cardViews.put(card.getId(), cardPanel); cardViews.put(card.getId(), cardPanel);
if (duplicated) {
sortIntoGrid(card);
eventSource.addSpecificCard(card, "add-specific-card");
// Update layout
layoutGrid();
// Update draw
cardScroll.revalidate();
repaint();
}
} }
private ArrayList<DragCardGridListener> listeners = new ArrayList<>(); private final ArrayList<DragCardGridListener> listeners = new ArrayList<>();
public void addDragCardGridListener(DragCardGridListener l) { public void addDragCardGridListener(DragCardGridListener l) {
listeners.add(l); listeners.add(l);
@ -1214,14 +1707,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
card.setSelected(true); card.setSelected(true);
cardViews.get(card.getId()).update(card); cardViews.get(card.getId()).update(card);
} }
} else { } else if (card.isSelected()) {
if (card.isSelected()) {
card.setSelected(false); card.setSelected(false);
cardViews.get(card.getId()).update(card); cardViews.get(card.getId()).update(card);
} }
} }
} }
}
private void toggleSelected(CardView targetCard) { private void toggleSelected(CardView targetCard) {
targetCard.setSelected(!targetCard.isSelected()); targetCard.setSelected(!targetCard.isSelected());
@ -1251,12 +1742,14 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} }
/** /**
* Add a card to the cardGrid, in the position that the current sort dictates * Add a card to the cardGrid, in the position that the current sort
* dictates
*
* @param newCard Card to add to the cardGrid array. * @param newCard Card to add to the cardGrid array.
*/ */
private void sortIntoGrid(CardView newCard) { private void sortIntoGrid(CardView newCard) {
// Ensure row 1 exists // Ensure row 1 exists
if (cardGrid.size() == 0) { if (cardGrid.isEmpty()) {
cardGrid.add(0, new ArrayList<>()); cardGrid.add(0, new ArrayList<>());
maxStackSize.add(0, 0); maxStackSize.add(0, 0);
} }
@ -1321,7 +1814,8 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} }
/** /**
* Delete any empty columns / rows from the grid, and eleminate any empty space in stacks * Delete any empty columns / rows from the grid, and eleminate any empty
* space in stacks
*/ */
private void trimGrid() { private void trimGrid() {
// Compact stacks and rows // Compact stacks and rows
@ -1460,12 +1954,14 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} }
/** /**
* Note: This class can't just be a JPanel, because a JPanel doesn't draw when it has Opaque = false, but * Note: This class can't just be a JPanel, because a JPanel doesn't draw when
* this class needs to go into a JLayeredPane while being translucent, so it NEEDS Opaque = false in order * it has Opaque = false, but this class needs to go into a JLayeredPane while
* to behave correctly. * being translucent, so it NEEDS Opaque = false in order to behave correctly.
* Thus this simple class is needed to implement a translucent box in a JLayeredPane. * Thus this simple class is needed to implement a translucent box in a
* JLayeredPane.
*/ */
class SelectionBox extends JComponent { class SelectionBox extends JComponent {
public SelectionBox() { public SelectionBox() {
setOpaque(false); setOpaque(false);
} }