Finished the new Drag & Drop deck view. It is currently implemented in main deck editor, and limited deck construction.

Still to do:
* Integrate it into the draft view
This commit is contained in:
Mark Langen 2016-09-28 20:55:26 -06:00
parent 56a3c6dc8c
commit 615b93f8c3
16 changed files with 455 additions and 91 deletions

View file

@ -148,7 +148,7 @@ public class CardArea extends JPanel implements MouseListener {
tmp.setAbility(card); // cross-reference, required for ability picker tmp.setAbility(card); // cross-reference, required for ability picker
card = tmp; 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.setBounds(rectangle);
cardPanel.addMouseListener(this); cardPanel.addMouseListener(this);

View file

@ -59,7 +59,7 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener
currentCards = new ArrayList<>(source.dragCardList()); currentCards = new ArrayList<>(source.dragCardList());
// Make a view for the first one and add it to us // 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()) { for (MouseListener l: dragView.getMouseListeners()) {
dragView.removeMouseListener(l); dragView.removeMouseListener(l);
} }
@ -132,11 +132,11 @@ public class CardDraggerGlassPane implements MouseListener, MouseMotionListener
glassPane.remove(dragView); glassPane.remove(dragView);
glassPane.repaint(); glassPane.repaint();
// Update the target, and do the drop
updateCurrentTarget(e, true);
// Let the drag source know // Let the drag source know
source.dragCardEnd(currentDragTarget); source.dragCardEnd(currentDragTarget);
// Update the target, and do the drop
updateCurrentTarget(e, true);
} }
@Override @Override

View file

@ -58,11 +58,7 @@ public class CardEventSource implements EventSource<Event>, Serializable {
dispatcher.fireEvent(new Event(card, message)); dispatcher.fireEvent(new Event(card, message));
} }
public void addSpecificCardSideboard(SimpleCardView card, String message) { public void addSpecificCard(SimpleCardView card, String message) {
dispatcher.fireEvent(new Event(card, message));
}
public void addSpecificCardMaindeck(SimpleCardView card, String message) {
dispatcher.fireEvent(new Event(card, message)); dispatcher.fireEvent(new Event(card, message));
} }

View file

@ -134,7 +134,7 @@ public class CardGrid extends javax.swing.JLayeredPane implements MouseListener,
} }
private void addCard(CardView card, BigCard bigCard, UUID gameId, boolean drawImage) { 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); cards.put(card.getId(), cardImg);
cardImg.addMouseListener(this); cardImg.addMouseListener(this);
add(cardImg); add(cardImg);

View file

@ -265,7 +265,7 @@ public class Cards extends javax.swing.JPanel {
} }
private void addCard(CardView card, BigCard bigCard, UUID gameId) { 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) { if (zone != null) {
mageCard.setZone(zone); mageCard.setZone(zone);
} }

View file

@ -421,7 +421,7 @@ public class CardsList extends javax.swing.JPanel implements MouseListener, ICar
} }
private MageCard addCard(CardView card, BigCard bigCard, UUID gameId) { 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); cardArea.add(cardImg);
cardImg.update(card); cardImg.update(card);
cardImg.addMouseListener(this); cardImg.addMouseListener(this);

View file

