Various new Drag & Drop deck editor improvements

* Shift-Click / Shift-Drag now work as expected as far as multi-selection
* Deck editor saves split pane split positions
* Card layout and sort settings are now saved along side the a deck when saving to the .dck format, so that you have back the exact same deck layout when you re-load the deck.
* Fixed the symbol image downloader to work around some of the large-size symbol images being missing on gatherer. Falls back to the medium sized images currently for those symbols.
This commit is contained in:
Mark Langen 2016-10-04 00:04:13 -06:00
parent 38cbf1a687
commit f6d50ce04f
11 changed files with 516 additions and 238 deletions

View file

@ -34,6 +34,9 @@ package mage.client.deckeditor;
import mage.cards.Card;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckCardInfo;
import mage.cards.decks.DeckCardLayout;
import mage.cards.decks.DeckCardLists;
import mage.client.cards.BigCard;
import mage.client.cards.CardEventSource;
import mage.client.cards.DragCardGrid;
@ -43,9 +46,12 @@ 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.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
@ -59,6 +65,40 @@ public class DeckArea extends javax.swing.JPanel {
private Deck lastDeck = new Deck();
private BigCard lastBigCard = null;
public DeckCardLayout getCardLayout() {
return deckList.getCardLayout();
}
public DeckCardLayout getSideboardLayout() {
return sideboardList.getCardLayout();
}
public static class Settings {
public DragCardGrid.Settings maindeckSettings;
public DragCardGrid.Settings sideboardSetings;
public int dividerLocation;
private static Pattern parser = Pattern.compile("([^|]*)\\|([^|]*)\\|([^|]*)");
public static Settings parse(String s) {
Matcher m = parser.matcher(s);
if (m.find()) {
Settings settings = new Settings();
settings.maindeckSettings = DragCardGrid.Settings.parse(m.group(1));
settings.sideboardSetings = DragCardGrid.Settings.parse(m.group(2));
settings.dividerLocation = Integer.parseInt(m.group(3));
return settings;
} else {
return null;
}
}
@Override
public String toString() {
return maindeckSettings.toString() + "|" + sideboardSetings.toString() + "|" + dividerLocation;
}
}
/**
* Creates new form DeckArea
*/
@ -117,6 +157,22 @@ public class DeckArea extends javax.swing.JPanel {
});
}
public Settings saveSettings() {
Settings settings = new Settings();
settings.maindeckSettings = deckList.saveSettings();
settings.sideboardSetings = sideboardList.saveSettings();
settings.dividerLocation = deckAreaSplitPane.getDividerLocation();
return settings;
}
public void loadSettings(Settings s) {
if (s != null) {
deckList.loadSettings(s.maindeckSettings);
sideboardList.loadSettings(s.sideboardSetings);
deckAreaSplitPane.setDividerLocation(s.dividerLocation);
}
}
public void cleanUp() {
deckList.cleanUp();
sideboardList.cleanUp();
@ -161,11 +217,21 @@ public class DeckArea extends javax.swing.JPanel {
}
public void loadDeck(Deck deck, BigCard bigCard) {
loadDeck(deck, false, bigCard);
}
public void loadDeck(Deck deck, boolean useLayout, BigCard bigCard) {
lastDeck = deck;
lastBigCard = bigCard;
deckList.setCards(new CardsView(filterHidden(lastDeck.getCards())), lastBigCard);
deckList.setCards(
new CardsView(filterHidden(lastDeck.getCards())),
useLayout ? deck.getCardsLayout() : null,
lastBigCard);
if (sideboardList.isVisible()) {
sideboardList.setCards(new CardsView(filterHidden(lastDeck.getSideboard())), lastBigCard);
sideboardList.setCards(
new CardsView(filterHidden(lastDeck.getSideboard())),
useLayout ? deck.getSideboardLayout() : null,
lastBigCard);
}
}

View file

@ -28,10 +28,7 @@
package mage.client.deckeditor;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
@ -50,6 +47,7 @@ import javax.swing.filechooser.FileFilter;
import mage.cards.Card;
import mage.cards.Sets;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckCardLists;
import mage.cards.decks.importer.DeckImporter;
import mage.cards.decks.importer.DeckImporterUtil;
import mage.cards.repository.CardInfo;
@ -62,6 +60,7 @@ import mage.client.constants.Constants.DeckEditorMode;
import mage.client.deck.generator.DeckGenerator.DeckGeneratorException;
import mage.client.deck.generator.DeckGenerator;
import mage.client.dialog.AddLandDialog;
import mage.client.dialog.PreferencesDialog;
import mage.client.plugins.impl.Plugins;
import mage.client.util.Event;
import mage.client.util.Listener;
@ -106,12 +105,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
deckArea.setOpaque(false);
jPanel1.setOpaque(false);
jSplitPane1.setOpaque(false);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jSplitPane1.setDividerLocation(0.3);
}
});
restoreDividerLocationsAndDeckAreaSettings();
countdown = new Timer(1000,
new ActionListener() {
@Override
@ -128,12 +122,22 @@ public class DeckEditorPanel extends javax.swing.JPanel {
}
}
});
// Set up tracking to save the deck editor settings when the deck editor is hidden.
addHierarchyListener((HierarchyEvent e) -> {
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
if (!isShowing()) {
saveDividerLocationsAndDeckAreaSettings();
}
}
});
}
/**
* Free resources so GC can remove unused objects from memory
*/
public void cleanUp() {
saveDividerLocationsAndDeckAreaSettings();
if (updateDeckTask != null) {
updateDeckTask.cancel(true);
}
@ -152,6 +156,24 @@ public class DeckEditorPanel extends javax.swing.JPanel {
this.bigCard = null;
}
private void saveDividerLocationsAndDeckAreaSettings() {
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION, Integer.toString(jSplitPane1.getDividerLocation()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, this.deckArea.saveSettings().toString());
}
private void restoreDividerLocationsAndDeckAreaSettings() {
// Load horizontal split position setting
String dividerLocation = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_HORIZONTAL_DIVIDER_LOCATION, "");
if (!dividerLocation.isEmpty()) {
jSplitPane1.setDividerLocation(Integer.parseInt(dividerLocation));
}
// Load deck area settings
this.deckArea.loadSettings(
DeckArea.Settings.parse(
PreferencesDialog.getCachedValue(PreferencesDialog.KEY_EDITOR_DECKAREA_SETTINGS, "")));
}
public void changeGUISize() {
this.cardSelector.changeGUISize();
this.deckArea.changeGUISize();
@ -556,10 +578,14 @@ public class DeckEditorPanel extends javax.swing.JPanel {
}
private void refreshDeck() {
refreshDeck(false);
}
private void refreshDeck(boolean useLayout) {
try {
setCursor(new Cursor(Cursor.WAIT_CURSOR));
this.txtDeckName.setText(deck.getName());
deckArea.loadDeck(deck, bigCard);
deckArea.loadDeck(deck, useLayout, bigCard);
} finally {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
@ -615,13 +641,6 @@ public class DeckEditorPanel extends javax.swing.JPanel {
jSplitPane1.setTopComponent(cardSelector);
jSplitPane1.setBottomComponent(deckArea);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jSplitPane1.setDividerLocation(0.6);
}
});
bigCard.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
cardInfoPane = Plugins.getInstance().getCardInfoPane();
@ -878,7 +897,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
} finally {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
refreshDeck();
refreshDeck(true);
try {
if (file != null) {
MageFrame.getPreferences().put("lastDeckFolder", file.getCanonicalPath());
@ -919,7 +938,10 @@ public class DeckEditorPanel extends javax.swing.JPanel {
fileName += ".dck";
}
setCursor(new Cursor(Cursor.WAIT_CURSOR));
Sets.saveDeck(fileName, deck.getDeckCardLists());
DeckCardLists cardLists = deck.getDeckCardLists();
cardLists.setCardLayout(deckArea.getCardLayout());
cardLists.setSideboardLayout(deckArea.getSideboardLayout());
Sets.saveDeck(fileName, cardLists);
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage() + "\nTry ensuring that the selected directory is writable.", "Error saving deck", JOptionPane.ERROR_MESSAGE);
} finally {