From 72fe5ad996a04fa4cf6293d178cbe1882dffb01b Mon Sep 17 00:00:00 2001 From: drdev Date: Sat, 18 Jan 2014 05:50:11 +0000 Subject: [PATCH] Add FDeckViewer to display deck list when double-clicking Improve support for opening modal dialog on top of another modal dialog --- .gitattributes | 1 + .../forge/gui/deckchooser/DeckgenUtil.java | 56 ------- .../forge/gui/deckchooser/FDeckChooser.java | 2 +- .../forge/gui/deckchooser/FDeckViewer.java | 144 ++++++++++++++++++ .../gauntlet/CSubmenuGauntletContests.java | 15 -- .../src/main/java/forge/view/FDialog.java | 23 ++- 6 files changed, 164 insertions(+), 77 deletions(-) create mode 100644 forge-gui/src/main/java/forge/gui/deckchooser/FDeckViewer.java diff --git a/.gitattributes b/.gitattributes index abc8fef5983..2d64c7c09ec 100644 --- a/.gitattributes +++ b/.gitattributes @@ -15245,6 +15245,7 @@ forge-gui/src/main/java/forge/gui/deckchooser/DeckgenUtil.java -text forge-gui/src/main/java/forge/gui/deckchooser/DecksComboBox.java -text forge-gui/src/main/java/forge/gui/deckchooser/DecksComboBoxEvent.java -text forge-gui/src/main/java/forge/gui/deckchooser/FDeckChooser.java -text +forge-gui/src/main/java/forge/gui/deckchooser/FDeckViewer.java -text forge-gui/src/main/java/forge/gui/deckchooser/GenerateThemeDeck.java svneol=native#text/plain forge-gui/src/main/java/forge/gui/deckchooser/IDecksComboBoxListener.java -text forge-gui/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java -text diff --git a/forge-gui/src/main/java/forge/gui/deckchooser/DeckgenUtil.java b/forge-gui/src/main/java/forge/gui/deckchooser/DeckgenUtil.java index cf5d0e68e03..fb1b73d6946 100644 --- a/forge-gui/src/main/java/forge/gui/deckchooser/DeckgenUtil.java +++ b/forge-gui/src/main/java/forge/gui/deckchooser/DeckgenUtil.java @@ -1,11 +1,8 @@ package forge.gui.deckchooser; -import java.awt.Toolkit; -import java.awt.datatransfer.StringSelection; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map.Entry; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; @@ -13,7 +10,6 @@ import forge.Singletons; import forge.card.CardDb; import forge.deck.CardPool; import forge.deck.Deck; -import forge.deck.DeckSection; import forge.deck.generation.DeckGenerator2Color; import forge.deck.generation.DeckGenerator3Color; import forge.deck.generation.DeckGenerator5Color; @@ -195,58 +191,6 @@ public class DeckgenUtil { deckManager.setSelectedIndex(MyRandom.getRandom().nextInt(size)); } - /** Shows decklist dialog for a given deck. - * @param lst0 {@link javax.swing.JList} - */ - public static void showDecklist(final Deck deck) { - if (deck == null) { return; } - - // Dump into map and display. - final String nl = System.getProperty("line.separator"); - final StringBuilder deckList = new StringBuilder(); - final String dName = deck.getName(); - deckList.append(dName == null ? "" : dName + nl + nl); - - int nLines = 0; - for (DeckSection s : DeckSection.values()){ - CardPool cp = deck.get(s); - if (cp == null || cp.isEmpty()) { - continue; - } - deckList.append(s.toString()).append(": "); - if (s.isSingleCard()) { - deckList.append(cp.get(0).getName()).append(nl); - nLines++; - } - else { - deckList.append(nl); - nLines++; - for (final Entry ev : cp) { - deckList.append(ev.getValue()).append(" ").append(ev.getKey()).append(nl); - nLines++; - } - } - deckList.append(nl); - nLines++; - } - - final StringBuilder msg = new StringBuilder(); - if (nLines <= 32) { - msg.append(deckList.toString()); - } - else { - msg.append("Decklist too long for dialog." + nl + nl); - } - - msg.append("Copy Decklist to Clipboard?"); - - // Output - if (FOptionPane.showConfirmDialog(msg.toString(), "Decklist", "OK", "Cancel")) { - final StringSelection ss = new StringSelection(deckList.toString()); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null); - } - } // End showDecklist - /** * Checks lengths of selected values for color lists * to see if a deck generator exists. Alert and visual reminder if fail. diff --git a/forge-gui/src/main/java/forge/gui/deckchooser/FDeckChooser.java b/forge-gui/src/main/java/forge/gui/deckchooser/FDeckChooser.java index 6b2b0124293..c5dcb464ea8 100644 --- a/forge-gui/src/main/java/forge/gui/deckchooser/FDeckChooser.java +++ b/forge-gui/src/main/java/forge/gui/deckchooser/FDeckChooser.java @@ -50,7 +50,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener { @Override public void run() { if (selectedDeckType != DeckType.COLOR_DECK && selectedDeckType != DeckType.THEME_DECK) { - DeckgenUtil.showDecklist(getDeck()); + FDeckViewer.show(getDeck()); } } }); diff --git a/forge-gui/src/main/java/forge/gui/deckchooser/FDeckViewer.java b/forge-gui/src/main/java/forge/gui/deckchooser/FDeckViewer.java new file mode 100644 index 00000000000..b6ae8f231da --- /dev/null +++ b/forge-gui/src/main/java/forge/gui/deckchooser/FDeckViewer.java @@ -0,0 +1,144 @@ +package forge.gui.deckchooser; + +import java.awt.Dimension; +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.swing.JLabel; + +import forge.deck.CardPool; +import forge.deck.Deck; +import forge.deck.DeckSection; +import forge.gui.toolbox.FButton; +import forge.gui.toolbox.FOptionPane; +import forge.gui.toolbox.itemmanager.CardManager; +import forge.gui.toolbox.itemmanager.ItemManagerContainer; +import forge.gui.toolbox.itemmanager.views.ItemCellRenderer; +import forge.gui.toolbox.itemmanager.views.ItemColumn; +import forge.gui.toolbox.itemmanager.views.SColumnUtil; +import forge.gui.toolbox.itemmanager.views.ItemColumn.ColumnDef; +import forge.item.PaperCard; +import forge.view.FDialog; + +@SuppressWarnings("serial") +public class FDeckViewer extends FDialog { + private final Deck deck; + private final List sections = new ArrayList(); + private final CardManager cardManager; + private DeckSection currentSection; + + private final FButton btnCopyToClipboard = new FButton("Copy to Clipboard"); + private final FButton btnChangeSection = new FButton("Change Section"); + private final FButton btnClose = new FButton("Close"); + + public static void show(final Deck deck) { + if (deck == null) { return; } + + FDeckViewer deckViewer = new FDeckViewer(deck); + deckViewer.setVisible(true); + deckViewer.dispose(); + } + + private FDeckViewer(Deck deck0) { + this.deck = deck0; + this.setTitle(deck.getName()); + this.cardManager = new CardManager(false); + this.cardManager.setPool(deck.getMain()); + this.setDefaultFocus(this.cardManager.getTable().getComponent()); + + for (Entry entry : deck) { + this.sections.add(entry.getKey()); + } + this.currentSection = DeckSection.Main; + updateCaption(); + + this.btnCopyToClipboard.setFocusable(false); + this.btnCopyToClipboard.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + FDeckViewer.this.copyToClipboard(); + } + }); + this.btnChangeSection.setFocusable(false); + if (this.sections.size() > 1) { + this.btnChangeSection.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + FDeckViewer.this.changeSection(); + } + }); + } + else { + this.btnChangeSection.setEnabled(false); + } + this.btnClose.setFocusable(false); + this.btnClose.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + FDeckViewer.this.setVisible(false); + } + }); + + final int width = 700; + final int height = 600; + this.setPreferredSize(new Dimension(width, height)); + this.setSize(width, height); + + this.add(new ItemManagerContainer(this.cardManager), "w 100%, pushy, growy, spanx 4, gapbottom 10px, wrap"); + this.add(this.btnCopyToClipboard, "w 200px!, h 26px!, gapright 5px"); + this.add(this.btnChangeSection, "w 200px!, h 26px!"); + this.add(new JLabel(), "pushx, growx"); + this.add(this.btnClose, "w 120px!, h 26px!"); + + Map columns = SColumnUtil.getDeckDefaultColumns(); + columns.get(ColumnDef.DECK_QUANTITY).setCellRenderer(new ItemCellRenderer()); //prevent displaying +/- buttons + this.cardManager.getTable().setup(columns); + } + + private void changeSection() { + int index = sections.indexOf(currentSection); + index = (index + 1) % sections.size(); + currentSection = sections.get(index); + this.cardManager.setPool(this.deck.get(currentSection)); + updateCaption(); + } + + private void updateCaption() { + this.cardManager.setCaption(deck.getName() + " - " + currentSection.name()); + } + + private void copyToClipboard() { + final String nl = System.getProperty("line.separator"); + final StringBuilder deckList = new StringBuilder(); + final String dName = deck.getName(); + deckList.append(dName == null ? "" : dName + nl + nl); + + for (DeckSection s : DeckSection.values()){ + CardPool cp = deck.get(s); + if (cp == null || cp.isEmpty()) { + continue; + } + deckList.append(s.toString()).append(": "); + if (s.isSingleCard()) { + deckList.append(cp.get(0).getName()).append(nl); + } + else { + deckList.append(nl); + for (final Entry ev : cp) { + deckList.append(ev.getValue()).append(" ").append(ev.getKey()).append(nl); + } + } + deckList.append(nl); + } + + final StringSelection ss = new StringSelection(deckList.toString()); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null); + FOptionPane.showMessageDialog("Deck list for '" + deck.getName() + "' copied to clipboard."); + } +} diff --git a/forge-gui/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java b/forge-gui/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java index 64f3c223f3d..4d9cd762ba2 100644 --- a/forge-gui/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java +++ b/forge-gui/src/main/java/forge/gui/home/gauntlet/CSubmenuGauntletContests.java @@ -2,13 +2,10 @@ package forge.gui.home.gauntlet; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; import java.io.File; import java.util.ArrayList; import java.util.List; -import javax.swing.JList; import javax.swing.SwingUtilities; import forge.Command; @@ -19,7 +16,6 @@ import forge.game.player.RegisteredPlayer; import forge.gauntlet.GauntletData; import forge.gauntlet.GauntletIO; import forge.gui.SOverlayUtils; -import forge.gui.deckchooser.DeckgenUtil; import forge.gui.framework.ICDoc; import forge.net.FServer; import forge.net.Lobby; @@ -38,16 +34,6 @@ public enum CSubmenuGauntletContests implements ICDoc { private final VSubmenuGauntletContests view = VSubmenuGauntletContests.SINGLETON_INSTANCE; - private final MouseAdapter madDecklist = new MouseAdapter() { - @SuppressWarnings("unchecked") - @Override - public void mouseClicked(final MouseEvent e) { - final GauntletData gd = view.getGauntletLister().getSelectedGauntlet(); - if (e.getClickCount() == 2) - DeckgenUtil.showDecklist( gd.getDecks().get(((JList)e.getSource()).getSelectedIndex()) ); - } - }; - private final ActionListener actStartGame = new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { @@ -71,7 +57,6 @@ public enum CSubmenuGauntletContests implements ICDoc { @Override public void initialize() { view.getBtnStart().addActionListener(actStartGame); - view.getLstDecks().addMouseListener(madDecklist); view.getLstDecks().initialize(); updateData(); diff --git a/forge-gui/src/main/java/forge/view/FDialog.java b/forge-gui/src/main/java/forge/view/FDialog.java index 00da781905e..7878dc13a6b 100644 --- a/forge-gui/src/main/java/forge/view/FDialog.java +++ b/forge-gui/src/main/java/forge/view/FDialog.java @@ -23,6 +23,7 @@ import java.awt.event.MouseMotionAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowFocusListener; import java.awt.geom.RoundRectangle2D; +import java.util.Stack; import javax.swing.JComponent; import javax.swing.JOptionPane; @@ -147,18 +148,29 @@ public class FDialog extends SkinnedDialog implements ITitleBarOwner, KeyEventDi if (this.isVisible() == visible) { return; } if (visible) { - setLocationRelativeTo(JOptionPane.getRootFrame()); + if (openModals.isEmpty()) { + setLocationRelativeTo(JOptionPane.getRootFrame()); + } + else { + setLocationRelativeTo(openModals.peek()); + } KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this); //support handling keyboard shortcuts in dialog if (isModal()) { - backdropPanel.setVisible(true); - Singletons.getView().getNavigationBar().setMenuShortcutsEnabled(false); + if (openModals.isEmpty()) { + backdropPanel.setVisible(true); + Singletons.getView().getNavigationBar().setMenuShortcutsEnabled(false); + } + openModals.push(this); } } else { KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this); if (isModal()) { - backdropPanel.setVisible(false); - Singletons.getView().getNavigationBar().setMenuShortcutsEnabled(true); + openModals.pop(); + if (openModals.isEmpty()) { + backdropPanel.setVisible(false); + Singletons.getView().getNavigationBar().setMenuShortcutsEnabled(true); + } } } super.setVisible(visible); @@ -317,6 +329,7 @@ public class FDialog extends SkinnedDialog implements ITitleBarOwner, KeyEventDi return getIconImages().isEmpty() ? null : getIconImages().get(0); } + private static final Stack openModals = new Stack(); private static final BackdropPanel backdropPanel = new BackdropPanel(); public static JPanel getBackdropPanel() {