@ -128,7 +128,7 @@ public class DraftGrid extends javax.swing.JPanel implements MouseListener {
List<CardView> sortedCards = new ArrayList<>(booster.values()); List<CardView> sortedCards = new ArrayList<>(booster.values());
Collections.sort(sortedCards, new CardViewRarityComparator()); Collections.sort(sortedCards, new CardViewRarityComparator());
for (CardView card: sortedCards) { 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); cardImg.addMouseListener(this);
add(cardImg); add(cardImg);
cardImg.update(card); cardImg.update(card);

View file

@ -10,27 +10,21 @@ import mage.client.util.*;
import mage.client.util.Event; import mage.client.util.Event;
import mage.constants.CardType; import mage.constants.CardType;
import mage.game.GameException; import mage.game.GameException;
import mage.interfaces.plugin.CardPlugin;
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 org.mage.plugins.card.CardPluginImpl;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.EtchedBorder; import javax.swing.border.Border;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener; import javax.swing.event.PopupMenuListener;
import java.awt.*; import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.FlavorMap;
import java.awt.dnd.*;
import java.awt.event.*; import java.awt.event.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Array;
import java.util.*; import java.util.*;
/** /**
@ -77,6 +71,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} }
trimGrid(); trimGrid();
layoutGrid(); layoutGrid();
cardScroll.revalidate();
cardScroll.repaint(); cardScroll.repaint();
} }
} }
@ -318,18 +313,14 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Remove empty rows / cols / spaces in stacks // Remove empty rows / cols / spaces in stacks
trimGrid(); trimGrid();
layoutGrid(); layoutGrid();
cardScroll.revalidate();
cardScroll.repaint(); cardScroll.repaint();
} else { } else {
// 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, lastBigCard); addCardView(card);
if (role == Role.SIDEBOARD) { eventSource.addSpecificCard(card, "add-specific-card");
eventSource.addSpecificCardSideboard(card, "add-specific-card-sideboard");
} else if (role == Role.MAINDECK) {
eventSource.addSpecificCardMaindeck(card, "add-specific-card-maindeck");
}
} }
layoutGrid(); layoutGrid();
cardContent.repaint(); cardContent.repaint();
@ -338,6 +329,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
public void changeGUISize() { public void changeGUISize() {
layoutGrid(); layoutGrid();
cardScroll.getVerticalScrollBar().setUnitIncrement(CardRenderer.getCardTopHeight(getCardWidth()));
cardContent.repaint(); cardContent.repaint();
} }
@ -365,6 +357,25 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
public void setRole(Role role) { public void setRole(Role role) {
this.role = role; this.role = role;
updateCounts();
}
public void removeSelection() {
for (ArrayList<ArrayList<CardView>> gridRow : cardGrid) {
for (ArrayList<CardView> 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 { public enum Sort {
@ -395,7 +406,46 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
private String text; 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<CardView> card);
void showAll();
};
// Constants // Constants
public static int COUNT_LABEL_HEIGHT = 20; 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 // Top bar with dropdowns for sort / filter / etc
JButton sortButton; JButton sortButton;
JButton filterButton; JButton filterButton;
JButton visibilityButton;
// Popup for toolbar // Popup for toolbar
JPopupMenu filterPopup; JPopupMenu filterPopup;
@ -424,6 +475,10 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
JPopupMenu sortPopup; JPopupMenu sortPopup;
JCheckBox separateCreaturesCb; JCheckBox separateCreaturesCb;
JLabel deckNameAndCountLabel;
JLabel landCountLabel;
JLabel creatureCountLabel;
// Main two controls holding the scrollable card grid // Main two controls holding the scrollable card grid
JScrollPane cardScroll; JScrollPane cardScroll;
JLayeredPane cardContent; JLayeredPane cardContent;
@ -440,7 +495,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
float cardSizeMod = 1.0f; float cardSizeMod = 1.0f;
// The role (maindeck or sideboard) // The role (maindeck or sideboard)
Role role; Role role = Role.MAINDECK;
// Dragging // Dragging
private CardDraggerGlassPane dragger = new CardDraggerGlassPane(this); private CardDraggerGlassPane dragger = new CardDraggerGlassPane(this);
@ -456,8 +511,18 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
private boolean separateCreatures = true; private boolean separateCreatures = true;
public enum Role { public enum Role {
MAINDECK, MAINDECK("Maindeck"),
SIDEBOARD SIDEBOARD("Sideboard");
Role(String name) {
this.name = name;
}
public String getName() {
return name;
}
private String name;
} }
// Constructor // Constructor
@ -467,10 +532,12 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Component init // Component init
setLayout(new BorderLayout()); setLayout(new BorderLayout());
setOpaque(false);
// Toolbar // Toolbar
sortButton = new JButton("Sort"); sortButton = new JButton("Sort");
filterButton = new JButton("Filter"); filterButton = new JButton("Filter");
visibilityButton = new JButton("Visibility");
addFocusListener(new FocusAdapter() { addFocusListener(new FocusAdapter() {
@Override @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 toolbar = new JPanel(new BorderLayout());
JPanel toolbarInner = new JPanel(); JPanel toolbarInner = new JPanel();
//toolbar.setBackground(new Color(250, 250, 250, 150)); toolbar.setBackground(new Color(250, 250, 250, 150));
toolbar.setOpaque(true); toolbar.setOpaque(true);
toolbarInner.setOpaque(false); toolbarInner.setOpaque(false);
toolbarInner.add(deckNameAndCountLabel);
toolbarInner.add(landCountLabel);
toolbarInner.add(creatureCountLabel);
toolbarInner.add(sortButton); toolbarInner.add(sortButton);
toolbarInner.add(filterButton); toolbarInner.add(filterButton);
toolbarInner.add(visibilityButton);
toolbarInner.add(loadButton); toolbarInner.add(loadButton);
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);
final JSlider sizeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 50); final JSlider sizeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 50);
sizeSlider.setOpaque(false);
sizeSlider.setPreferredSize(new Dimension(100, (int)sizeSlider.getPreferredSize().getHeight())); sizeSlider.setPreferredSize(new Dimension(100, (int)sizeSlider.getPreferredSize().getHeight()));
sizeSlider.addChangeListener(new ChangeListener() { sizeSlider.addChangeListener(new ChangeListener() {
@Override @Override
@ -522,16 +604,22 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Content // Content
cardContent = new JLayeredPane(); cardContent = new JLayeredPane();
cardContent.setLayout(null); cardContent.setLayout(null);
cardContent.setOpaque(false);
cardContent.addMouseListener(new MouseAdapter() { cardContent.addMouseListener(new MouseAdapter() {
private boolean isDragging = false;
@Override @Override
public void mousePressed(MouseEvent e) { public void mousePressed(MouseEvent e) {
isDragging = true;
beginSelectionDrag(e.getX(), e.getY()); beginSelectionDrag(e.getX(), e.getY());
updateSelectionDrag(e.getX(), e.getY()); updateSelectionDrag(e.getX(), e.getY());
} }
@Override @Override
public void mouseReleased(MouseEvent e) { public void mouseReleased(MouseEvent e) {
updateSelectionDrag(e.getX(), e.getY()); if (isDragging) {
endSelectionDrag(e.getX(), e.getY()); isDragging = false;
updateSelectionDrag(e.getX(), e.getY());
endSelectionDrag(e.getX(), e.getY());
}
} }
}); });
cardContent.addMouseMotionListener(new MouseAdapter() { cardContent.addMouseMotionListener(new MouseAdapter() {
@ -543,6 +631,11 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
cardScroll = new JScrollPane(cardContent, cardScroll = new JScrollPane(cardContent,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_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); this.add(cardScroll, BorderLayout.CENTER);
// Insert arrow // Insert arrow
@ -616,6 +709,33 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
makeButtonPopup(sortButton, sortPopup); 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 // Filter popup
filterPopup = new JPopupMenu(); filterPopup = new JPopupMenu();
filterPopup.setPreferredSize(new Dimension(300, 300)); filterPopup.setPreferredSize(new Dimension(300, 300));
@ -624,12 +744,76 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
filterButton.setVisible(false); filterButton.setVisible(false);
loadButton.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 * Deselect all cards in this DragCardGrid
*/ */
private void deselectAll() { public void deselectAll() {
for (ArrayList<ArrayList<CardView>> gridRow : cardGrid) { for (ArrayList<ArrayList<CardView>> gridRow : cardGrid) {
for (ArrayList<CardView> stack : gridRow) { for (ArrayList<CardView> stack : gridRow) {
for (CardView card : stack) { for (CardView card : stack) {
@ -642,6 +826,19 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} }
} }
private void hideSelection() {
Collection<CardView> toHide = dragCardList();
for (DragCardGridListener l : listeners) {
l.hideCards(toHide);
}
}
private void showAll() {
for (DragCardGridListener l : listeners) {
l.showAll();
}
}
/** /**
* Selection drag handling * Selection drag handling
*/ */
@ -654,6 +851,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
// Store the drag start location // Store the drag start location
selectionDragStartX = x; selectionDragStartX = x;
selectionDragStartY = y; selectionDragStartY = y;
// Notify selection
notifyCardsSelected();
} }
private void updateSelectionDrag(int x, int y) { private void updateSelectionDrag(int x, int y) {
@ -738,7 +938,6 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
try { try {
setCursor(new Cursor(Cursor.WAIT_CURSOR)); setCursor(new Cursor(Cursor.WAIT_CURSOR));
Deck deck = Deck.load(DeckImporterUtil.importDeck(file.getPath()), true, true); 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); setCards(new CardsView(deck.getCards()), null);
} catch (GameException ex) { } catch (GameException ex) {
JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); 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(); trimGrid();
// First sort all cards by name
Collections.sort(allCards, new CardViewNameComparator());
// Now re-insert all of the cards using the current sort // Now re-insert all of the cards using the current sort
for (CardView card : allCards) { for (CardView card : allCards) {
sortIntoGrid(card); sortIntoGrid(card);
@ -810,7 +1012,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, bigCard); addCardView(newCard);
try { try {
// 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
@ -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); allCards.add(card);
// Update counts
for (CardTypeCounter counter : allCounters) {
counter.add(card);
}
updateCounts();
// Create the card view // 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); 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() { cardPanel.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 1) { if (SwingUtilities.isRightMouseButton(e)) {
cardClicked(card, e); // Select if not selected
} else { if (!card.isSelected()) {
if (e.isAltDown()) { selectCard(card);
eventSource.altDoubleClick(card, "alt-double-click"); }
// Show menu
showCardRightClickMenu(card, e);
} else if (SwingUtilities.isLeftMouseButton(e)) {
if (e.getClickCount() == 1) {
cardClicked(card, e);
} else { } 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() { cardPanel.addMouseMotionListener(new MouseAdapter() {
@Override @Override
public void mouseDragged(MouseEvent e) { public void mouseDragged(MouseEvent e) {
@ -876,7 +1124,19 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
cardViews.put(card.getId(), cardPanel); cardViews.put(card.getId(), cardPanel);
} }
private void cardClicked(CardView targetCard, MouseEvent e) { private ArrayList<DragCardGridListener> 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 // Set the selected card to the target card
for (CardView card : allCards) { for (CardView card : allCards) {
if (card == targetCard) { 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) { private void removeCardView(CardView card) {
allCards.remove(card); allCards.remove(card);
// Remove fromcounts
for (CardTypeCounter counter : allCounters) {
counter.remove(card);
}
updateCounts();
cardContent.remove(cardViews.get(card.getId())); cardContent.remove(cardViews.get(card.getId()));
cardViews.remove(card.getId()); cardViews.remove(card.getId());
} }
@ -1064,6 +1336,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg
} }
if (stackCountLabels.get(rowIndex).size() <= colIndex) { if (stackCountLabels.get(rowIndex).size() <= colIndex) {
JLabel countLabel = new JLabel("", SwingConstants.CENTER); JLabel countLabel = new JLabel("", SwingConstants.CENTER);
countLabel.setForeground(Color.WHITE);
cardContent.add(countLabel, new Integer(0)); cardContent.add(countLabel, new Integer(0));
stackCountLabels.get(rowIndex).add(countLabel); 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) { private static void makeButtonPopup(final AbstractButton button, final JPopupMenu popup) {
button.addMouseListener(new MouseAdapter() { button.addActionListener(new ActionListener() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void actionPerformed(ActionEvent e) {
popup.show(button, 0, button.getHeight()); 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) { public static void main(String[] args) {

View file

@ -162,7 +162,7 @@ public class ChoiceDialog extends IDialogPanel {
} }
CardView card = cardList.get(i); 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)); cardImg.setLocation(dx, dy + j*(height + 30));
add(cardImg); add(cardImg);

View file

@ -124,7 +124,7 @@ public class StackDialog extends IDialogPanel {
card = tmp; 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.setBorder(BorderFactory.createLineBorder(Color.red));
cardImg.setLocation(dx, dy); cardImg.setLocation(dx, dy);

View file

@ -1234,6 +1234,6 @@ public class CardSelector extends javax.swing.JPanel implements ComponentListene
@Override @Override
public void dragCardDrop(MouseEvent e, DragCardSource source, Collection<CardView> cards) { public void dragCardDrop(MouseEvent e, DragCardSource source, Collection<CardView> 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
} }
} }

View file

@ -32,18 +32,20 @@
*/ */
package mage.client.deckeditor; package mage.client.deckeditor;
import mage.cards.Card;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.client.cards.BigCard; import mage.client.cards.BigCard;
import mage.client.cards.CardsList; import mage.client.cards.CardEventSource;
import mage.client.cards.DragCardGrid; import mage.client.cards.DragCardGrid;
import mage.client.constants.Constants.DeckEditorMode; import mage.client.constants.Constants.DeckEditorMode;
import mage.client.util.Event; import mage.client.util.Event;
import mage.client.util.GUISizeHelper; import mage.client.util.GUISizeHelper;
import mage.client.util.Listener; import mage.client.util.Listener;
import mage.view.CardView;
import mage.view.CardsView; import mage.view.CardsView;
import org.apache.log4j.Logger;
import javax.swing.*; import javax.swing.*;
import java.util.*;
/** /**
* *
@ -51,6 +53,12 @@ import javax.swing.*;
*/ */
public class DeckArea extends javax.swing.JPanel { public class DeckArea extends javax.swing.JPanel {
private CardEventSource maindeckVirtualEvent = new CardEventSource();
private CardEventSource sideboardVirtualEvent = new CardEventSource();
private Set<UUID> hiddenCards = new HashSet<>();
private Deck lastDeck = new Deck();
private BigCard lastBigCard = null;
/** /**
* Creates new form DeckArea * Creates new form DeckArea
*/ */
@ -61,6 +69,52 @@ public class DeckArea extends javax.swing.JPanel {
//sideboardList.setOpaque(false); //sideboardList.setOpaque(false);
deckList.setRole(DragCardGrid.Role.MAINDECK); deckList.setRole(DragCardGrid.Role.MAINDECK);
sideboardList.setRole(DragCardGrid.Role.SIDEBOARD); 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<CardView> 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<CardView> 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() { public void cleanUp() {
@ -96,16 +150,28 @@ public class DeckArea extends javax.swing.JPanel {
//this.sideboardList.setDeckEditorMode(mode); //this.sideboardList.setDeckEditorMode(mode);
} }
private Set<Card> filterHidden(Set<Card> cards) {
Set<Card> newSet = new LinkedHashSet<>();
for (Card card : cards) {
if (!hiddenCards.contains(card.getId())) {
newSet.add(card);
}
}
return newSet;
}
public void loadDeck(Deck deck, BigCard bigCard) { public void loadDeck(Deck deck, BigCard bigCard) {
deckList.setCards(new CardsView(deck.getCards()), bigCard); lastDeck = deck;
Logger.getLogger(DeckArea.class).info("Loading, sideboard is visible=" + sideboardList.isVisible()); lastBigCard = bigCard;
deckList.setCards(new CardsView(filterHidden(lastDeck.getCards())), lastBigCard);
if (sideboardList.isVisible()) { if (sideboardList.isVisible()) {
sideboardList.setCards(new CardsView(deck.getSideboard()), bigCard); sideboardList.setCards(new CardsView(filterHidden(lastDeck.getSideboard())), lastBigCard);
} }
} }
public void addDeckEventListener(Listener<Event> listener) { public void addDeckEventListener(Listener<Event> listener) {
deckList.addCardEventListener(listener); deckList.addCardEventListener(listener);
maindeckVirtualEvent.addListener(listener);
} }
public void clearDeckEventListeners() { public void clearDeckEventListeners() {
@ -114,6 +180,7 @@ public class DeckArea extends javax.swing.JPanel {
public void addSideboardEventListener(Listener<Event> listener) { public void addSideboardEventListener(Listener<Event> listener) {
sideboardList.addCardEventListener(listener); sideboardList.addCardEventListener(listener);
sideboardVirtualEvent.addListener(listener);
} }
public void clearSideboardEventListeners() { public void clearSideboardEventListeners() {

View file

@ -81,6 +81,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
private final JFileChooser fcSelectDeck; private final JFileChooser fcSelectDeck;
private final JFileChooser fcImportDeck; private final JFileChooser fcImportDeck;
private Deck deck = new Deck(); private Deck deck = new Deck();
private Map<UUID, Card> temporaryCards = new HashMap<>(); // Cards dragged out of one part of the view into another
private boolean isShowCardInfo = false; private boolean isShowCardInfo = false;
private UUID tableId; private UUID tableId;
private DeckEditorMode mode; private DeckEditorMode mode;
@ -104,7 +105,12 @@ public class DeckEditorPanel extends javax.swing.JPanel {
deckArea.setOpaque(false); deckArea.setOpaque(false);
jPanel1.setOpaque(false); jPanel1.setOpaque(false);
jSplitPane1.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, countdown = new Timer(1000,
new ActionListener() { new ActionListener() {
@Override @Override
@ -160,25 +166,25 @@ public class DeckEditorPanel extends javax.swing.JPanel {
switch (mode) { switch (mode) {
case LIMITED_BUILDING: case LIMITED_BUILDING:
this.deckArea.setOrientation(/*limitedBuildingOrientation = */true);
this.btnAddLand.setVisible(true); this.btnAddLand.setVisible(true);
this.txtTimeRemaining.setVisible(true); this.txtTimeRemaining.setVisible(true);
// Fall through to sideboarding
case SIDEBOARDING: case SIDEBOARDING:
this.btnSubmit.setVisible(true); this.btnSubmit.setVisible(true);
this.btnSubmitTimer.setVisible(true); this.btnSubmitTimer.setVisible(true);
if (deck != null) { if (mode == DeckEditorMode.SIDEBOARDING) {
this.cardSelector.loadSideboard(new ArrayList<>(deck.getSideboard()), this.bigCard); this.deckArea.setOrientation(/*limitedBuildingOrientation = */false);
} else /*(if (mode == LIMITED_BUILDING)*/ {
this.deckArea.setOrientation(/*limitedBuildingOrientation = */true);
} }
// TODO: take from preferences this.cardSelector.setVisible(false);
this.deckArea.setOrientation(/*limitedBuildingOrientation = */false);
this.cardSelector.switchToGrid();
this.btnExit.setVisible(false); this.btnExit.setVisible(false);
this.btnImport.setVisible(false); this.btnImport.setVisible(false);
this.btnGenDeck.setVisible(false); this.btnGenDeck.setVisible(false);
if (!SessionHandler.isTestMode()) { if (!SessionHandler.isTestMode()) {
this.btnLoad.setVisible(false); this.btnLoad.setVisible(false);
} }
this.deckArea.showSideboard(false); this.deckArea.showSideboard(true);
countdown.stop(); countdown.stop();
this.timeout = time; this.timeout = time;
setTimeout(timeout); setTimeout(timeout);
@ -195,6 +201,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
this.btnSubmit.setVisible(false); this.btnSubmit.setVisible(false);
this.btnSubmitTimer.setVisible(false); this.btnSubmitTimer.setVisible(false);
this.btnAddLand.setVisible(true); this.btnAddLand.setVisible(true);
this.cardSelector.setVisible(true);
this.cardSelector.loadCards(this.bigCard); this.cardSelector.loadCards(this.bigCard);
//this.cardTableSelector.loadCards(this.bigCard); //this.cardTableSelector.loadCards(this.bigCard);
this.btnExit.setVisible(true); this.btnExit.setVisible(true);
@ -211,8 +218,24 @@ public class DeckEditorPanel extends javax.swing.JPanel {
this.deckArea.setDeckEditorMode(mode); 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() { private void init() {
this.cardSelector.setVisible(true); //this.cardSelector.setVisible(true);
this.jPanel1.setVisible(true); this.jPanel1.setVisible(true);
for (ICardGrid component : this.cardSelector.getCardGridComponents()) { for (ICardGrid component : this.cardSelector.getCardGridComponents()) {
component.clearCardEventListeners(); component.clearCardEventListeners();
@ -233,10 +256,10 @@ public class DeckEditorPanel extends javax.swing.JPanel {
} }
break; break;
case "remove-main": case "remove-main":
//DeckEditorPanel.this.deckArea.getDeckList().handleDoubleClick(); DeckEditorPanel.this.deckArea.getDeckList().removeSelection();
break; break;
case "remove-sideboard": case "remove-sideboard":
//DeckEditorPanel.this.deckArea.getSideboardList().handleDoubleClick(); DeckEditorPanel.this.deckArea.getSideboardList().removeSelection();
break; break;
} }
refreshDeck(); refreshDeck();
@ -277,19 +300,23 @@ public class DeckEditorPanel extends javax.swing.JPanel {
} }
case "set-number": { case "set-number": {
setCardNumberToCardsList(event, deck.getCards()); setCardNumberToCardsList(event, deck.getCards());
break;
} }
case "remove-specific-card": { case "remove-specific-card": {
SimpleCardView cardView = (SimpleCardView) event.getSource(); SimpleCardView cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getCards()) { for (Card card : deck.getCards()) {
if (card.getId().equals(cardView.getId())) { if (card.getId().equals(cardView.getId())) {
deck.getCards().remove(card); deck.getCards().remove(card);
storeTemporaryCard(card);
break; break;
} }
} }
break;
} }
case "add-specific-card-maindeck": { case "add-specific-card": {
SimpleCardView cardView = (CardView) event.getSource(); SimpleCardView cardView = (CardView) event.getSource();
deck.getCards().add(CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber()).getCard()); deck.getCards().add(retrieveTemporaryCard(cardView));
break;
} }
} }
} else { } else {
@ -315,13 +342,16 @@ public class DeckEditorPanel extends javax.swing.JPanel {
for (Card card : deck.getCards()) { for (Card card : deck.getCards()) {
if (card.getId().equals(cardView.getId())) { if (card.getId().equals(cardView.getId())) {
deck.getCards().remove(card); deck.getCards().remove(card);
storeTemporaryCard(card);
break; break;
} }
} }
break;
} }
case "add-specific-card-maindeck": { case "add-specific-card": {
SimpleCardView cardView = (CardView) event.getSource(); 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; break;
case "set-number": { case "set-number": {
setCardNumberToCardsList(event, deck.getSideboard()); setCardNumberToCardsList(event, deck.getSideboard());
break;
} }
case "remove-specific-card": { case "remove-specific-card": {
cardView = (SimpleCardView) event.getSource(); cardView = (SimpleCardView) event.getSource();
for (Card card : deck.getSideboard()) { for (Card card : deck.getSideboard()) {
if (card.getId().equals(cardView.getId())) { if (card.getId().equals(cardView.getId())) {
deck.getSideboard().remove(card); deck.getSideboard().remove(card);
storeTemporaryCard(card);
break; break;
} }
} }
break;
} }
case "add-specific-card-sideboard": { case "add-specific-card": {
cardView = (CardView) event.getSource(); cardView = (CardView) event.getSource();
deck.getSideboard().add(CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber()).getCard()); deck.getSideboard().add(retrieveTemporaryCard(cardView));
break;
} }
} }
} else { } else {
@ -385,13 +419,16 @@ public class DeckEditorPanel extends javax.swing.JPanel {
for (Card card : deck.getSideboard()) { for (Card card : deck.getSideboard()) {
if (card.getId().equals(cardView.getId())) { if (card.getId().equals(cardView.getId())) {
deck.getSideboard().remove(card); deck.getSideboard().remove(card);
storeTemporaryCard(card);
break; break;
} }
} }
break;
} }
case "add-specific-card-sideboard": { case "add-specific-card": {
SimpleCardView cardView = (CardView) event.getSource(); 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 "double-click":
case "alt-double-click": case "alt-double-click":

View file

@ -249,7 +249,7 @@ public class MageBook extends JComponent {
if (cardDimension == null) { if (cardDimension == null) {
cardDimension = new Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight); 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); cardImg.setBounds(rectangle);
jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10); jLayeredPane.add(cardImg, JLayeredPane.DEFAULT_LAYER, 10);
cardImg.update(card); cardImg.update(card);

View file

@ -25,7 +25,7 @@ public interface MagePlugins {
MagePermanent getMagePermanent(PermanentView card, BigCard bigCard, Dimension dimension, UUID gameId, boolean loadImage); 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(); boolean isThemePluginLoaded();

View file

@ -107,10 +107,12 @@ public class Plugins implements MagePlugins {
} }
@Override @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) { if (cardPlugin != null) {
mageActionCallback.refreshSession(); if (previewable) {
mageActionCallback.setCardPreviewComponent(bigCard); mageActionCallback.refreshSession();
mageActionCallback.setCardPreviewComponent(bigCard);
}
return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage); return cardPlugin.getMageCard(card, dimension, gameId, mageActionCallback, false, !MageFrame.isLite() && loadImage);
} else { } else {
return new Card(card, bigCard, Config.dimensions, gameId); return new Card(card, bigCard, Config.dimensions, gameId);