-
-
-
+
+
@@ -17,6 +16,7 @@
+
diff --git a/src/main/java/forge/control/FControl.java b/src/main/java/forge/control/FControl.java
index 589ed4fe355..577e3557d05 100644
--- a/src/main/java/forge/control/FControl.java
+++ b/src/main/java/forge/control/FControl.java
@@ -270,11 +270,9 @@ public enum FControl {
Component[] children = display.getComponentsInLayer(JLayeredPane.DEFAULT_LAYER);
if (children.length != 0) { children[0].setSize(display.getSize()); }
- children = display.getComponentsInLayer(FView.TARGETING_LAYER);
- if (children.length != 0) { children[0].setSize(display.getSize()); }
-
- children = display.getComponentsInLayer(JLayeredPane.MODAL_LAYER);
- if (children.length != 0) { children[0].setSize(display.getSize()); }
+ for (Component child : display.getComponentsInLayer(JLayeredPane.MODAL_LAYER)) {
+ child.setSize(display.getSize());
+ }
}
/** @return {@link forge.game.player.Player} */
diff --git a/src/main/java/forge/gui/WrapLayout.java b/src/main/java/forge/gui/WrapLayout.java
index d04531275ed..c48313ffa00 100644
--- a/src/main/java/forge/gui/WrapLayout.java
+++ b/src/main/java/forge/gui/WrapLayout.java
@@ -39,8 +39,8 @@ public class WrapLayout extends FlowLayout {
* and the indicated horizontal and vertical gaps.
*
* The value of the alignment argument must be one of
- * WrapLayout, WrapLayout,
- * or WrapLayout.
+ * FlowLayout.LEFT, FlowLayout.CENTER,
+ * or FlowLayout.RIGHT.
* @param align the alignment value
* @param hgap the horizontal gap between components
* @param vgap the vertical gap between components
diff --git a/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java b/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java
index c3975eb9e2e..65b0fc71f88 100644
--- a/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java
+++ b/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java
@@ -23,10 +23,11 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import forge.Card;
+import forge.deck.DeckBase;
import forge.gui.CardContainer;
import forge.gui.deckeditor.SEditorIO.EditorPreference;
import forge.gui.deckeditor.controllers.ACEditorBase;
-import forge.gui.deckeditor.views.VFilters;
+import forge.gui.deckeditor.controllers.CCardCatalog;
import forge.gui.match.controllers.CDetail;
import forge.gui.match.controllers.CPicture;
import forge.item.InventoryItem;
@@ -74,7 +75,7 @@ public enum CDeckEditorUI implements CardContainer {
/**
* @return ACEditorBase, ?>
*/
- public ACEditorBase, ?> getCurrentEditorController() {
+ public ACEditorBase extends InventoryItem, ? extends DeckBase> getCurrentEditorController() {
return childController;
}
@@ -93,7 +94,7 @@ public enum CDeckEditorUI implements CardContainer {
childController.getTableCatalog().setWantUnique(wantUnique);
childController.getTableDeck().setWantUnique(wantUnique);
}
- VFilters.SINGLETON_INSTANCE.getLayoutControl().buildFilter();
+ CCardCatalog.SINGLETON_INSTANCE.applyCurrentFilter();
}
//========== Other methods
diff --git a/src/main/java/forge/gui/deckeditor/SEditorIO.java b/src/main/java/forge/gui/deckeditor/SEditorIO.java
index 1ffef3df1ee..f5e0c30ed2c 100644
--- a/src/main/java/forge/gui/deckeditor/SEditorIO.java
+++ b/src/main/java/forge/gui/deckeditor/SEditorIO.java
@@ -47,9 +47,8 @@ public class SEditorIO {
}
/** Preferences (must match with PREFS file). */
- public enum EditorPreference { /** */
- stats_deck, /** */
- stats_catalog,
+ public enum EditorPreference {
+ stats_deck,
display_unique_only,
elastic_columns
}
diff --git a/src/main/java/forge/gui/deckeditor/SEditorUtil.java b/src/main/java/forge/gui/deckeditor/SEditorUtil.java
index 8b74923ecdd..2c177211e04 100644
--- a/src/main/java/forge/gui/deckeditor/SEditorUtil.java
+++ b/src/main/java/forge/gui/deckeditor/SEditorUtil.java
@@ -1,16 +1,14 @@
package forge.gui.deckeditor;
import javax.swing.ImageIcon;
-import javax.swing.JLabel;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
+
import forge.Command;
-
-
-import forge.card.CardRulesPredicates;
import forge.card.CardRules;
+import forge.card.CardRulesPredicates;
import forge.gui.deckeditor.views.ITableContainer;
import forge.gui.deckeditor.views.VCardCatalog;
import forge.gui.deckeditor.views.VCurrentDeck;
@@ -19,6 +17,7 @@ import forge.gui.toolbox.FSkin;
import forge.item.InventoryItem;
import forge.item.ItemPoolView;
import forge.util.Aggregates;
+import forge.util.TextUtil;
/**
@@ -31,53 +30,39 @@ import forge.util.Aggregates;
*
*/
public final class SEditorUtil {
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_ARTIFACT =
- new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_ARTIFACT, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_CREATURE =
- new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_CREATURE, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_ENCHANTMENT =
- new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_ENCHANTMENT, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_INSTANT =
- new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_INSTANT, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_LAND =
- new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_LAND, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_PLANESWALKER =
- new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_PLANESWALKER, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_SORCERY =
- new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_SORCERY, 18, 18));
+ /** An enum to encapsulate metadata for the stats/filter objects. */
+ public static enum StatTypes {
+ TOTAL (FSkin.ZoneImages.ICO_HAND, null),
+
+ WHITE (FSkin.ManaImages.IMG_WHITE, CardRulesPredicates.Presets.IS_WHITE),
+ BLUE (FSkin.ManaImages.IMG_BLUE, CardRulesPredicates.Presets.IS_BLUE),
+ BLACK (FSkin.ManaImages.IMG_BLACK, CardRulesPredicates.Presets.IS_BLACK),
+ RED (FSkin.ManaImages.IMG_RED, CardRulesPredicates.Presets.IS_RED),
+ GREEN (FSkin.ManaImages.IMG_GREEN, CardRulesPredicates.Presets.IS_GREEN),
+ COLORLESS (FSkin.ManaImages.IMG_COLORLESS, CardRulesPredicates.Presets.IS_COLORLESS),
+ MULTICOLOR (FSkin.EditorImages.IMG_MULTI, CardRulesPredicates.Presets.IS_MULTICOLOR),
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_TOTAL =
- new ImageIcon(FSkin.getImage(FSkin.ZoneImages.ICO_HAND, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_MULTI =
- new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_MULTI, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_BLACK =
- new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_BLACK, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_BLUE =
- new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_BLUE, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_GREEN =
- new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_GREEN, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_RED =
- new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_RED, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_WHITE =
- new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_WHITE, 18, 18));
- /** Pre-cached resized version. */
- public static final ImageIcon ICO_COLORLESS =
- new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_X, 18, 18));
+ LAND (FSkin.EditorImages.IMG_LAND, CardRulesPredicates.Presets.IS_LAND),
+ ARTIFACT (FSkin.EditorImages.IMG_ARTIFACT, CardRulesPredicates.Presets.IS_ARTIFACT),
+ CREATURE (FSkin.EditorImages.IMG_CREATURE, CardRulesPredicates.Presets.IS_CREATURE),
+ ENCHANTMENT (FSkin.EditorImages.IMG_ENCHANTMENT, CardRulesPredicates.Presets.IS_ENCHANTMENT),
+ PLANESWALKER (FSkin.EditorImages.IMG_PLANESWALKER, CardRulesPredicates.Presets.IS_PLANESWALKER),
+ INSTANT (FSkin.EditorImages.IMG_INSTANT, CardRulesPredicates.Presets.IS_INSTANT),
+ SORCERY (FSkin.EditorImages.IMG_SORCERY, CardRulesPredicates.Presets.IS_SORCERY);
+
+ public final ImageIcon img;
+ public final Predicate predicate;
+ StatTypes(FSkin.SkinProp prop, Predicate pred) {
+ img = new ImageIcon(FSkin.getImage(prop, 18, 18));
+ predicate = pred;
+ }
+
+ public String toLabelString() {
+ return TextUtil.enumToLabel(this) + " cards";
+ }
+ }
+
/**
* Divides X by Y, multiplies by 100, rounds, returns.
*
@@ -86,12 +71,7 @@ public final class SEditorUtil {
* @return rounded result (int)
*/
public static int calculatePercentage(final int x0, final int y0) {
- return (int) Math.round((double) x0 / (double) y0 * 100);
- }
-
- public static void setLabelTextSum(JLabel label, final ItemPoolView deck, Predicate predicate) {
- int sum = Aggregates.sum(Iterables.filter(deck, Predicates.compose(predicate, deck.getFnToCard())), deck.getFnToCount());
- label.setText(String.valueOf(sum));
+ return (int) Math.round((double) (x0 * 100) / (double) y0);
}
/**
@@ -102,27 +82,25 @@ public final class SEditorUtil {
* @param view {@link forge.gui.deckeditor.views.ITableContainer}
*/
public static void setStats(final ItemPoolView deck, final ITableContainer view) {
- view.getLblTotal().setText(String.valueOf(deck.countAll()));
-
- setLabelTextSum(view.getLblCreature(), deck, CardRulesPredicates.Presets.IS_CREATURE);
- setLabelTextSum(view.getLblLand(), deck, CardRulesPredicates.Presets.IS_LAND);
- setLabelTextSum(view.getLblEnchantment(), deck, CardRulesPredicates.Presets.IS_ENCHANTMENT);
- setLabelTextSum(view.getLblArtifact(), deck, CardRulesPredicates.Presets.IS_ARTIFACT);
- setLabelTextSum(view.getLblInstant(), deck, CardRulesPredicates.Presets.IS_INSTANT);
- setLabelTextSum(view.getLblSorcery(), deck, CardRulesPredicates.Presets.IS_SORCERY);
- setLabelTextSum(view.getLblPlaneswalker(), deck, CardRulesPredicates.Presets.IS_PLANESWALKER);
- setLabelTextSum(view.getLblColorless(), deck, CardRulesPredicates.Presets.IS_COLORLESS);
- setLabelTextSum(view.getLblBlack(), deck, CardRulesPredicates.Presets.IS_BLACK);
- setLabelTextSum(view.getLblBlue(), deck, CardRulesPredicates.Presets.IS_BLUE);
- setLabelTextSum(view.getLblGreen(), deck, CardRulesPredicates.Presets.IS_GREEN);
- setLabelTextSum(view.getLblRed(), deck, CardRulesPredicates.Presets.IS_RED);
- setLabelTextSum(view.getLblWhite(), deck, CardRulesPredicates.Presets.IS_WHITE);
+ for (StatTypes s : StatTypes.values()) {
+ switch (s) {
+ case TOTAL:
+ view.getStatLabel(StatTypes.TOTAL).setText(String.valueOf(deck.countAll()));
+ break;
+ case COLORLESS:
+ break; // TODO: why?
+ default:
+ view.getStatLabel(s).setText(String.valueOf(
+ Aggregates.sum(Iterables.filter(deck, Predicates.compose(s.predicate, deck.getFnToCard())), deck.getFnToCount())));
+ }
+ }
} // getStats()
/**
* Resets components that may have been changed
* by various configurations of the deck editor.
*/
+ @SuppressWarnings("serial")
public static void resetUI() {
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setVisible(true);
@@ -142,16 +120,13 @@ public final class SEditorUtil {
VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("Current Deck");
VCurrentDeck.SINGLETON_INSTANCE.getBtnPrintProxies().setVisible(true);
-
VCurrentDeck.SINGLETON_INSTANCE.getBtnDoSideboard().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getLblTitle().setText("Title:");
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnSave())
- .setCommand(new Command() { private static final long serialVersionUID = -7995834050136126035L;
-
- @Override
- public void execute() { SEditorIO.saveDeck(); } });
+ .setCommand(new Command() {
+ @Override public void execute() { SEditorIO.saveDeck(); } });
}
}
diff --git a/src/main/java/forge/gui/deckeditor/SFilterUtil.java b/src/main/java/forge/gui/deckeditor/SFilterUtil.java
index 1e1147a1d7e..e1e9306dade 100644
--- a/src/main/java/forge/gui/deckeditor/SFilterUtil.java
+++ b/src/main/java/forge/gui/deckeditor/SFilterUtil.java
@@ -1,336 +1,120 @@
package forge.gui.deckeditor;
-import java.awt.Graphics;
-import java.awt.Image;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JPanel;
-import javax.swing.SwingConstants;
-import javax.swing.border.EmptyBorder;
-
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
-import forge.card.CardEdition;
-import forge.card.CardRulesPredicates;
import forge.card.CardRules;
-import forge.game.GameFormat;
-import forge.gui.WrapLayout;
-import forge.gui.deckeditor.views.VFilters;
+import forge.card.CardRulesPredicates;
+import forge.gui.deckeditor.views.VCardCatalog;
+import forge.gui.deckeditor.views.VCardCatalog.RangeTypes;
+import forge.gui.toolbox.FLabel;
+import forge.gui.toolbox.FSpinner;
import forge.item.CardPrinted;
import forge.util.ComparableOp;
+import forge.util.Pair;
import forge.util.PredicateString.StringOp;
/**
* Static factory; holds blocks of form elements and predicates
* which are used in various editing environments.
*
- * (S at beginning of class name denotes a static factory.)
- */
-public class SFilterUtil {
- /** An enum to encapsulate metadata for the checkbox objects in the color/type filter maps. */
- private enum FilterProperty {
- WHITE (SEditorUtil.ICO_WHITE.getImage(), "White Cards"),
- BLUE (SEditorUtil.ICO_BLUE.getImage(), "Blue Cards"),
- BLACK (SEditorUtil.ICO_BLACK.getImage(), "Black Cards"),
- RED (SEditorUtil.ICO_RED.getImage(), "Red Cards"),
- GREEN (SEditorUtil.ICO_GREEN.getImage(), "Green Cards"),
- COLORLESS (SEditorUtil.ICO_COLORLESS.getImage(), "Colorless Cards"),
- MULTICOLOR (SEditorUtil.ICO_MULTI.getImage(), "Multicolor Cards"),
-
- LAND (SEditorUtil.ICO_LAND.getImage(), "Land Cards"),
- ARTIFACT (SEditorUtil.ICO_ARTIFACT.getImage(), "Artifact Cards"),
- CREATURE (SEditorUtil.ICO_CREATURE.getImage(), "Creature Cards"),
- ENCHANTMENT (SEditorUtil.ICO_ENCHANTMENT.getImage(), "Enchantment Cards"),
- PLANESWALKER (SEditorUtil.ICO_PLANESWALKER.getImage(), "Planeswalker Cards"),
- INSTANT (SEditorUtil.ICO_INSTANT.getImage(), "Instant Cards"),
- SORCERY (SEditorUtil.ICO_SORCERY.getImage(), "Sorcery Cards");
-
- private final Image img;
- private final String tooltip;
-
- FilterProperty(final Image img0, final String tooltip0) {
- img = img0;
- tooltip = tooltip0;
- }
-
- public Image getImage() {
- return img;
- }
-
- public String getTooltip() {
- return tooltip;
- }
- }
-
- private static final FilterProperty[] COLOR_FILTER_PROPERTIES = {
- FilterProperty.WHITE,
- FilterProperty.BLUE,
- FilterProperty.BLACK,
- FilterProperty.RED,
- FilterProperty.GREEN,
- FilterProperty.COLORLESS,
- FilterProperty.MULTICOLOR
- };
-
- private static final FilterProperty[] TYPE_FILTER_PROPERTIES = {
- FilterProperty.LAND,
- FilterProperty.ARTIFACT,
- FilterProperty.CREATURE,
- FilterProperty.ENCHANTMENT,
- FilterProperty.PLANESWALKER,
- FilterProperty.INSTANT,
- FilterProperty.SORCERY
- };
-
- private static final Map MAP_COLOR_CHECKBOXES =
- new HashMap();
-
- private static final Map MAP_TYPE_CHECKBOXES =
- new HashMap();
-
- /**
-
- */
- private static boolean preventFiltering = false;
-
+ * (S at beginning of class name denotes a static factory.)
+ */
+public class SFilterUtil {
/**
- * This will prevent a filter event on a checkbox state change.
- * It's used for programmatic changes to the checkboxes when rebuilding
- * the filter each time is expensive.
- *
- * @return boolean true if filtering is prevented
- */
- public static boolean isFilteringPrevented() {
- return preventFiltering;
- }
-
- /**
- * This will prevent a filter event on a checkbox state change.
- * It's used for programmatic changes to the checkboxes when rebuilding
- * the filter each time is expensive.
- *
- * @param bool0 true to prevent filtering
- */
- public static void setPreventFiltering(final boolean bool0) {
- preventFiltering = bool0;
- }
-
- /**
- * Fills and returns a JPanel with checkboxes for color filter set.
- *
- * @return {@link javax.swing.JPanel}
- */
- public static JPanel populateColorFilters() {
- final JPanel pnl = new JPanel(new WrapLayout(SwingConstants.CENTER, 10, 5));
- pnl.setOpaque(false);
-
- MAP_COLOR_CHECKBOXES.clear();
- for (FilterProperty p : COLOR_FILTER_PROPERTIES) {
- ChbPnl chbPnl = new ChbPnl(p.getImage(), p.getTooltip());
- MAP_COLOR_CHECKBOXES.put(p, chbPnl);
- pnl.add(chbPnl);
- }
-
- return pnl;
- }
-
- /**
- * Fills and returns a JPanel with checkboxes for type filter set.
- *
- * @return {@link javax.swing.JPanel}
- */
- public static JPanel populateTypeFilters() {
- final JPanel pnl = new JPanel(new WrapLayout(SwingConstants.CENTER, 10, 5));
- pnl.setOpaque(false);
-
- MAP_TYPE_CHECKBOXES.clear();
- for (FilterProperty p : TYPE_FILTER_PROPERTIES) {
- ChbPnl chbPnl = new ChbPnl(p.getImage(), p.getTooltip());
- MAP_TYPE_CHECKBOXES.put(p, chbPnl);
- pnl.add(chbPnl);
- }
-
- return pnl;
- }
-
- /** Turns all type checkboxes off or on.
- * @param select0 boolean */
- public static void toggleTypeCheckboxes(final boolean select0) {
- for (ChbPnl p : MAP_TYPE_CHECKBOXES.values()) {
- p.getCheckBox().setSelected(select0);
- }
- }
-
- /** Turns all color checkboxes off or on.
- * @param select0 boolean */
- public static void toggleColorCheckboxes(final boolean select0) {
- for (ChbPnl p : MAP_COLOR_CHECKBOXES.values()) {
- p.getCheckBox().setSelected(select0);
- }
- }
-
- /**
- * Assembles checkboxes for color and returns a filter predicate.
+ * queries color filters for state and returns a predicate.
*
* Handles "multicolor" label, which is quite tricky.
- *
- * @return Predicate
*/
- public static Predicate buildColorFilter() {
- if (MAP_COLOR_CHECKBOXES.isEmpty()) { return Predicates.alwaysTrue(); }
-
- final List> colors = new ArrayList>();
-
- if (MAP_COLOR_CHECKBOXES.get(FilterProperty.WHITE).getCheckBox().isSelected()) { colors.add(CardRulesPredicates.Presets.IS_WHITE); }
- if (MAP_COLOR_CHECKBOXES.get(FilterProperty.BLUE).getCheckBox().isSelected()) { colors.add(CardRulesPredicates.Presets.IS_BLUE); }
- if (MAP_COLOR_CHECKBOXES.get(FilterProperty.BLACK).getCheckBox().isSelected()) { colors.add(CardRulesPredicates.Presets.IS_BLACK); }
- if (MAP_COLOR_CHECKBOXES.get(FilterProperty.RED).getCheckBox().isSelected()) { colors.add(CardRulesPredicates.Presets.IS_RED); }
- if (MAP_COLOR_CHECKBOXES.get(FilterProperty.GREEN).getCheckBox().isSelected()) { colors.add(CardRulesPredicates.Presets.IS_GREEN); }
- if (MAP_COLOR_CHECKBOXES.get(FilterProperty.COLORLESS).getCheckBox().isSelected()) { colors.add(CardRulesPredicates.Presets.IS_COLORLESS); }
-
- final Predicate preColors = colors.size() == 6 ? null : Predicates.or(colors);
-
- boolean wantMulticolor = MAP_COLOR_CHECKBOXES.get(FilterProperty.MULTICOLOR).getCheckBox().isSelected();
- final Predicate preExceptMulti = wantMulticolor ? null : Predicates.not(CardRulesPredicates.Presets.IS_MULTICOLOR);
-
- Predicate preFinal = colors.isEmpty() && wantMulticolor ? CardRulesPredicates.Presets.IS_MULTICOLOR : optimizedAnd(preExceptMulti, preColors);
+ public static Predicate buildColorAndTypeFilter(Map statLabels) {
+ final List> colors = new ArrayList>();
+ final List> types = new ArrayList>();
+
+ boolean wantMulticolor = false;
+ Predicate preExceptMulti = null;
+ for (SEditorUtil.StatTypes s : SEditorUtil.StatTypes.values()) {
+ switch (s) {
+ case WHITE: case BLUE: case BLACK: case RED: case GREEN: case COLORLESS:
+ if (statLabels.get(s).isSelected()) { colors.add(s.predicate); }
+ break;
+ case MULTICOLOR:
+ wantMulticolor = statLabels.get(s).isSelected();
+ preExceptMulti = wantMulticolor ? null : Predicates.not(CardRulesPredicates.Presets.IS_MULTICOLOR);
+ break;
+ case LAND: case ARTIFACT: case CREATURE: case ENCHANTMENT: case PLANESWALKER: case INSTANT: case SORCERY:
+ if (statLabels.get(s).isSelected()) { types.add(s.predicate); }
+ break;
+
+ case TOTAL:
+ // ignore
+ break;
+
+ default:
+ throw new RuntimeException("unhandled enum value: " + s);
+ }
+ }
+ Predicate preColors = colors.size() == 6 ? null : Predicates.or(colors);
+ Predicate preFinal = colors.isEmpty() && wantMulticolor ?
+ CardRulesPredicates.Presets.IS_MULTICOLOR : optimizedAnd(preExceptMulti, preColors);
+
+ if (null == preFinal && 7 == types.size()) {
+ return Predicates.alwaysTrue();
+ }
+
+ Predicate typesFinal = Predicates.compose(Predicates.or(types), CardPrinted.FN_GET_RULES);
if (null == preFinal) {
+ return typesFinal;
+ }
+
+ Predicate colorFinal = Predicates.compose(preFinal, CardPrinted.FN_GET_RULES);
+ if (7 == types.size()) {
+ return colorFinal;
+ }
+
+ return Predicates.and(colorFinal, typesFinal);
+ }
+
+ /**
+ * builds a string search filter
+ */
+ public static Predicate buildTextFilter(String text, boolean invert, boolean inName, boolean inType, boolean inText) {
+ if (text.trim().isEmpty()) {
return Predicates.alwaysTrue();
}
-
- return Predicates.compose(preFinal, CardPrinted.FN_GET_RULES);
- }
-
- /**
- * Filters the set/format combo box.
- *
- * @return Predicate
- */
- public static Predicate buildSetAndFormatFilter() {
- // Set/Format filter
- JComboBox cbox = VFilters.SINGLETON_INSTANCE.getCbxSets();
- if (cbox.getSelectedIndex() == 0) {
- return Predicates.alwaysTrue();
- }
-
- final Object selected = cbox.getSelectedItem();
- final Predicate filter;
- if (selected instanceof CardEdition) {
- filter = CardPrinted.Predicates.printedInSets(((CardEdition) selected).getCode());
- } else {
- filter = ((GameFormat) selected).getFilterRules();
- }
-
- return filter;
- }
-
- /**
- * Assembles checkboxes for type and returns a filter predicate.
- *
- * @return Predicate
- */
- public static Predicate buildTypeFilter() {
- if (MAP_TYPE_CHECKBOXES.isEmpty()) { return Predicates.alwaysTrue(); }
-
- final List> ors = new ArrayList>();
- if (MAP_TYPE_CHECKBOXES.get(FilterProperty.LAND).getCheckBox().isSelected()) { ors.add(CardRulesPredicates.Presets.IS_LAND); }
- if (MAP_TYPE_CHECKBOXES.get(FilterProperty.ARTIFACT).getCheckBox().isSelected()) { ors.add(CardRulesPredicates.Presets.IS_ARTIFACT); }
- if (MAP_TYPE_CHECKBOXES.get(FilterProperty.CREATURE).getCheckBox().isSelected()) { ors.add(CardRulesPredicates.Presets.IS_CREATURE); }
- if (MAP_TYPE_CHECKBOXES.get(FilterProperty.ENCHANTMENT).getCheckBox().isSelected()) { ors.add(CardRulesPredicates.Presets.IS_ENCHANTMENT); }
- if (MAP_TYPE_CHECKBOXES.get(FilterProperty.PLANESWALKER).getCheckBox().isSelected()) { ors.add(CardRulesPredicates.Presets.IS_PLANESWALKER); }
- if (MAP_TYPE_CHECKBOXES.get(FilterProperty.INSTANT).getCheckBox().isSelected()) { ors.add(CardRulesPredicates.Presets.IS_INSTANT); }
- if (MAP_TYPE_CHECKBOXES.get(FilterProperty.SORCERY).getCheckBox().isSelected()) { ors.add(CardRulesPredicates.Presets.IS_SORCERY); }
-
- if (ors.size() == 7) {
- return Predicates.alwaysTrue();
- }
-
- return Predicates.compose(Predicates.or(ors), CardPrinted.FN_GET_RULES);
- }
-
- /**
- * Validates text field input (from txfContains and txfWithout),
- * then assembles AND and NOT predicates accordingly, ANDs
- * together, and returns.
- *
- * @return Predicate
- */
- public static Predicate buildTextFilter() {
- Predicate filterAnd = null;
- Predicate filterNot = null;
-
- final String strContains = VFilters.SINGLETON_INSTANCE.getTxfContains().getText();
- final String strWithout = VFilters.SINGLETON_INSTANCE.getTxfWithout().getText();
-
- final boolean useName = VFilters.SINGLETON_INSTANCE.getChbTextName().isSelected();
- final boolean useType = VFilters.SINGLETON_INSTANCE.getChbTextType().isSelected();
- final boolean useText = VFilters.SINGLETON_INSTANCE.getChbTextText().isSelected();
-
- if (!strContains.isEmpty()) {
- final String[] splitContains = strContains
+
+ String[] splitText = text
.replaceAll(",", "")
.replaceAll(" ", " ")
.toLowerCase().split(" ");
- final List> ands = new ArrayList>();
+ List> terms = new ArrayList>();
+ for (String s : splitText) {
+ List> subands = new ArrayList>();
- for (final String s : splitContains) {
- final List> subands = new ArrayList>();
+ if (inName) { subands.add(CardRulesPredicates.name(StringOp.CONTAINS_IC, s)); }
+ if (inType) { subands.add(CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, s)); }
+
+ // rules cannot compare in ignore-case way
+ if (inText) { subands.add(CardRulesPredicates.rules(StringOp.CONTAINS, s)); }
- if (useName) { subands.add(CardRulesPredicates.name(StringOp.CONTAINS_IC, s)); }
- if (useType) { subands.add(CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, s)); }
- // rules cannot compare in ignore-case way
- if (useText) { subands.add(CardRulesPredicates.rules(StringOp.CONTAINS, s)); }
-
- ands.add(Predicates.or(subands));
- }
- filterAnd = Predicates.and(ands);
+ terms.add(Predicates.or(subands));
}
-
- if (!strWithout.isEmpty()) {
- final String[] splitWithout = strWithout
- .replaceAll(" ", " ")
- .replaceAll(",", "")
- .toLowerCase().split(" ");
-
- final List> nots = new ArrayList>();
-
- for (final String s : splitWithout) {
- final List> subnots = new ArrayList>();
-
- if (useName) { subnots.add(CardRulesPredicates.name(StringOp.CONTAINS_IC, s)); }
- if (useType) { subnots.add(CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, s)); }
- // rules cannot compare in ignore-case way
- if (useText) { subnots.add(CardRulesPredicates.rules(StringOp.CONTAINS, s)); }
-
- nots.add(Predicates.or(subnots));
- }
- filterNot = Predicates.not(Predicates.or(nots));
- }
- Predicate preResult = optimizedAnd(filterAnd, filterNot);
- if (preResult == null) {
- return Predicates.alwaysTrue();
- }
- return Predicates.compose(preResult, CardPrinted.FN_GET_RULES);
+ Predicate textFilter = invert ? Predicates.not(Predicates.or(terms)) : Predicates.and(terms);
+
+ return Predicates.compose(textFilter, CardPrinted.FN_GET_RULES);
}
- private static Predicate getCardRulesFieldPredicate(String min, String max, CardRulesPredicates.LeafNumber.CardField field) {
- boolean hasMin = !("*".equals(min));
- boolean hasMax = !("10+".equals(max));
+ private static Predicate getCardRulesFieldPredicate(int min, int max, CardRulesPredicates.LeafNumber.CardField field) {
+ boolean hasMin = 0 != min;
+ boolean hasMax = 10 != max;
- Predicate pMin = !hasMin ? null : new CardRulesPredicates.LeafNumber(field, ComparableOp.GT_OR_EQUAL, Integer.valueOf(min));
- Predicate pMax = !hasMax ? null : new CardRulesPredicates.LeafNumber(field, ComparableOp.LT_OR_EQUAL, Integer.valueOf(max));
+ Predicate pMin = !hasMin ? null : new CardRulesPredicates.LeafNumber(field, ComparableOp.GT_OR_EQUAL, min);
+ Predicate pMax = !hasMax ? null : new CardRulesPredicates.LeafNumber(field, ComparableOp.LT_OR_EQUAL, max);
return optimizedAnd(pMin, pMax);
}
@@ -341,78 +125,23 @@ public class SFilterUtil {
}
/**
- * Validates combo box input, assembles predicate filters for each case,
- * stacks them all together, and returns the predicate.
- *
- * @return Predicate
+ * builds a filter for an interval on a card field
*/
- public static Predicate buildIntervalFilter() {
- final VFilters view = VFilters.SINGLETON_INSTANCE;
+ public static Predicate buildIntervalFilter(
+ Map> spinners, VCardCatalog.RangeTypes field) {
+ Pair sPair = spinners.get(field);
+ Predicate fieldFilter = getCardRulesFieldPredicate(
+ Integer.valueOf(sPair.a.getValue().toString()), Integer.valueOf(sPair.b.getValue().toString()), field.cardField);
- // Must include -1 so non-creatures are included by default.
- Predicate preToughness = getCardRulesFieldPredicate(view.getCbxTLow().getSelectedItem().toString(), view.getCbxTHigh().getSelectedItem().toString(), CardRulesPredicates.LeafNumber.CardField.TOUGHNESS);
- Predicate prePower = getCardRulesFieldPredicate(view.getCbxPLow().getSelectedItem().toString(), view.getCbxPHigh().getSelectedItem().toString(), CardRulesPredicates.LeafNumber.CardField.POWER);
- Predicate preCMC = getCardRulesFieldPredicate(view.getCbxCMCLow().getSelectedItem().toString(), view.getCbxCMCHigh().getSelectedItem().toString(), CardRulesPredicates.LeafNumber.CardField.CMC);
+ if (null != fieldFilter && VCardCatalog.RangeTypes.CMC != field)
+ {
+ fieldFilter = Predicates.and(fieldFilter, CardRulesPredicates.Presets.IS_CREATURE);
+ }
- Predicate preCreature = optimizedAnd(preToughness, prePower);
- preCreature = preCreature == null ? null : Predicates.and(preCreature, CardRulesPredicates.Presets.IS_CREATURE);
-
- Predicate preFinal = optimizedAnd(preCMC, preCreature);
- if (preFinal == null) {
+ if (fieldFilter == null) {
return Predicates.alwaysTrue();
} else {
- return Predicates.compose(preFinal, CardPrinted.FN_GET_RULES);
- }
- }
-
- //========== Custom class handling
-
- /**
- * A panel with a checkbox and an icon, which will toggle the
- * checkbox when anywhere in the panel is clicked.
- */
- @SuppressWarnings("serial")
- private static class ChbPnl extends JPanel implements ItemListener {
- private final JCheckBox checkBox = new JCheckBox();
- private final Image img;
-
- public ChbPnl(final Image img0, final String tooltip) {
- super();
- this.img = img0;
- this.setOpaque(false);
- checkBox.setBorder(new EmptyBorder(0, 20, 0, 0));
- checkBox.setOpaque(false);
- checkBox.setSelected(true);
- checkBox.addItemListener(this);
- checkBox.setToolTipText(tooltip);
- add(checkBox);
-
- this.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseClicked(final MouseEvent me) {
- checkBox.doClick();
- }
- });
- }
-
- public JCheckBox getCheckBox() {
- return this.checkBox;
- }
-
- @Override
- protected void paintComponent(final Graphics g) {
- super.paintComponent(g);
- g.drawImage(img, 0, 0, null);
- }
-
- /* (non-Javadoc)
- * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
- */
- @Override
- public void itemStateChanged(final ItemEvent arg0) {
- if (!preventFiltering) {
- VFilters.SINGLETON_INSTANCE.getLayoutControl().buildFilter();
- }
+ return Predicates.compose(fieldFilter, CardPrinted.FN_GET_RULES);
}
}
}
diff --git a/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java b/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java
index 4d42b294558..b876368724c 100644
--- a/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java
+++ b/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java
@@ -1,11 +1,50 @@
package forge.gui.deckeditor.controllers;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.JComponent;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.KeyStroke;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+
import forge.Command;
+import forge.Singletons;
+import forge.card.CardEdition;
+import forge.card.EditionCollection;
+import forge.deck.DeckBase;
+import forge.game.GameFormat;
import forge.gui.deckeditor.CDeckEditorUI;
+import forge.gui.deckeditor.SEditorUtil;
+import forge.gui.deckeditor.SFilterUtil;
import forge.gui.deckeditor.views.VCardCatalog;
+import forge.gui.deckeditor.views.VCardCatalog.RangeTypes;
import forge.gui.framework.ICDoc;
+import forge.gui.home.quest.DialogChooseSets;
import forge.gui.toolbox.FLabel;
+import forge.gui.toolbox.FSpinner;
+import forge.item.CardPrinted;
import forge.item.InventoryItem;
+import forge.item.ItemPredicate;
+import forge.quest.QuestWorld;
+import forge.quest.data.GameFormatQuest;
+import forge.util.Pair;
/**
* Controls the "card catalog" panel in the deck editor UI.
@@ -17,7 +56,12 @@ public enum CCardCatalog implements ICDoc {
/** */
SINGLETON_INSTANCE;
- // refresh analysis on add
+ private final Set> activePredicates = new HashSet>();
+ private final Set activeFormats = new HashSet();
+ private final Set activeWorlds = new HashSet();
+ private final Set activeRanges = EnumSet.noneOf(RangeTypes.class);
+
+ private boolean disableFiltering = false;
private CCardCatalog() {
}
@@ -38,8 +82,8 @@ public enum CCardCatalog implements ICDoc {
@Override
@SuppressWarnings("serial")
public void initialize() {
- // Add/remove buttons
- ((FLabel) VCardCatalog.SINGLETON_INSTANCE.getBtnAdd()).setCommand(new Command() {
+ // Add/remove buttons (refresh analysis on add)
+ VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().setCommand(new Command() {
@Override
public void execute() {
CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().addCard();
@@ -48,8 +92,7 @@ public enum CCardCatalog implements ICDoc {
CProbabilities.SINGLETON_INSTANCE.update();
}
});
-
- ((FLabel) VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4()).setCommand(new Command() {
+ VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setCommand(new Command() {
@Override
public void execute() {
final InventoryItem item = CDeckEditorUI.SINGLETON_INSTANCE
@@ -65,6 +108,180 @@ public enum CCardCatalog implements ICDoc {
CProbabilities.SINGLETON_INSTANCE.update();
}
});
+
+ final Command updateFilterCommand = new Command() {
+ @Override
+ public void execute() {
+ if (!disableFiltering) {
+ applyCurrentFilter();
+ }
+ }
+ };
+
+ for (FLabel statLabel : VCardCatalog.SINGLETON_INSTANCE.getStatLabels().values()) {
+ statLabel.setCommand(updateFilterCommand);
+ }
+
+ VCardCatalog.SINGLETON_INSTANCE.getStatLabel(SEditorUtil.StatTypes.TOTAL).setCommand(new Command() {
+ private boolean lastToggle = true;
+
+ @Override
+ public void execute() {
+ disableFiltering = true;
+ lastToggle = !lastToggle;
+ for (SEditorUtil.StatTypes s : SEditorUtil.StatTypes.values()) {
+ if (SEditorUtil.StatTypes.TOTAL != s) {
+ VCardCatalog.SINGLETON_INSTANCE.getStatLabel(s).setSelected(lastToggle);
+ }
+ }
+ disableFiltering = false;
+ applyCurrentFilter();
+ }
+ });
+
+ // assemble add restriction menu
+ VCardCatalog.SINGLETON_INSTANCE.getBtnAddRestriction().setCommand(new Command() {
+ @Override
+ public void execute() {
+ JPopupMenu popup = new JPopupMenu("Popup");
+ addMenuItem(popup, "Current text search", canSearch(),
+ KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
+ new Command() {
+ @Override
+ public void execute() {
+ addRestriction(buildSearchRestriction(), null, null);
+ }
+ });
+ JMenu fmt = new JMenu("Format");
+ for (final GameFormat f : Singletons.getModel().getFormats()) {
+ addMenuItem(fmt, f.getName(), !isActive(activeFormats, f), null, new Command() {
+ @Override
+ public void execute() {
+ addRestriction(buildFormatRestriction(f.toString(), f), activeFormats, f);
+ }
+ });
+ }
+ popup.add(fmt);
+ addMenuItem(popup, "Edition (set)...", true, null, new Command() {
+ @Override
+ public void execute() {
+ final List setCodes = new ArrayList();
+ new DialogChooseSets(setCodes, new Runnable() {
+ @Override
+ public void run() {
+ if (setCodes.isEmpty()) {
+ return;
+ }
+
+ GameFormat f = new GameFormat(null, setCodes, null);
+
+ StringBuilder label = new StringBuilder("Sets:");
+ boolean truncated = false;
+ for (String code : setCodes)
+ {
+ // don't let the full label get too long
+ if (32 > label.length()) {
+ label.append(" ").append(code).append(";");
+ } else {
+ truncated = true;
+ break;
+ }
+ }
+
+ // chop off last semicolons
+ label.delete(label.length() - 1, label.length());
+
+ if (truncated) {
+ label.append("...");
+ }
+
+ addRestriction(buildFormatRestriction(label.toString(), f), null, null);
+ }
+ });
+ }
+ });
+ JMenu range = new JMenu("Value range");
+ for (final RangeTypes t : RangeTypes.values()) {
+ addMenuItem(range, t.toLabelString() + " restriction", !isActive(activeRanges, t), null, new Command() {
+ @Override
+ public void execute() {
+ addRestriction(buildRangeRestriction(t), activeRanges, t);
+ }
+ });
+ }
+ popup.add(range);
+ JMenu world = new JMenu("Quest world");
+ for (final QuestWorld w : Singletons.getModel().getWorlds()) {
+ addMenuItem(world, w.getName(), !isActive(activeWorlds, w), null, new Command() {
+ @Override
+ public void execute() {
+ addRestriction(buildWorldRestriction(w), activeWorlds, w);
+ }
+ });
+ }
+ popup.add(world);
+ popup.show(VCardCatalog.SINGLETON_INSTANCE.getBtnAddRestriction(), 0, 0);
+ }
+ });
+
+ VCardCatalog.SINGLETON_INSTANCE.getCbSearchMode().addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent arg0) {
+ applyCurrentFilter();
+ }
+ });
+
+ VCardCatalog.SINGLETON_INSTANCE.getTxfSearch().addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent e) {
+ if (e.getKeyCode() == 10) {
+ if (e.isControlDown() || e.isMetaDown()) {
+ if (canSearch()) {
+ addRestriction(buildSearchRestriction(), null, null);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ applyCurrentFilter();
+ }
+ });
+
+ VCardCatalog.SINGLETON_INSTANCE.getLblName().setCommand(updateFilterCommand);
+ VCardCatalog.SINGLETON_INSTANCE.getLblType().setCommand(updateFilterCommand);
+ VCardCatalog.SINGLETON_INSTANCE.getLblText().setCommand(updateFilterCommand);
+
+ // ensure mins can's exceed maxes and maxes can't fall below mins
+ for (Pair sPair : VCardCatalog.SINGLETON_INSTANCE.getSpinners().values()) {
+ final FSpinner min = sPair.a;
+ final FSpinner max = sPair.b;
+
+ min.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent arg0) {
+ if (Integer.parseInt(max.getValue().toString()) <
+ Integer.parseInt(min.getValue().toString()))
+ {
+ max.setValue(min.getValue());
+ }
+ applyCurrentFilter();
+ }
+ });
+
+ max.addChangeListener(new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent arg0) {
+ if (Integer.parseInt(min.getValue().toString()) >
+ Integer.parseInt(max.getValue().toString()))
+ {
+ min.setValue(max.getValue());
+ }
+ applyCurrentFilter();
+ }
+ });
+ }
}
/* (non-Javadoc)
@@ -73,4 +290,220 @@ public enum CCardCatalog implements ICDoc {
@Override
public void update() {
}
+
+ @SuppressWarnings("unchecked")
+ public void applyCurrentFilter() {
+ // The main trick here is to apply a CardPrinted predicate
+ // to the table. CardRules will lead to difficulties.
+
+ List> cardPredicates = new ArrayList>();
+ cardPredicates.add(Predicates.instanceOf(CardPrinted.class));
+ cardPredicates.add(SFilterUtil.buildColorAndTypeFilter(VCardCatalog.SINGLETON_INSTANCE.getStatLabels()));
+ cardPredicates.addAll(activePredicates);
+
+ // apply current values in the range filters
+ for (RangeTypes t : RangeTypes.values()) {
+ if (activeRanges.contains(t)) {
+ cardPredicates.add(SFilterUtil.buildIntervalFilter(VCardCatalog.SINGLETON_INSTANCE.getSpinners(), t));
+ }
+ }
+
+ // get the current contents of the search box
+ cardPredicates.add(SFilterUtil.buildTextFilter(
+ VCardCatalog.SINGLETON_INSTANCE.getTxfSearch().getText(),
+ 0 != VCardCatalog.SINGLETON_INSTANCE.getCbSearchMode().getSelectedIndex(),
+ VCardCatalog.SINGLETON_INSTANCE.getLblName().isSelected(),
+ VCardCatalog.SINGLETON_INSTANCE.getLblType().isSelected(),
+ VCardCatalog.SINGLETON_INSTANCE.getLblText().isSelected()));
+
+ Predicate super CardPrinted> cardFilter = Predicates.and(cardPredicates);
+
+ // Until this is filterable, always show packs and decks in the card shop.
+ List> itemPredicates = new ArrayList>();
+ itemPredicates.add(cardFilter);
+ itemPredicates.add(ItemPredicate.Presets.IS_PACK);
+ itemPredicates.add(ItemPredicate.Presets.IS_DECK);
+ Predicate filter = Predicates.or(itemPredicates);
+
+ // Apply to table
+ // TODO: is there really no way to make this type safe?
+ ((ACEditorBase)CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController())
+ .getTableCatalog().setFilter(filter);
+ }
+
+ private boolean canSearch() {
+ return !VCardCatalog.SINGLETON_INSTANCE.getTxfSearch().getText().isEmpty() &&
+ (VCardCatalog.SINGLETON_INSTANCE.getLblName().isSelected() ||
+ VCardCatalog.SINGLETON_INSTANCE.getLblType().isSelected() ||
+ VCardCatalog.SINGLETON_INSTANCE.getLblText().isSelected());
+ }
+
+ private boolean isActive(Set activeSet, T key) {
+ return activeSet.contains(key);
+ }
+
+ private JMenuItem createMenuItem(String label, boolean enabled, KeyStroke accelerator, final Command onClick) {
+ JMenuItem item = new JMenuItem(label);
+ item.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ if (null != onClick) {
+ onClick.execute();
+ }
+ }
+ });
+ item.setEnabled(enabled);
+ item.setAccelerator(accelerator);
+ return item;
+ }
+
+ private void addMenuItem(JPopupMenu parent, String label, boolean enabled, KeyStroke accelerator, Command onClick) {
+ parent.add(createMenuItem(label, enabled, accelerator, onClick));
+ }
+
+ private void addMenuItem(JMenuItem parent, String label, boolean enabled, KeyStroke accelerator, Command onClick) {
+ parent.add(createMenuItem(label, enabled, accelerator, onClick));
+ }
+
+ @SuppressWarnings("serial")
+ private void addRestriction(Pair> restriction, final Set activeSet, final T key) {
+ final Predicate predicate = restriction.b;
+
+ if (null != predicate && activePredicates.contains(predicate)) {
+ return;
+ }
+
+ VCardCatalog.SINGLETON_INSTANCE.addRestrictionWidget(restriction.a, new Command() {
+ @Override
+ public void execute() {
+ if (null != key) {
+ activeSet.remove(key);
+ }
+ if (null != predicate) {
+ activePredicates.remove(predicate);
+ }
+ applyCurrentFilter();
+ }
+ });
+
+ if (null != key) {
+ activeSet.add(key);
+ }
+ if (null != predicate) {
+ activePredicates.add(predicate);
+ }
+ applyCurrentFilter();
+ }
+
+ private Pair> buildRangeRestriction(RangeTypes t) {
+ Pair s = VCardCatalog.SINGLETON_INSTANCE.getSpinners().get(t);
+ s.a.setValue(0);
+ s.b.setValue(10);
+
+ return new Pair>(
+ VCardCatalog.SINGLETON_INSTANCE.buildRangeRestrictionWidget(t), null);
+ }
+
+ private String buildSearchRestrictionText(String text, boolean isInverse, boolean wantName, boolean wantType, boolean wantText) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(isInverse ? "Without" : "Contains");
+ sb.append(": '").append(text).append("' in:");
+ if (wantName) { sb.append(" name,"); }
+ if (wantType) { sb.append(" type,"); }
+ if (wantText) { sb.append(" text,"); }
+ sb.delete(sb.length() - 1, sb.length()); // chop off last comma
+
+ return sb.toString();
+ }
+
+ private Pair> buildSearchRestriction() {
+ boolean isInverse =
+ VCardCatalog.SEARCH_MODE_INVERSE_INDEX == VCardCatalog.SINGLETON_INSTANCE.getCbSearchMode().getSelectedIndex();
+ String text = VCardCatalog.SINGLETON_INSTANCE.getTxfSearch().getText();
+ boolean wantName = VCardCatalog.SINGLETON_INSTANCE.getLblName().getSelected();
+ boolean wantType = VCardCatalog.SINGLETON_INSTANCE.getLblType().getSelected();
+ boolean wantText = VCardCatalog.SINGLETON_INSTANCE.getLblText().getSelected();
+
+ String shortText = buildSearchRestrictionText(text, isInverse, wantName, wantType, wantText);
+ String fullText = null;
+ if (25 < text.length()) {
+ fullText = shortText;
+ shortText = buildSearchRestrictionText(text.substring(0, 22) + "...",
+ isInverse, wantName, wantType, wantText);
+ }
+
+ VCardCatalog.SINGLETON_INSTANCE.getTxfSearch().setText("");
+
+ return new Pair>(
+ VCardCatalog.SINGLETON_INSTANCE.buildPlainRestrictionWidget(shortText, fullText),
+ SFilterUtil.buildTextFilter(text, isInverse, wantName, wantType, wantText));
+ }
+
+ private Pair> buildFormatRestriction(String displayName, GameFormat format) {
+ EditionCollection editions = Singletons.getModel().getEditions();
+ StringBuilder tooltip = new StringBuilder("Sets:");
+
+ int lastLen = 0;
+ int lineLen = 0;
+
+ // use HTML tooltips so we can insert line breaks
+ List sets = null == format ? null : format.getAllowedSetCodes();
+ if (null == sets || sets.isEmpty()) {
+ tooltip.append(" All");
+ } else {
+ for (String code : sets) {
+ // don't let a single line get too long
+ if (50 < lineLen) {
+ tooltip.append("
");
+ lastLen += lineLen;
+ lineLen = 0;
+ }
+
+ CardEdition edition = editions.get(code);
+ tooltip.append(" ").append(edition.getName()).append(" (").append(code).append("),");
+ lineLen = tooltip.length() - lastLen;
+ }
+
+ // chop off last comma
+ tooltip.delete(tooltip.length() - 1, tooltip.length());
+
+ tooltip.append("
Allowing identical cards from other sets");
+ }
+
+ List bannedCards = null == format ? null : format.getBannedCardNames();
+ if (null != bannedCards && !bannedCards.isEmpty()) {
+ tooltip.append("
Banned:");
+ lastLen += lineLen;
+ lineLen = 0;
+
+ for (String cardName : bannedCards) {
+ // don't let a single line get too long
+ if (50 < lineLen) {
+ tooltip.append("
");
+ lastLen += lineLen;
+ lineLen = 0;
+ }
+
+ tooltip.append(" ").append(cardName).append(";");
+ lineLen = tooltip.length() - lastLen;
+ }
+
+ // chop off last semicolon
+ tooltip.delete(tooltip.length() - 1, tooltip.length());
+ }
+ tooltip.append("");
+
+ return new Pair>(
+ VCardCatalog.SINGLETON_INSTANCE.buildPlainRestrictionWidget(displayName, tooltip.toString()),
+ format.getFilterRules());
+ }
+
+ private Pair> buildWorldRestriction(QuestWorld world) {
+ GameFormatQuest format = world.getFormat();
+ if (null == format) {
+ // assumes that no world other than the main world will have a null format
+ format = Singletons.getModel().getQuest().getMainFormat();
+ }
+ return buildFormatRestriction(world.getName(), format);
+ }
}
diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java
index 997b887f74f..75e24ad8845 100644
--- a/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java
+++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java
@@ -33,7 +33,6 @@ import forge.gui.deckeditor.views.VAllDecks;
import forge.gui.deckeditor.views.VCardCatalog;
import forge.gui.deckeditor.views.VCurrentDeck;
import forge.gui.deckeditor.views.VDeckgen;
-import forge.gui.deckeditor.views.VFilters;
import forge.gui.framework.DragCell;
import forge.gui.framework.SRearrangingUtil;
import forge.gui.home.sanctioned.CSubmenuDraft;
@@ -55,7 +54,6 @@ public class CEditorDraftingProcess extends ACEditorBase
private IBoosterDraft boosterDraft;
private String ccAddLabel = "Add card";
- private DragCell filtersParent = null;
private DragCell allDecksParent = null;
private DragCell deckGenParent = null;
@@ -297,17 +295,6 @@ public class CEditorDraftingProcess extends ACEditorBase
}
}
- if (VFilters.SINGLETON_INSTANCE.getParentCell() != null) {
- filtersParent = VFilters.SINGLETON_INSTANCE.getParentCell();
- filtersParent.removeDoc(VFilters.SINGLETON_INSTANCE);
- VFilters.SINGLETON_INSTANCE.setParentCell(null);
-
- // If filters was first tab, the new first tab needs re-selecting.
- if (filtersParent.getDocs().size() > 0) {
- filtersParent.setSelected(filtersParent.getDocs().get(0));
- }
- }
-
// Fill in gaps
SwingUtilities.invokeLater(new Runnable() {
@Override
@@ -340,16 +327,10 @@ public class CEditorDraftingProcess extends ACEditorBase
VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(true);
//Re-add tabs
- if (filtersParent != null) {
-
- filtersParent.addDoc(VFilters.SINGLETON_INSTANCE);
- }
if (deckGenParent != null) {
-
deckGenParent.addDoc(VDeckgen.SINGLETON_INSTANCE);
}
if (allDecksParent != null) {
-
allDecksParent.addDoc(VAllDecks.SINGLETON_INSTANCE);
}
diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java
index 23db62b0427..4f611eb9f75 100644
--- a/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java
+++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java
@@ -12,7 +12,6 @@ import forge.gui.deckeditor.SEditorIO;
import forge.gui.deckeditor.SEditorIO.EditorPreference;
import forge.gui.deckeditor.tables.SColumnUtil;
import forge.gui.deckeditor.tables.SColumnUtil.ColumnName;
-import forge.gui.deckeditor.views.VCardCatalog;
import forge.gui.deckeditor.views.VCurrentDeck;
import forge.gui.deckeditor.views.VEditorPreferences;
import forge.gui.framework.ICDoc;
@@ -57,6 +56,7 @@ public enum CEditorPreferences implements ICDoc {
prefsDict.put(prefsInstance.getChbCatalogAI(), ColumnName.CAT_AI);
prefsDict.put(prefsInstance.getChbCatalogPower(), ColumnName.CAT_POWER);
prefsDict.put(prefsInstance.getChbCatalogToughness(), ColumnName.CAT_TOUGHNESS);
+ prefsDict.put(prefsInstance.getChbCatalogOwned(), ColumnName.CAT_OWNED);
// Deck
prefsDict.put(prefsInstance.getChbDeckColor(), ColumnName.DECK_COLOR);
@@ -82,8 +82,6 @@ public enum CEditorPreferences implements ICDoc {
}
// Catalog/Deck Stats
- VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogStats().setSelected(
- SEditorIO.getPref(EditorPreference.stats_catalog));
VEditorPreferences.SINGLETON_INSTANCE.getChbDeckStats().setSelected(
SEditorIO.getPref(EditorPreference.stats_deck));
VEditorPreferences.SINGLETON_INSTANCE.getChbCardDisplayUnique().setSelected(
@@ -94,9 +92,6 @@ public enum CEditorPreferences implements ICDoc {
if (!SEditorIO.getPref(EditorPreference.stats_deck)) {
VCurrentDeck.SINGLETON_INSTANCE.getPnlStats().setVisible(false);
}
- if (!SEditorIO.getPref(EditorPreference.stats_catalog)) {
- VCardCatalog.SINGLETON_INSTANCE.getPnlStats().setVisible(false);
- }
boolean wantElastic = SEditorIO.getPref(EditorPreference.elastic_columns);
boolean wantUnique = SEditorIO.getPref(EditorPreference.display_unique_only);
@@ -110,13 +105,6 @@ public enum CEditorPreferences implements ICDoc {
curEditor.getTableDeck().updateView(true);
}
- VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogStats().addItemListener(new ItemListener() {
- @Override public void itemStateChanged(final ItemEvent e) {
- VCardCatalog.SINGLETON_INSTANCE.getPnlStats().setVisible(
- ((JCheckBox) e.getSource()).isSelected());
- SEditorIO.setPref(EditorPreference.stats_catalog, ((JCheckBox) e.getSource()).isSelected());
- SEditorIO.savePreferences(); } });
-
VEditorPreferences.SINGLETON_INSTANCE.getChbDeckStats().addItemListener(new ItemListener() {
@Override public void itemStateChanged(final ItemEvent e) {
VCurrentDeck.SINGLETON_INSTANCE.getPnlStats().setVisible(
diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java
index 4b643691272..9e9a01c5cf2 100644
--- a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java
+++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java
@@ -117,15 +117,14 @@ public final class CEditorQuestCardShop extends ACEditorBase> columnsCatalog = SColumnUtil.getCatalogDefaultColumns();
final List> columnsDeck = SColumnUtil.getDeckDefaultColumns();
- // Add "price", "decks", and "new" column in catalog and deck
+ // Add spell shop-specific columns
columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_PURCHASE_PRICE));
columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions(
this.fnPriceCompare, this.fnPriceGet);
- // card shop doesn't need "New" column
- //columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_NEW));
- //columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions(
- // this.questData.getCards().getFnNewCompare(), this.questData.getCards().getFnNewGet());
+ columnsCatalog.add(1, SColumnUtil.getColumn(ColumnName.CAT_OWNED));
+ columnsCatalog.get(1).setSortAndDisplayFunctions(
+ questData.getCards().getFnOwnedCompare(), questData.getCards().getFnOwnedGet());
columnsDeck.add(SColumnUtil.getColumn(ColumnName.DECK_SALE_PRICE));
columnsDeck.get(columnsDeck.size() - 1).setSortAndDisplayFunctions(
@@ -139,7 +138,7 @@ public final class CEditorQuestCardShop extends ACEditorBase
(C at beginning of class name denotes a control class.)
- *
- */
-public enum CFilters implements ICDoc {
- /** */
- SINGLETON_INSTANCE;
-
- private boolean filtersAllEnabled = true;
-
- //========== Overridden methods
-
- /* (non-Javadoc)
- * @see forge.gui.framework.ICDoc#getCommandOnSelect()
- */
- @Override
- public Command getCommandOnSelect() {
- return null;
- }
-
- /* (non-Javadoc)
- * @see forge.gui.framework.ICDoc#initialize()
- */
- @SuppressWarnings("serial")
- @Override
- public void initialize() {
- final ItemListener iliFilter = new ItemListener() {
- @Override
- public void itemStateChanged(final ItemEvent arg0) {
- if (!SFilterUtil.isFilteringPrevented()) {
- buildFilter();
- }
- }
- };
-
- VFilters.SINGLETON_INSTANCE.getCbxSets().addItemListener(iliFilter);
- VFilters.SINGLETON_INSTANCE.getCbxPLow().addItemListener(iliFilter);
- VFilters.SINGLETON_INSTANCE.getCbxPHigh().addItemListener(iliFilter);
- VFilters.SINGLETON_INSTANCE.getCbxTLow().addItemListener(iliFilter);
- VFilters.SINGLETON_INSTANCE.getCbxTHigh().addItemListener(iliFilter);
- VFilters.SINGLETON_INSTANCE.getCbxCMCLow().addItemListener(iliFilter);
- VFilters.SINGLETON_INSTANCE.getCbxCMCHigh().addItemListener(iliFilter);
-
- ((FLabel) VFilters.SINGLETON_INSTANCE.getBtnToggle()).setCommand(new Command() {
- @Override
- public void execute() {
- SFilterUtil.setPreventFiltering(true);
- toggleColorTypeSetFilter();
- SFilterUtil.setPreventFiltering(false);
- buildFilter();
- }
- });
-
- ((FLabel) VFilters.SINGLETON_INSTANCE.getBtnResetIntervals()).setCommand(new Command() {
- @Override
- public void execute() {
- SFilterUtil.setPreventFiltering(true);
- VFilters.SINGLETON_INSTANCE.getCbxPLow().setSelectedIndex(0);
- VFilters.SINGLETON_INSTANCE.getCbxTLow().setSelectedIndex(0);
- VFilters.SINGLETON_INSTANCE.getCbxCMCLow().setSelectedIndex(0);
-
- VFilters.SINGLETON_INSTANCE.getCbxPHigh().setSelectedIndex(
- VFilters.SINGLETON_INSTANCE.getCbxPHigh().getItemCount() - 1);
- VFilters.SINGLETON_INSTANCE.getCbxTHigh().setSelectedIndex(
- VFilters.SINGLETON_INSTANCE.getCbxTHigh().getItemCount() - 1);
- VFilters.SINGLETON_INSTANCE.getCbxCMCHigh().setSelectedIndex(
- VFilters.SINGLETON_INSTANCE.getCbxCMCHigh().getItemCount() - 1);
-
- SFilterUtil.setPreventFiltering(false);
- buildFilter();
- }
- });
-
- ((FLabel) VFilters.SINGLETON_INSTANCE.getBtnResetText()).setCommand(new Command() {
- @Override
- public void execute() {
- VFilters.SINGLETON_INSTANCE.getTxfContains().setText("");
- VFilters.SINGLETON_INSTANCE.getTxfWithout().setText("");
- buildFilter();
- }
- });
-
- VFilters.SINGLETON_INSTANCE.getTxfContains().addKeyListener(new KeyAdapter() {
- @Override
- public void keyReleased(final KeyEvent e) {
- if (e.getKeyCode() == 10) { buildFilter(); }
- }
- });
-
- VFilters.SINGLETON_INSTANCE.getTxfWithout().addKeyListener(new KeyAdapter() {
- @Override
- public void keyReleased(final KeyEvent e) {
- if (e.getKeyCode() == 10) { buildFilter(); }
- }
- });
- }
-
- /* (non-Javadoc)
- * @see forge.gui.framework.ICDoc#update()
- */
- @Override
- public void update() {
- }
-
- /**
- * Clear filter button_action performed.
- *
- * @param e
- * the e
- */
- private void toggleColorTypeSetFilter() {
- VFilters.SINGLETON_INSTANCE.getCbxSets().setSelectedIndex(0);
-
- if (filtersAllEnabled) {
- filtersAllEnabled = false;
- SFilterUtil.toggleColorCheckboxes(false);
- SFilterUtil.toggleTypeCheckboxes(false);
- }
- else {
- filtersAllEnabled = true;
- SFilterUtil.toggleColorCheckboxes(true);
- SFilterUtil.toggleTypeCheckboxes(true);
- }
- }
-
- //===========
-
- /**
- *
- * Assembles filter from the ones available. To prevent a block
- * of filters from being used, set its parent panel's visibility to false.
- *
- * @param extends InventoryItem
- * @param extends DeckBase
- */
- @SuppressWarnings("unchecked")
- public void buildFilter() {
- // The main trick here is to apply a CardPrinted predicate
- // to the table. CardRules will lead to difficulties.
-
- final ACEditorBase ed = (ACEditorBase)
- CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController();
-
- Predicate super CardPrinted> classFilter = Predicates.instanceOf(CardPrinted.class);
- Predicate color = SFilterUtil.buildColorFilter();
- Predicate type = SFilterUtil.buildTypeFilter();
- Predicate set = SFilterUtil.buildSetAndFormatFilter();
- Predicate text = SFilterUtil.buildTextFilter();
- Predicate interval = SFilterUtil.buildIntervalFilter();
-
- // Until this is filterable, always show packs and decks in the card shop.
- Predicate super CardPrinted> cardFilter = Predicates.and(classFilter, color, type, set, text, interval);
-
- Predicate super CardPrinted> itemFilter = Predicates.or(cardFilter, ItemPredicate.Presets.IS_PACK, ItemPredicate.Presets.IS_DECK);
-
- // Apply to table
- ed.getTableCatalog().setFilter((Predicate) itemFilter);
- }
-}
diff --git a/src/main/java/forge/gui/deckeditor/tables/EditorTableModel.java b/src/main/java/forge/gui/deckeditor/tables/EditorTableModel.java
index 040f67e28ef..269874c8389 100644
--- a/src/main/java/forge/gui/deckeditor/tables/EditorTableModel.java
+++ b/src/main/java/forge/gui/deckeditor/tables/EditorTableModel.java
@@ -19,6 +19,7 @@ Forge Team
*/
package forge.gui.deckeditor.tables;
+import java.awt.Cursor;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
@@ -225,7 +226,7 @@ public final class EditorTableModel extends AbstractTab
header.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
- if (null == header.getResizingColumn()) {
+ if (Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR) != header.getCursor()) {
headerClicked(e);
}
}
diff --git a/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java b/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java
index 3f9441d0e2c..174c5800215 100644
--- a/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java
+++ b/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java
@@ -72,6 +72,7 @@ public final class SColumnUtil {
CAT_AI, /** */
CAT_NEW, /** */
CAT_PURCHASE_PRICE, /** */
+ CAT_OWNED, /** */
DECK_QUANTITY, /** */
DECK_NAME, /** */
DECK_COST, /** */
diff --git a/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java b/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java
index c59be9b3aad..5a318daae5c 100644
--- a/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java
+++ b/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java
@@ -46,8 +46,6 @@ public class TableColumnInfo extends TableColumn {
/** */
public TableColumnInfo() {
super();
- setResizable(true);
- setMinWidth(30);
}
/**
diff --git a/src/main/java/forge/gui/deckeditor/views/ITableContainer.java b/src/main/java/forge/gui/deckeditor/views/ITableContainer.java
index 460fd4b16a9..ab4402e8c6c 100644
--- a/src/main/java/forge/gui/deckeditor/views/ITableContainer.java
+++ b/src/main/java/forge/gui/deckeditor/views/ITableContainer.java
@@ -1,8 +1,10 @@
package forge.gui.deckeditor.views;
-import javax.swing.JLabel;
import javax.swing.JTable;
+import forge.gui.deckeditor.SEditorUtil;
+import forge.gui.toolbox.FLabel;
+
/**
* Dictates methods needed for a class to act as a container for
* a EditorTableView deck editing component.
@@ -19,47 +21,5 @@ public interface ITableContainer {
*/
void setTableView(JTable tbl0);
- // Various card count total labels
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblTotal();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblBlack();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblBlue();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblGreen();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblRed();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblWhite();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblColorless();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblArtifact();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblEnchantment();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblCreature();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblSorcery();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblInstant();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblPlaneswalker();
-
- /** @return {@link javax.swing.JLabel} */
- JLabel getLblLand();
-}
+ FLabel getStatLabel(SEditorUtil.StatTypes s);
+ }
diff --git a/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java b/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java
index ff775d0e61e..22c9e819ce0 100644
--- a/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java
+++ b/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java
@@ -1,12 +1,22 @@
package forge.gui.deckeditor.views;
-import javax.swing.ImageIcon;
-import javax.swing.JLabel;
+import java.awt.Container;
+import java.awt.FlowLayout;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.BorderFactory;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
+import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
+import forge.Command;
+import forge.card.CardRulesPredicates;
+import forge.gui.WrapLayout;
import forge.gui.deckeditor.SEditorUtil;
import forge.gui.deckeditor.controllers.CCardCatalog;
import forge.gui.framework.DragCell;
@@ -15,6 +25,10 @@ import forge.gui.framework.EDocID;
import forge.gui.framework.IVDoc;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin;
+import forge.gui.toolbox.FSpinner;
+import forge.gui.toolbox.FTextField;
+import forge.util.Pair;
+import forge.util.TextUtil;
/**
* Assembles Swing components of card catalog in deck editor.
@@ -25,55 +39,75 @@ import forge.gui.toolbox.FSkin;
public enum VCardCatalog implements IVDoc, ITableContainer {
/** */
SINGLETON_INSTANCE;
+
+ public static final int SEARCH_MODE_INVERSE_INDEX = 1;
// Fields used with interface IVDoc
private DragCell parentCell;
private final DragTab tab = new DragTab("Card Catalog");
- // Total and color count labels
- private final JPanel pnlStats = new JPanel();
- private final JLabel lblTotal = buildLabel(SEditorUtil.ICO_TOTAL);
- private final JLabel lblBlack = buildLabel(SEditorUtil.ICO_BLACK);
- private final JLabel lblBlue = buildLabel(SEditorUtil.ICO_BLUE);
- private final JLabel lblGreen = buildLabel(SEditorUtil.ICO_GREEN);
- private final JLabel lblRed = buildLabel(SEditorUtil.ICO_RED);
- private final JLabel lblWhite = buildLabel(SEditorUtil.ICO_WHITE);
- private final JLabel lblColorless = buildLabel(SEditorUtil.ICO_COLORLESS);
-
- // Card type labels
- private final JLabel lblArtifact = buildLabel(SEditorUtil.ICO_ARTIFACT);
- private final JLabel lblCreature = buildLabel(SEditorUtil.ICO_CREATURE);
- private final JLabel lblEnchantment = buildLabel(SEditorUtil.ICO_ENCHANTMENT);
- private final JLabel lblInstant = buildLabel(SEditorUtil.ICO_INSTANT);
- private final JLabel lblLand = buildLabel(SEditorUtil.ICO_LAND);
- private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.ICO_PLANESWALKER);
- private final JLabel lblSorcery = buildLabel(SEditorUtil.ICO_SORCERY);
-
- private final JLabel lblTitle = new FLabel.Builder()
- .fontSize(14).build();
-
+ // panel where special instructions appear
private final JPanel pnlHeader = new JPanel(new MigLayout("insets 0, gap 0"));
+ private final FLabel lblTitle = new FLabel.Builder().fontSize(14).build();
+ // Total and color count labels/filter toggles
+ private final JPanel pnlStats = new JPanel();
+ private final Map statLabels =
+ new HashMap();
+
+ // card transfer buttons
private final JPanel pnlAddButtons =
new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3"));
-
- private final JLabel btnAdd = new FLabel.Builder()
+ private final FLabel btnAdd = new FLabel.Builder()
.fontSize(14)
.text("Add card")
.tooltip("Add selected card to current deck (or double click the row)")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_PLUS))
.iconScaleAuto(false).hoverable(true).build();
-
- private final JLabel btnAdd4 = new FLabel.Builder()
+ private final FLabel btnAdd4 = new FLabel.Builder()
.fontSize(14)
.text("Add 4 of card")
.tooltip("Add up to 4 of selected card to current deck")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_PLUS))
.iconScaleAuto(false).hoverable(true).build();
+ // restriction button and search widgets
+ private final JPanel pnlSearch = new JPanel(new MigLayout("insets 0, gap 5px, center"));
+ private final FLabel btnAddRestriction = new FLabel.Builder()
+ .text("Filter by")
+ .tooltip("Filter shown cards by various properties")
+ .hoverable(true).opaque(true).reactOnMouseDown(true).build();
+ private final JComboBox cbSearchMode = new JComboBox();
+ private final JTextField txfSearch = new FTextField.Builder().build();
+ private final FLabel lblName = new FLabel.Builder().text("Name").selectable(true).selected(true).hoverable(true).opaque(true).build();
+ private final FLabel lblType = new FLabel.Builder().text("Type").selectable(true).selected(true).hoverable(true).opaque(true).build();
+ private final FLabel lblText = new FLabel.Builder().text("Text").selectable(true).selected(true).hoverable(true).opaque(true).build();
+ private final JPanel pnlRestrictions = new JPanel(new WrapLayout(FlowLayout.LEFT, 10, 5));
+
+ // restriction widgets
+ public static enum RangeTypes {
+ CMC (CardRulesPredicates.LeafNumber.CardField.CMC),
+ POWER (CardRulesPredicates.LeafNumber.CardField.POWER),
+ TOUGHNESS (CardRulesPredicates.LeafNumber.CardField.TOUGHNESS);
+
+ public final CardRulesPredicates.LeafNumber.CardField cardField;
+
+ RangeTypes(CardRulesPredicates.LeafNumber.CardField cardField) {
+ this.cardField = cardField;
+ }
+
+ public String toLabelString() {
+ if (this == CMC) { return toString(); }
+ return TextUtil.enumToLabel(this);
+ }
+ }
+ private final Map> spinners = new HashMap>();
+
+ // card table
private JTable tblCards = null;
private final JScrollPane scroller = new JScrollPane();
+
//========== Constructor
/** */
private VCardCatalog() {
@@ -82,238 +116,172 @@ public enum VCardCatalog implements IVDoc, ITableContainer {
scroller.setBorder(null);
scroller.getViewport().setBorder(null);
- lblTotal.setToolTipText("Total Card Count");
- lblBlack.setToolTipText("Black Card Count");
- lblBlue.setToolTipText("Blue Card Count");
- lblGreen.setToolTipText("Green Card Count");
- lblRed.setToolTipText("Red Card Count");
- lblWhite.setToolTipText("White Card Count");
- lblColorless.setToolTipText("Total Card Count");
- lblArtifact.setToolTipText("Artifact Card Count");
- lblCreature.setToolTipText("Creature Card Count");
- lblColorless.setToolTipText("Colorless Card Count");
- lblEnchantment.setToolTipText("Enchantment Card Count");
- lblInstant.setToolTipText("Instant Card Count");
- lblLand.setToolTipText("Land Card Count");
- lblPlaneswalker.setToolTipText("Planeswalker Card Count");
- lblSorcery.setToolTipText("Sorcery Card Count");
-
pnlStats.setOpaque(false);
pnlStats.setLayout(new MigLayout("insets 0, gap 5px, ax center, wrap 7"));
-
- final String constraints = "w 57px!, h 20px!";
- pnlStats.add(lblTotal, constraints);
- pnlStats.add(lblWhite, constraints);
- pnlStats.add(lblBlue, constraints);
- pnlStats.add(lblBlack, constraints);
- pnlStats.add(lblRed, constraints);
- pnlStats.add(lblGreen, constraints);
- pnlStats.add(lblColorless, constraints);
-
- pnlStats.add(lblLand, constraints);
- pnlStats.add(lblArtifact, constraints);
- pnlStats.add(lblCreature, constraints);
- pnlStats.add(lblEnchantment, constraints);
- pnlStats.add(lblPlaneswalker, constraints);
- pnlStats.add(lblInstant, constraints);
- pnlStats.add(lblSorcery, constraints);
-
- pnlAddButtons.setOpaque(false);
+
+ for (SEditorUtil.StatTypes s : SEditorUtil.StatTypes.values()) {
+ FLabel label = buildToggleLabel(s, SEditorUtil.StatTypes.TOTAL != s);
+ statLabels.put(s, label);
+ pnlStats.add(label, "w 57px!, h 20px!");
+ }
+
+ statLabels.get(SEditorUtil.StatTypes.TOTAL).setToolTipText("Total cards (click to toggle all filters)");
+
+ pnlAddButtons.setOpaque(false);
pnlAddButtons.add(btnAdd, "w 30%!, h 30px!, gap 0 0 5px 5px");
pnlAddButtons.add(btnAdd4, "w 30%!, h 30px!, gap 5% 5% 5px 5px");
+
+ pnlSearch.setOpaque(false);
+ pnlSearch.add(btnAddRestriction, "center, width pref+4");
+ cbSearchMode.addItem("With");
+ cbSearchMode.addItem("Without");
+ pnlSearch.add(cbSearchMode, "center");
+ pnlSearch.add(txfSearch, "pushx, growx");
+ pnlSearch.add(new FLabel.Builder().text("in").build());
+ pnlSearch.add(lblName, "width pref+4");
+ pnlSearch.add(lblType, "width pref+4");
+ pnlSearch.add(lblText, "width pref+4");
+
+ pnlRestrictions.setOpaque(false);
pnlHeader.setOpaque(false);
pnlHeader.add(lblTitle, "w 100%!, h 100%!");
+
+ // fill spinner map
+ for (RangeTypes t : RangeTypes.values()) {
+ spinners.put(t, new Pair(
+ new FSpinner.Builder().maxValue(10).build(),
+ new FSpinner.Builder().maxValue(10).build()));
+ }
}
//========== Overridden from IVDoc
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#getDocumentID()
- */
@Override
public EDocID getDocumentID() {
return EDocID.EDITOR_CATALOG;
}
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#getTabLabel()
- */
@Override
public DragTab getTabLabel() {
return tab;
}
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#getLayoutControl()
- */
@Override
public CCardCatalog getLayoutControl() {
return CCardCatalog.SINGLETON_INSTANCE;
}
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell)
- */
@Override
public void setParentCell(DragCell cell0) {
this.parentCell = cell0;
}
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#getParentCell()
- */
@Override
public DragCell getParentCell() {
return this.parentCell;
}
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#populate()
- */
@Override
public void populate() {
- parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3"));
- parentCell.getBody().add(pnlHeader, "w 98%!, h 30px!, gap 1% 0 1% 10px");
- parentCell.getBody().add(pnlStats, "w 96%, h 50px!, gap 2% 0 1% 1%");
- parentCell.getBody().add(pnlAddButtons, "w 96%!, gap 2% 0 0 0");
- parentCell.getBody().add(scroller, "w 98%!, h 100% - 35px, gap 1% 0 1% 1%");
+ JPanel parentBody = parentCell.getBody();
+ parentBody.setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3"));
+ parentBody.add(pnlHeader, "w 98%!, h 30px!, gap 1% 1% 0 0");
+ parentBody.add(pnlStats, "w 96%, h 50px!, gap 2% 0 1% 1%");
+ parentBody.add(pnlAddButtons, "w 96%!, gapleft 1%");
+ parentBody.add(pnlSearch, "w 96%, gapleft 1%");
+ parentBody.add(pnlRestrictions, "w 96%, gapleft 1%, gapright push");
+ parentBody.add(scroller, "w 98%!, h 100% - 35px, gap 1% 0 0 1%");
}
//========== Overridden from ITableContainer
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#setTableView()
- */
@Override
public void setTableView(final JTable tbl0) {
this.tblCards = tbl0;
scroller.setViewportView(tblCards);
}
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblTotal()
- */
@Override
- public JLabel getLblTotal() { return lblTotal; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblBlack()
- */
- @Override
- public JLabel getLblBlack() { return lblBlack; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblBlue()
- */
- @Override
- public JLabel getLblBlue() { return lblBlue; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblGreen()
- */
- @Override
- public JLabel getLblGreen() { return lblGreen; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblRed()
- */
- @Override
- public JLabel getLblRed() { return lblRed; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblWhite()
- */
- @Override
- public JLabel getLblWhite() { return lblWhite; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblColorless()
- */
- @Override
- public JLabel getLblColorless() { return lblColorless; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblArtifact()
- */
- @Override
- public JLabel getLblArtifact() { return lblArtifact; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblEnchantment()
- */
- @Override
- public JLabel getLblEnchantment() { return lblEnchantment; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblCreature()
- */
- @Override
- public JLabel getLblCreature() { return lblCreature; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblSorcery()
- */
- @Override
- public JLabel getLblSorcery() { return lblSorcery; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblInstant()
- */
- @Override
- public JLabel getLblInstant() { return lblInstant; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblPlaneswalker()
- */
- @Override
- public JLabel getLblPlaneswalker() { return lblPlaneswalker; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblLand()
- */
- @Override
- public JLabel getLblLand() { return lblLand; }
+ public FLabel getStatLabel(SEditorUtil.StatTypes s) {
+ return statLabels.get(s);
+ }
//========== Accessor/mutator methods
+ public JPanel getPnlHeader() { return pnlHeader; }
+ public FLabel getLblTitle() { return lblTitle; }
+ public JPanel getPnlAddButtons() { return pnlAddButtons; }
+ public FLabel getBtnAdd() { return btnAdd; }
+ public FLabel getBtnAdd4() { return btnAdd4; }
+ public FLabel getLblName() { return lblName; }
+ public FLabel getLblType() { return lblType; }
+ public FLabel getLblText() { return lblText; }
+
+ public FLabel getBtnAddRestriction() { return btnAddRestriction; }
+ public JComboBox getCbSearchMode() { return cbSearchMode; }
+ public JTextField getTxfSearch() { return txfSearch; }
- /** @return {@link javax.swing.JLabel} */
- public JLabel getLblTitle() {
- return lblTitle;
+ public Map getStatLabels() {
+ return statLabels;
}
-
- /** @return {@link javax.swing.JLabel} */
- public JLabel getBtnAdd() {
- return btnAdd;
+ public Map> getSpinners() {
+ return spinners;
}
-
- /** @return {@link javax.swing.JLabel} */
- public JLabel getBtnAdd4() {
- return btnAdd4;
- }
-
- /** @return {@link javax.swing.JPanel} */
- public JPanel getPnlHeader() {
- return pnlHeader;
- }
-
- /** @return {@link javax.swing.JPanel} */
- public JPanel getPnlStats() {
- return pnlStats;
- }
-
- /** @return {@link javax.swing.JPanel} */
- public JPanel getPnlAddButtons() {
- return pnlAddButtons;
- }
-
+
//========== Other methods
-
- private JLabel buildLabel(final ImageIcon icon0) {
- final JLabel lbl = new FLabel.Builder().text("0")
- .icon(icon0).iconScaleAuto(false)
- .fontSize(11)
+ private FLabel buildToggleLabel(SEditorUtil.StatTypes s, boolean selectable) {
+ return new FLabel.Builder()
+ .icon(s.img).iconScaleAuto(false)
+ .text("0").fontSize(11)
+ .tooltip(s.toLabelString())
+ .hoverable(true).selectable(selectable).selected(selectable)
.build();
+ }
- return lbl;
+ @SuppressWarnings("serial")
+ public void addRestrictionWidget(JComponent component, final Command onRemove) {
+ final JPanel pnl = new JPanel(new MigLayout("insets 2, gap 2, h 30!"));
+
+ pnl.setOpaque(false);
+ pnl.setBorder(BorderFactory.createMatteBorder(1, 2, 1, 2, FSkin.getColor(FSkin.Colors.CLR_TEXT)));
+
+ final Container parent = pnlRestrictions.getParent();
+
+ pnl.add(component, "h 30!, center");
+ pnl.add(new FLabel.Builder().text("X").fontSize(10).hoverable(true)
+ .tooltip("Remove filter").cmdClick(new Command() {
+ @Override
+ public void execute() {
+ pnlRestrictions.remove(pnl);
+ pnlRestrictions.validate();
+ parent.validate();
+ parent.repaint();
+
+ onRemove.execute();
+ }
+ }).build(), "top");
+
+ pnlRestrictions.add(pnl, "h 30!");
+
+ pnlRestrictions.validate();
+ parent.validate();
+ parent.repaint();
+ }
+
+ public JComponent buildRangeRestrictionWidget(RangeTypes t) {
+ JPanel pnl = new JPanel(new MigLayout("insets 0, gap 2"));
+ pnl.setOpaque(false);
+
+ Pair s = spinners.get(t);
+ pnl.add(s.a, "w 45!");
+ pnl.add(new FLabel.Builder().text("<=").fontSize(11).build());
+ pnl.add(new FLabel.Builder().text(t.toLabelString()).fontSize(11).build());
+ pnl.add(new FLabel.Builder().text("<=").fontSize(11).build());
+ pnl.add(s.b, "w 45!");
+
+ return pnl;
+ }
+
+ public JComponent buildPlainRestrictionWidget(String label, String tooltip) {
+ return new FLabel.Builder().text(label).tooltip(tooltip).fontSize(11).build();
}
}
diff --git a/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java b/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java
index dc1a252881a..754c6ba3d64 100644
--- a/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java
+++ b/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java
@@ -1,8 +1,8 @@
package forge.gui.deckeditor.views;
-import java.awt.Insets;
+import java.util.HashMap;
+import java.util.Map;
-import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
@@ -101,7 +101,7 @@ public enum VCurrentDeck implements IVDoc, ITableContainer {
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_EDIT))
.iconScaleAuto(false).hoverable(true).build();
- private final JTextField txfTitle = new FTextField();
+ private final JTextField txfTitle = new FTextField.Builder().text("[New Deck]").build();
private final JPanel pnlRemove = new JPanel();
private final JPanel pnlHeader = new JPanel();
@@ -110,21 +110,8 @@ public enum VCurrentDeck implements IVDoc, ITableContainer {
.fontSize(14).build();
private final JPanel pnlStats = new JPanel();
- private final JLabel lblTotal = buildLabel(SEditorUtil.ICO_TOTAL);
- private final JLabel lblBlack = buildLabel(SEditorUtil.ICO_BLACK);
- private final JLabel lblBlue = buildLabel(SEditorUtil.ICO_BLUE);
- private final JLabel lblGreen = buildLabel(SEditorUtil.ICO_GREEN);
- private final JLabel lblRed = buildLabel(SEditorUtil.ICO_RED);
- private final JLabel lblWhite = buildLabel(SEditorUtil.ICO_WHITE);
- private final JLabel lblColorless = buildLabel(SEditorUtil.ICO_COLORLESS);
-
- private final JLabel lblArtifact = buildLabel(SEditorUtil.ICO_ARTIFACT);
- private final JLabel lblCreature = buildLabel(SEditorUtil.ICO_CREATURE);
- private final JLabel lblEnchantment = buildLabel(SEditorUtil.ICO_ENCHANTMENT);
- private final JLabel lblInstant = buildLabel(SEditorUtil.ICO_INSTANT);
- private final JLabel lblLand = buildLabel(SEditorUtil.ICO_LAND);
- private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.ICO_PLANESWALKER);
- private final JLabel lblSorcery = buildLabel(SEditorUtil.ICO_SORCERY);
+ private final Map statLabels =
+ new HashMap();
private JTable tblCards = null;
private final JScrollPane scroller = new JScrollPane(tblCards);
@@ -132,16 +119,6 @@ public enum VCurrentDeck implements IVDoc, ITableContainer {
//========== Constructor
private VCurrentDeck() {
- // Title text area
- txfTitle.setText("[New Deck]");
- txfTitle.setMargin(new Insets(5, 5, 5, 5));
- txfTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
- txfTitle.setOpaque(true);
- txfTitle.setEditable(true);
- txfTitle.setFocusable(true);
- txfTitle.setOpaque(true);
- txfTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
-
// Header area
pnlHeader.setOpaque(false);
pnlHeader.setLayout(new MigLayout("insets 0, gap 0, ax center, hidemode 3"));
@@ -166,45 +143,17 @@ public enum VCurrentDeck implements IVDoc, ITableContainer {
scroller.setBorder(null);
scroller.getViewport().setBorder(null);
- lblTotal.setToolTipText("Total Card Count");
- lblBlack.setToolTipText("Black Card Count");
- lblBlue.setToolTipText("Blue Card Count");
- lblGreen.setToolTipText("Green Card Count");
- lblRed.setToolTipText("Red Card Count");
- lblWhite.setToolTipText("White Card Count");
- lblColorless.setToolTipText("Total Card Count");
- lblArtifact.setToolTipText("Artifact Card Count");
- lblCreature.setToolTipText("Creature Card Count");
- lblColorless.setToolTipText("Colorless Card Count");
- lblEnchantment.setToolTipText("Enchantment Card Count");
- lblInstant.setToolTipText("Instant Card Count");
- lblLand.setToolTipText("Land Card Count");
- lblPlaneswalker.setToolTipText("Planeswalker Card Count");
- lblSorcery.setToolTipText("Sorcery Card Count");
-
pnlStats.setOpaque(false);
pnlStats.setLayout(new MigLayout("insets 0, gap 5px, ax center, wrap 7"));
-
- final String constraints = "w 55px!, h 20px!";
- pnlStats.add(lblTotal, constraints);
- pnlStats.add(lblWhite, constraints);
- pnlStats.add(lblBlue, constraints);
- pnlStats.add(lblBlack, constraints);
- pnlStats.add(lblRed, constraints);
- pnlStats.add(lblGreen, constraints);
- pnlStats.add(lblColorless, constraints);
-
- pnlStats.add(lblLand, constraints);
- pnlStats.add(lblArtifact, constraints);
- pnlStats.add(lblCreature, constraints);
- pnlStats.add(lblEnchantment, constraints);
- pnlStats.add(lblPlaneswalker, constraints);
- pnlStats.add(lblInstant, constraints);
- pnlStats.add(lblSorcery, constraints);
-
- pnlRemoveButtons.setOpaque(false);
- pnlRemoveButtons.add(btnRemove, "w 30%!, h 30px!, gap 0 0 5px 5px");
- pnlRemoveButtons.add(btnRemove4, "w 30%!, h 30px!, gap 0 0 5px 5px");
+ for (SEditorUtil.StatTypes s : SEditorUtil.StatTypes.values()) {
+ FLabel label = buildLabel(s);
+ statLabels.put(s, label);
+ pnlStats.add(label, "w 55px!, h 20px!");
+ }
+
+ pnlRemoveButtons.setOpaque(false);
+ pnlRemoveButtons.add(btnRemove, "w 30%!, h 30px!, gap 0 0 5px 5px");
+ pnlRemoveButtons.add(btnRemove4, "w 30%!, h 30px!, gap 0 0 5px 5px");
pnlRemoveButtons.add(btnDoSideboard, "w 30%!, h 30px!, gap 0 0 5px 5px");
}
@@ -278,95 +227,12 @@ public enum VCurrentDeck implements IVDoc, ITableContainer {
scroller.setViewportView(tblCards);
}
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblTotal()
- */
- @Override
- public JLabel getLblTotal() { return lblTotal; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblTotal()
- */
public JLabel getLblTitle() { return lblTitle; }
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblBlack()
- */
@Override
- public JLabel getLblBlack() { return lblBlack; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblBlue()
- */
- @Override
- public JLabel getLblBlue() { return lblBlue; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblGreen()
- */
- @Override
- public JLabel getLblGreen() { return lblGreen; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblRed()
- */
- @Override
- public JLabel getLblRed() { return lblRed; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblWhite()
- */
- @Override
- public JLabel getLblWhite() { return lblWhite; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblColorless()
- */
- @Override
- public JLabel getLblColorless() { return lblColorless; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblArtifact()
- */
- @Override
- public JLabel getLblArtifact() { return lblArtifact; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblEnchantment()
- */
- @Override
- public JLabel getLblEnchantment() { return lblEnchantment; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblCreature()
- */
- @Override
- public JLabel getLblCreature() { return lblCreature; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblSorcery()
- */
- @Override
- public JLabel getLblSorcery() { return lblSorcery; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblInstant()
- */
- @Override
- public JLabel getLblInstant() { return lblInstant; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblPlaneswalker()
- */
- @Override
- public JLabel getLblPlaneswalker() { return lblPlaneswalker; }
-
- /* (non-Javadoc)
- * @see forge.gui.deckeditor.views.ITableContainer#getLblLand()
- */
- @Override
- public JLabel getLblLand() { return lblLand; }
+ public FLabel getStatLabel(SEditorUtil.StatTypes s) {
+ return statLabels.get(s);
+ }
//========== Retrieval
@@ -432,12 +298,11 @@ public enum VCurrentDeck implements IVDoc, ITableContainer {
//========== Other methods
- private JLabel buildLabel(final ImageIcon icon0) {
- final JLabel lbl = new FLabel.Builder().text("0")
- .icon(icon0).iconScaleAuto(false)
- .fontSize(11)
- .build();
-
- return lbl;
+ private FLabel buildLabel(SEditorUtil.StatTypes s) {
+ return new FLabel.Builder()
+ .icon(s.img).iconScaleAuto(false)
+ .text("0").fontSize(11)
+ .tooltip(s.toLabelString())
+ .build();
}
}
diff --git a/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java b/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java
index a983cd7d8a6..c4431280b0f 100644
--- a/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java
+++ b/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java
@@ -52,6 +52,7 @@ public enum VEditorPreferences implements IVDoc {
private JCheckBox chbCatalogAI = new FCheckBox("AI");
private JCheckBox chbCatalogPower = new FCheckBox("Power");
private JCheckBox chbCatalogToughness = new FCheckBox("Toughness");
+ private JCheckBox chbCatalogOwned = new FCheckBox("Owned (Spell shop)");
private JCheckBox chbDeckColor = new FCheckBox("Color");
private JCheckBox chbDeckRarity = new FCheckBox("Rarity");
@@ -62,7 +63,6 @@ public enum VEditorPreferences implements IVDoc {
private JCheckBox chbDeckToughness = new FCheckBox("Toughness");
private JCheckBox chbDeckStats = new FCheckBox("Show stats in current deck");
- private JCheckBox chbCatalogStats = new FCheckBox("Show stats in card catalog");
private JCheckBox chbElasticColumns = new FCheckBox("Use elastic resizing when changing column widths");
private JCheckBox chbCardDisplayUnique = new FCheckBox("Show unique cards only (only affects Constructed)");
@@ -84,6 +84,7 @@ public enum VEditorPreferences implements IVDoc {
chbCatalogAI.setFont(FSkin.getFont(12));
chbCatalogPower.setFont(FSkin.getFont(12));
chbCatalogToughness.setFont(FSkin.getFont(12));
+ chbCatalogOwned.setFont(FSkin.getFont(12));
chbDeckColor.setFont(FSkin.getFont(12));
chbDeckRarity.setFont(FSkin.getFont(12));
@@ -94,17 +95,14 @@ public enum VEditorPreferences implements IVDoc {
chbDeckToughness.setFont(FSkin.getFont(12));
chbDeckStats.setFont(FSkin.getFont(12));
- chbCatalogStats.setFont(FSkin.getFont(12));
chbElasticColumns.setFont(FSkin.getFont(12));
chbDeckStats.setSelected(true);
- chbCatalogStats.setSelected(true);
chbElasticColumns.setSelected(false);
chbCardDisplayUnique.setFont(FSkin.getFont(12));
chbCardDisplayUnique.setSelected(false);
pnl.add(lblStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1");
- pnl.add(chbCatalogStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1");
pnl.add(chbDeckStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1");
pnl.add(chbElasticColumns, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1");
@@ -116,7 +114,8 @@ public enum VEditorPreferences implements IVDoc {
pnl.add(chbCatalogSet, constraints);
pnl.add(chbCatalogPower, constraints);
pnl.add(chbCatalogToughness, constraints);
- pnl.add(chbCatalogAI, constraints + ", wrap");
+ pnl.add(chbCatalogAI, constraints);
+ pnl.add(chbCatalogOwned, constraints + ", wrap");
pnl.add(lblDeck, constraints + ", span 2 1");
pnl.add(chbDeckColor, constraints);
@@ -224,6 +223,11 @@ public enum VEditorPreferences implements IVDoc {
return chbCatalogToughness;
}
+ /** @return {@link javax.swing.JCheckBox} */
+ public JCheckBox getChbCatalogOwned() {
+ return chbCatalogOwned;
+ }
+
/** @return {@link javax.swing.JCheckBox} */
public JCheckBox getChbDeckColor() {
return chbDeckColor;
@@ -269,15 +273,8 @@ public enum VEditorPreferences implements IVDoc {
return chbElasticColumns;
}
- /** @return {@link javax.swing.JCheckBox} */
- public JCheckBox getChbCatalogStats() {
- return chbCatalogStats;
- }
-
/** @return {@link javax.swing.JCheckBox} */
public JCheckBox getChbCardDisplayUnique() {
return chbCardDisplayUnique;
}
- //========== Other methods
-
}
diff --git a/src/main/java/forge/gui/deckeditor/views/VFilters.java b/src/main/java/forge/gui/deckeditor/views/VFilters.java
deleted file mode 100644
index 0562b7ee4bb..00000000000
--- a/src/main/java/forge/gui/deckeditor/views/VFilters.java
+++ /dev/null
@@ -1,333 +0,0 @@
-package forge.gui.deckeditor.views;
-
-import java.awt.Insets;
-
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextField;
-import javax.swing.border.MatteBorder;
-
-import net.miginfocom.swing.MigLayout;
-import forge.Singletons;
-import forge.card.CardEdition;
-import forge.game.GameFormat;
-import forge.gui.deckeditor.SFilterUtil;
-import forge.gui.deckeditor.controllers.CFilters;
-import forge.gui.framework.DragCell;
-import forge.gui.framework.DragTab;
-import forge.gui.framework.EDocID;
-import forge.gui.framework.IVDoc;
-import forge.gui.toolbox.FCheckBox;
-import forge.gui.toolbox.FLabel;
-import forge.gui.toolbox.FSkin;
-import forge.gui.toolbox.FTextField;
-
-/**
- * Assembles Swing components of deck editor filter tab.
- *
- *
(V at beginning of class name denotes a view class.)
- */
-public enum VFilters implements IVDoc {
- /** */
- SINGLETON_INSTANCE;
-
- // Fields used with interface IVDoc
- private DragCell parentCell;
- private final DragTab tab = new DragTab("Filters");
-
- // Text filter components
- private final JTextField txfContains = new FTextField();
- private final JTextField txfWithout = new FTextField();
- private final JLabel lblContains = new FLabel.Builder()
- .text("Contains:").fontSize(14).build();
- private final JLabel lblWithout = new FLabel.Builder()
- .text("Without:").fontSize(14).build();
-
- private final JCheckBox chbName = new FCheckBox("Name");
- private final JCheckBox chbType = new FCheckBox("Type");
- private final JCheckBox chbText = new FCheckBox("Text");
-
- // Interval filter components
- private final JComboBox cbxSets = new JComboBox();
- private final JComboBox cbxPLow = new JComboBox();
- private final JComboBox cbxPHigh = new JComboBox();
- private final JComboBox cbxTLow = new JComboBox();
- private final JComboBox cbxTHigh = new JComboBox();
- private final JComboBox cbxCMCLow = new JComboBox();
- private final JComboBox cbxCMCHigh = new JComboBox();
-
- private final JLabel lblP = new FLabel.Builder()
- .fontSize(12).text(" <= Power <= ").build();
-
- private final JLabel lblT = new FLabel.Builder()
- .fontSize(12).text(" <= Toughness <= ").build();
-
- private final JLabel lblCMC = new FLabel.Builder()
- .fontSize(12).text(" <= CMC <= ").build();
-
- // Title labels
- private final JLabel lblProperties = new FLabel.Builder()
- .text("Properties").tooltip("Filter by color, type, set, or format. Click to toggle.")
- .hoverable(true).fontSize(14).build();
-
- private final JLabel lblText = new FLabel.Builder()
- .text("Card Text").tooltip("Filter by card name, type, and text, space delimited. Click to reset.")
- .hoverable(true).fontSize(14).build();
-
- private final JLabel lblIntervals = new FLabel.Builder()
- .text("Intervals").tooltip("Filter by power, toughness, or converted mana cost. Click to reset.")
- .hoverable(true).fontSize(14).build();
-
- // Container components
- private final JPanel pnlText = new JPanel(new MigLayout(
- "insets 0, gap 0, wrap 3, ax center"));
- private final JPanel pnlIntervals = new JPanel(new MigLayout(
- "insets 0, gap 0, wrap 3, ax center"));
-
- private JPanel pnlContainer = new JPanel(new MigLayout("insets 0, gap 0, wrap"));
- private JScrollPane scroller = new JScrollPane(pnlContainer);
-
- //========== Constructor
- private VFilters() {
- String constraints = "";
-
- // Sets/formats combo box
- cbxSets.addItem("All sets and formats");
- for (final GameFormat s : Singletons.getModel().getFormats()) {
- cbxSets.addItem(s);
- }
- for (final CardEdition s : Singletons.getModel().getEditions()) {
- cbxSets.addItem(s);
- }
-
- // Color/type searches
- lblProperties.setBorder(new MatteBorder(0, 0, 1, 0,
- FSkin.getColor(FSkin.Colors.CLR_BORDERS)));
- lblText.setBorder(new MatteBorder(0, 0, 1, 0,
- FSkin.getColor(FSkin.Colors.CLR_BORDERS)));
- lblIntervals.setBorder(new MatteBorder(0, 0, 1, 0,
- FSkin.getColor(FSkin.Colors.CLR_BORDERS)));
-
- // Text search
- txfContains.setMargin(new Insets(5, 5, 5, 5));
- txfContains.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
- txfContains.setOpaque(true);
- txfContains.setEditable(true);
- txfContains.setFocusable(true);
- txfContains.setOpaque(true);
- txfContains.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
-
- txfWithout.setMargin(new Insets(5, 5, 5, 5));
- txfWithout.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
- txfWithout.setOpaque(true);
- txfWithout.setEditable(true);
- txfWithout.setFocusable(true);
- txfWithout.setOpaque(true);
- txfWithout.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
-
- pnlText.setOpaque(false);
- pnlText.add(lblText, "w 210px!, h 25px!");
- pnlText.add(lblContains, "w 80px!, h 30px!");
- pnlText.add(txfContains, "pushx, growx, span 2 1, gap 5px 5px 2px 2px, h 30px!");
- pnlText.add(lblWithout, "w 80px!, h 30px!");
- pnlText.add(txfWithout, "pushx, growx, span 2 1, gap 5px 5px 2px 2px, h 30px!");
- pnlText.add(chbName, "pushx, growx, w 70px!, h 25px!, gap 5px 5px 2px 2px");
- pnlText.add(chbType, "pushx, growx, w 70px!, h 25px!, gap 0 5px 2px 2px");
- pnlText.add(chbText, "w 60px!, h 25px!, gap 0 5px 2px 2px");
-
- chbName.setSelected(true);
- chbType.setSelected(true);
- chbText.setSelected(true);
-
- cbxPLow.addItem("*");
- cbxTLow.addItem("*");
- cbxCMCLow.addItem("*");
-
- // Interval search
- for (int i = 0; i < 10; i++) {
- cbxPLow.addItem(i);
- cbxTLow.addItem(i);
- cbxCMCLow.addItem(i);
- cbxPHigh.addItem(i);
- cbxTHigh.addItem(i);
- cbxCMCHigh.addItem(i);
- }
-
- cbxPHigh.addItem("10+");
- cbxTHigh.addItem("10+");
- cbxCMCHigh.addItem("10+");
-
- cbxPLow.setSelectedItem("*");
- cbxTLow.setSelectedItem("*");
- cbxCMCLow.setSelectedItem("*");
- cbxPHigh.setSelectedItem("10+");
- cbxTHigh.setSelectedItem("10+");
- cbxCMCHigh.setSelectedItem("10+");
-
- constraints = "w 80px!, h 25px!, gap 0 0 0 0";
- pnlIntervals.add(cbxPLow, constraints);
- pnlIntervals.add(lblP, "w 100px!, h 25px!");
- pnlIntervals.add(cbxPHigh, constraints);
-
- pnlIntervals.add(cbxTLow, constraints);
- pnlIntervals.add(lblT, "w 100px!, h 25px!");
- pnlIntervals.add(cbxTHigh, constraints);
-
- pnlIntervals.add(cbxCMCLow, constraints);
- pnlIntervals.add(lblCMC, "w 100px!, h 25px!");
- pnlIntervals.add(cbxCMCHigh, constraints);
-
- pnlIntervals.setOpaque(false);
-
- // Core layout
- final String constraints2 = "w 90%!, gap 5% 0 1% 0";
- pnlContainer.add(lblProperties, "w 90%!, h 25px!, gap 5% 0 1% 0");
- pnlContainer.add(SFilterUtil.populateColorFilters(), constraints2);
- pnlContainer.add(SFilterUtil.populateTypeFilters(), constraints2);
- pnlContainer.add(cbxSets, constraints2 + ", h 25px!");
-
- pnlContainer.add(lblText, "w 90%!, h 25px!, gap 5% 0 15px 0");
- pnlContainer.add(pnlText, constraints2);
-
- pnlContainer.add(lblIntervals, "w 90%!, h 25px!, gap 5% 0 15px 0");
- pnlContainer.add(pnlIntervals, constraints2);
-
- pnlContainer.setOpaque(false);
- scroller.setOpaque(false);
- scroller.getViewport().setOpaque(false);
- scroller.setBorder(null);
- scroller.getViewport().setBorder(null);
- }
-
- //========== Overridden methods
-
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#getDocumentID()
- */
- @Override
- public EDocID getDocumentID() {
- return EDocID.EDITOR_FILTERS;
- }
-
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#getTabLabel()
- */
- @Override
- public DragTab getTabLabel() {
- return tab;
- }
-
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#getLayoutControl()
- */
- @Override
- public CFilters getLayoutControl() {
- return CFilters.SINGLETON_INSTANCE;
- }
-
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell)
- */
- @Override
- public void setParentCell(final DragCell cell0) {
- this.parentCell = cell0;
- }
-
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#getParentCell()
- */
- @Override
- public DragCell getParentCell() {
- return this.parentCell;
- }
-
- /* (non-Javadoc)
- * @see forge.gui.framework.IVDoc#populate()
- */
- @Override
- public void populate() {
- parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap"));
- parentCell.getBody().add(scroller, "w 96%!, h 96%, gap 2% 0 2% 0");
- }
-
- //========== Retrieval methods
- /** @return {javax.swing.JLabel} */
- public JLabel getBtnToggle() {
- return lblProperties;
- }
-
- /** @return {javax.swing.JLabel} */
- public JLabel getBtnResetText() {
- return lblText;
- }
-
- /** @return {javax.swing.JLabel} */
- public JLabel getBtnResetIntervals() {
- return lblIntervals;
- }
-
- /** @return {javax.swing.JComboBox} */
- public JComboBox getCbxSets() {
- return cbxSets;
- }
-
- /** @return {javax.swing.JTextField} */
- public JTextField getTxfContains() {
- return txfContains;
- }
-
- /** @return {javax.swing.JTextField} */
- public JTextField getTxfWithout() {
- return txfWithout;
- }
-
- /** @return {javax.swing.JComboBox} */
- public JComboBox getCbxPLow() {
- return cbxPLow;
- }
-
- /** @return {javax.swing.JComboBox} */
- public JComboBox getCbxPHigh() {
- return cbxPHigh;
- }
-
- /** @return {javax.swing.JComboBox} */
- public JComboBox getCbxTLow() {
- return cbxTLow;
- }
-
- /** @return {javax.swing.JComboBox} */
- public JComboBox getCbxTHigh() {
- return cbxTHigh;
- }
-
- /** @return {javax.swing.JComboBox} */
- public JComboBox getCbxCMCLow() {
- return cbxCMCLow;
- }
-
- /** @return {javax.swing.JComboBox} */
- public JComboBox getCbxCMCHigh() {
- return cbxCMCHigh;
- }
-
- /** @return {javax.swing.JCheckBox} */
- public JCheckBox getChbTextName() {
- return chbName;
- }
-
- /** @return {javax.swing.JCheckBox} */
- public JCheckBox getChbTextType() {
- return chbType;
- }
-
- /** @return {javax.swing.JCheckBox} */
- public JCheckBox getChbTextText() {
- return chbText;
- }
- //========== Custom class handling
-
-}
diff --git a/src/main/java/forge/gui/deckeditor/views/VStatistics.java b/src/main/java/forge/gui/deckeditor/views/VStatistics.java
index 2dd1b5001b3..ecfd5f4c2bd 100644
--- a/src/main/java/forge/gui/deckeditor/views/VStatistics.java
+++ b/src/main/java/forge/gui/deckeditor/views/VStatistics.java
@@ -43,22 +43,22 @@ public enum VStatistics implements IVDoc {
// Total and color count labels
private final JPanel pnlStats = new JPanel();
- private final JLabel lblMulti = buildLabel(SEditorUtil.ICO_MULTI, true);
- private final JLabel lblBlack = buildLabel(SEditorUtil.ICO_BLACK, false);
- private final JLabel lblBlue = buildLabel(SEditorUtil.ICO_BLUE, true);
- private final JLabel lblGreen = buildLabel(SEditorUtil.ICO_GREEN, false);
- private final JLabel lblRed = buildLabel(SEditorUtil.ICO_RED, true);
- private final JLabel lblWhite = buildLabel(SEditorUtil.ICO_WHITE, false);
- private final JLabel lblColorless = buildLabel(SEditorUtil.ICO_COLORLESS, true);
+ private final JLabel lblMulti = buildLabel(SEditorUtil.StatTypes.MULTICOLOR, true);
+ private final JLabel lblBlack = buildLabel(SEditorUtil.StatTypes.BLACK, false);
+ private final JLabel lblBlue = buildLabel(SEditorUtil.StatTypes.BLUE, true);
+ private final JLabel lblGreen = buildLabel(SEditorUtil.StatTypes.GREEN, false);
+ private final JLabel lblRed = buildLabel(SEditorUtil.StatTypes.RED, true);
+ private final JLabel lblWhite = buildLabel(SEditorUtil.StatTypes.WHITE, false);
+ private final JLabel lblColorless = buildLabel(SEditorUtil.StatTypes.COLORLESS, true);
// Card type labels
- private final JLabel lblArtifact = buildLabel(SEditorUtil.ICO_ARTIFACT, true);
- private final JLabel lblCreature = buildLabel(SEditorUtil.ICO_CREATURE, false);
- private final JLabel lblEnchantment = buildLabel(SEditorUtil.ICO_ENCHANTMENT, true);
- private final JLabel lblInstant = buildLabel(SEditorUtil.ICO_INSTANT, false);
- private final JLabel lblLand = buildLabel(SEditorUtil.ICO_LAND, true);
- private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.ICO_PLANESWALKER, false);
- private final JLabel lblSorcery = buildLabel(SEditorUtil.ICO_SORCERY, true);
+ private final JLabel lblArtifact = buildLabel(SEditorUtil.StatTypes.ARTIFACT, true);
+ private final JLabel lblCreature = buildLabel(SEditorUtil.StatTypes.CREATURE, false);
+ private final JLabel lblEnchantment = buildLabel(SEditorUtil.StatTypes.ENCHANTMENT, true);
+ private final JLabel lblInstant = buildLabel(SEditorUtil.StatTypes.INSTANT, false);
+ private final JLabel lblLand = buildLabel(SEditorUtil.StatTypes.LAND, true);
+ private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.StatTypes.PLANESWALKER, false);
+ private final JLabel lblSorcery = buildLabel(SEditorUtil.StatTypes.SORCERY, true);
// CMC labels
private final JLabel lblCMC0 = buildLabel(
@@ -251,9 +251,9 @@ public enum VStatistics implements IVDoc {
//========== Other methods
- private JLabel buildLabel(final ImageIcon icon0, final boolean zebra) {
+ private JLabel buildLabel(ImageIcon icon, boolean zebra) {
final JLabel lbl = new FLabel.Builder().text("0")
- .icon(icon0).iconScaleAuto(false)
+ .icon(icon).iconScaleAuto(false)
.fontSize(11).build();
if (zebra) {
@@ -263,4 +263,8 @@ public enum VStatistics implements IVDoc {
return lbl;
}
+
+ private JLabel buildLabel(SEditorUtil.StatTypes statType, boolean zebra) {
+ return buildLabel(statType.img, zebra);
+ }
}
diff --git a/src/main/java/forge/gui/framework/EDocID.java b/src/main/java/forge/gui/framework/EDocID.java
index a370661c30e..a74d12fa918 100644
--- a/src/main/java/forge/gui/framework/EDocID.java
+++ b/src/main/java/forge/gui/framework/EDocID.java
@@ -8,7 +8,6 @@ import forge.gui.deckeditor.views.VCardCatalog;
import forge.gui.deckeditor.views.VCurrentDeck;
import forge.gui.deckeditor.views.VDeckgen;
import forge.gui.deckeditor.views.VEditorPreferences;
-import forge.gui.deckeditor.views.VFilters;
import forge.gui.deckeditor.views.VProbabilities;
import forge.gui.deckeditor.views.VStatistics;
import forge.gui.home.gauntlet.VSubmenuGauntletBuild;
@@ -51,7 +50,6 @@ public enum EDocID { /** */
CARD_DETAIL (VDetail.SINGLETON_INSTANCE), /** */
CARD_ANTES (VAntes.SINGLETON_INSTANCE), /** */
- EDITOR_FILTERS (VFilters.SINGLETON_INSTANCE), /** */
EDITOR_PREFERENCES (VEditorPreferences.SINGLETON_INSTANCE), /** */
EDITOR_ALLDECKS (VAllDecks.SINGLETON_INSTANCE), /** */
EDITOR_STATISTICS (VStatistics.SINGLETON_INSTANCE), /** */
diff --git a/src/main/java/forge/gui/framework/SLayoutIO.java b/src/main/java/forge/gui/framework/SLayoutIO.java
index 34b72ff5b9f..9b84c645f1d 100644
--- a/src/main/java/forge/gui/framework/SLayoutIO.java
+++ b/src/main/java/forge/gui/framework/SLayoutIO.java
@@ -190,7 +190,9 @@ public final class SLayoutIO {
}
else if (element.getName().getLocalPart().equals("doc")) {
event = reader.nextEvent();
- cell.addDoc(EDocID.valueOf(event.asCharacters().getData()).getDoc());
+ try {
+ cell.addDoc(EDocID.valueOf(event.asCharacters().getData()).getDoc());
+ } catch (IllegalArgumentException e) { /* ignore; just don't add invalid element */ }
}
}
}
diff --git a/src/main/java/forge/gui/home/gauntlet/VSubmenuGauntletBuild.java b/src/main/java/forge/gui/home/gauntlet/VSubmenuGauntletBuild.java
index 795894cc9bd..659bbebe7f1 100644
--- a/src/main/java/forge/gui/home/gauntlet/VSubmenuGauntletBuild.java
+++ b/src/main/java/forge/gui/home/gauntlet/VSubmenuGauntletBuild.java
@@ -1,7 +1,6 @@
package forge.gui.home.gauntlet;
import java.awt.Color;
-import java.awt.Insets;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
@@ -68,7 +67,7 @@ public enum VSubmenuGauntletBuild implements IVSubmenu {
private final JScrollPane scrRight = new FScrollPane(lstRight,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
- private final JTextField txfFilename = new FTextField();
+ private final JTextField txfFilename = new FTextField.Builder().text(GauntletIO.TXF_PROMPT).build();
private final FLabel lblDesc1 = new FLabel.Builder()
.text("Left/right arrows add or remove decks.")
@@ -139,16 +138,6 @@ public enum VSubmenuGauntletBuild implements IVSubmenu {
grpRadios.add(radColorDecks);
grpRadios.add(radThemeDecks);
- // Text areas
- txfFilename.setText(GauntletIO.TXF_PROMPT);
- txfFilename.setMargin(new Insets(5, 5, 5, 5));
- txfFilename.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
- txfFilename.setOpaque(true);
- txfFilename.setEditable(true);
- txfFilename.setFocusable(true);
- txfFilename.setOpaque(true);
- txfFilename.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
-
// File handling panel
final FLabel lblFilename = new FLabel.Builder()
.text("Gauntlet Name:").fontSize(14).build();
diff --git a/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java b/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java
index f25ddf46295..7cac8a8ec95 100644
--- a/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java
+++ b/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java
@@ -61,11 +61,11 @@ public enum CSubmenuQuestData implements ICDoc {
new Command() { @Override public void execute() { newQuest(); } });
view.getBtnCustomFormat().setCommand(new Command() { @Override public void execute() {
- new DialogCustomFormat(customFormatCodes);
+ new DialogChooseSets(customFormatCodes, null);
} });
view.getBtnPrizeCustomFormat().setCommand(new Command() { @Override public void execute() {
- new DialogCustomFormat(customPrizeFormatCodes);
+ new DialogChooseSets(customPrizeFormatCodes, null);
} });
}
diff --git a/src/main/java/forge/gui/home/quest/DialogCustomFormat.java b/src/main/java/forge/gui/home/quest/DialogChooseSets.java
similarity index 90%
rename from src/main/java/forge/gui/home/quest/DialogCustomFormat.java
rename to src/main/java/forge/gui/home/quest/DialogChooseSets.java
index 259ca095dcc..fbce6fc3ce9 100644
--- a/src/main/java/forge/gui/home/quest/DialogCustomFormat.java
+++ b/src/main/java/forge/gui/home/quest/DialogChooseSets.java
@@ -1,150 +1,158 @@
-package forge.gui.home.quest;
-
-import java.awt.BorderLayout;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JDialog;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.WindowConstants;
-
-import forge.card.CardEdition;
-import forge.Singletons;
-
-/**
- * TODO: Write javadoc for this type.
- *
- */
-public class DialogCustomFormat extends JDialog {
-
- private static final long serialVersionUID = 3155211532871888181L;
- private JScrollPane scrollPane;
- private final JButton btnOK = new JButton("OK");
- private final JButton btnCancel = new JButton("Cancel");
- private final JPanel buttonPanel = new JPanel();
- private final List customFormat;
- private final List choices = new ArrayList();
-
-
- /**
- * Create the dialog.
- *
- * @param userFormat
- * GameFormatQuest, the user-defined format to update
- *
- */
- public DialogCustomFormat(List userFormat) {
-
- customFormat = userFormat;
- if (customFormat == null) {
- throw new RuntimeException("Null GameFormatQuest in DialogCustomFormat");
- }
-
- this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
- List editions = new ArrayList();
-
- for (CardEdition ce : Singletons.getModel().getEditions()) {
- if (canChoose(ce.getCode())) {
- editions.add(ce);
- }
- }
-
- Collections.sort(editions);
- Collections.reverse(editions);
-
- final int numEditions = editions.size();
- final int columns = 3;
- final int rows = numEditions / columns + (numEditions % columns == 0 ? 0 : 1);
-
-
- int getIdx = 0;
-
- JPanel p = new JPanel();
- p.setSize(600, 400);
- p.setLayout(new GridLayout(rows, columns, 10, 0));
-
- for (int row = 0; row < rows; row++) {
- for (int col = 0; col < columns; col++) {
- getIdx = row + (col * rows);
- JCheckBox box;
- if (getIdx < numEditions) {
- CardEdition edition = getIdx < numEditions ? editions.get(getIdx) : null;
- box = new JCheckBox(edition.getName());
- box.setName(edition.getCode());
- box.setSelected(customFormat.contains(edition.getCode()));
- choices.add(box);
- } else {
- box = new JCheckBox();
- box.setEnabled(false);
- }
-
- p.add(box);
- }
- }
- scrollPane = new JScrollPane(p);
-
- getContentPane().add(scrollPane, BorderLayout.CENTER);
- btnOK.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent arg0) {
- updateCustomFormat();
- dispose();
- }
- });
- buttonPanel.add(btnOK, BorderLayout.WEST);
- btnCancel.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent arg0) {
- dispose();
- }
- });
- buttonPanel.add(btnCancel, BorderLayout.EAST);
- getContentPane().add(buttonPanel, BorderLayout.SOUTH);
-
- this.setSize(600, 450);
- this.setLocationRelativeTo(null);
- this.setTitle("Choose sets for custom format:");
- this.setVisible(true);
-
- }
-
- /**
- * Make some sets unselectable (currently only Alpha and Beta).
- * Note that these sets can still be (theoretically) unlocked
- * later, for an exorbitant price. There'd be nothing to be
- * gained from allowing these initially (Unlimited already covers
- * their cardbase), and a lot to be lost (namely, easy early access
- * to extremely expensive cards...) --BBU
- *
- * @param setCode
- * String, set code
- * @return boolean, this set can be selected.
- *
- */
- private boolean canChoose(final String setCode) {
- if (setCode == null) {
- return true;
- }
- return !"LEA".equals(setCode) && !"LEB".equals(setCode)
- && !"MBP".equals(setCode) && !"VAN".equals(setCode)
- && !"ARC".equals(setCode) && !"PC2".equals(setCode);
- }
-
- /**
- * Update the custom format in accordance with the selections.
- */
- void updateCustomFormat() {
- customFormat.clear();
- for (JCheckBox box : choices) {
- if (box.isSelected()) {
- customFormat.add(box.getName());
- }
- }
- }
-}
+package forge.gui.home.quest;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.WindowConstants;
+
+import forge.card.CardEdition;
+import forge.Singletons;
+
+/**
+ * TODO: Write javadoc for this type.
+ *
+ */
+public class DialogChooseSets extends JDialog {
+
+ private static final long serialVersionUID = 3155211532871888181L;
+ private JScrollPane scrollPane;
+ private final JButton btnOK = new JButton("OK");
+ private final JButton btnCancel = new JButton("Cancel");
+ private final JPanel buttonPanel = new JPanel();
+ private final List customFormat;
+ private final Runnable onOk;
+ private final List choices = new ArrayList();
+
+
+ /**
+ * Create the dialog.
+ *
+ * @param userFormat
+ * GameFormatQuest, the user-defined format to update
+ *
+ */
+ public DialogChooseSets(List userFormat, Runnable onOk) {
+
+ customFormat = userFormat;
+ this.onOk = onOk;
+
+ if (customFormat == null) {
+ throw new RuntimeException("Null GameFormatQuest in DialogCustomFormat");
+ }
+
+ this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ List editions = new ArrayList();
+
+ for (CardEdition ce : Singletons.getModel().getEditions()) {
+ if (canChoose(ce.getCode())) {
+ editions.add(ce);
+ }
+ }
+
+ Collections.sort(editions);
+ Collections.reverse(editions);
+
+ final int numEditions = editions.size();
+ final int columns = 3;
+ final int rows = numEditions / columns + (numEditions % columns == 0 ? 0 : 1);
+
+
+ int getIdx = 0;
+
+ JPanel p = new JPanel();
+ p.setLayout(new GridLayout(rows, columns, 10, 0));
+
+ for (int row = 0; row < rows; row++) {
+ for (int col = 0; col < columns; col++) {
+ getIdx = row + (col * rows);
+ JCheckBox box;
+ if (getIdx < numEditions) {
+ CardEdition edition = getIdx < numEditions ? editions.get(getIdx) : null;
+ box = new JCheckBox(String.format("%s (%s)", edition.getName(), edition.getCode()));
+ box.setName(edition.getCode());
+ box.setSelected(customFormat.contains(edition.getCode()));
+ choices.add(box);
+ } else {
+ box = new JCheckBox();
+ box.setEnabled(false);
+ }
+
+ p.add(box);
+ }
+ }
+ scrollPane = new JScrollPane(p);
+
+ getContentPane().add(scrollPane, BorderLayout.CENTER);
+ btnOK.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(final ActionEvent arg0) {
+ updateCustomFormat();
+ dispose();
+ }
+ });
+ buttonPanel.add(btnOK, BorderLayout.WEST);
+ getRootPane().setDefaultButton(btnOK);
+
+ btnCancel.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(final ActionEvent arg0) {
+ dispose();
+ }
+ });
+ buttonPanel.add(btnCancel, BorderLayout.EAST);
+ getContentPane().add(buttonPanel, BorderLayout.SOUTH);
+
+ this.setSize(600, 450);
+ this.setLocationRelativeTo(null);
+ this.setTitle("Choose sets");
+ this.setVisible(true);
+
+ }
+
+ /**
+ * Make some sets unselectable (currently only Alpha and Beta).
+ * Note that these sets can still be (theoretically) unlocked
+ * later, for an exorbitant price. There'd be nothing to be
+ * gained from allowing these initially (Unlimited already covers
+ * their cardbase), and a lot to be lost (namely, easy early access
+ * to extremely expensive cards...) --BBU
+ *
+ * @param setCode
+ * String, set code
+ * @return boolean, this set can be selected.
+ *
+ */
+ private boolean canChoose(final String setCode) {
+ if (setCode == null) {
+ return true;
+ }
+ return !"LEA".equals(setCode) && !"LEB".equals(setCode)
+ && !"MBP".equals(setCode) && !"VAN".equals(setCode)
+ && !"ARC".equals(setCode) && !"PC2".equals(setCode);
+ }
+
+ /**
+ * Update the custom format in accordance with the selections.
+ */
+ void updateCustomFormat() {
+ customFormat.clear();
+ for (JCheckBox box : choices) {
+ if (box.isSelected()) {
+ customFormat.add(box.getName());
+ }
+ }
+
+ if (null != onOk) {
+ onOk.run();
+ }
+ }
+}
diff --git a/src/main/java/forge/gui/toolbox/FLabel.java b/src/main/java/forge/gui/toolbox/FLabel.java
index 70720767c9d..6a752fdbf6c 100644
--- a/src/main/java/forge/gui/toolbox/FLabel.java
+++ b/src/main/java/forge/gui/toolbox/FLabel.java
@@ -51,7 +51,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
* new FLabel.Builder().method1(foo).method2(bar).method3(baz)...
*
and then call build() to make the label (don't forget that part).
*/
- public static class Builder extends FLabel {
+ public static class Builder {
//========== Default values for FLabel are set here.
private double bldIconScaleFactor = 0.8;
private int bldFontStyle = Font.PLAIN;
@@ -61,10 +61,12 @@ public class FLabel extends JLabel implements ILocalRepaint {
private Point bldIconInsets = new Point(0, 0);
private boolean bldSelectable = false;
+ private boolean bldSelected = false;
private boolean bldHoverable = false;
private boolean bldOpaque = false;
private boolean bldIconInBackground = false;
private boolean bldIconScaleAuto = true;
+ private boolean reactOnMouseDown = false;
private String bldText, bldToolTip;
private ImageIcon bldIcon;
@@ -103,6 +105,14 @@ public class FLabel extends JLabel implements ILocalRepaint {
/**@param b0 boolean
* @return {@link forge.gui.toolbox.Builder} */
public Builder selectable(final boolean b0) { this.bldSelectable = b0; return this; }
+
+ /**@param b0 boolean
+ * @return {@link forge.gui.toolbox.Builder} */
+ public Builder selected(final boolean b0) { this.bldSelected = b0; return this; }
+
+ /**@param b0 boolean that controls when the label responds to mouse events
+ * @return {@link forge.gui.toolbox.Builder} */
+ public Builder reactOnMouseDown(final boolean b0) { this.reactOnMouseDown = b0; return this; }
/**@param c0 {@link forge.Command} to execute if clicked
* @return {@link forge.gui.toolbox.Builder} */
@@ -158,6 +168,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
this.iconInBackground = b0.bldIconInBackground;
this.iconScaleAuto = b0.bldIconScaleAuto;
this.selectable = b0.bldSelectable;
+ this.selected = b0.bldSelected;
this.iconAlignX = b0.bldIconAlignX;
this.iconInsets = b0.bldIconInsets;
@@ -165,8 +176,8 @@ public class FLabel extends JLabel implements ILocalRepaint {
this.setFontSize(b0.bldFontSize);
this.setIconAlpha(b0.bldIconAlpha);
this.setCommand(b0.bldCmd);
+ this.setReactOnMouseDown(b0.reactOnMouseDown);
this.setFontAlign(b0.bldFontAlign);
- this.setText(b0.bldText);
this.setToolTipText(b0.bldToolTip);
this.setHoverable(b0.bldHoverable);
@@ -176,8 +187,6 @@ public class FLabel extends JLabel implements ILocalRepaint {
// Non-custom display properties
this.setForeground(clrText);
this.setBackground(clrInactive);
- this.setVerticalTextPosition(SwingConstants.CENTER);
- this.setVerticalAlignment(SwingConstants.CENTER);
// Resize adapter
this.removeComponentListener(cadResize);
@@ -202,7 +211,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
private int fontStyle, iconAlignX;
private int iw, ih;
private boolean selectable, selected, hoverable, hovered, opaque,
- iconInBackground, iconScaleAuto;
+ iconInBackground, iconScaleAuto, reactOnMouseDown;
private Point iconInsets;
// Various variables used in image rendering.
@@ -246,19 +255,35 @@ public class FLabel extends JLabel implements ILocalRepaint {
private final MouseAdapter madEvents = new MouseAdapter() {
@Override
public void mouseEntered(final MouseEvent e) {
- hovered = true; repaintSelf();
+ if (hoverable) {
+ hovered = true; repaintSelf();
+ }
}
@Override
public void mouseExited(final MouseEvent e) {
- hovered = false; repaintSelf();
+ if (hoverable) {
+ hovered = false; repaintSelf();
+ }
}
+
+ private void _doMouseAction() {
+ if (selectable) { setSelected(!selected); }
+ if (cmdClick != null && FLabel.this.isEnabled()) { cmdClick.execute(); }
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e) {
+ if (reactOnMouseDown) {
+ _doMouseAction();
+ }
+ }
+
@Override
public void mouseClicked(final MouseEvent e) {
- if (cmdClick != null && FLabel.this.isEnabled()) { cmdClick.execute(); }
- if (!selectable) { return; }
- if (selected) { setSelected(false); }
- else { setSelected(true); }
+ if (!reactOnMouseDown) {
+ _doMouseAction();
+ }
}
};
@@ -278,6 +303,10 @@ public class FLabel extends JLabel implements ILocalRepaint {
repaintSelf();
}
+ public boolean getSelected() {
+ return this.selected;
+ }
+
/** Sets alpha if icon is in background.
* @param f0 float */
// NOT public; must be set when label is built.
@@ -359,6 +388,10 @@ public class FLabel extends JLabel implements ILocalRepaint {
this.cmdClick = c0;
}
+ public void setReactOnMouseDown(boolean b0) {
+ this.reactOnMouseDown = b0;
+ }
+
@Override
public void setOpaque(final boolean b0) {
// Must be overridden to allow drawing order of background, icon, string
diff --git a/src/main/java/forge/gui/toolbox/FSpinner.java b/src/main/java/forge/gui/toolbox/FSpinner.java
new file mode 100644
index 00000000000..177dc439820
--- /dev/null
+++ b/src/main/java/forge/gui/toolbox/FSpinner.java
@@ -0,0 +1,49 @@
+package forge.gui.toolbox;
+
+import java.awt.Insets;
+
+import javax.swing.JFormattedTextField;
+import javax.swing.JSpinner;
+import javax.swing.SpinnerNumberModel;
+import javax.swing.text.NumberFormatter;
+
+/**
+ * A custom instance of JSpinner using Forge skin properties. Only numeric
+ * integer spinners are implemented, since that's all we've needed so far.
+ *
+ */
+@SuppressWarnings("serial")
+public class FSpinner extends JSpinner {
+ public static class Builder {
+ //========== Default values for FTextField are set here.
+ private int initialValue = 0;
+ private int minValue = 0;
+ private int maxValue = Integer.MAX_VALUE;
+ private String toolTip;
+
+ public FSpinner build() { return new FSpinner(this); }
+
+ public Builder initialValue(int i0) { initialValue = i0; return this; }
+ public Builder minValue(int i0) { minValue = i0; return this; }
+ public Builder maxValue(int i0) { maxValue = i0; return this; }
+
+ public Builder tooltip(String s0) { toolTip = s0; return this; }
+ }
+
+ private FSpinner(Builder builder) {
+ this.setOpaque(false);
+
+ this.setModel(new SpinnerNumberModel(builder.initialValue, builder.minValue, builder.maxValue, 1));
+ this.setEditor(new JSpinner.NumberEditor(this, "##"));
+ JFormattedTextField txt = ((JSpinner.NumberEditor)this.getEditor()).getTextField();
+ ((NumberFormatter)txt.getFormatter()).setAllowsInvalid(false);
+ txt.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
+ txt.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
+ txt.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT));
+ txt.setMargin(new Insets(5, 5, 5, 5));
+ txt.setOpaque(true);
+
+ this.setToolTipText(builder.toolTip);
+ this.setFocusable(true);
+ }
+}
diff --git a/src/main/java/forge/gui/toolbox/FTextField.java b/src/main/java/forge/gui/toolbox/FTextField.java
index 1228bd0d554..8d41124a37b 100644
--- a/src/main/java/forge/gui/toolbox/FTextField.java
+++ b/src/main/java/forge/gui/toolbox/FTextField.java
@@ -1,6 +1,11 @@
package forge.gui.toolbox;
+import java.awt.Insets;
+
import javax.swing.JTextField;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.PlainDocument;
/**
* A custom instance of JTextArea using Forge skin properties.
@@ -8,13 +13,64 @@ import javax.swing.JTextField;
*/
@SuppressWarnings("serial")
public class FTextField extends JTextField {
- /** */
- public FTextField() {
- super();
+ /**
+ * Uses the Builder pattern to facilitate/encourage inline styling.
+ * Credit to Effective Java 2 (Joshua Bloch).
+ * Methods in builder can be chained. To declare:
+ * new FTextField.Builder().method1(foo).method2(bar).method3(baz)...
+ *
and then call build() to make the widget (don't forget that part).
+ */
+ public static class Builder {
+ //========== Default values for FTextField are set here.
+ private int maxLength = 0; // <=0 indicates no maximum
+ private boolean readonly = false;
+ private String text;
+ private String toolTip;
+
+ public FTextField build() { return new FTextField(this); }
+
+ public Builder maxLength(int i0) { maxLength = i0; return this; }
+ public Builder readonly(boolean b0) { readonly = b0; return this; }
+
+ public Builder text(String s0) { text = s0; return this; }
+ public Builder tooltip(String s0) { toolTip = s0; return this; }
+ }
+
+ private FTextField(Builder builder) {
this.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
+ this.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
this.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT));
- this.setOpaque(false);
- this.setFocusable(false);
- this.setEditable(false);
+ this.setMargin(new Insets(5, 5, 5, 5));
+ this.setOpaque(true);
+
+ if (0 < builder.maxLength)
+ {
+ this.setDocument(new _LengthLimitedDocument(builder.maxLength));
+ }
+
+ this.setEditable(!builder.readonly);
+ this.setText(builder.text);
+ this.setToolTipText(builder.toolTip);
+ this.setFocusable(true);
+ }
+
+ private static class _LengthLimitedDocument extends PlainDocument {
+ private final int _limit;
+
+ _LengthLimitedDocument(int limit) { _limit = limit; }
+
+ // called each time a character is typed or a string is pasted
+ @Override
+ public void insertString(int offset, String s, AttributeSet attributeSet)
+ throws BadLocationException {
+ if (_limit <= this.getLength()) {
+ return;
+ }
+ int newLen = this.getLength() + s.length();
+ if (_limit < newLen) {
+ s = s.substring(0, _limit - this.getLength());
+ }
+ super.insertString(offset, s, attributeSet);
+ }
}
}
diff --git a/src/main/java/forge/quest/QuestController.java b/src/main/java/forge/quest/QuestController.java
index 3d70a7615e7..fa519e00eca 100644
--- a/src/main/java/forge/quest/QuestController.java
+++ b/src/main/java/forge/quest/QuestController.java
@@ -137,6 +137,13 @@ public class QuestController {
return (getWorldFormat() == null ? this.questFormat : getWorldFormat());
}
+ /**
+ * Gets the custom format for the main world, if any.
+ */
+ public GameFormatQuest getMainFormat() {
+ return this.questFormat;
+ }
+
/**
* Gets the current event.
*
diff --git a/src/main/java/forge/quest/QuestRewardCardChooser.java b/src/main/java/forge/quest/QuestRewardCardChooser.java
new file mode 100644
index 00000000000..48334d014b8
--- /dev/null
+++ b/src/main/java/forge/quest/QuestRewardCardChooser.java
@@ -0,0 +1,237 @@
+package forge.quest;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import forge.Singletons;
+import forge.item.CardDb;
+import forge.item.CardPrinted;
+import forge.card.CardRules;
+import forge.item.InventoryItem;
+import forge.item.ItemPool;
+
+/**
+ * Resolves a card chooser InventoryItem into a CardPrinted.
+ * The initial version includes "duplicate", other type may be added later.
+ *
+ */
+public class QuestRewardCardChooser implements InventoryItem {
+
+ /**
+ * Possible types for this object.
+ */
+ public enum poolType {
+ /** The player's own cardpool (duplicate card). */
+ playerCards,
+ /** Filtered by a predicate that will be parsed. */
+ predicateFilter
+ }
+
+ private poolType type;
+ private final String description;
+ private final Predicate predicates;
+
+ /**
+ * The constructor.
+ * The parameter indicates the more specific type.
+ * @param setType String, the type of the choosable card.
+ * @param creationParameters String, used to build the predicates and description for the predicateFilter type
+ */
+ public QuestRewardCardChooser(final poolType setType, final String[] creationParameters) {
+ type = setType;
+ if (type == poolType.playerCards) {
+ description = "a duplicate card";
+ predicates = null;
+ } else {
+ description = buildDescription(creationParameters);
+ predicates = buildPredicates(creationParameters);
+ }
+ }
+
+ private String buildDescription(final String [] input) {
+ final String defaultDescription = "a card";
+ if (input == null || input.length < 1) {
+ return defaultDescription;
+ }
+
+ String buildDesc = null;
+
+ for (String s : input) {
+ if (s.startsWith("desc:") || s.startsWith("Desc:")) {
+ String[] tmp = s.split(":");
+ if (tmp.length > 1) {
+ buildDesc = new String(tmp[1]);
+ } else {
+ buildDesc = new String();
+ }
+ } else if (buildDesc != null) {
+ if (s.contains(":")) {
+ return buildDesc;
+ } else {
+ buildDesc = buildDesc + " " + s;
+ }
+ }
+ }
+
+ if (buildDesc != null) {
+ return buildDesc;
+ }
+ return defaultDescription;
+ }
+
+
+ private Predicate buildPredicates(final String [] input) {
+ if (input == null || input.length < 1) {
+ return null;
+ }
+
+ Predicate filters = Singletons.getModel().getQuest().getFormat().getFilterPrinted();
+ Predicate filterRules = null;
+ Predicate filterRarity = null;
+
+ for (String s : input) {
+ if (s.startsWith("sets:") || s.startsWith("Sets:")) {
+ final String[] tmp = s.split(":");
+ if (tmp.length > 1) {
+ String [] setcodes = tmp[1].split(",");
+ if (setcodes.length > 0) {
+ List sets = new ArrayList();
+ for (String code : setcodes) {
+ if (Singletons.getModel().getEditions().contains(code)) {
+ // System.out.println("Set " + code + " was found!");
+ sets.add(code);
+ }
+ // else { System.out.println("Unknown set code " + code); }
+ }
+ if (sets.size() > 0) {
+ filters = CardPrinted.Predicates.printedInSets(sets, true);
+ }
+ }
+ }
+ } else if (s.startsWith("rules:") || s.startsWith("Rules:")) {
+ final String[] tmp = s.split(":");
+ if (tmp.length > 1) {
+ String [] ruleCodes = tmp[1].split(",");
+ if (ruleCodes.length > 0) {
+ for (String rule : ruleCodes) {
+ final Predicate newRule = BoosterUtils.parseRulesLimitation(rule);
+ if (newRule != null) {
+ filterRules = (filterRules == null ? newRule : Predicates.and(filterRules, newRule));
+ }
+ }
+ }
+ }
+ } else if (s.startsWith("rarity:") || s.startsWith("Rarity:")) {
+ final String[] tmp = s.split(":");
+ if (tmp.length > 1) {
+ String [] rarityCodes = tmp[1].split(",");
+ if (rarityCodes.length > 0) {
+ for (String rarity : rarityCodes) {
+ if (rarity.startsWith("C") || rarity.startsWith("c")) {
+ filterRarity = (filterRarity == null ? CardPrinted.Predicates.Presets.IS_COMMON : Predicates.or(filterRarity, CardPrinted.Predicates.Presets.IS_COMMON));
+ } else if (rarity.startsWith("U") || rarity.startsWith("u")) {
+ filterRarity = (filterRarity == null ? CardPrinted.Predicates.Presets.IS_UNCOMMON : Predicates.or(filterRarity, CardPrinted.Predicates.Presets.IS_UNCOMMON));
+ } else if (rarity.startsWith("R") || rarity.startsWith("r")) {
+ filterRarity = (filterRarity == null ? CardPrinted.Predicates.Presets.IS_RARE : Predicates.or(filterRarity, CardPrinted.Predicates.Presets.IS_RARE));
+ } else if (rarity.startsWith("M") || rarity.startsWith("m")) {
+ filterRarity = (filterRarity == null ? CardPrinted.Predicates.Presets.IS_MYTHIC_RARE : Predicates.or(filterRarity, CardPrinted.Predicates.Presets.IS_MYTHIC_RARE));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (filterRules != null) {
+ final Predicate rulesPrinted = Predicates.compose(filterRules, CardPrinted.FN_GET_RULES);
+ filters = Predicates.and(filters, rulesPrinted);
+ }
+ if (filterRarity != null) {
+ filters = Predicates.and(filters, filterRarity);
+ }
+ return filters;
+ }
+
+ /**
+ * The name.
+ *
+ * @return the name
+ */
+ @Override
+ public String getName() {
+ return description;
+ }
+
+ /**
+ * A QuestRewardCardChooser ought to always be resolved to an actual card, hence no images.
+ *
+ * @return an empty string
+ */
+ @Override
+ public String getImageFilename() {
+ return "";
+ }
+
+ /**
+ * The item type.
+ *
+ * @return item type
+ */
+ @Override
+ public String getItemType() {
+ switch (type) {
+ case playerCards:
+ return "duplicate card";
+ case predicateFilter: default:
+ return "chosen card";
+ }
+ }
+
+ /**
+ * Get type as enum.
+ * @return enum, item type.
+ */
+ public poolType getType() {
+ return type;
+ }
+
+ /**
+ * Produces a list of options to choose from.
+ *
+ * @return a List or null if could not create a list.
+ */
+ public final List getChoices() {
+ if (type == poolType.playerCards) {
+ final ItemPool playerCards = Singletons.getModel().getQuest().getAssets().getCardPool();
+ if (!playerCards.isEmpty()) { // Maybe a redundant check since it's hard to win a duel without any cards...
+
+ List cardChoices = new ArrayList();
+ for (final Map.Entry card : playerCards) {
+ cardChoices.add(card.getKey());
+ }
+ Collections.sort(cardChoices);
+
+ return Collections.unmodifiableList(cardChoices);
+ }
+
+ } else if (type == poolType.predicateFilter) {
+ List cardChoices = new ArrayList();
+
+ for (final CardPrinted card : Iterables.filter(CardDb.instance().getAllTraditionalCards(), predicates)) {
+ cardChoices.add(card);
+ }
+ Collections.sort(cardChoices);
+
+ return Collections.unmodifiableList(cardChoices);
+ } else {
+ throw new RuntimeException("Unknown QuestRewardCardType: " + type);
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/forge/quest/QuestUtilCards.java b/src/main/java/forge/quest/QuestUtilCards.java
index 4681b3f1789..f75ff7ba079 100644
--- a/src/main/java/forge/quest/QuestUtilCards.java
+++ b/src/main/java/forge/quest/QuestUtilCards.java
@@ -576,20 +576,10 @@ public final class QuestUtilCards {
this.qa.getNewCardList().clear();
}
- /**
- * Gets the fn new compare.
- *
- * @return the fnNewCompare
- */
public Function, Comparable>> getFnNewCompare() {
return this.fnNewCompare;
}
- /**
- * Gets the fn new get.
- *
- * @return the fnNewGet
- */
public Function, Object> getFnNewGet() {
return this.fnNewGet;
}
@@ -600,7 +590,8 @@ public final class QuestUtilCards {
// deck editors
// Maybe we should consider doing so later
/** The fn new compare. */
- private final Function, Comparable>> fnNewCompare = new Function, Comparable>>() {
+ private final Function, Comparable>> fnNewCompare =
+ new Function, Comparable>>() {
@Override
public Comparable> apply(final Entry from) {
return QuestUtilCards.this.qa.getNewCardList().contains(from.getKey()) ? Integer.valueOf(1) : Integer
@@ -609,10 +600,38 @@ public final class QuestUtilCards {
};
/** The fn new get. */
- private final Function, Object> fnNewGet = new Function, Object>() {
+ private final Function, Object> fnNewGet =
+ new Function, Object>() {
@Override
public Object apply(final Entry from) {
return QuestUtilCards.this.qa.getNewCardList().contains(from.getKey()) ? "NEW" : "";
}
};
+
+ public Function, Comparable>> getFnOwnedCompare() {
+ return this.fnOwnedCompare;
+ }
+
+ public Function, Object> getFnOwnedGet() {
+ return this.fnOwnedGet;
+ }
+
+ // These functions provide a way to sort and compare cards in the spell shop according to how many are already owned
+ private final Function, Comparable>> fnOwnedCompare =
+ new Function, Comparable>>() {
+ @Override
+ public Comparable> apply(final Entry from) {
+ InventoryItem i = from.getKey();
+ return i instanceof CardPrinted ? QuestUtilCards.this.qa.getCardPool().count((CardPrinted)i) : null;
+ }
+ };
+
+ private final Function, Object> fnOwnedGet =
+ new Function, Object>() {
+ @Override
+ public Object apply(final Entry from) {
+ InventoryItem i = from.getKey();
+ return i instanceof CardPrinted ? QuestUtilCards.this.qa.getCardPool().count((CardPrinted)i) : null;
+ }
+ };
}
diff --git a/src/main/java/forge/util/Pair.java b/src/main/java/forge/util/Pair.java
new file mode 100644
index 00000000000..a2a69e6334c
--- /dev/null
+++ b/src/main/java/forge/util/Pair.java
@@ -0,0 +1,11 @@
+package forge.util;
+
+public class Pair {
+ public final T a;
+ public final V b;
+
+ public Pair(T a, V b) {
+ this.a = a;
+ this.b = b;
+ }
+}
diff --git a/src/main/java/forge/util/TextUtil.java b/src/main/java/forge/util/TextUtil.java
index f734453e717..99795041f94 100644
--- a/src/main/java/forge/util/TextUtil.java
+++ b/src/main/java/forge/util/TextUtil.java
@@ -2,6 +2,7 @@ package forge.util;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
@@ -77,5 +78,13 @@ public class TextUtil {
return result.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
}
-
+
+ /**
+ * Converts an enum value to a printable label but upcasing the first letter
+ * and lcasing all subsequent letters
+ */
+ public static String enumToLabel(Enum> val) {
+ return val.toString().substring(0, 1).toUpperCase(Locale.ENGLISH) +
+ val.toString().substring(1).toLowerCase(Locale.ENGLISH);
+ }
}
diff --git a/src/main/java/forge/view/FView.java b/src/main/java/forge/view/FView.java
index 68147a21fdd..d4c7d5d16fc 100644
--- a/src/main/java/forge/view/FView.java
+++ b/src/main/java/forge/view/FView.java
@@ -35,8 +35,6 @@ public enum FView {
/** */
SINGLETON_INSTANCE;
- /** */
- public static final Integer TARGETING_LAYER = JLayeredPane.MODAL_LAYER - 1;
private final List allCells = new ArrayList();
private SplashFrame frmSplash;
@@ -84,8 +82,7 @@ public enum FView {
// Note: when adding new panels here, keep in mind that the layered pane
// has a null layout, so new components will be W0 x H0 pixels - gotcha!
// FControl has a method called "sizeComponents" which will fix this.
- lpnDocument.add(TargetingOverlay.SINGLETON_INSTANCE.getPanel(), TARGETING_LAYER);
-
+ lpnDocument.add(TargetingOverlay.SINGLETON_INSTANCE.getPanel(), JLayeredPane.MODAL_LAYER);
pnlInsets.add(pnlContent, BorderLayout.CENTER);
pnlInsets.setBackgroundTexture(FSkin.getIcon(FSkin.Backgrounds.BG_TEXTURE));
pnlInsets.setCornerDiameter(0);