mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
- fixed resize cursor not appearing when hovering between columns in table headers
- added forge-specific spinner widget (FSpinner) - allowed labels to have their toggle state read externally and added configuration to set whether the onClick command is executed on mouse button down or mouse button up (FLabel) - added builder pattern to FTextField and autoset properties to common values - fixed header comments in WrapLayout - renamed DialogCustomFormat to the more generic DialogChooseSets since I use it now from the filters too; extended its functionality to run a specified command on ok button click - removed Filters dockable panel - added old filters functionality to the stats buttons above the catalog table (stats can no longer be removed via a preference setting) - combined scattered metadata about the filters (e.g. icon, label, filter predicate) into a single enum - rewrote filter utility functions to not have any side effects (they now use no global data/singletons) - added "Owned" column to spell shop catalog, indicating number of cards already owned by player (can remove column with preference) - don't count the "click" as a sort command when resizing a column - exposed top-level main world custom format in QuestController -- other format-retrieving methods would be masked by the current world selection - added utility fn to TextUtils to create a (locale-independent) Title out of an ENUM - added a templated Pair<T, V> utility class for ad-hoc two-value parameter returning - prevented invalid enum values in editor_preferred.xml from causing errors
This commit is contained in:
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -13984,7 +13984,6 @@ src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java -text
|
||||
src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java svneol=native#text/plain
|
||||
src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java -text
|
||||
src/main/java/forge/gui/deckeditor/controllers/CEditorVariant.java -text
|
||||
src/main/java/forge/gui/deckeditor/controllers/CFilters.java -text
|
||||
src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java -text
|
||||
src/main/java/forge/gui/deckeditor/controllers/CStatistics.java -text
|
||||
src/main/java/forge/gui/deckeditor/package-info.java -text
|
||||
@@ -14004,7 +14003,6 @@ src/main/java/forge/gui/deckeditor/views/VCardCatalog.java -text
|
||||
src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java -text
|
||||
src/main/java/forge/gui/deckeditor/views/VDeckgen.java -text
|
||||
src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java -text
|
||||
src/main/java/forge/gui/deckeditor/views/VFilters.java -text
|
||||
src/main/java/forge/gui/deckeditor/views/VProbabilities.java -text
|
||||
src/main/java/forge/gui/deckeditor/views/VStatistics.java -text
|
||||
src/main/java/forge/gui/download/GuiDownloadPicturesLQ.java svneol=native#text/plain
|
||||
@@ -14055,7 +14053,6 @@ src/main/java/forge/gui/home/quest/CSubmenuDuels.java -text
|
||||
src/main/java/forge/gui/home/quest/CSubmenuQuestData.java -text
|
||||
src/main/java/forge/gui/home/quest/CSubmenuQuestDecks.java -text
|
||||
src/main/java/forge/gui/home/quest/CSubmenuQuestPrefs.java -text
|
||||
src/main/java/forge/gui/home/quest/DialogCustomFormat.java -text
|
||||
src/main/java/forge/gui/home/quest/IVQuestStats.java -text
|
||||
src/main/java/forge/gui/home/quest/PnlEvent.java -text
|
||||
src/main/java/forge/gui/home/quest/QuestFileLister.java -text
|
||||
|
||||
4
.settings/org.eclipse.m2e.core.prefs
Normal file
4
.settings/org.eclipse.m2e.core.prefs
Normal file
@@ -0,0 +1,4 @@
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
||||
@@ -3,7 +3,6 @@
|
||||
<cell x="0.77443" y="0.37698" w="0.22557" h="0.62302">
|
||||
<doc>CARD_PICTURE</doc>
|
||||
<doc>EDITOR_PREFERENCES</doc>
|
||||
<doc>EDITOR_FILTERS</doc>
|
||||
</cell>
|
||||
<cell x="0.38722" y="0.0" w="0.38722" h="1.0">
|
||||
<doc>EDITOR_CURRENTDECK</doc>
|
||||
@@ -18,4 +17,4 @@
|
||||
<cell x="0.0" y="0.0" w="0.38722" h="1.0">
|
||||
<doc>EDITOR_CATALOG</doc>
|
||||
</cell>
|
||||
</layout>
|
||||
</layout>
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
<preferences type="editor">
|
||||
<pref name="display_unique_only" value="true"></pref>
|
||||
<pref name="elastic_columns" value="false"></pref>
|
||||
<pref name="stats_catalog" value="true"></pref>
|
||||
<pref name="stats_deck" value="true"></pref>
|
||||
<col enumval="CAT_QUANTITY" identifier="Quantity" show="true" sortpriority="3" sortstate="ASC" width="30"></col>
|
||||
<col enumval="CAT_NAME" identifier="Name" show="true" sortpriority="0" sortstate="NONE" width="262"></col>
|
||||
<col enumval="CAT_COST" identifier="Cost" show="true" sortpriority="2" sortstate="DESC" width="82"></col>
|
||||
<col enumval="CAT_COLOR" identifier="Color" show="true" sortpriority="3" sortstate="DESC" width="54"></col>
|
||||
<col enumval="CAT_TYPE" identifier="Type" show="true" sortpriority="1" sortstate="ASC" width="217"></col>
|
||||
<col enumval="CAT_COLOR" identifier="Color" show="true" sortpriority="4" sortstate="DESC" width="54"></col>
|
||||
<col enumval="CAT_TYPE" identifier="Type" show="true" sortpriority="3" sortstate="ASC" width="217"></col>
|
||||
<col enumval="CAT_POWER" identifier="Power" show="true" sortpriority="0" sortstate="NONE" width="30"></col>
|
||||
<col enumval="CAT_TOUGHNESS" identifier="Toughness" show="true" sortpriority="0" sortstate="NONE" width="30"></col>
|
||||
<col enumval="CAT_CMC" identifier="CMC" show="true" sortpriority="0" sortstate="NONE" width="30"></col>
|
||||
@@ -17,6 +16,7 @@
|
||||
<col enumval="CAT_AI" identifier="AI" show="false" sortpriority="0" sortstate="NONE" width="30"></col>
|
||||
<col enumval="CAT_NEW" identifier="New" show="true" sortpriority="1" sortstate="ASC" width="34"></col>
|
||||
<col enumval="CAT_PURCHASE_PRICE" identifier="Purchase Price" show="true" sortpriority="2" sortstate="ASC" width="40"></col>
|
||||
<col enumval="CAT_OWNED" identifier="Owned" show="true" sortpriority="1" sortstate="ASC" width="75"></col>
|
||||
<col enumval="DECK_QUANTITY" identifier="Quantity" show="true" sortpriority="0" sortstate="NONE" width="30"></col>
|
||||
<col enumval="DECK_NAME" identifier="Name" show="true" sortpriority="3" sortstate="ASC" width="262"></col>
|
||||
<col enumval="DECK_COST" identifier="Cost" show="true" sortpriority="1" sortstate="ASC" width="82"></col>
|
||||
|
||||
@@ -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} */
|
||||
|
||||
@@ -39,8 +39,8 @@ public class WrapLayout extends FlowLayout {
|
||||
* and the indicated horizontal and vertical gaps.
|
||||
* <p>
|
||||
* The value of the alignment argument must be one of
|
||||
* <code>WrapLayout</code>, <code>WrapLayout</code>,
|
||||
* or <code>WrapLayout</code>.
|
||||
* <code>FlowLayout.LEFT</code>, <code>FlowLayout.CENTER</code>,
|
||||
* or <code>FlowLayout.RIGHT</code>.
|
||||
* @param align the alignment value
|
||||
* @param hgap the horizontal gap between components
|
||||
* @param vgap the vertical gap between components
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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<CardRules> predicate;
|
||||
|
||||
StatTypes(FSkin.SkinProp prop, Predicate<CardRules> 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 <T extends InventoryItem> void setLabelTextSum(JLabel label, final ItemPoolView<T> deck, Predicate<CardRules> 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 <T extends InventoryItem> void setStats(final ItemPoolView<T> 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(); } });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
* <br><br>
|
||||
* <i>(S at beginning of class name denotes a static factory.)</i>
|
||||
*/
|
||||
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<FilterProperty, ChbPnl> MAP_COLOR_CHECKBOXES =
|
||||
new HashMap<FilterProperty, ChbPnl>();
|
||||
|
||||
private static final Map<FilterProperty, ChbPnl> MAP_TYPE_CHECKBOXES =
|
||||
new HashMap<FilterProperty, ChbPnl>();
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
private static boolean preventFiltering = false;
|
||||
|
||||
* <i>(S at beginning of class name denotes a static factory.)</i>
|
||||
*/
|
||||
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.
|
||||
* <br><br>
|
||||
* Handles "multicolor" label, which is quite tricky.
|
||||
*
|
||||
* @return Predicate<CardPrinted>
|
||||
*/
|
||||
public static Predicate<CardPrinted> buildColorFilter() {
|
||||
if (MAP_COLOR_CHECKBOXES.isEmpty()) { return Predicates.alwaysTrue(); }
|
||||
|
||||
final List<Predicate<CardRules>> colors = new ArrayList<Predicate<CardRules>>();
|
||||
|
||||
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<CardRules> preColors = colors.size() == 6 ? null : Predicates.or(colors);
|
||||
|
||||
boolean wantMulticolor = MAP_COLOR_CHECKBOXES.get(FilterProperty.MULTICOLOR).getCheckBox().isSelected();
|
||||
final Predicate<CardRules> preExceptMulti = wantMulticolor ? null : Predicates.not(CardRulesPredicates.Presets.IS_MULTICOLOR);
|
||||
|
||||
Predicate<CardRules> preFinal = colors.isEmpty() && wantMulticolor ? CardRulesPredicates.Presets.IS_MULTICOLOR : optimizedAnd(preExceptMulti, preColors);
|
||||
public static Predicate<CardPrinted> buildColorAndTypeFilter(Map<SEditorUtil.StatTypes, FLabel> statLabels) {
|
||||
final List<Predicate<CardRules>> colors = new ArrayList<Predicate<CardRules>>();
|
||||
final List<Predicate<CardRules>> types = new ArrayList<Predicate<CardRules>>();
|
||||
|
||||
boolean wantMulticolor = false;
|
||||
Predicate<CardRules> 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<CardRules> preColors = colors.size() == 6 ? null : Predicates.or(colors);
|
||||
Predicate<CardRules> preFinal = colors.isEmpty() && wantMulticolor ?
|
||||
CardRulesPredicates.Presets.IS_MULTICOLOR : optimizedAnd(preExceptMulti, preColors);
|
||||
|
||||
if (null == preFinal && 7 == types.size()) {
|
||||
return Predicates.alwaysTrue();
|
||||
}
|
||||
|
||||
Predicate<CardPrinted> typesFinal = Predicates.compose(Predicates.or(types), CardPrinted.FN_GET_RULES);
|
||||
if (null == preFinal) {
|
||||
return typesFinal;
|
||||
}
|
||||
|
||||
Predicate<CardPrinted> 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<CardPrinted> 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<CardPrinted>
|
||||
*/
|
||||
public static Predicate<CardPrinted> buildSetAndFormatFilter() {
|
||||
// Set/Format filter
|
||||
JComboBox cbox = VFilters.SINGLETON_INSTANCE.getCbxSets();
|
||||
if (cbox.getSelectedIndex() == 0) {
|
||||
return Predicates.alwaysTrue();
|
||||
}
|
||||
|
||||
final Object selected = cbox.getSelectedItem();
|
||||
final Predicate<CardPrinted> 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<CardPrinted>
|
||||
*/
|
||||
public static Predicate<CardPrinted> buildTypeFilter() {
|
||||
if (MAP_TYPE_CHECKBOXES.isEmpty()) { return Predicates.alwaysTrue(); }
|
||||
|
||||
final List<Predicate<CardRules>> ors = new ArrayList<Predicate<CardRules>>();
|
||||
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<CardPrinted>
|
||||
*/
|
||||
public static Predicate<CardPrinted> buildTextFilter() {
|
||||
Predicate<CardRules> filterAnd = null;
|
||||
Predicate<CardRules> 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<Predicate<CardRules>> ands = new ArrayList<Predicate<CardRules>>();
|
||||
List<Predicate<CardRules>> terms = new ArrayList<Predicate<CardRules>>();
|
||||
for (String s : splitText) {
|
||||
List<Predicate<CardRules>> subands = new ArrayList<Predicate<CardRules>>();
|
||||
|
||||
for (final String s : splitContains) {
|
||||
final List<Predicate<CardRules>> subands = new ArrayList<Predicate<CardRules>>();
|
||||
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<Predicate<CardRules>> nots = new ArrayList<Predicate<CardRules>>();
|
||||
|
||||
for (final String s : splitWithout) {
|
||||
final List<Predicate<CardRules>> subnots = new ArrayList<Predicate<CardRules>>();
|
||||
|
||||
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<CardRules> preResult = optimizedAnd(filterAnd, filterNot);
|
||||
if (preResult == null) {
|
||||
return Predicates.alwaysTrue();
|
||||
}
|
||||
return Predicates.compose(preResult, CardPrinted.FN_GET_RULES);
|
||||
Predicate<CardRules> textFilter = invert ? Predicates.not(Predicates.or(terms)) : Predicates.and(terms);
|
||||
|
||||
return Predicates.compose(textFilter, CardPrinted.FN_GET_RULES);
|
||||
}
|
||||
|
||||
private static Predicate<CardRules> getCardRulesFieldPredicate(String min, String max, CardRulesPredicates.LeafNumber.CardField field) {
|
||||
boolean hasMin = !("*".equals(min));
|
||||
boolean hasMax = !("10+".equals(max));
|
||||
private static Predicate<CardRules> getCardRulesFieldPredicate(int min, int max, CardRulesPredicates.LeafNumber.CardField field) {
|
||||
boolean hasMin = 0 != min;
|
||||
boolean hasMax = 10 != max;
|
||||
|
||||
Predicate<CardRules> pMin = !hasMin ? null : new CardRulesPredicates.LeafNumber(field, ComparableOp.GT_OR_EQUAL, Integer.valueOf(min));
|
||||
Predicate<CardRules> pMax = !hasMax ? null : new CardRulesPredicates.LeafNumber(field, ComparableOp.LT_OR_EQUAL, Integer.valueOf(max));
|
||||
Predicate<CardRules> pMin = !hasMin ? null : new CardRulesPredicates.LeafNumber(field, ComparableOp.GT_OR_EQUAL, min);
|
||||
Predicate<CardRules> 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<CardPrinted>
|
||||
* builds a filter for an interval on a card field
|
||||
*/
|
||||
public static Predicate<CardPrinted> buildIntervalFilter() {
|
||||
final VFilters view = VFilters.SINGLETON_INSTANCE;
|
||||
public static Predicate<CardPrinted> buildIntervalFilter(
|
||||
Map<RangeTypes, Pair<FSpinner, FSpinner>> spinners, VCardCatalog.RangeTypes field) {
|
||||
Pair<FSpinner, FSpinner> sPair = spinners.get(field);
|
||||
Predicate<CardRules> 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<CardRules> preToughness = getCardRulesFieldPredicate(view.getCbxTLow().getSelectedItem().toString(), view.getCbxTHigh().getSelectedItem().toString(), CardRulesPredicates.LeafNumber.CardField.TOUGHNESS);
|
||||
Predicate<CardRules> prePower = getCardRulesFieldPredicate(view.getCbxPLow().getSelectedItem().toString(), view.getCbxPHigh().getSelectedItem().toString(), CardRulesPredicates.LeafNumber.CardField.POWER);
|
||||
Predicate<CardRules> 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<CardRules> preCreature = optimizedAnd(preToughness, prePower);
|
||||
preCreature = preCreature == null ? null : Predicates.and(preCreature, CardRulesPredicates.Presets.IS_CREATURE);
|
||||
|
||||
Predicate<CardRules> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Predicate<CardPrinted>> activePredicates = new HashSet<Predicate<CardPrinted>>();
|
||||
private final Set<GameFormat> activeFormats = new HashSet<GameFormat>();
|
||||
private final Set<QuestWorld> activeWorlds = new HashSet<QuestWorld>();
|
||||
private final Set<RangeTypes> 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<String> setCodes = new ArrayList<String>();
|
||||
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<FSpinner, FSpinner> 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<Predicate<? super CardPrinted>> cardPredicates = new ArrayList<Predicate<? super CardPrinted>>();
|
||||
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<Predicate<? super CardPrinted>> itemPredicates = new ArrayList<Predicate<? super CardPrinted>>();
|
||||
itemPredicates.add(cardFilter);
|
||||
itemPredicates.add(ItemPredicate.Presets.IS_PACK);
|
||||
itemPredicates.add(ItemPredicate.Presets.IS_DECK);
|
||||
Predicate<CardPrinted> filter = Predicates.or(itemPredicates);
|
||||
|
||||
// Apply to table
|
||||
// TODO: is there really no way to make this type safe?
|
||||
((ACEditorBase<CardPrinted, DeckBase>)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 <T> boolean isActive(Set<T> 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 <T> void addRestriction(Pair<JComponent, Predicate<CardPrinted>> restriction, final Set<T> activeSet, final T key) {
|
||||
final Predicate<CardPrinted> 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<JComponent, Predicate<CardPrinted>> buildRangeRestriction(RangeTypes t) {
|
||||
Pair<FSpinner, FSpinner> s = VCardCatalog.SINGLETON_INSTANCE.getSpinners().get(t);
|
||||
s.a.setValue(0);
|
||||
s.b.setValue(10);
|
||||
|
||||
return new Pair<JComponent, Predicate<CardPrinted>>(
|
||||
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<JComponent, Predicate<CardPrinted>> 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<JComponent, Predicate<CardPrinted>>(
|
||||
VCardCatalog.SINGLETON_INSTANCE.buildPlainRestrictionWidget(shortText, fullText),
|
||||
SFilterUtil.buildTextFilter(text, isInverse, wantName, wantType, wantText));
|
||||
}
|
||||
|
||||
private Pair<JComponent, Predicate<CardPrinted>> buildFormatRestriction(String displayName, GameFormat format) {
|
||||
EditionCollection editions = Singletons.getModel().getEditions();
|
||||
StringBuilder tooltip = new StringBuilder("<html>Sets:");
|
||||
|
||||
int lastLen = 0;
|
||||
int lineLen = 0;
|
||||
|
||||
// use HTML tooltips so we can insert line breaks
|
||||
List<String> 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("<br>");
|
||||
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("<br><br>Allowing identical cards from other sets");
|
||||
}
|
||||
|
||||
List<String> bannedCards = null == format ? null : format.getBannedCardNames();
|
||||
if (null != bannedCards && !bannedCards.isEmpty()) {
|
||||
tooltip.append("<br><br>Banned:");
|
||||
lastLen += lineLen;
|
||||
lineLen = 0;
|
||||
|
||||
for (String cardName : bannedCards) {
|
||||
// don't let a single line get too long
|
||||
if (50 < lineLen) {
|
||||
tooltip.append("<br>");
|
||||
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("</html>");
|
||||
|
||||
return new Pair<JComponent, Predicate<CardPrinted>>(
|
||||
VCardCatalog.SINGLETON_INSTANCE.buildPlainRestrictionWidget(displayName, tooltip.toString()),
|
||||
format.getFilterRules());
|
||||
}
|
||||
|
||||
private Pair<JComponent, Predicate<CardPrinted>> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<CardPrinted, DeckGroup>
|
||||
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<CardPrinted, DeckGroup>
|
||||
}
|
||||
}
|
||||
|
||||
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<CardPrinted, DeckGroup>
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -117,15 +117,14 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
|
||||
final List<TableColumnInfo<InventoryItem>> columnsCatalog = SColumnUtil.getCatalogDefaultColumns();
|
||||
final List<TableColumnInfo<InventoryItem>> 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<InventoryItem, Deck
|
||||
columnsDeck.get(columnsDeck.size() - 1).setSortAndDisplayFunctions(
|
||||
this.fnDeckCompare, this.fnDeckGet);
|
||||
|
||||
// don't need AI column for eaither table
|
||||
// don't need AI column for either table
|
||||
columnsCatalog.remove(SColumnUtil.getColumn(ColumnName.CAT_AI));
|
||||
columnsDeck.remove(SColumnUtil.getColumn(ColumnName.DECK_AI));
|
||||
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
package forge.gui.deckeditor.controllers;
|
||||
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
import forge.Command;
|
||||
import forge.deck.DeckBase;
|
||||
import forge.gui.deckeditor.CDeckEditorUI;
|
||||
import forge.gui.deckeditor.SFilterUtil;
|
||||
import forge.gui.deckeditor.views.VFilters;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.gui.toolbox.FLabel;
|
||||
import forge.item.CardPrinted;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.item.ItemPredicate;
|
||||
|
||||
/**
|
||||
* Controls the "filters" panel in the deck editor UI.
|
||||
*
|
||||
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
|
||||
*
|
||||
*/
|
||||
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 <TItem extends InventoryItem, TModel extends DeckBase> 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 <TItem>   extends InventoryItem
|
||||
* @param <TModel>   extends DeckBase
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <TItem extends InventoryItem, TModel extends DeckBase> void buildFilter() {
|
||||
// The main trick here is to apply a CardPrinted predicate
|
||||
// to the table. CardRules will lead to difficulties.
|
||||
|
||||
final ACEditorBase<TItem, TModel> ed = (ACEditorBase<TItem, TModel>)
|
||||
CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController();
|
||||
|
||||
Predicate<? super CardPrinted> classFilter = Predicates.instanceOf(CardPrinted.class);
|
||||
Predicate<CardPrinted> color = SFilterUtil.buildColorFilter();
|
||||
Predicate<CardPrinted> type = SFilterUtil.buildTypeFilter();
|
||||
Predicate<CardPrinted> set = SFilterUtil.buildSetAndFormatFilter();
|
||||
Predicate<CardPrinted> text = SFilterUtil.buildTextFilter();
|
||||
Predicate<CardPrinted> 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<TItem>) itemFilter);
|
||||
}
|
||||
}
|
||||
@@ -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<T extends InventoryItem> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ public final class SColumnUtil {
|
||||
CAT_AI, /** */
|
||||
CAT_NEW, /** */
|
||||
CAT_PURCHASE_PRICE, /** */
|
||||
CAT_OWNED, /** */
|
||||
DECK_QUANTITY, /** */
|
||||
DECK_NAME, /** */
|
||||
DECK_COST, /** */
|
||||
|
||||
@@ -46,8 +46,6 @@ public class TableColumnInfo<T> extends TableColumn {
|
||||
/** */
|
||||
public TableColumnInfo() {
|
||||
super();
|
||||
setResizable(true);
|
||||
setMinWidth(30);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<CCardCatalog>, 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<SEditorUtil.StatTypes, FLabel> statLabels =
|
||||
new HashMap<SEditorUtil.StatTypes, FLabel>();
|
||||
|
||||
// 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<RangeTypes, Pair<FSpinner, FSpinner>> spinners = new HashMap<RangeTypes, Pair<FSpinner, FSpinner>>();
|
||||
|
||||
// card table
|
||||
private JTable tblCards = null;
|
||||
private final JScrollPane scroller = new JScrollPane();
|
||||
|
||||
|
||||
//========== Constructor
|
||||
/** */
|
||||
private VCardCatalog() {
|
||||
@@ -82,238 +116,172 @@ public enum VCardCatalog implements IVDoc<CCardCatalog>, 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<FSpinner, FSpinner>(
|
||||
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<SEditorUtil.StatTypes, FLabel> getStatLabels() {
|
||||
return statLabels;
|
||||
}
|
||||
|
||||
/** @return {@link javax.swing.JLabel} */
|
||||
public JLabel getBtnAdd() {
|
||||
return btnAdd;
|
||||
public Map<RangeTypes, Pair<FSpinner, FSpinner>> 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<FSpinner, FSpinner> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<CCurrentDeck>, 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<CCurrentDeck>, 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<SEditorUtil.StatTypes, FLabel> statLabels =
|
||||
new HashMap<SEditorUtil.StatTypes, FLabel>();
|
||||
|
||||
private JTable tblCards = null;
|
||||
private final JScrollPane scroller = new JScrollPane(tblCards);
|
||||
@@ -132,16 +119,6 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck>, 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<CCurrentDeck>, 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<CCurrentDeck>, 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<CCurrentDeck>, 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public enum VEditorPreferences implements IVDoc<CEditorPreferences> {
|
||||
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<CEditorPreferences> {
|
||||
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<CEditorPreferences> {
|
||||
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<CEditorPreferences> {
|
||||
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<CEditorPreferences> {
|
||||
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<CEditorPreferences> {
|
||||
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<CEditorPreferences> {
|
||||
return chbElasticColumns;
|
||||
}
|
||||
|
||||
/** @return {@link javax.swing.JCheckBox} */
|
||||
public JCheckBox getChbCatalogStats() {
|
||||
return chbCatalogStats;
|
||||
}
|
||||
|
||||
/** @return {@link javax.swing.JCheckBox} */
|
||||
public JCheckBox getChbCardDisplayUnique() {
|
||||
return chbCardDisplayUnique;
|
||||
}
|
||||
//========== Other methods
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
|
||||
*/
|
||||
public enum VFilters implements IVDoc<CFilters> {
|
||||
/** */
|
||||
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
|
||||
|
||||
}
|
||||
@@ -43,22 +43,22 @@ public enum VStatistics implements IVDoc<CStatistics> {
|
||||
|
||||
// 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<CStatistics> {
|
||||
|
||||
//========== 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<CStatistics> {
|
||||
|
||||
return lbl;
|
||||
}
|
||||
|
||||
private JLabel buildLabel(SEditorUtil.StatTypes statType, boolean zebra) {
|
||||
return buildLabel(statType.img, zebra);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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), /** */
|
||||
|
||||
@@ -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 */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<CSubmenuGauntletBuild> {
|
||||
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<CSubmenuGauntletBuild> {
|
||||
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();
|
||||
|
||||
@@ -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);
|
||||
} });
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> customFormat;
|
||||
private final List<JCheckBox> choices = new ArrayList<JCheckBox>();
|
||||
|
||||
|
||||
/**
|
||||
* Create the dialog.
|
||||
*
|
||||
* @param userFormat
|
||||
* GameFormatQuest, the user-defined format to update
|
||||
*
|
||||
*/
|
||||
public DialogCustomFormat(List<String> userFormat) {
|
||||
|
||||
customFormat = userFormat;
|
||||
if (customFormat == null) {
|
||||
throw new RuntimeException("Null GameFormatQuest in DialogCustomFormat");
|
||||
}
|
||||
|
||||
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
List<CardEdition> editions = new ArrayList<CardEdition>();
|
||||
|
||||
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<String> customFormat;
|
||||
private final Runnable onOk;
|
||||
private final List<JCheckBox> choices = new ArrayList<JCheckBox>();
|
||||
|
||||
|
||||
/**
|
||||
* Create the dialog.
|
||||
*
|
||||
* @param userFormat
|
||||
* GameFormatQuest, the user-defined format to update
|
||||
*
|
||||
*/
|
||||
public DialogChooseSets(List<String> 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<CardEdition> editions = new ArrayList<CardEdition>();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
|
||||
* <code>new FLabel.Builder().method1(foo).method2(bar).method3(baz)...</code>
|
||||
* <br>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
|
||||
|
||||
49
src/main/java/forge/gui/toolbox/FSpinner.java
Normal file
49
src/main/java/forge/gui/toolbox/FSpinner.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
* <code>new FTextField.Builder().method1(foo).method2(bar).method3(baz)...</code>
|
||||
* <br>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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
237
src/main/java/forge/quest/QuestRewardCardChooser.java
Normal file
237
src/main/java/forge/quest/QuestRewardCardChooser.java
Normal file
@@ -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<CardPrinted> 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<CardPrinted> buildPredicates(final String [] input) {
|
||||
if (input == null || input.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Predicate<CardPrinted> filters = Singletons.getModel().getQuest().getFormat().getFilterPrinted();
|
||||
Predicate<CardRules> filterRules = null;
|
||||
Predicate<CardPrinted> 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<String> sets = new ArrayList<String>();
|
||||
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<CardRules> 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<CardPrinted> 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<CardPrinted> or null if could not create a list.
|
||||
*/
|
||||
public final List<CardPrinted> getChoices() {
|
||||
if (type == poolType.playerCards) {
|
||||
final ItemPool<CardPrinted> 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<CardPrinted> cardChoices = new ArrayList<CardPrinted>();
|
||||
for (final Map.Entry<CardPrinted, Integer> card : playerCards) {
|
||||
cardChoices.add(card.getKey());
|
||||
}
|
||||
Collections.sort(cardChoices);
|
||||
|
||||
return Collections.unmodifiableList(cardChoices);
|
||||
}
|
||||
|
||||
} else if (type == poolType.predicateFilter) {
|
||||
List<CardPrinted> cardChoices = new ArrayList<CardPrinted>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -576,20 +576,10 @@ public final class QuestUtilCards {
|
||||
this.qa.getNewCardList().clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fn new compare.
|
||||
*
|
||||
* @return the fnNewCompare
|
||||
*/
|
||||
public Function<Entry<InventoryItem, Integer>, Comparable<?>> getFnNewCompare() {
|
||||
return this.fnNewCompare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fn new get.
|
||||
*
|
||||
* @return the fnNewGet
|
||||
*/
|
||||
public Function<Entry<InventoryItem, Integer>, 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<Entry<InventoryItem, Integer>, Comparable<?>> fnNewCompare = new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
|
||||
private final Function<Entry<InventoryItem, Integer>, Comparable<?>> fnNewCompare =
|
||||
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
|
||||
@Override
|
||||
public Comparable<?> apply(final Entry<InventoryItem, Integer> 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<Entry<InventoryItem, Integer>, Object> fnNewGet = new Function<Entry<InventoryItem, Integer>, Object>() {
|
||||
private final Function<Entry<InventoryItem, Integer>, Object> fnNewGet =
|
||||
new Function<Entry<InventoryItem, Integer>, Object>() {
|
||||
@Override
|
||||
public Object apply(final Entry<InventoryItem, Integer> from) {
|
||||
return QuestUtilCards.this.qa.getNewCardList().contains(from.getKey()) ? "NEW" : "";
|
||||
}
|
||||
};
|
||||
|
||||
public Function<Entry<InventoryItem, Integer>, Comparable<?>> getFnOwnedCompare() {
|
||||
return this.fnOwnedCompare;
|
||||
}
|
||||
|
||||
public Function<Entry<InventoryItem, Integer>, 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<Entry<InventoryItem, Integer>, Comparable<?>> fnOwnedCompare =
|
||||
new Function<Entry<InventoryItem, Integer>, Comparable<?>>() {
|
||||
@Override
|
||||
public Comparable<?> apply(final Entry<InventoryItem, Integer> from) {
|
||||
InventoryItem i = from.getKey();
|
||||
return i instanceof CardPrinted ? QuestUtilCards.this.qa.getCardPool().count((CardPrinted)i) : null;
|
||||
}
|
||||
};
|
||||
|
||||
private final Function<Entry<InventoryItem, Integer>, Object> fnOwnedGet =
|
||||
new Function<Entry<InventoryItem, Integer>, Object>() {
|
||||
@Override
|
||||
public Object apply(final Entry<InventoryItem, Integer> from) {
|
||||
InventoryItem i = from.getKey();
|
||||
return i instanceof CardPrinted ? QuestUtilCards.this.qa.getCardPool().count((CardPrinted)i) : null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
11
src/main/java/forge/util/Pair.java
Normal file
11
src/main/java/forge/util/Pair.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package forge.util;
|
||||
|
||||
public class Pair<T, V> {
|
||||
public final T a;
|
||||
public final V b;
|
||||
|
||||
public Pair(T a, V b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,6 @@ public enum FView {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
/** */
|
||||
public static final Integer TARGETING_LAYER = JLayeredPane.MODAL_LAYER - 1;
|
||||
private final List<DragCell> allCells = new ArrayList<DragCell>();
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user