diff --git a/Mage.Client/src/main/java/mage/client/cards/CardArea.java b/Mage.Client/src/main/java/mage/client/cards/CardArea.java index 6fad717b2a2..8ebd826c3e8 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardArea.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardArea.java @@ -148,7 +148,7 @@ public class CardArea extends JPanel implements MouseListener { tmp.setAbility(card); // cross-reference, required for ability picker card = tmp; } - MageCard cardPanel = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, true); + MageCard cardPanel = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, true, true); cardPanel.setBounds(rectangle); cardPanel.addMouseListener(this); diff --git a/Mage.Client/src/main/java/mage/client/cards/CardDraggerGlassPane.java b/Mage.Client/src/main/java/mage/client/cards/CardDraggerGlassPane.java index 738d229d084..2ca05863488 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardDraggerGlassPane.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardDraggerGlassPane.java @@ -59,7 +59,7 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener currentCards = new ArrayList<>(source.dragCardList()); // Make a view for the first one and add it to us - dragView = Plugins.getInstance().getMageCard(currentCards.get(0), null, new Dimension(100, 140), null, true); + dragView = Plugins.getInstance().getMageCard(currentCards.get(0), null, new Dimension(100, 140), null, true, false); for (MouseListener l: dragView.getMouseListeners()) { dragView.removeMouseListener(l); } @@ -132,11 +132,11 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener glassPane.remove(dragView); glassPane.repaint(); - // Update the target, and do the drop - updateCurrentTarget(e, true); - // Let the drag source know source.dragCardEnd(currentDragTarget); + + // Update the target, and do the drop + updateCurrentTarget(e, true); } @Override diff --git a/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java b/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java index a19939f8e7f..0327dc887d9 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardEventSource.java @@ -58,11 +58,7 @@ public class CardEventSource implements EventSource, Serializable { dispatcher.fireEvent(new Event(card, message)); } - public void addSpecificCardSideboard(SimpleCardView card, String message) { - dispatcher.fireEvent(new Event(card, message)); - } - - public void addSpecificCardMaindeck(SimpleCardView card, String message) { + public void addSpecificCard(SimpleCardView card, String message) { dispatcher.fireEvent(new Event(card, message)); } 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 e1b407004b0..4ba0d96b5d3 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardGrid.java @@ -134,7 +134,7 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener, } private void addCard(CardView card, BigCard bigCard, UUID gameId, boolean drawImage) { - MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, drawImage); + MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, drawImage, true); cards.put(card.getId(), cardImg); cardImg.addMouseListener(this); add(cardImg); diff --git a/Mage.Client/src/main/java/mage/client/cards/Cards.java b/Mage.Client/src/main/java/mage/client/cards/Cards.java index d4b91472b65..8cd01f78ac7 100644 --- a/Mage.Client/src/main/java/mage/client/cards/Cards.java +++ b/Mage.Client/src/main/java/mage/client/cards/Cards.java @@ -265,7 +265,7 @@ public class Cards extends javax.swing.JPanel { } private void addCard(CardView card, BigCard bigCard, UUID gameId) { - MageCard mageCard = Plugins.getInstance().getMageCard(card, bigCard, getCardDimension(), gameId, true); + MageCard mageCard = Plugins.getInstance().getMageCard(card, bigCard, getCardDimension(), gameId, true, true); if (zone != null) { mageCard.setZone(zone); } 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 e27eed4806a..012abe40999 100644 --- a/Mage.Client/src/main/java/mage/client/cards/CardsList.java +++ b/Mage.Client/src/main/java/mage/client/cards/CardsList.java @@ -421,7 +421,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar } private MageCard addCard(CardView card, BigCard bigCard, UUID gameId) { - MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, true); + MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, true, true); cardArea.add(cardImg); cardImg.update(card); cardImg.addMouseListener(this); diff --git a/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java b/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java index 14ec6de8b2d..4dc525154a7 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DraftGrid.java @@ -128,7 +128,7 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener { List sortedCards = new ArrayList<>(booster.values()); Collections.sort(sortedCards, new CardViewRarityComparator()); for (CardView card: sortedCards) { - MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, dimension, null, true); + MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, dimension, null, true, true); cardImg.addMouseListener(this); add(cardImg); cardImg.update(card); diff --git a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java index 788c9fb6766..cd8c96e7b2a 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java @@ -10,27 +10,21 @@ import mage.client.util.*; import mage.client.util.Event; import mage.constants.CardType; import mage.game.GameException; -import mage.interfaces.plugin.CardPlugin; import mage.view.CardView; import mage.view.CardsView; import org.apache.log4j.Logger; import org.mage.card.arcane.CardRenderer; -import org.mage.plugins.card.CardPluginImpl; import javax.swing.*; -import javax.swing.border.EtchedBorder; +import javax.swing.border.Border; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import java.awt.*; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.FlavorMap; -import java.awt.dnd.*; import java.awt.event.*; import java.io.File; import java.io.IOException; -import java.lang.reflect.Array; import java.util.*; /** @@ -77,6 +71,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } trimGrid(); layoutGrid(); + cardScroll.revalidate(); cardScroll.repaint(); } } @@ -318,18 +313,14 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg // Remove empty rows / cols / spaces in stacks trimGrid(); layoutGrid(); + cardScroll.revalidate(); cardScroll.repaint(); } else { // Add new cards to grid for (CardView card : cards) { card.setSelected(true); - addCardView(card, lastBigCard); - if (role == Role.SIDEBOARD) { - eventSource.addSpecificCardSideboard(card, "add-specific-card-sideboard"); - } else if (role == Role.MAINDECK) { - eventSource.addSpecificCardMaindeck(card, "add-specific-card-maindeck"); - } - + addCardView(card); + eventSource.addSpecificCard(card, "add-specific-card"); } layoutGrid(); cardContent.repaint(); @@ -338,6 +329,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg public void changeGUISize() { layoutGrid(); + cardScroll.getVerticalScrollBar().setUnitIncrement(CardRenderer.getCardTopHeight(getCardWidth())); cardContent.repaint(); } @@ -365,6 +357,25 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg public void setRole(Role role) { this.role = role; + updateCounts(); + } + + public void removeSelection() { + for (ArrayList> gridRow : cardGrid) { + for (ArrayList stack : gridRow) { + for (int i = 0; i < stack.size(); ++i) { + CardView card = stack.get(i); + if (card.isSelected()) { + eventSource.removeSpecificCard(card, "remove-specific-card"); + stack.set(i, null); + removeCardView(card); + } + } + } + } + trimGrid(); + layoutGrid(); + cardContent.repaint(); } public enum Sort { @@ -395,7 +406,46 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg private String text; } + private abstract class CardTypeCounter { + protected abstract boolean is(CardView card); + int get() { + return count; + } + void add(CardView card) { + if (is(card)) { + ++count; + } + } + void remove(CardView card) { + if (is(card)) { + --count; + } + } + private int count = 0; + } + + // Counters we use + private CardTypeCounter creatureCounter = new CardTypeCounter() { + @Override + protected boolean is(CardView card) { + return card.getCardTypes().contains(CardType.CREATURE); + } + }; + private CardTypeCounter landCounter = new CardTypeCounter() { + @Override + protected boolean is(CardView card) { + return card.getCardTypes().contains(CardType.LAND); + } + }; + private CardTypeCounter[] allCounters = {creatureCounter, landCounter}; + + // Listener + public interface DragCardGridListener { + void cardsSelected(); + void hideCards(Collection card); + void showAll(); + }; // Constants public static int COUNT_LABEL_HEIGHT = 20; @@ -417,6 +467,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg // Top bar with dropdowns for sort / filter / etc JButton sortButton; JButton filterButton; + JButton visibilityButton; // Popup for toolbar JPopupMenu filterPopup; @@ -424,6 +475,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg JPopupMenu sortPopup; JCheckBox separateCreaturesCb; + JLabel deckNameAndCountLabel; + JLabel landCountLabel; + JLabel creatureCountLabel; + // Main two controls holding the scrollable card grid JScrollPane cardScroll; JLayeredPane cardContent; @@ -440,7 +495,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg float cardSizeMod = 1.0f; // The role (maindeck or sideboard) - Role role; + Role role = Role.MAINDECK; // Dragging private CardDraggerGlassPane dragger = new CardDraggerGlassPane(this); @@ -456,8 +511,18 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg private boolean separateCreatures = true; public enum Role { - MAINDECK, - SIDEBOARD + MAINDECK("Maindeck"), + SIDEBOARD("Sideboard"); + + Role(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + private String name; } // Constructor @@ -467,10 +532,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg // Component init setLayout(new BorderLayout()); + setOpaque(false); // Toolbar sortButton = new JButton("Sort"); filterButton = new JButton("Filter"); + visibilityButton = new JButton("Visibility"); addFocusListener(new FocusAdapter() { @Override @@ -488,17 +555,32 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } }); + // Name and count label + deckNameAndCountLabel = new JLabel(); + + // Count labels + landCountLabel = new JLabel("", new ImageIcon(getClass().getResource("/buttons/type_land.png")), SwingConstants.LEFT); + landCountLabel.setToolTipText("Number of lands in deck"); + creatureCountLabel = new JLabel("", new ImageIcon(getClass().getResource("/buttons/type_creatures.png")), SwingConstants.LEFT); + creatureCountLabel.setToolTipText("Number of creatures in deck"); + JPanel toolbar = new JPanel(new BorderLayout()); JPanel toolbarInner = new JPanel(); - //toolbar.setBackground(new Color(250, 250, 250, 150)); + toolbar.setBackground(new Color(250, 250, 250, 150)); toolbar.setOpaque(true); toolbarInner.setOpaque(false); + toolbarInner.add(deckNameAndCountLabel); + toolbarInner.add(landCountLabel); + toolbarInner.add(creatureCountLabel); toolbarInner.add(sortButton); toolbarInner.add(filterButton); + toolbarInner.add(visibilityButton); toolbarInner.add(loadButton); toolbar.add(toolbarInner, BorderLayout.WEST); JPanel sliderPanel = new JPanel(new GridBagLayout()); + sliderPanel.setOpaque(false); final JSlider sizeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 50); + sizeSlider.setOpaque(false); sizeSlider.setPreferredSize(new Dimension(100, (int)sizeSlider.getPreferredSize().getHeight())); sizeSlider.addChangeListener(new ChangeListener() { @Override @@ -522,16 +604,22 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg // Content cardContent = new JLayeredPane(); cardContent.setLayout(null); + cardContent.setOpaque(false); cardContent.addMouseListener(new MouseAdapter() { + private boolean isDragging = false; @Override public void mousePressed(MouseEvent e) { + isDragging = true; beginSelectionDrag(e.getX(), e.getY()); updateSelectionDrag(e.getX(), e.getY()); } @Override public void mouseReleased(MouseEvent e) { - updateSelectionDrag(e.getX(), e.getY()); - endSelectionDrag(e.getX(), e.getY()); + if (isDragging) { + isDragging = false; + updateSelectionDrag(e.getX(), e.getY()); + endSelectionDrag(e.getX(), e.getY()); + } } }); cardContent.addMouseMotionListener(new MouseAdapter() { @@ -543,6 +631,11 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg cardScroll = new JScrollPane(cardContent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + cardScroll.setOpaque(false); + cardScroll.getViewport().setOpaque(false); + cardScroll.setViewportBorder(BorderFactory.createEmptyBorder()); + cardScroll.setBorder(BorderFactory.createLineBorder(Color.gray, 1)); + cardScroll.getVerticalScrollBar().setUnitIncrement(CardRenderer.getCardTopHeight(getCardWidth())); this.add(cardScroll, BorderLayout.CENTER); // Insert arrow @@ -616,6 +709,33 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg makeButtonPopup(sortButton, sortPopup); } + // Visibility popup + { + final JPopupMenu visPopup = new JPopupMenu(); + JMenuItem hideSelected = new JMenuItem("Hide selected"); + hideSelected.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + hideSelection(); + } + }); + visPopup.add(hideSelected); + JMenuItem showAll = new JMenuItem("Show all"); + showAll.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showAll(); + } + }); + visPopup.add(showAll); + visibilityButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + visPopup.show(e.getComponent(), 0, e.getComponent().getHeight()); + } + }); + } + // Filter popup filterPopup = new JPopupMenu(); filterPopup.setPreferredSize(new Dimension(300, 300)); @@ -624,12 +744,76 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg filterButton.setVisible(false); loadButton.setVisible(false); + // Right click in card area + initCardAreaPopup(); + + // Update counts + updateCounts(); + } + + public void initCardAreaPopup() { + final JPopupMenu menu = new JPopupMenu(); + + final JMenuItem hideSelected = new JMenuItem("Hide selected"); + hideSelected.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + hideSelection(); + } + }); + menu.add(hideSelected); + + JMenuItem showAll = new JMenuItem("Show all"); + showAll.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showAll(); + } + }); + menu.add(showAll); + + JMenu sortMenu = new JMenu("Sort by..."); + for (final Sort sort : Sort.values()) { + JMenuItem subSort = new JMenuItem(sort.getText()); + subSort.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + cardSort = sort; + resort(); + } + }); + sortMenu.add(subSort); + } + sortMenu.add(new JPopupMenu.Separator()); + final JCheckBoxMenuItem separateButton = new JCheckBoxMenuItem("Separate creatures"); + separateButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + separateCreatures = !separateCreatures; + separateCreaturesCb.setSelected(separateCreatures); + resort(); + } + }); + sortMenu.add(separateButton); + menu.add(sortMenu); + + // Hook up to card content + cardContent.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + hideSelected.setEnabled(dragCardList().size() > 0); + separateButton.setSelected(separateCreatures); + menu.show(e.getComponent(), e.getX(), e.getY()); + } + } + }); } /** * Deselect all cards in this DragCardGrid */ - private void deselectAll() { + public void deselectAll() { for (ArrayList> gridRow : cardGrid) { for (ArrayList stack : gridRow) { for (CardView card : stack) { @@ -642,6 +826,19 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } } + private void hideSelection() { + Collection toHide = dragCardList(); + for (DragCardGridListener l : listeners) { + l.hideCards(toHide); + } + } + + private void showAll() { + for (DragCardGridListener l : listeners) { + l.showAll(); + } + } + /** * Selection drag handling */ @@ -654,6 +851,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg // Store the drag start location selectionDragStartX = x; selectionDragStartY = y; + + // Notify selection + notifyCardsSelected(); } private void updateSelectionDrag(int x, int y) { @@ -738,7 +938,6 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg try { setCursor(new Cursor(Cursor.WAIT_CURSOR)); Deck deck = Deck.load(DeckImporterUtil.importDeck(file.getPath()), true, true); - Logger.getLogger(DragCardGrid.class).info("Loaded " + deck.getCards().size()); setCards(new CardsView(deck.getCards()), null); } catch (GameException ex) { JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); @@ -767,6 +966,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } trimGrid(); + // First sort all cards by name + Collections.sort(allCards, new CardViewNameComparator()); + // Now re-insert all of the cards using the current sort for (CardView card : allCards) { sortIntoGrid(card); @@ -810,7 +1012,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg for (CardView newCard: cardsView.values()) { if (!cardViews.containsKey(newCard.getId())) { // Is a new card - addCardView(newCard, bigCard); + addCardView(newCard); try { // Put it into the appropirate place in the grid given the current sort @@ -837,27 +1039,73 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } } - private void addCardView(final CardView card, BigCard bigCard) { + private void updateCounts() { + deckNameAndCountLabel.setText(role.getName() + " - " + allCards.size()); + creatureCountLabel.setText("" + creatureCounter.get()); + landCountLabel.setText("" + landCounter.get()); + } + + private void showCardRightClickMenu(final CardView card, MouseEvent e) { + JPopupMenu menu = new JPopupMenu(); + JMenuItem hide = new JMenuItem("Hide"); + hide.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + //if (card.isSelected() && dragCardList().size() > 1) { + // Hide all selected + hideSelection(); + //} + } + }); + menu.add(hide); + menu.show(e.getComponent(), e.getX(), e.getY()); + } + + private void addCardView(final CardView card) { allCards.add(card); + // Update counts + for (CardTypeCounter counter : allCounters) { + counter.add(card); + } + updateCounts(); + // Create the card view - final MageCard cardPanel = Plugins.getInstance().getMageCard(card, bigCard, new Dimension(100, 140), null, true); + final MageCard cardPanel = Plugins.getInstance().getMageCard(card, lastBigCard, new Dimension(100, 140), null, true, true); + cardPanel.update(card); cardPanel.setTextOffset(0); + // Remove mouse wheel listeners so that scrolling works + 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 (e.getClickCount() == 1) { - cardClicked(card, e); - } else { - if (e.isAltDown()) { - eventSource.altDoubleClick(card, "alt-double-click"); + 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 { - eventSource.doubleClick(card, "double-click"); + if (e.isAltDown()) { + eventSource.altDoubleClick(card, "alt-double-click"); + } else { + eventSource.doubleClick(card, "double-click"); + } } } } }); + + // Add a motion listener to process drags cardPanel.addMouseMotionListener(new MouseAdapter() { @Override public void mouseDragged(MouseEvent e) { @@ -876,7 +1124,19 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg cardViews.put(card.getId(), cardPanel); } - private void cardClicked(CardView targetCard, MouseEvent e) { + private ArrayList listeners = new ArrayList<>(); + + public void addDragCardGridListener(DragCardGridListener l) { + listeners.add(l); + } + + private void notifyCardsSelected() { + for (DragCardGridListener listener : listeners) { + listener.cardsSelected(); + } + } + + private void selectCard(CardView targetCard) { // Set the selected card to the target card for (CardView card : allCards) { if (card == targetCard) { @@ -893,8 +1153,20 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } } + private void cardClicked(CardView targetCard, MouseEvent e) { + selectCard(targetCard); + notifyCardsSelected(); + } + private void removeCardView(CardView card) { allCards.remove(card); + + // Remove fromcounts + for (CardTypeCounter counter : allCounters) { + counter.remove(card); + } + updateCounts(); + cardContent.remove(cardViews.get(card.getId())); cardViews.remove(card.getId()); } @@ -1064,6 +1336,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } if (stackCountLabels.get(rowIndex).size() <= colIndex) { JLabel countLabel = new JLabel("", SwingConstants.CENTER); + countLabel.setForeground(Color.WHITE); cardContent.add(countLabel, new Integer(0)); stackCountLabels.get(rowIndex).add(countLabel); } @@ -1103,23 +1376,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } private static void makeButtonPopup(final AbstractButton button, final JPopupMenu popup) { - button.addMouseListener(new MouseAdapter() { + button.addActionListener(new ActionListener() { @Override - public void mouseClicked(MouseEvent e) { + public void actionPerformed(ActionEvent e) { popup.show(button, 0, button.getHeight()); } }); - popup.addPopupMenuListener(new PopupMenuListener() { - @Override - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { - button.setSelected(false); - } - - @Override - public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} - @Override - public void popupMenuCanceled(PopupMenuEvent e) {} - }); } public static void main(String[] args) { diff --git a/Mage.Client/src/main/java/mage/client/components/ext/dlg/impl/ChoiceDialog.java b/Mage.Client/src/main/java/mage/client/components/ext/dlg/impl/ChoiceDialog.java index cb6c9779b17..b9dccca8050 100644 --- a/Mage.Client/src/main/java/mage/client/components/ext/dlg/impl/ChoiceDialog.java +++ b/Mage.Client/src/main/java/mage/client/components/ext/dlg/impl/ChoiceDialog.java @@ -162,7 +162,7 @@ public class ChoiceDialog extends IDialogPanel { } CardView card = cardList.get(i); - MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, getCardDimension(), gameId, true); + MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, getCardDimension(), gameId, true, true); cardImg.setLocation(dx, dy + j*(height + 30)); add(cardImg); diff --git a/Mage.Client/src/main/java/mage/client/components/ext/dlg/impl/StackDialog.java b/Mage.Client/src/main/java/mage/client/components/ext/dlg/impl/StackDialog.java index 9c239e29bc3..3748528ca45 100644 --- a/Mage.Client/src/main/java/mage/client/components/ext/dlg/impl/StackDialog.java +++ b/Mage.Client/src/main/java/mage/client/components/ext/dlg/impl/StackDialog.java @@ -124,7 +124,7 @@ public class StackDialog extends IDialogPanel { card = tmp; } - MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, getCardDimension(), gameId, true); + MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, getCardDimension(), gameId, true, true); //cardImg.setBorder(BorderFactory.createLineBorder(Color.red)); cardImg.setLocation(dx, dy); 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 5dc6e5961b9..357dc99d2db 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/CardSelector.java @@ -1234,6 +1234,6 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene @Override public void dragCardDrop(MouseEvent e, DragCardSource source, Collection cards) { - // Nothing to do, just eat the dropped cards, they're being removed from the deck or sideboard + // Need to add cards back to tally } } 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 8793b97cc4b..68dd871c894 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckArea.java @@ -32,18 +32,20 @@ */ package mage.client.deckeditor; +import mage.cards.Card; import mage.cards.decks.Deck; import mage.client.cards.BigCard; -import mage.client.cards.CardsList; +import mage.client.cards.CardEventSource; import mage.client.cards.DragCardGrid; import mage.client.constants.Constants.DeckEditorMode; import mage.client.util.Event; import mage.client.util.GUISizeHelper; import mage.client.util.Listener; +import mage.view.CardView; import mage.view.CardsView; -import org.apache.log4j.Logger; import javax.swing.*; +import java.util.*; /** * @@ -51,6 +53,12 @@ import javax.swing.*; */ public class DeckArea extends javax.swing.JPanel { + private CardEventSource maindeckVirtualEvent = new CardEventSource(); + private CardEventSource sideboardVirtualEvent = new CardEventSource(); + private Set hiddenCards = new HashSet<>(); + private Deck lastDeck = new Deck(); + private BigCard lastBigCard = null; + /** * Creates new form DeckArea */ @@ -61,6 +69,52 @@ public class DeckArea extends javax.swing.JPanel { //sideboardList.setOpaque(false); deckList.setRole(DragCardGrid.Role.MAINDECK); sideboardList.setRole(DragCardGrid.Role.SIDEBOARD); + + // When a selection happens in one pane, deselect the selection in the other + deckList.addDragCardGridListener(new DragCardGrid.DragCardGridListener() { + @Override + public void cardsSelected() { + sideboardList.deselectAll(); + } + + @Override + public void hideCards(Collection cards) { + // Add to hidden and move to sideboard + for (CardView card : cards) { + hiddenCards.add(card.getId()); + maindeckVirtualEvent.removeSpecificCard(card, "remove-specific-card"); + sideboardVirtualEvent.addSpecificCard(card, "add-specific-card"); + } + loadDeck(lastDeck, lastBigCard); + } + + @Override + public void showAll() { + hiddenCards.clear(); + loadDeck(lastDeck, lastBigCard); + } + }); + sideboardList.addDragCardGridListener(new DragCardGrid.DragCardGridListener() { + @Override + public void cardsSelected() { + deckList.deselectAll(); + } + + @Override + public void hideCards(Collection cards) { + // Just add to hidden, already in sideboard + for (CardView card : cards) { + hiddenCards.add(card.getId()); + } + loadDeck(lastDeck, lastBigCard); + } + + @Override + public void showAll() { + hiddenCards.clear(); + loadDeck(lastDeck, lastBigCard); + } + }); } public void cleanUp() { @@ -96,16 +150,28 @@ public class DeckArea extends javax.swing.JPanel { //this.sideboardList.setDeckEditorMode(mode); } + private Set filterHidden(Set cards) { + Set newSet = new LinkedHashSet<>(); + for (Card card : cards) { + if (!hiddenCards.contains(card.getId())) { + newSet.add(card); + } + } + return newSet; + } + public void loadDeck(Deck deck, BigCard bigCard) { - deckList.setCards(new CardsView(deck.getCards()), bigCard); - Logger.getLogger(DeckArea.class).info("Loading, sideboard is visible=" + sideboardList.isVisible()); + lastDeck = deck; + lastBigCard = bigCard; + deckList.setCards(new CardsView(filterHidden(lastDeck.getCards())), lastBigCard); if (sideboardList.isVisible()) { - sideboardList.setCards(new CardsView(deck.getSideboard()), bigCard); + sideboardList.setCards(new CardsView(filterHidden(lastDeck.getSideboard())), lastBigCard); } } public void addDeckEventListener(Listener listener) { deckList.addCardEventListener(listener); + maindeckVirtualEvent.addListener(listener); } public void clearDeckEventListeners() { @@ -114,6 +180,7 @@ public class DeckArea extends javax.swing.JPanel { public void addSideboardEventListener(Listener listener) { sideboardList.addCardEventListener(listener); + sideboardVirtualEvent.addListener(listener); } public void clearSideboardEventListeners() { 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 53f5d35ec00..3e4a9f77f2c 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -81,6 +81,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { private final JFileChooser fcSelectDeck; private final JFileChooser fcImportDeck; private Deck deck = new Deck(); + private Map temporaryCards = new HashMap<>(); // Cards dragged out of one part of the view into another private boolean isShowCardInfo = false; private UUID tableId; private DeckEditorMode mode; @@ -104,7 +105,12 @@ public class DeckEditorPanel extends javax.swing.JPanel { deckArea.setOpaque(false); jPanel1.setOpaque(false); jSplitPane1.setOpaque(false); - jSplitPane1.setResizeWeight(0.3); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + jSplitPane1.setDividerLocation(0.3); + } + }); countdown = new Timer(1000, new ActionListener() { @Override @@ -160,25 +166,25 @@ public class DeckEditorPanel extends javax.swing.JPanel { switch (mode) { case LIMITED_BUILDING: - this.deckArea.setOrientation(/*limitedBuildingOrientation = */true); this.btnAddLand.setVisible(true); this.txtTimeRemaining.setVisible(true); + // Fall through to sideboarding case SIDEBOARDING: this.btnSubmit.setVisible(true); this.btnSubmitTimer.setVisible(true); - if (deck != null) { - this.cardSelector.loadSideboard(new ArrayList<>(deck.getSideboard()), this.bigCard); + if (mode == DeckEditorMode.SIDEBOARDING) { + this.deckArea.setOrientation(/*limitedBuildingOrientation = */false); + } else /*(if (mode == LIMITED_BUILDING)*/ { + this.deckArea.setOrientation(/*limitedBuildingOrientation = */true); } - // TODO: take from preferences - this.deckArea.setOrientation(/*limitedBuildingOrientation = */false); - this.cardSelector.switchToGrid(); + this.cardSelector.setVisible(false); this.btnExit.setVisible(false); this.btnImport.setVisible(false); this.btnGenDeck.setVisible(false); if (!SessionHandler.isTestMode()) { this.btnLoad.setVisible(false); } - this.deckArea.showSideboard(false); + this.deckArea.showSideboard(true); countdown.stop(); this.timeout = time; setTimeout(timeout); @@ -195,6 +201,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { this.btnSubmit.setVisible(false); this.btnSubmitTimer.setVisible(false); this.btnAddLand.setVisible(true); + this.cardSelector.setVisible(true); this.cardSelector.loadCards(this.bigCard); //this.cardTableSelector.loadCards(this.bigCard); this.btnExit.setVisible(true); @@ -211,8 +218,24 @@ public class DeckEditorPanel extends javax.swing.JPanel { this.deckArea.setDeckEditorMode(mode); } + private Card retrieveTemporaryCard(SimpleCardView cardView) { + Card card = temporaryCards.get(cardView.getId()); + if (card == null) { + // Need to make a new card + card = CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber()).getCard(); + } else { + // Only need a temporary card once + temporaryCards.remove(cardView.getId()); + } + return card; + } + + private void storeTemporaryCard(Card card) { + temporaryCards.put(card.getId(), card); + } + private void init() { - this.cardSelector.setVisible(true); + //this.cardSelector.setVisible(true); this.jPanel1.setVisible(true); for (ICardGrid component : this.cardSelector.getCardGridComponents()) { component.clearCardEventListeners(); @@ -233,10 +256,10 @@ public class DeckEditorPanel extends javax.swing.JPanel { } break; case "remove-main": - //DeckEditorPanel.this.deckArea.getDeckList().handleDoubleClick(); + DeckEditorPanel.this.deckArea.getDeckList().removeSelection(); break; case "remove-sideboard": - //DeckEditorPanel.this.deckArea.getSideboardList().handleDoubleClick(); + DeckEditorPanel.this.deckArea.getSideboardList().removeSelection(); break; } refreshDeck(); @@ -277,19 +300,23 @@ public class DeckEditorPanel extends javax.swing.JPanel { } case "set-number": { setCardNumberToCardsList(event, deck.getCards()); + break; } case "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; } } + break; } - case "add-specific-card-maindeck": { + case "add-specific-card": { SimpleCardView cardView = (CardView) event.getSource(); - deck.getCards().add(CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber()).getCard()); + deck.getCards().add(retrieveTemporaryCard(cardView)); + break; } } } else { @@ -315,13 +342,16 @@ public class DeckEditorPanel extends javax.swing.JPanel { for (Card card : deck.getCards()) { if (card.getId().equals(cardView.getId())) { deck.getCards().remove(card); + storeTemporaryCard(card); break; } } + break; } - case "add-specific-card-maindeck": { + case "add-specific-card": { SimpleCardView cardView = (CardView) event.getSource(); - deck.getCards().add(CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber()).getCard()); + deck.getCards().add(retrieveTemporaryCard(cardView)); + break; } } } @@ -362,19 +392,23 @@ public class DeckEditorPanel extends javax.swing.JPanel { 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; } } + break; } - case "add-specific-card-sideboard": { + case "add-specific-card": { cardView = (CardView) event.getSource(); - deck.getSideboard().add(CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber()).getCard()); + deck.getSideboard().add(retrieveTemporaryCard(cardView)); + break; } } } else { @@ -385,13 +419,16 @@ public class DeckEditorPanel extends javax.swing.JPanel { for (Card card : deck.getSideboard()) { if (card.getId().equals(cardView.getId())) { deck.getSideboard().remove(card); + storeTemporaryCard(card); break; } } + break; } - case "add-specific-card-sideboard": { + case "add-specific-card": { SimpleCardView cardView = (CardView) event.getSource(); - deck.getSideboard().add(CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber()).getCard()); + deck.getSideboard().add(retrieveTemporaryCard(cardView)); + break; } case "double-click": case "alt-double-click": diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java b/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java index 63aaac456ad..4a0f99bbb9a 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java @@ -249,7 +249,7 @@ public class MageBook extends JComponent { if (cardDimension == null) { cardDimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight); } - final MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, true); + final MageCard cardImg = Plugins.getInstance().getMageCard(card, bigCard, cardDimension, gameId, true, true); cardImg.setBounds(rectangle); jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10); cardImg.update(card); 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 b04ea767242..4790245038e 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java +++ b/Mage.Client/src/main/java/mage/client/plugins/MagePlugins.java @@ -25,7 +25,7 @@ public interface MagePlugins { MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage); - MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage); + MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable); boolean isThemePluginLoaded(); 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 054e6aaa52f..b49551e60f6 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 @@ -107,10 +107,12 @@ public class Plugins implements MagePlugins { } @Override - public MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage) { + public MageCard getMageCard(CardView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage, boolean previewable) { if (cardPlugin != null) { - mageActionCallback.refreshSession(); - mageActionCallback.setCardPreviewComponent(bigCard); + if (previewable) { + mageActionCallback.refreshSession(); + mageActionCallback.setCardPreviewComponent(bigCard); + } return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage); } else { return new Card(card, bigCard, Config.dimensions, gameId);