Integrate filters into ItemManager

This commit is contained in:
drdev
2013-12-16 09:10:40 +00:00
parent 8ebf514dab
commit d56cecdba4
53 changed files with 1653 additions and 2208 deletions

1
.gitattributes vendored
View File

@@ -15482,6 +15482,7 @@ forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/CardToughnessFilte
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/CardTypeFilter.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/CardTypeFilter.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/ItemFilter.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/ItemFilter.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/ListLabelFilter.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/ListLabelFilter.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/StatTypeFilter.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/TextSearchFilter.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/TextSearchFilter.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/ToggleButtonsFilter.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/ToggleButtonsFilter.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/ValueRangeFilter.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/filters/ValueRangeFilter.java -text

View File

@@ -123,6 +123,13 @@ public class Aggregates {
return uniques.values(); return uniques.values();
} }
public static final <K, U> int uniqueCount(final Iterable<U> source, final Function<U, K> fnUniqueKey) {
final Map<K, U> uniques = new Hashtable<K, U>();
for (final U c : source) {
uniques.put(fnUniqueKey.apply(c), c);
}
return uniques.size();
}
public static <T> T itemWithMin(final Iterable<T> source, final Function<T, Integer> valueAccessor) { public static <T> T itemWithMin(final Iterable<T> source, final Function<T, Integer> valueAccessor) {
if (source == null) { return null; } if (source == null) { return null; }

View File

@@ -1,5 +1,6 @@
package forge.util; package forge.util;
import java.awt.event.KeyEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@@ -78,13 +79,13 @@ public class TextUtil {
int len = input.length(); int len = input.length();
int start = 0; int start = 0;
int idx = 1; int idx = 1;
for (int iC = 0; iC < len; iC++ ) { for (int iC = 0; iC < len; iC++) {
char c = input.charAt(iC); char c = input.charAt(iC);
if( closePar > 0 && c == closePar && nPar > 0 ) { nPar--; } if (closePar > 0 && c == closePar && nPar > 0) { nPar--; }
else if( openPar > 0 && c == openPar ) nPar++; else if (openPar > 0 && c == openPar) nPar++;
if( c == delimiter && nPar == 0 && idx < maxEntries) { if (c == delimiter && nPar == 0 && idx < maxEntries) {
if( iC > start || !skipEmpty ) { if (iC > start || !skipEmpty) {
result.add(input.subSequence(start, iC).toString()); result.add(input.subSequence(start, iC).toString());
idx++; idx++;
} }
@@ -92,7 +93,7 @@ public class TextUtil {
} }
} }
if( len > start || !skipEmpty ) if (len > start || !skipEmpty)
result.add(input.subSequence(start, len).toString()); result.add(input.subSequence(start, len).toString());
String[] toReturn = result.toArray(ArrayUtils.EMPTY_STRING_ARRAY); String[] toReturn = result.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
@@ -122,12 +123,20 @@ public class TextUtil {
public static String buildFourColumnList(String firstLine, Iterable<PaperCard> cAnteRemoved) { public static String buildFourColumnList(String firstLine, Iterable<PaperCard> cAnteRemoved) {
StringBuilder sb = new StringBuilder(firstLine); StringBuilder sb = new StringBuilder(firstLine);
int i = 0; int i = 0;
for(PaperCard cp: cAnteRemoved) { for (PaperCard cp: cAnteRemoved) {
if ( i != 0 ) sb.append(", "); if (i != 0) { sb.append(", "); }
if ( i % 4 == 0 ) sb.append("\n"); if (i % 4 == 0) { sb.append("\n"); }
sb.append(cp); sb.append(cp);
i++; i++;
} }
return sb.toString(); return sb.toString();
} }
public static boolean isPrintableChar(char c) {
Character.UnicodeBlock block = Character.UnicodeBlock.of(c);
return (!Character.isISOControl(c)) &&
c != KeyEvent.CHAR_UNDEFINED &&
block != null &&
block != Character.UnicodeBlock.SPECIALS;
}
} }

View File

@@ -53,7 +53,6 @@ import forge.Singletons;
import forge.deck.DeckBase; import forge.deck.DeckBase;
import forge.gui.GuiUtils; import forge.gui.GuiUtils;
import forge.gui.deckeditor.controllers.ACEditorBase; import forge.gui.deckeditor.controllers.ACEditorBase;
import forge.gui.deckeditor.controllers.CCardCatalog;
import forge.gui.deckeditor.controllers.CEditorConstructed; import forge.gui.deckeditor.controllers.CEditorConstructed;
import forge.gui.deckeditor.controllers.CProbabilities; import forge.gui.deckeditor.controllers.CProbabilities;
import forge.gui.deckeditor.controllers.CStatistics; import forge.gui.deckeditor.controllers.CStatistics;
@@ -238,7 +237,7 @@ public enum CDeckEditorUI implements ICDoc, IMenuProvider {
KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), KeyStroke.getKeyStroke(KeyEvent.VK_F, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
new Runnable() { new Runnable() {
@Override public void run() { @Override public void run() {
VCardCatalog.SINGLETON_INSTANCE.getTxfSearch().requestFocusInWindow(); VCardCatalog.SINGLETON_INSTANCE.getItemManager().focusSearch();
} }
}); });
} }
@@ -331,7 +330,7 @@ public enum CDeckEditorUI implements ICDoc, IMenuProvider {
} else if (KeyEvent.VK_F == e.getKeyCode()) { } else if (KeyEvent.VK_F == e.getKeyCode()) {
// let ctrl/cmd-F set focus to the text filter box // let ctrl/cmd-F set focus to the text filter box
if (e.isControlDown() || e.isMetaDown()) { if (e.isControlDown() || e.isMetaDown()) {
VCardCatalog.SINGLETON_INSTANCE.getTxfSearch().requestFocusInWindow(); VCardCatalog.SINGLETON_INSTANCE.getItemManager().focusSearch();
} }
} }
} }
@@ -438,7 +437,7 @@ public enum CDeckEditorUI implements ICDoc, IMenuProvider {
deckTable.setWantElasticColumns(wantElastic); deckTable.setWantElasticColumns(wantElastic);
catView.setWantUnique(wantUnique); catView.setWantUnique(wantUnique);
deckView.setWantUnique(wantUnique); deckView.setWantUnique(wantUnique);
CCardCatalog.SINGLETON_INSTANCE.applyCurrentFilter(); catView.buildFilterPredicate();
} }
private class _FindAsYouType extends KeyAdapter { private class _FindAsYouType extends KeyAdapter {

View File

@@ -19,12 +19,16 @@ package forge.gui.deckeditor.controllers;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import forge.Command;
import forge.deck.DeckBase; import forge.deck.DeckBase;
import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.framework.IVDoc; import forge.gui.framework.IVDoc;
import forge.gui.framework.SRearrangingUtil; import forge.gui.framework.SRearrangingUtil;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.view.FView; import forge.view.FView;
@@ -63,6 +67,41 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
private final FScreen screen; private final FScreen screen;
private ItemManager<TItem> catalogManager; private ItemManager<TItem> catalogManager;
private ItemManager<TItem> deckManager; private ItemManager<TItem> deckManager;
// card transfer buttons
private final FLabel btnAdd = new FLabel.Builder()
.fontSize(14)
.text("Add card")
.tooltip("Add selected card to current deck (or double click the row or hit the spacebar)")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_PLUS))
.iconScaleAuto(false).hoverable().build();
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().build();
private final FLabel btnRemove = new FLabel.Builder()
.fontSize(14)
.text("Remove card")
.tooltip("Remove selected card from current deck (or double click the row or hit the spacebar)")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_MINUS))
.iconScaleAuto(false).hoverable().build();
private final FLabel btnRemove4 = new FLabel.Builder()
.fontSize(14)
.text("Remove 4 of card")
.tooltip("Remove up to 4 of selected card to current deck")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_MINUS))
.iconScaleAuto(false).hoverable().build();
private final FLabel btnCycleSection = new FLabel.Builder()
.fontSize(14)
.text("Change Section")
.tooltip("Toggle between editing the deck and the sideboard/planar/scheme/vanguard parts of this deck")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_EDIT))
.iconScaleAuto(false).hoverable().build();
protected ACEditorBase(FScreen screen0) { protected ACEditorBase(FScreen screen0) {
this.screen = screen0; this.screen = screen0;
@@ -128,8 +167,25 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
* *
* @param itemManager &emsp; {@link forge.gui.toolbox.itemmanager.ItemManager} * @param itemManager &emsp; {@link forge.gui.toolbox.itemmanager.ItemManager}
*/ */
@SuppressWarnings("serial")
public void setDeckManager(final ItemManager<TItem> itemManager) { public void setDeckManager(final ItemManager<TItem> itemManager) {
this.deckManager = itemManager; this.deckManager = itemManager;
btnRemove.setCommand(new Command() {
@Override
public void run() {
CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 1);
}
});
btnRemove4.setCommand(new Command() {
@Override
public void run() {
CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 4);
}
});
itemManager.getPnlButtons().add(btnRemove, "w 30%!, h 30px!, gapx 5");
itemManager.getPnlButtons().add(btnRemove4, "w 30%!, h 30px!, gapx 5");
itemManager.getPnlButtons().add(btnCycleSection, "w 30%!, h 30px!, gapx 5");
} }
/** /**
@@ -146,8 +202,24 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
* *
* @param itemManager &emsp; {@link forge.gui.toolbox.itemmanager.ItemManager} * @param itemManager &emsp; {@link forge.gui.toolbox.itemmanager.ItemManager}
*/ */
@SuppressWarnings("serial")
public void setCatalogManager(final ItemManager<TItem> itemManager) { public void setCatalogManager(final ItemManager<TItem> itemManager) {
this.catalogManager = itemManager; this.catalogManager = itemManager;
btnAdd.setCommand(new Command() {
@Override
public void run() {
CDeckEditorUI.SINGLETON_INSTANCE.addSelectedCards(false, 1);
}
});
btnAdd4.setCommand(new Command() {
@Override
public void run() {
CDeckEditorUI.SINGLETON_INSTANCE.addSelectedCards(false, 4);
}
});
itemManager.getPnlButtons().add(btnAdd, "w 30%!, h 30px!, h 30px!, gapx 5");
itemManager.getPnlButtons().add(btnAdd4, "w 30%!, h 30px!, h 30px!, gapx 5");
} }
/** /**
@@ -179,4 +251,10 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
return parent; return parent;
} }
public FLabel getBtnAdd() { return btnAdd; }
public FLabel getBtnAdd4() { return btnAdd4; }
public FLabel getBtnRemove() { return btnRemove; }
public FLabel getBtnRemove4() { return btnRemove4; }
public FLabel getBtnCycleSection() { return btnCycleSection; }
} }

View File

@@ -1,52 +1,7 @@
package forge.gui.deckeditor.controllers; package forge.gui.deckeditor.controllers;
import java.awt.Toolkit;
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.Map;
import java.util.Set;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSpinner;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.Command; import forge.Command;
import forge.Singletons;
import forge.card.CardEdition;
import forge.deck.DeckBase;
import forge.game.GameFormat;
import forge.gui.GuiUtils;
import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.deckeditor.views.VCardCatalog;
import forge.gui.deckeditor.views.VCardCatalog.RangeTypes;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.home.quest.DialogChooseSets;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSpinner;
import forge.gui.toolbox.itemmanager.SFilterUtil;
import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes;
import forge.item.PaperCard;
import forge.item.ItemPredicate;
import forge.quest.QuestWorld;
import forge.quest.data.GameFormatQuest;
/** /**
* Controls the "card catalog" panel in the deck editor UI. * Controls the "card catalog" panel in the deck editor UI.
@@ -58,13 +13,6 @@ public enum CCardCatalog implements ICDoc {
/** */ /** */
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
private final Set<Predicate<PaperCard>> activePredicates = new HashSet<Predicate<PaperCard>>();
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() { private CCardCatalog() {
} }
@@ -82,293 +30,7 @@ public enum CCardCatalog implements ICDoc {
* @see forge.gui.framework.ICDoc#initialize() * @see forge.gui.framework.ICDoc#initialize()
*/ */
@Override @Override
@SuppressWarnings("serial")
public void initialize() { public void initialize() {
// Add/remove buttons (refresh analysis on add)
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().setCommand(new Command() {
@Override
public void run() {
CDeckEditorUI.SINGLETON_INSTANCE.addSelectedCards(false, 1);
}
});
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setCommand(new Command() {
@Override
public void run() {
CDeckEditorUI.SINGLETON_INSTANCE.addSelectedCards(false, 4);
}
});
final Command updateFilterCommand = new Command() {
@Override
public void run() {
if (!disableFiltering) {
applyCurrentFilter();
}
}
};
for (Map.Entry<SItemManagerUtil.StatTypes, FLabel> entry : VCardCatalog.SINGLETON_INSTANCE.getStatLabels().entrySet()) {
final FLabel statLabel = entry.getValue();
statLabel.setCommand(updateFilterCommand);
//hook so right-clicking a filter in a group toggles itself off and toggles on all other filters in group
final SItemManagerUtil.StatTypes st = entry.getKey();
final int group = st.group;
if (group > 0) {
statLabel.setRightClickCommand(new Command() {
@SuppressWarnings("incomplete-switch")
@Override
public void run() {
if (!disableFiltering) {
disableFiltering = true;
boolean foundSelected = false;
for (SItemManagerUtil.StatTypes s : SItemManagerUtil.StatTypes.values()) {
if (s.group == group && s != st) {
FLabel lbl = VCardCatalog.SINGLETON_INSTANCE.getItemManager().getStatLabel(s);
if (s == StatTypes.MULTICOLOR) {
switch (st) {
case WHITE:
case BLUE:
case BLACK:
case RED:
case GREEN:
//ensure multicolor filter selected after right-clicking a color filter
if (!lbl.getSelected()) {
lbl.setSelected(true);
}
continue;
}
}
if (lbl.getSelected()) {
foundSelected = true;
lbl.setSelected(false);
}
}
}
if (!statLabel.getSelected()) {
statLabel.setSelected(true);
}
else if (!foundSelected) {
//if statLabel only label in group selected, re-select all other labels in group
for (SItemManagerUtil.StatTypes s : SItemManagerUtil.StatTypes.values()) {
if (s.group == group && s != st) {
FLabel lbl = VCardCatalog.SINGLETON_INSTANCE.getItemManager().getStatLabel(s);
if (!lbl.getSelected()) {
lbl.setSelected(true);
}
}
}
}
disableFiltering = false;
applyCurrentFilter();
}
}
});
}
}
VCardCatalog.SINGLETON_INSTANCE.getStatLabels().get(SItemManagerUtil.StatTypes.TOTAL).setCommand(new Command() {
private boolean lastToggle = true;
@Override
public void run() {
disableFiltering = true;
lastToggle = !lastToggle;
for (SItemManagerUtil.StatTypes s : SItemManagerUtil.StatTypes.values()) {
if (SItemManagerUtil.StatTypes.TOTAL != s) {
VCardCatalog.SINGLETON_INSTANCE.getItemManager().getStatLabel(s).setSelected(lastToggle);
}
}
disableFiltering = false;
applyCurrentFilter();
}
});
// assemble add restriction menu
final Command addRestrictionCommand = new Command() {
@Override
public void run() {
JPopupMenu popup = new JPopupMenu("RestrictionPopupMenu");
GuiUtils.addMenuItem(popup, "Current text search",
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
new Runnable() {
@Override
public void run() {
addRestriction(buildSearchRestriction(), null, null);
}
}, canSearch());
JMenu fmt = new JMenu("Format");
for (final GameFormat f : Singletons.getModel().getFormats()) {
GuiUtils.addMenuItem(fmt, f.getName(), null, new Runnable() {
@Override
public void run() {
addRestriction(buildFormatRestriction(f.toString(), f, true), activeFormats, f);
}
}, !isActive(activeFormats, f));
}
popup.add(fmt);
GuiUtils.addMenuItem(popup, "Sets...", null, new Runnable() {
@Override
public void run() {
final DialogChooseSets dialog = new DialogChooseSets(null, null, true);
dialog.setOkCallback(new Runnable() {
@Override
public void run() {
List<String> setCodes = dialog.getSelectedSets();
if (setCodes.isEmpty()) {
return;
}
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(buildSetRestriction(label.toString(), setCodes, dialog.getWantReprints()), null, null);
}
});
}
});
JMenu range = new JMenu("Value range");
for (final RangeTypes t : RangeTypes.values()) {
GuiUtils.addMenuItem(range, t.toLabelString() + " restriction", null, new Runnable() {
@Override
public void run() {
addRestriction(buildRangeRestriction(t), activeRanges, t);
}
}, !isActive(activeRanges, t));
}
popup.add(range);
JMenu world = new JMenu("Quest world");
for (final QuestWorld w : Singletons.getModel().getWorlds()) {
GameFormatQuest format = w.getFormat();
if (null == format) {
// assumes that no world other than the main world will have a null format
format = Singletons.getModel().getQuest().getMainFormat();
}
final GameFormatQuest f = format;
GuiUtils.addMenuItem(world, w.getName(), null, new Runnable() {
@Override
public void run() {
addRestriction(buildFormatRestriction(w.getName(), f, true), activeWorlds, w);
}
}, !isActive(activeWorlds, w) && null != f);
}
popup.add(world);
popup.show(VCardCatalog.SINGLETON_INSTANCE.getBtnAddRestriction(), 0,
VCardCatalog.SINGLETON_INSTANCE.getBtnAddRestriction().getHeight());
}
};
FLabel btnAddRestriction = VCardCatalog.SINGLETON_INSTANCE.getBtnAddRestriction();
btnAddRestriction.setCommand(addRestrictionCommand);
btnAddRestriction.setRightClickCommand(addRestrictionCommand); //show menu on right-click too
VCardCatalog.SINGLETON_INSTANCE.getCbSearchMode().addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
applyCurrentFilter();
}
});
Runnable addSearchRestriction = new Runnable() {
@Override
public void run() {
if (canSearch()) {
addRestriction(buildSearchRestriction(), null, null);
}
}
};
// add search restriction on ctrl-enter from either the textbox or combobox
VCardCatalog.SINGLETON_INSTANCE.getCbSearchMode().addKeyListener(new _OnCtrlEnter(addSearchRestriction));
VCardCatalog.SINGLETON_INSTANCE.getTxfSearch().addKeyListener(new _OnCtrlEnter(addSearchRestriction) {
private boolean keypressPending;
@Override
public void keyReleased(KeyEvent e) {
if (KeyEvent.VK_ENTER == e.getKeyCode() && 0 == e.getModifiers()) {
// set focus to table when a plain enter is typed into the text filter box
CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getCatalogManager().getTable().requestFocusInWindow();
} else if (keypressPending) {
// do this in keyReleased instead of keyTyped since the textbox text isn't updated until the key is released
// but depend on keypressPending since otherwise we pick up hotkeys and other unwanted stuff
applyCurrentFilter();
}
}
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
keypressPending = KeyEvent.VK_ENTER != e.getKeyCode();
}
});
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.getLeft();
final FSpinner max = sPair.getRight();
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();
}
});
}
}
private class _OnCtrlEnter extends KeyAdapter {
private final Runnable action;
_OnCtrlEnter(Runnable action) {
this.action = action;
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
if (e.isControlDown() || e.isMetaDown()) {
action.run();
}
}
}
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -377,207 +39,4 @@ public enum CCardCatalog implements ICDoc {
@Override @Override
public void update() { 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 PaperCard>> cardPredicates = new ArrayList<Predicate<? super PaperCard>>();
cardPredicates.add(Predicates.instanceOf(PaperCard.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().getSelected(),
VCardCatalog.SINGLETON_INSTANCE.getLblType().getSelected(),
VCardCatalog.SINGLETON_INSTANCE.getLblText().getSelected()));
Predicate<PaperCard> cardFilter = Predicates.and(cardPredicates);
// show packs and decks in the card shop according to the toggle setting
// this is special-cased apart from the buildColorAndTypeFilter() above
if (VCardCatalog.SINGLETON_INSTANCE.getItemManager().getStatLabel(StatTypes.PACK).getSelected()) {
List<Predicate<? super PaperCard>> itemPredicates = new ArrayList<Predicate<? super PaperCard>>();
itemPredicates.add(cardFilter);
itemPredicates.add(ItemPredicate.Presets.IS_PACK);
itemPredicates.add(ItemPredicate.Presets.IS_DECK);
cardFilter = Predicates.or(itemPredicates);
}
// Apply to table
// TODO: is there really no way to make this type safe?
ACEditorBase<?, ?> editor = CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController();
if (null != editor) {
((ACEditorBase<PaperCard, DeckBase>)editor).getCatalogManager().setFilterPredicate(cardFilter);
}
}
private boolean canSearch() {
return !VCardCatalog.SINGLETON_INSTANCE.getTxfSearch().getText().isEmpty() &&
(VCardCatalog.SINGLETON_INSTANCE.getLblName().getSelected() ||
VCardCatalog.SINGLETON_INSTANCE.getLblType().getSelected() ||
VCardCatalog.SINGLETON_INSTANCE.getLblText().getSelected());
}
private <T> boolean isActive(Set<T> activeSet, T key) {
return activeSet.contains(key);
}
@SuppressWarnings("serial")
private <T> void addRestriction(Pair<? extends JComponent, Predicate<PaperCard>> restriction, final Set<T> activeSet, final T key) {
final Predicate<PaperCard> predicate = restriction.getRight();
if (null != predicate && activePredicates.contains(predicate)) {
return;
}
VCardCatalog.SINGLETON_INSTANCE.addRestrictionWidget(restriction.getLeft(), new Command() {
@Override
public void run() {
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<JPanel, Predicate<PaperCard>> buildRangeRestriction(RangeTypes t) {
final Pair<FSpinner, FSpinner> s = VCardCatalog.SINGLETON_INSTANCE.getSpinners().get(t);
s.getLeft().setValue(0);
s.getRight().setValue(10);
// set focus to lower bound widget
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
((JSpinner.DefaultEditor)s.getLeft().getEditor()).getTextField().requestFocusInWindow();
}
});
return Pair.of(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<FLabel, Predicate<PaperCard>> 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 Pair.of(
VCardCatalog.SINGLETON_INSTANCE.buildPlainRestrictionWidget(shortText, fullText),
SFilterUtil.buildTextFilter(text, isInverse, wantName, wantType, wantText));
}
private Pair<FLabel, Predicate<PaperCard>> buildFormatRestriction(String displayName, GameFormat format, boolean allowReprints) {
CardEdition.Collection editions = Singletons.getMagicDb().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 = 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());
if (allowReprints) {
tooltip.append("<br><br>Allowing identical cards from other sets");
}
}
List<String> bannedCards = 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 Pair.of(
VCardCatalog.SINGLETON_INSTANCE.buildPlainRestrictionWidget(displayName, tooltip.toString()),
allowReprints ? format.getFilterRules() : format.getFilterPrinted());
}
private Pair<FLabel, Predicate<PaperCard>> buildSetRestriction(String displayName, List<String> setCodes, boolean allowReprints) {
return buildFormatRestriction(displayName, new GameFormat(null, setCodes, null), allowReprints);
}
} }

View File

@@ -19,7 +19,6 @@ import forge.gui.deckeditor.DeckImport;
import forge.gui.deckeditor.SEditorIO; import forge.gui.deckeditor.SEditorIO;
import forge.gui.deckeditor.views.VCurrentDeck; import forge.gui.deckeditor.views.VCurrentDeck;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.toolbox.FLabel;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.properties.NewConstants; import forge.properties.NewConstants;
@@ -75,40 +74,43 @@ public enum CCurrentDeck implements ICDoc {
@Override @Override
@SuppressWarnings("serial") @SuppressWarnings("serial")
public void initialize() { public void initialize() {
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnSave()) VCurrentDeck.SINGLETON_INSTANCE.getBtnSave().setCommand(new Command() {
.setCommand(new Command() { @Override @Override
public void run() { SEditorIO.saveDeck(); } }); public void run() {
SEditorIO.saveDeck();
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs()) }
.setCommand(new Command() { @Override });
public void run() { exportDeck(); } }); VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs().setCommand(new Command() {
@Override
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnPrintProxies()) public void run() {
.setCommand(new Command() { @Override exportDeck();
public void run() { printProxies(); } }); }
});
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnOpen()) VCurrentDeck.SINGLETON_INSTANCE.getBtnPrintProxies().setCommand(new Command() {
.setCommand(new Command() { @Override @Override
public void run() { openDeck(); } }); public void run() {
printProxies();
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnNew()) }
.setCommand(new Command() { @Override });
public void run() { newDeck(); } }); VCurrentDeck.SINGLETON_INSTANCE.getBtnOpen().setCommand(new Command() {
@Override
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove()).setCommand(new Command() { public void run() {
@Override public void run() { openDeck();
CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 1);
} });
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4()).setCommand(new Command() {
@Override public void run() {
CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, 4);
} }
}); });
VCurrentDeck.SINGLETON_INSTANCE.getBtnImport() VCurrentDeck.SINGLETON_INSTANCE.getBtnNew().setCommand(new Command() {
.setCommand(new Command() { @Override @Override
public void run() { importDeck(); } }); public void run() {
newDeck();
}
});
VCurrentDeck.SINGLETON_INSTANCE.getBtnImport().setCommand(new Command() {
@Override
public void run() {
importDeck();
}
});
} }
/** /**

View File

@@ -20,7 +20,6 @@ import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.deckeditor.SEditorIO; import forge.gui.deckeditor.SEditorIO;
import forge.gui.deckeditor.views.VDeckgen; import forge.gui.deckeditor.views.VDeckgen;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.toolbox.FLabel;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.properties.ForgePreferences.FPref; import forge.properties.ForgePreferences.FPref;
@@ -53,21 +52,30 @@ public enum CDeckgen implements ICDoc {
@SuppressWarnings("serial") @SuppressWarnings("serial")
@Override @Override
public void initialize() { public void initialize() {
((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandCardpool()).setCommand(new Command() { VDeckgen.SINGLETON_INSTANCE.getBtnRandCardpool().setCommand(new Command() {
@Override @Override
public void run() { public void run() {
newRandomConstructed(); newRandomConstructed();
} }
}); });
VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck2().setCommand(new Command() {
((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck2()).setCommand(new Command() { @Override
@Override public void run() { newGenerateConstructed(2); } }); public void run() {
newGenerateConstructed(2);
((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck3()).setCommand(new Command() { }
@Override public void run() { newGenerateConstructed(3); } }); });
VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck3().setCommand(new Command() {
((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck5()).setCommand(new Command() { @Override
@Override public void run() { newGenerateConstructed(5); } }); public void run() {
newGenerateConstructed(3);
}
});
VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck5().setCommand(new Command() {
@Override
public void run() {
newGenerateConstructed(5);
}
});
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -37,7 +37,6 @@ import forge.gui.deckeditor.views.VCurrentDeck;
import forge.gui.deckeditor.views.VDeckgen; import forge.gui.deckeditor.views.VDeckgen;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.itemmanager.CardManager; import forge.gui.toolbox.itemmanager.CardManager;
import forge.gui.toolbox.itemmanager.SItemManagerIO; import forge.gui.toolbox.itemmanager.SItemManagerIO;
import forge.gui.toolbox.itemmanager.SItemManagerUtil; import forge.gui.toolbox.itemmanager.SItemManagerUtil;
@@ -87,8 +86,8 @@ public final class CEditorCommander extends ACEditorBase<PaperCard, Deck> {
boolean wantUnique = SItemManagerIO.getPref(EditorPreference.display_unique_only); boolean wantUnique = SItemManagerIO.getPref(EditorPreference.display_unique_only);
this.setCatalogManager(new CardManager(VCardCatalog.SINGLETON_INSTANCE.getStatLabels(), wantUnique)); this.setCatalogManager(new CardManager(wantUnique));
this.setDeckManager(new CardManager(VCurrentDeck.SINGLETON_INSTANCE.getStatLabels(), wantUnique)); this.setDeckManager(new CardManager(wantUnique));
final Supplier<Deck> newCreator = new Supplier<Deck>() { final Supplier<Deck> newCreator = new Supplier<Deck>() {
@Override @Override
@@ -180,26 +179,26 @@ public final class CEditorCommander extends ACEditorBase<PaperCard, Deck> {
*/ */
@Override @Override
public void update() { public void update() {
final List<TableColumnInfo<InventoryItem>> lstCatalogCols = SColumnUtil.getCatalogDefaultColumns(); final List<TableColumnInfo<InventoryItem>> lstCatalogCols = SColumnUtil.getCatalogDefaultColumns();
lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY)); lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY));
this.getCatalogManager().getTable().setup(lstCatalogCols); this.getCatalogManager().getTable().setup(lstCatalogCols);
this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns()); this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns());
SItemManagerUtil.resetUI(); SItemManagerUtil.resetUI(this);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setVisible(false); this.getBtnRemove4().setVisible(false);
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setVisible(false); this.getBtnAdd4().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getBtnDoSideboard().setVisible(true); this.getBtnCycleSection().setVisible(true);
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnDoSideboard()).setCommand(new Command() { this.getBtnCycleSection().setCommand(new Command() {
private static final long serialVersionUID = -9082606944024479599L; private static final long serialVersionUID = -9082606944024479599L;
@Override @Override
public void run() { public void run() {
cycleEditorMode(); cycleEditorMode();
} }); }
});
deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE); deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE);
allDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE); allDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE);

View File

@@ -33,7 +33,6 @@ import forge.gui.deckeditor.SEditorIO;
import forge.gui.deckeditor.views.VCardCatalog; import forge.gui.deckeditor.views.VCardCatalog;
import forge.gui.deckeditor.views.VCurrentDeck; import forge.gui.deckeditor.views.VCurrentDeck;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.itemmanager.CardManager; import forge.gui.toolbox.itemmanager.CardManager;
import forge.gui.toolbox.itemmanager.SItemManagerIO; import forge.gui.toolbox.itemmanager.SItemManagerIO;
import forge.gui.toolbox.itemmanager.SItemManagerUtil; import forge.gui.toolbox.itemmanager.SItemManagerUtil;
@@ -89,8 +88,8 @@ public final class CEditorConstructed extends ACEditorBase<PaperCard, Deck> {
boolean wantUnique = SItemManagerIO.getPref(EditorPreference.display_unique_only); boolean wantUnique = SItemManagerIO.getPref(EditorPreference.display_unique_only);
this.setCatalogManager(new CardManager(VCardCatalog.SINGLETON_INSTANCE.getStatLabels(), wantUnique)); this.setCatalogManager(new CardManager(wantUnique));
this.setDeckManager(new CardManager(VCurrentDeck.SINGLETON_INSTANCE.getStatLabels(), wantUnique)); this.setDeckManager(new CardManager(wantUnique));
final Supplier<Deck> newCreator = new Supplier<Deck>() { final Supplier<Deck> newCreator = new Supplier<Deck>() {
@Override @Override
@@ -294,15 +293,16 @@ public final class CEditorConstructed extends ACEditorBase<PaperCard, Deck> {
this.getCatalogManager().getTable().setup(lstCatalogCols); this.getCatalogManager().getTable().setup(lstCatalogCols);
this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns()); this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns());
SItemManagerUtil.resetUI(); SItemManagerUtil.resetUI(this);
VCurrentDeck.SINGLETON_INSTANCE.getBtnDoSideboard().setVisible(true); this.getBtnCycleSection().setVisible(true);
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnDoSideboard()).setCommand(new Command() { this.getBtnCycleSection().setCommand(new Command() {
@Override @Override
public void run() { public void run() {
cycleEditorMode(); cycleEditorMode();
} }); }
});
this.controller.refreshModel(); this.controller.refreshModel();
} }

View File

@@ -66,8 +66,8 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
public CEditorDraftingProcess() { public CEditorDraftingProcess() {
super(FScreen.DRAFTING_PROCESS); super(FScreen.DRAFTING_PROCESS);
final CardManager catalogManager = new CardManager(VCardCatalog.SINGLETON_INSTANCE.getStatLabels(), false); final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(VCurrentDeck.SINGLETON_INSTANCE.getStatLabels(), false); final CardManager deckManager = new CardManager(false);
catalogManager.setAlwaysNonUnique(true); catalogManager.setAlwaysNonUnique(true);
deckManager.setAlwaysNonUnique(true); deckManager.setAlwaysNonUnique(true);
@@ -252,8 +252,8 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
this.getCatalogManager().getTable().setup(SColumnUtil.getCatalogDefaultColumns()); this.getCatalogManager().getTable().setup(SColumnUtil.getCatalogDefaultColumns());
this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns()); this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns());
ccAddLabel = VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().getText(); ccAddLabel = this.getBtnAdd().getText();
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().setText("Choose Card"); this.getBtnAdd().setText("Choose Card");
if (this.getDeckManager().getPool() == null) { //avoid showing next choice or resetting pool if just switching back to Draft screen if (this.getDeckManager().getPool() == null) { //avoid showing next choice or resetting pool if just switching back to Draft screen
this.showChoices(this.boosterDraft.nextChoice()); this.showChoices(this.boosterDraft.nextChoice());
@@ -264,11 +264,11 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
} }
//Remove buttons //Remove buttons
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setVisible(false); this.getBtnAdd4().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove().setVisible(false); this.getBtnRemove().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setVisible(false); this.getBtnRemove4().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getBtnDoSideboard().setVisible(false); this.getBtnCycleSection().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(false); VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(false);
@@ -293,12 +293,12 @@ public class CEditorDraftingProcess extends ACEditorBase<PaperCard, DeckGroup> {
@Override @Override
public void resetUIChanges() { public void resetUIChanges() {
//Re-rename buttons //Re-rename buttons
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().setText(ccAddLabel); this.getBtnAdd().setText(ccAddLabel);
//Re-add buttons //Re-add buttons
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setVisible(true); this.getBtnAdd4().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove().setVisible(true); this.getBtnRemove().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setVisible(true); this.getBtnRemove4().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(true); VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(true);

View File

@@ -62,8 +62,8 @@ public final class CEditorLimited extends ACEditorBase<PaperCard, DeckGroup> {
public CEditorLimited(final IStorage<DeckGroup> deckMap0, FScreen screen0) { public CEditorLimited(final IStorage<DeckGroup> deckMap0, FScreen screen0) {
super(screen0); super(screen0);
final CardManager catalogManager = new CardManager(VCardCatalog.SINGLETON_INSTANCE.getStatLabels(), false); final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(VCurrentDeck.SINGLETON_INSTANCE.getStatLabels(), false); final CardManager deckManager = new CardManager(false);
catalogManager.setAlwaysNonUnique(true); catalogManager.setAlwaysNonUnique(true);
deckManager.setAlwaysNonUnique(true); deckManager.setAlwaysNonUnique(true);
@@ -163,7 +163,7 @@ public final class CEditorLimited extends ACEditorBase<PaperCard, DeckGroup> {
this.getCatalogManager().getTable().setup(SColumnUtil.getCatalogDefaultColumns()); this.getCatalogManager().getTable().setup(SColumnUtil.getCatalogDefaultColumns());
this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns()); this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns());
SItemManagerUtil.resetUI(); SItemManagerUtil.resetUI(this);
VCurrentDeck.SINGLETON_INSTANCE.getBtnPrintProxies().setVisible(false); VCurrentDeck.SINGLETON_INSTANCE.getBtnPrintProxies().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs().setVisible(false); VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs().setVisible(false);

View File

@@ -14,7 +14,6 @@ import forge.gui.toolbox.itemmanager.SItemManagerIO.EditorPreference;
import forge.gui.toolbox.itemmanager.table.TableColumnInfo; import forge.gui.toolbox.itemmanager.table.TableColumnInfo;
import forge.gui.toolbox.itemmanager.table.SColumnUtil; import forge.gui.toolbox.itemmanager.table.SColumnUtil;
import forge.gui.toolbox.itemmanager.table.SColumnUtil.ColumnName; import forge.gui.toolbox.itemmanager.table.SColumnUtil.ColumnName;
import forge.gui.deckeditor.views.VCurrentDeck;
import forge.gui.deckeditor.views.VEditorPreferences; import forge.gui.deckeditor.views.VEditorPreferences;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.item.InventoryItem; import forge.item.InventoryItem;
@@ -90,17 +89,11 @@ public enum CEditorPreferences implements ICDoc {
} }
// Catalog/Deck Stats // Catalog/Deck Stats
VEditorPreferences.SINGLETON_INSTANCE.getChbDeckStats().setSelected(
SItemManagerIO.getPref(EditorPreference.stats_deck));
VEditorPreferences.SINGLETON_INSTANCE.getChbCardDisplayUnique().setSelected( VEditorPreferences.SINGLETON_INSTANCE.getChbCardDisplayUnique().setSelected(
SItemManagerIO.getPref(EditorPreference.display_unique_only)); SItemManagerIO.getPref(EditorPreference.display_unique_only));
VEditorPreferences.SINGLETON_INSTANCE.getChbElasticColumns().setSelected( VEditorPreferences.SINGLETON_INSTANCE.getChbElasticColumns().setSelected(
SItemManagerIO.getPref(EditorPreference.elastic_columns)); SItemManagerIO.getPref(EditorPreference.elastic_columns));
if (!SItemManagerIO.getPref(EditorPreference.stats_deck)) {
VCurrentDeck.SINGLETON_INSTANCE.setStatsVisible(false);
}
boolean wantElastic = SItemManagerIO.getPref(EditorPreference.elastic_columns); boolean wantElastic = SItemManagerIO.getPref(EditorPreference.elastic_columns);
boolean wantUnique = SItemManagerIO.getPref(EditorPreference.display_unique_only); boolean wantUnique = SItemManagerIO.getPref(EditorPreference.display_unique_only);
ACEditorBase<?, ?> curEditor = CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); ACEditorBase<?, ?> curEditor = CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController();
@@ -113,13 +106,6 @@ public enum CEditorPreferences implements ICDoc {
curEditor.getDeckManager().updateView(true); curEditor.getDeckManager().updateView(true);
} }
VEditorPreferences.SINGLETON_INSTANCE.getChbDeckStats().addItemListener(new ItemListener() {
@Override public void itemStateChanged(final ItemEvent e) {
VCurrentDeck.SINGLETON_INSTANCE.setStatsVisible(
((JCheckBox) e.getSource()).isSelected());
SItemManagerIO.setPref(EditorPreference.stats_deck, ((JCheckBox) e.getSource()).isSelected());
SItemManagerIO.savePreferences(CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getCatalogManager().getTable()); } });
VEditorPreferences.SINGLETON_INSTANCE.getChbElasticColumns().addItemListener(new ItemListener() { VEditorPreferences.SINGLETON_INSTANCE.getChbElasticColumns().addItemListener(new ItemListener() {
@Override public void itemStateChanged(final ItemEvent e) { @Override public void itemStateChanged(final ItemEvent e) {
ACEditorBase<?, ?> curEditor = CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); ACEditorBase<?, ?> curEditor = CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController();

View File

@@ -38,7 +38,6 @@ import forge.gui.deckeditor.views.VDeckgen;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
import forge.gui.home.quest.CSubmenuQuestDecks; import forge.gui.home.quest.CSubmenuQuestDecks;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.itemmanager.CardManager; import forge.gui.toolbox.itemmanager.CardManager;
import forge.gui.toolbox.itemmanager.SItemManagerUtil; import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.gui.toolbox.itemmanager.table.TableColumnInfo; import forge.gui.toolbox.itemmanager.table.TableColumnInfo;
@@ -98,8 +97,8 @@ public final class CEditorQuest extends ACEditorBase<PaperCard, Deck> {
this.questData = questData0; this.questData = questData0;
final CardManager catalogManager = new CardManager(VCardCatalog.SINGLETON_INSTANCE.getStatLabels(), false); final CardManager catalogManager = new CardManager(false);
final CardManager deckManager = new CardManager(VCurrentDeck.SINGLETON_INSTANCE.getStatLabels(), false); final CardManager deckManager = new CardManager(false);
catalogManager.setAlwaysNonUnique(true); catalogManager.setAlwaysNonUnique(true);
deckManager.setAlwaysNonUnique(true); deckManager.setAlwaysNonUnique(true);
@@ -281,11 +280,11 @@ public final class CEditorQuest extends ACEditorBase<PaperCard, Deck> {
this.getCatalogManager().getTable().setup(columnsCatalog); this.getCatalogManager().getTable().setup(columnsCatalog);
this.getDeckManager().getTable().setup(columnsDeck); this.getDeckManager().getTable().setup(columnsDeck);
SItemManagerUtil.resetUI(); SItemManagerUtil.resetUI(this);
VCurrentDeck.SINGLETON_INSTANCE.getBtnSave().setVisible(true); VCurrentDeck.SINGLETON_INSTANCE.getBtnSave().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnDoSideboard().setVisible(true); this.getBtnCycleSection().setVisible(true);
((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnDoSideboard()).setCommand(new Command() { this.getBtnCycleSection().setCommand(new Command() {
@Override @Override
public void run() { public void run() {
sideboardMode = !sideboardMode; sideboardMode = !sideboardMode;

View File

@@ -129,8 +129,8 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
this.questData = qd; this.questData = qd;
final InventoryItemManager catalogManager = new InventoryItemManager(VCardCatalog.SINGLETON_INSTANCE.getStatLabels(), false); final InventoryItemManager catalogManager = new InventoryItemManager(false);
final InventoryItemManager deckManager = new InventoryItemManager(VCurrentDeck.SINGLETON_INSTANCE.getStatLabels(), false); final InventoryItemManager deckManager = new InventoryItemManager(false);
catalogManager.setAlwaysNonUnique(true); catalogManager.setAlwaysNonUnique(true);
deckManager.setAlwaysNonUnique(true); deckManager.setAlwaysNonUnique(true);
@@ -144,15 +144,15 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
if (showingFullCatalog) { if (showingFullCatalog) {
this.getCatalogManager().setPool(fullCatalogCards, true); this.getCatalogManager().setPool(fullCatalogCards, true);
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().setEnabled(false); this.getBtnAdd().setEnabled(false);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove().setEnabled(false); this.getBtnRemove().setEnabled(false);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setEnabled(false); this.getBtnRemove4().setEnabled(false);
fullCatalogToggle.setText("Return to spell shop"); fullCatalogToggle.setText("Return to spell shop");
} else { } else {
this.getCatalogManager().setPool(cardsForSale); this.getCatalogManager().setPool(cardsForSale);
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().setEnabled(true); this.getBtnAdd().setEnabled(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove().setEnabled(true); this.getBtnRemove().setEnabled(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setEnabled(true); this.getBtnRemove4().setEnabled(true);
fullCatalogToggle.setText("See full catalog"); fullCatalogToggle.setText("See full catalog");
} }
} }
@@ -461,25 +461,25 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
this.getCatalogManager().getTable().setup(columnsCatalog); this.getCatalogManager().getTable().setup(columnsCatalog);
this.getDeckManager().getTable().setup(columnsDeck); this.getDeckManager().getTable().setup(columnsDeck);
SItemManagerUtil.resetUI(); SItemManagerUtil.resetUI(this);
CCTabLabel = VCardCatalog.SINGLETON_INSTANCE.getTabLabel().getText(); CCTabLabel = VCardCatalog.SINGLETON_INSTANCE.getTabLabel().getText();
VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText("Cards for sale"); VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText("Cards for sale");
CCAddLabel = VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().getText(); CCAddLabel = this.getBtnAdd().getText();
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().setText("Buy Card"); this.getBtnAdd().setText("Buy Card");
CDTabLabel = VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().getText(); CDTabLabel = VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().getText();
VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("Your Cards"); VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("Your Cards");
CDRemLabel = VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove().getText(); CDRemLabel = this.getBtnRemove().getText();
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove().setText("Sell Card"); this.getBtnRemove().setText("Sell Card");
VProbabilities.SINGLETON_INSTANCE.getTabLabel().setVisible(false); VProbabilities.SINGLETON_INSTANCE.getTabLabel().setVisible(false);
prevRem4Label = VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().getText(); prevRem4Label = this.getBtnRemove4().getText();
prevRem4Tooltip = VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().getToolTipText(); prevRem4Tooltip = this.getBtnRemove4().getToolTipText();
prevRem4Cmd = VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().getCommand(); prevRem4Cmd = this.getBtnRemove4().getCommand();
VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(false); VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(false);
@@ -493,9 +493,9 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
this.getCatalogManager().setPool(cardsForSale); this.getCatalogManager().setPool(cardsForSale);
this.getDeckManager().setPool(ownedItems); this.getDeckManager().setPool(ownedItems);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setText("Sell all extras"); this.getBtnRemove4().setText("Sell all extras");
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setToolTipText("Sell unneeded extra copies of all cards"); this.getBtnRemove4().setToolTipText("Sell unneeded extra copies of all cards");
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setCommand(new Command() { this.getBtnRemove4().setCommand(new Command() {
@Override @Override
public void run() { public void run() {
List<Map.Entry<InventoryItem, Integer>> cardsToRemove = new LinkedList<Map.Entry<InventoryItem,Integer>>(); List<Map.Entry<InventoryItem, Integer>> cardsToRemove = new LinkedList<Map.Entry<InventoryItem,Integer>>();
@@ -513,7 +513,7 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
} }
}); });
VCurrentDeck.SINGLETON_INSTANCE.getPnlRemButtons().add(creditsLabel, "gap 5px"); this.getDeckManager().getPnlButtons().add(creditsLabel, "gap 5px");
this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits());
final double multiPercent = this.multiplier * 100; final double multiPercent = this.multiplier * 100;
@@ -524,14 +524,14 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
if (maxSellPrice < Integer.MAX_VALUE) { if (maxSellPrice < Integer.MAX_VALUE) {
maxSellingPrice = String.format("Maximum selling price is %d credits.", maxSellPrice); maxSellingPrice = String.format("Maximum selling price is %d credits.", maxSellPrice);
} }
VCardCatalog.SINGLETON_INSTANCE.getPnlAddButtons().remove(VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4()); this.getCatalogManager().getPnlButtons().remove(this.getBtnAdd4());
VCardCatalog.SINGLETON_INSTANCE.getPnlAddButtons().add(fullCatalogToggle, "w 25%, h 30!", 0); this.getCatalogManager().getPnlButtons().add(fullCatalogToggle, "w 25%, h 30!", 0);
VCardCatalog.SINGLETON_INSTANCE.getPnlAddButtons().add(sellPercentageLabel); this.getCatalogManager().getPnlButtons().add(sellPercentageLabel);
this.sellPercentageLabel.setText("<html>Selling cards at " + formatter.format(multiPercent) this.sellPercentageLabel.setText("<html>Selling cards at " + formatter.format(multiPercent)
+ "% of their value.<br>" + maxSellingPrice + "</html>"); + "% of their value.<br>" + maxSellingPrice + "</html>");
VCardCatalog.SINGLETON_INSTANCE.getItemManager().getStatLabel(SItemManagerUtil.StatTypes.PACK).setVisible(true); //TODO: Add filter for SItemManagerUtil.StatTypes.PACK
deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE); deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE);
allDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE); allDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE);
probsParent = removeTab(VProbabilities.SINGLETON_INSTANCE); probsParent = removeTab(VProbabilities.SINGLETON_INSTANCE);
@@ -558,22 +558,22 @@ public final class CEditorQuestCardShop extends ACEditorBase<InventoryItem, Deck
CSubmenuQuestDecks.SINGLETON_INSTANCE.update(); CSubmenuQuestDecks.SINGLETON_INSTANCE.update();
// undo Card Shop Specifics // undo Card Shop Specifics
VCardCatalog.SINGLETON_INSTANCE.getPnlAddButtons().remove(sellPercentageLabel); this.getCatalogManager().getPnlButtons().remove(sellPercentageLabel);
VCardCatalog.SINGLETON_INSTANCE.getPnlAddButtons().remove(fullCatalogToggle); this.getCatalogManager().getPnlButtons().remove(fullCatalogToggle);
VCardCatalog.SINGLETON_INSTANCE.getPnlAddButtons().add(VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4()); this.getCatalogManager().getPnlButtons().add(this.getBtnAdd4());
VCurrentDeck.SINGLETON_INSTANCE.getPnlRemButtons().remove(creditsLabel); this.getDeckManager().getPnlButtons().remove(creditsLabel);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setText(prevRem4Label); this.getBtnRemove4().setText(prevRem4Label);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setToolTipText(prevRem4Tooltip); this.getBtnRemove4().setToolTipText(prevRem4Tooltip);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setCommand(prevRem4Cmd); this.getBtnRemove4().setCommand(prevRem4Cmd);
VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText(CCTabLabel); VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText(CCTabLabel);
VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText(CDTabLabel); VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText(CDTabLabel);
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd().setText(CCAddLabel); this.getBtnAdd().setText(CCAddLabel);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove().setText(CDRemLabel); this.getBtnRemove().setText(CDRemLabel);
VCardCatalog.SINGLETON_INSTANCE.getItemManager().getStatLabel(SItemManagerUtil.StatTypes.PACK).setVisible(false); //TODO: Remove filter for SItemManagerUtil.StatTypes.PACK
//Re-add tabs //Re-add tabs
if (deckGenParent != null) { if (deckGenParent != null) {

View File

@@ -28,8 +28,6 @@ import forge.deck.Deck;
import forge.deck.DeckSection; import forge.deck.DeckSection;
import forge.gui.deckeditor.SEditorIO; import forge.gui.deckeditor.SEditorIO;
import forge.gui.deckeditor.views.VAllDecks; 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.VDeckgen;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.FScreen; import forge.gui.framework.FScreen;
@@ -70,8 +68,8 @@ public final class CEditorVariant extends ACEditorBase<PaperCard, Deck> {
this.cardPoolCondition = poolCondition; this.cardPoolCondition = poolCondition;
this.setCatalogManager(new CardManager(VCardCatalog.SINGLETON_INSTANCE.getStatLabels(), true)); this.setCatalogManager(new CardManager(true));
this.setDeckManager(new CardManager(VCurrentDeck.SINGLETON_INSTANCE.getStatLabels(), true)); this.setDeckManager(new CardManager(true));
final Supplier<Deck> newCreator = new Supplier<Deck>() { final Supplier<Deck> newCreator = new Supplier<Deck>() {
@Override @Override
@@ -158,7 +156,7 @@ public final class CEditorVariant extends ACEditorBase<PaperCard, Deck> {
this.getCatalogManager().getTable().setup(lstCatalogCols); this.getCatalogManager().getTable().setup(lstCatalogCols);
this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns()); this.getDeckManager().getTable().setup(SColumnUtil.getDeckDefaultColumns());
SItemManagerUtil.resetUI(); SItemManagerUtil.resetUI(this);
deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE); deckGenParent = removeTab(VDeckgen.SINGLETON_INSTANCE);
allDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE); allDecksParent = removeTab(VAllDecks.SINGLETON_INSTANCE);

View File

@@ -12,7 +12,6 @@ import forge.deck.DeckBase;
import forge.gui.deckeditor.CDeckEditorUI; import forge.gui.deckeditor.CDeckEditorUI;
import forge.gui.deckeditor.views.VProbabilities; import forge.gui.deckeditor.views.VProbabilities;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.toolbox.FLabel;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.util.ItemPool; import forge.util.ItemPool;
@@ -45,8 +44,12 @@ public enum CProbabilities implements ICDoc {
@Override @Override
@SuppressWarnings("serial") @SuppressWarnings("serial")
public void initialize() { public void initialize() {
((FLabel) VProbabilities.SINGLETON_INSTANCE.getLblReshuffle()).setCommand( VProbabilities.SINGLETON_INSTANCE.getLblReshuffle().setCommand(new Command() {
new Command() { @Override public void run() { update(); } }); @Override
public void run() {
update();
}
});
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -1,38 +1,17 @@
package forge.gui.deckeditor.views; package forge.gui.deckeditor.views;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.tuple.Pair;
import forge.Command;
import forge.card.CardRulesPredicates;
import forge.gui.WrapLayout;
import forge.gui.deckeditor.controllers.CCardCatalog; import forge.gui.deckeditor.controllers.CCardCatalog;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab; import forge.gui.framework.DragTab;
import forge.gui.framework.EDocID; import forge.gui.framework.EDocID;
import forge.gui.framework.IVDoc; import forge.gui.framework.IVDoc;
import forge.gui.toolbox.FComboBoxWrapper;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FSpinner;
import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.ItemManagerContainer; import forge.gui.toolbox.itemmanager.ItemManagerContainer;
import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.util.TextUtil;
/** /**
* Assembles Swing components of card catalog in deck editor. * Assembles Swing components of card catalog in deck editor.
@@ -43,7 +22,7 @@ import forge.util.TextUtil;
public enum VCardCatalog implements IVDoc<CCardCatalog> { public enum VCardCatalog implements IVDoc<CCardCatalog> {
/** */ /** */
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
public static final int SEARCH_MODE_INVERSE_INDEX = 1; public static final int SEARCH_MODE_INVERSE_INDEX = 1;
// Fields used with interface IVDoc // Fields used with interface IVDoc
@@ -54,120 +33,16 @@ public enum VCardCatalog implements IVDoc<CCardCatalog> {
private final JPanel pnlHeader = new JPanel(new MigLayout("insets 0, gap 0, center")); private final JPanel pnlHeader = new JPanel(new MigLayout("insets 0, gap 0, center"));
private final FLabel lblTitle = new FLabel.Builder().fontSize(14).build(); private final FLabel lblTitle = new FLabel.Builder().fontSize(14).build();
// Total and color count labels/filter toggles
private final Dimension labelSize = new Dimension(60, 24);
private final JPanel pnlStats = new JPanel(new WrapLayout(FlowLayout.LEFT));
private final Map<SItemManagerUtil.StatTypes, FLabel> statLabels =
new HashMap<SItemManagerUtil.StatTypes, FLabel>();
// card transfer buttons
private final JPanel pnlAddButtons =
new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3"));
private final FLabel btnAdd = new FLabel.Builder()
.fontSize(14)
.text("Add card")
.tooltip("Add selected card to current deck (or double click the row or hit the spacebar)")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_PLUS))
.iconScaleAuto(false).hoverable().build();
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().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.ButtonBuilder()
.text("Add filter")
.tooltip("Click to add custom filters to the card list")
.reactOnMouseDown().build();
private final FComboBoxWrapper<String> cbSearchMode = new FComboBoxWrapper<String>();
private final JTextField txfSearch = new FTextField.Builder().ghostText("Search").build();
private final FLabel lblName = new FLabel.Builder().text("Name").hoverable().selectable().selected().build();
private final FLabel lblType = new FLabel.Builder().text("Type").hoverable().selectable().selected().build();
private final FLabel lblText = new FLabel.Builder().text("Text").hoverable().selectable().selected().build();
private final JPanel pnlRestrictions = new JPanel(new WrapLayout(FlowLayout.LEFT, 10, 5));
private final ItemManagerContainer itemManagerContainer = new ItemManagerContainer(); private final ItemManagerContainer itemManagerContainer = new ItemManagerContainer();
private ItemManager<? extends InventoryItem> itemManager; private ItemManager<? extends InventoryItem> itemManager;
// 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>>();
//========== Constructor //========== Constructor
/** */ /** */
private VCardCatalog() { private VCardCatalog() {
pnlStats.setOpaque(false);
for (SItemManagerUtil.StatTypes s : SItemManagerUtil.StatTypes.values()) {
FLabel label = buildToggleLabel(s, SItemManagerUtil.StatTypes.TOTAL != s);
statLabels.put(s, label);
JComponent component = label;
if (SItemManagerUtil.StatTypes.TOTAL == s) {
label.setToolTipText("Total cards (click to toggle all filters)");
} else if (SItemManagerUtil.StatTypes.PACK == s) {
// wrap in a constant-size panel so we can change its visibility without affecting layout
component = new JPanel(new MigLayout("insets 0, gap 0"));
component.setPreferredSize(labelSize);
component.setMinimumSize(labelSize);
component.setOpaque(false);
label.setVisible(false);
component.add(label);
}
pnlStats.add(component);
}
pnlAddButtons.setOpaque(false);
pnlAddButtons.add(btnAdd, "w 30%!, h 30px!, gap 10 10 5 5");
pnlAddButtons.add(btnAdd4, "w 30%!, h 30px!, gap 10 10 5 5");
pnlSearch.setOpaque(false);
pnlSearch.add(btnAddRestriction, "center, w pref+8, h pref+8");
pnlSearch.add(txfSearch, "pushx, growx");
cbSearchMode.addItem("in");
cbSearchMode.addItem("not in");
cbSearchMode.addTo(pnlSearch, "center");
pnlSearch.add(lblName, "w pref+8, h pref+8");
pnlSearch.add(lblType, "w pref+8, h pref+8");
pnlSearch.add(lblText, "w pref+8, h pref+8");
pnlRestrictions.setOpaque(false);
pnlHeader.setOpaque(false); pnlHeader.setOpaque(false);
pnlHeader.add(lblTitle, "center, gap 0 0 10 5"); pnlHeader.add(lblTitle, "center, gap 0 0 10 5");
// fill spinner map
for (RangeTypes t : RangeTypes.values()) {
FSpinner lowerBound = new FSpinner.Builder().maxValue(10).build();
FSpinner upperBound = new FSpinner.Builder().maxValue(10).build();
_setupSpinner(lowerBound);
_setupSpinner(upperBound);
spinners.put(t, Pair.of(lowerBound, upperBound));
}
} }
private void _setupSpinner (JSpinner spinner) {
spinner.setFocusable(false); // only the spinner text field should be focusable, not the up/down widget
}
//========== Overridden from IVDoc //========== Overridden from IVDoc
@Override @Override
@@ -198,20 +73,17 @@ public enum VCardCatalog implements IVDoc<CCardCatalog> {
@Override @Override
public void populate() { public void populate() {
JPanel parentBody = parentCell.getBody(); JPanel parentBody = parentCell.getBody();
parentBody.setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3")); parentBody.setLayout(new MigLayout("insets 5, gap 0, wrap, hidemode 3"));
parentBody.add(pnlHeader, "w 98%!, gap 1% 1% 5 0"); parentBody.add(pnlHeader, "pushx, growx");
parentBody.add(pnlStats, "w 100:520:520, center"); parentBody.add(itemManagerContainer, "push, grow");
parentBody.add(pnlAddButtons, "w 96%!, gap 1% 1% 5 5");
parentBody.add(pnlSearch, "w 96%, gap 1% 1%");
parentBody.add(pnlRestrictions, "w 96%, gapleft 1%, gapright push");
parentBody.add(itemManagerContainer, "w 98%!, h 100% - 35, gap 1% 0 0 1%");
} }
public ItemManager<? extends InventoryItem> getItemManager() { public ItemManager<? extends InventoryItem> getItemManager() {
return this.itemManager; return this.itemManager;
} }
public void setItemManager(final ItemManager<? extends InventoryItem> itemManager0) { public void setItemManager(final ItemManager<? extends InventoryItem> itemManager0) {
if (this.itemManager == itemManager0) { return; }
this.itemManager = itemManager0; this.itemManager = itemManager0;
itemManagerContainer.setItemManager(itemManager0); itemManagerContainer.setItemManager(itemManager0);
} }
@@ -219,90 +91,4 @@ public enum VCardCatalog implements IVDoc<CCardCatalog> {
//========== Accessor/mutator methods //========== Accessor/mutator methods
public JPanel getPnlHeader() { return pnlHeader; } public JPanel getPnlHeader() { return pnlHeader; }
public FLabel getLblTitle() { return lblTitle; } 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 FComboBoxWrapper<String> getCbSearchMode() { return cbSearchMode; }
public JTextField getTxfSearch() { return txfSearch; }
public Map<SItemManagerUtil.StatTypes, FLabel> getStatLabels() {
return statLabels;
}
public Map<RangeTypes, Pair<FSpinner, FSpinner>> getSpinners() {
return spinners;
}
//========== Other methods
private FLabel buildToggleLabel(SItemManagerUtil.StatTypes s, boolean selectable) {
String tooltip;
if (selectable) { //construct tooltip for selectable toggle labels, indicating click and right-click behavior
String labelString = s.toLabelString();
tooltip = labelString + " (click to toggle the filter, right-click to show only " + labelString.toLowerCase() + ")";
}
else { tooltip = ""; }
FLabel label = new FLabel.Builder()
.icon(s.img).iconScaleAuto(false)
.fontSize(11)
.tooltip(tooltip)
.hoverable().selectable(selectable).selected(selectable)
.build();
label.setPreferredSize(labelSize);
label.setMinimumSize(labelSize);
return label;
}
@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);
FSkin.get(pnl).setMatteBorder(1, 2, 1, 2, FSkin.getColor(FSkin.Colors.CLR_TEXT));
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 run() {
pnlRestrictions.remove(pnl);
refreshRestrictionWidgets();
onRemove.run();
}
}).build(), "top");
pnlRestrictions.add(pnl, "h 30!");
refreshRestrictionWidgets();
}
public void refreshRestrictionWidgets() {
Container parent = pnlRestrictions.getParent();
pnlRestrictions.validate();
parent.validate();
parent.repaint();
}
public JPanel 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.getLeft(), "w 45!, h 26!, center");
pnl.add(new FLabel.Builder().text("<=").fontSize(11).build(), "h 26!, center");
pnl.add(new FLabel.Builder().text(t.toLabelString()).fontSize(11).build(), "h 26!, center");
pnl.add(new FLabel.Builder().text("<=").fontSize(11).build(), "h 26!, center");
pnl.add(s.getRight(), "w 45!, h 26!, center");
return pnl;
}
public FLabel buildPlainRestrictionWidget(String label, String tooltip) {
return new FLabel.Builder().text(label).tooltip(tooltip).fontSize(11).build();
}
} }

View File

@@ -1,17 +1,8 @@
package forge.gui.deckeditor.views; package forge.gui.deckeditor.views;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import forge.gui.WrapLayout;
import forge.gui.deckeditor.controllers.CCurrentDeck; import forge.gui.deckeditor.controllers.CCurrentDeck;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab; import forge.gui.framework.DragTab;
@@ -22,7 +13,6 @@ import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FTextField; import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.ItemManagerContainer; import forge.gui.toolbox.itemmanager.ItemManagerContainer;
import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.item.InventoryItem; import forge.item.InventoryItem;
@@ -41,7 +31,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
// Other fields // Other fields
private final JLabel btnSave = new FLabel.Builder() private final FLabel btnSave = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("Save (in default directory)") .tooltip("Save (in default directory)")
.iconInBackground(true) .iconInBackground(true)
@@ -49,7 +39,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVE)) .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVE))
.text(" ").hoverable(true).build(); .text(" ").hoverable(true).build();
private final JLabel btnExport = new FLabel.Builder() private final FLabel btnExport = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("Save As") .tooltip("Save As")
.iconInBackground(true) .iconInBackground(true)
@@ -57,7 +47,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVEAS)) .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVEAS))
.text(" ").hoverable(true).build(); .text(" ").hoverable(true).build();
private final JLabel btnLoad = new FLabel.Builder() private final FLabel btnLoad = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("Load") .tooltip("Load")
.iconInBackground(true) .iconInBackground(true)
@@ -65,7 +55,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_OPEN)) .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_OPEN))
.text(" ").hoverable(true).build(); .text(" ").hoverable(true).build();
private final JLabel btnNew = new FLabel.Builder() private final FLabel btnNew = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("New Deck") .tooltip("New Deck")
.iconInBackground(true) .iconInBackground(true)
@@ -73,7 +63,7 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_NEW)) .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_NEW))
.text(" ").hoverable(true).build(); .text(" ").hoverable(true).build();
private final JLabel btnPrintProxies = new FLabel.Builder() private final FLabel btnPrintProxies = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.tooltip("Print to HTML file") .tooltip("Print to HTML file")
.iconInBackground(true) .iconInBackground(true)
@@ -81,30 +71,6 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_PRINT)) .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_PRINT))
.text(" ").hoverable(true).build(); .text(" ").hoverable(true).build();
private final JPanel pnlRemoveButtons =
new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3"));
private final FLabel btnRemove = new FLabel.Builder()
.fontSize(14)
.text("Remove card")
.tooltip("Remove selected card from current deck (or double click the row or hit the spacebar)")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_MINUS))
.iconScaleAuto(false).hoverable().build();
private final FLabel btnRemove4 = new FLabel.Builder()
.fontSize(14)
.text("Remove 4 of card")
.tooltip("Remove up to 4 of selected card to current deck")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_MINUS))
.iconScaleAuto(false).hoverable().build();
private final JLabel btnCycleSection = new FLabel.Builder()
.fontSize(14)
.text("Change Section")
.tooltip("Toggle between editing the deck and the sideboard/planar/scheme/vanguard parts of this deck")
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_EDIT))
.iconScaleAuto(false).hoverable().build();
private final FLabel btnImport = new FLabel.Builder() private final FLabel btnImport = new FLabel.Builder()
.fontSize(14) .fontSize(14)
.text("Import").tooltip("Attempt to import a deck from a non-Forge format") .text("Import").tooltip("Attempt to import a deck from a non-Forge format")
@@ -113,16 +79,9 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
private final FTextField txfTitle = new FTextField.Builder().ghostText("[New Deck]").build(); private final FTextField txfTitle = new FTextField.Builder().ghostText("[New Deck]").build();
private final JPanel pnlRemove = new JPanel();
private final JPanel pnlHeader = new JPanel(); private final JPanel pnlHeader = new JPanel();
private final JLabel lblTitle = new FLabel.Builder().text("Title") private final FLabel lblTitle = new FLabel.Builder().text("Title").fontSize(14).build();
.fontSize(14).build();
// Total and color count labels/filter toggles
private final JPanel pnlStats = new JPanel(new WrapLayout(FlowLayout.LEFT));
private final Map<SItemManagerUtil.StatTypes, FLabel> statLabels =
new HashMap<SItemManagerUtil.StatTypes, FLabel>();
private final ItemManagerContainer itemManagerContainer = new ItemManagerContainer(); private final ItemManagerContainer itemManagerContainer = new ItemManagerContainer();
private ItemManager<? extends InventoryItem> itemManager; private ItemManager<? extends InventoryItem> itemManager;
@@ -132,40 +91,17 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
private VCurrentDeck() { private VCurrentDeck() {
// Header area // Header area
pnlHeader.setOpaque(false); pnlHeader.setOpaque(false);
pnlHeader.setLayout(new MigLayout("insets 0, gap 0, ax center, hidemode 3")); pnlHeader.setLayout(new MigLayout("insets 3, gapx 3, hidemode 3"));
pnlHeader.add(lblTitle, "w 80px!, h 30px!, gap 5px 5px 0 0"); pnlHeader.add(lblTitle, "h 26px!");
pnlHeader.add(txfTitle, "pushx, growx, gap 0 5px 0 0"); pnlHeader.add(txfTitle, "pushx, growx");
pnlHeader.add(btnSave, "w 26px!, h 26px!, gap 0 5px 0 0"); pnlHeader.add(btnSave, "w 26px!, h 26px!");
pnlHeader.add(btnNew, "w 26px!, h 26px!, gap 0 5px 0 0"); pnlHeader.add(btnNew, "w 26px!, h 26px!");
pnlHeader.add(btnLoad, "w 26px!, h 26px!, gap 0 5px 0 0"); pnlHeader.add(btnLoad, "w 26px!, h 26px!");
pnlHeader.add(btnExport, "w 26px!, h 26px!, gap 0 5px 0 0"); pnlHeader.add(btnExport, "w 26px!, h 26px!");
pnlHeader.add(btnPrintProxies, "w 26px!, h 26px!, gap 0 5px 0 0"); pnlHeader.add(btnPrintProxies, "w 26px!, h 26px!");
pnlHeader.add(btnImport, "w 50px!, h 26px!, gap 0 0 20px 0"); pnlHeader.add(btnImport, "w 61px!, h 26px!");
pnlRemove.setOpaque(false);
pnlRemove.setLayout(new MigLayout("insets 0, gap 0, ax center"));
pnlRemove.add(btnRemove, "w 30%!, h 30px!, gap 10 10 5 5");
pnlRemove.add(btnRemove4, "w 30%!, h 30px!, gap 10 10 5 5");
pnlRemove.add(btnCycleSection, "w 30%!, h 30px!, gap 10 10 5 5");
pnlStats.setOpaque(false);
for (SItemManagerUtil.StatTypes s : SItemManagerUtil.StatTypes.values()) {
FLabel label = buildLabel(s);
statLabels.put(s, label);
if (SItemManagerUtil.StatTypes.PACK == s) {
pnlStats.add(buildLabel(null));
} else {
pnlStats.add(label);
}
}
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(btnCycleSection, "w 30%!, h 30px!, gap 0 0 5px 5px");
} }
//========== Overridden from IVDoc //========== Overridden from IVDoc
@@ -216,11 +152,9 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
@Override @Override
public void populate() { public void populate() {
final JPanel parentBody = parentCell.getBody(); final JPanel parentBody = parentCell.getBody();
parentBody.setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3, center")); parentBody.setLayout(new MigLayout("insets 5, gap 0, wrap, hidemode 3"));
parentBody.add(pnlHeader, "w 98%!, gap 1% 1% 5 0"); parentBody.add(pnlHeader, "pushx, growx");
parentBody.add(pnlStats, "w 100:500:500, center"); parentBody.add(itemManagerContainer, "push, grow");
parentBody.add(pnlRemoveButtons, "w 96%!, gap 2% 0 0 0");
parentBody.add(itemManagerContainer, "w 98%!, h 100% - 35, gap 1% 0 0 1%");
} }
public ItemManager<? extends InventoryItem> getItemManager() { public ItemManager<? extends InventoryItem> getItemManager() {
@@ -231,47 +165,33 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
this.itemManager = itemManager0; this.itemManager = itemManager0;
itemManagerContainer.setItemManager(itemManager0); itemManagerContainer.setItemManager(itemManager0);
} }
public Map<SItemManagerUtil.StatTypes, FLabel> getStatLabels() {
return statLabels;
}
public JLabel getLblTitle() { return lblTitle; } public FLabel getLblTitle() { return lblTitle; }
//========== Retrieval //========== Retrieval
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public FLabel getBtnRemove() { public FLabel getBtnSave() {
return btnRemove;
}
/** @return {@link javax.swing.JLabel} */
public FLabel getBtnRemove4() {
return btnRemove4;
}
/** @return {@link javax.swing.JLabel} */
public JLabel getBtnSave() {
return btnSave; return btnSave;
} }
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public JLabel getBtnSaveAs() { public FLabel getBtnSaveAs() {
return btnExport; return btnExport;
} }
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public JLabel getBtnPrintProxies() { public FLabel getBtnPrintProxies() {
return btnPrintProxies; return btnPrintProxies;
} }
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public JLabel getBtnOpen() { public FLabel getBtnOpen() {
return btnLoad; return btnLoad;
} }
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public JLabel getBtnNew() { public FLabel getBtnNew() {
return btnNew; return btnNew;
} }
@@ -285,55 +205,6 @@ public enum VCurrentDeck implements IVDoc<CCurrentDeck> {
return pnlHeader; return pnlHeader;
} }
/** @return {@link javax.swing.JPanel} */
public void setStatsVisible(boolean val) {
pnlStats.setVisible(val);
// TODO: invisibly ensure the cell is not too large on first show
// if the program is started with pnlStats invisible, the first time it
// is made visible, the scroller cell that surrounds the panel will
// be too large. it will jump back to the correct size after any resize
// event, or if it is hidden and made visible again. For the life of
// me, I cannot figure out how to "kick" it into the correct size from
// here without the following hack, which will cause a visible jitter
// when the panel is shown for the first time (subsequent hides and shows
// will not cause any jitter), but at least it will be the correct size:
if (val) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
pnlStats.setVisible(false);
pnlStats.setVisible(true);
}
});
}
}
/** @return {@link javax.swing.JPanel} */
public JPanel getPnlRemButtons() {
return pnlRemoveButtons;
}
/** @return {@link javax.swing.JPanel} */
public JLabel getBtnDoSideboard() {
return btnCycleSection;
}
//========== Other methods
private FLabel buildLabel(SItemManagerUtil.StatTypes s) {
FLabel label = new FLabel.Builder()
.icon(s == null ? null : s.img).iconScaleAuto(false)
.fontSize(11).tooltip(s == null ? null : s.toLabelString())
.build();
Dimension labelSize = new Dimension(57, 20);
label.setPreferredSize(labelSize);
label.setMinimumSize(labelSize);
return label;
}
/** /**
* TODO: Write javadoc for this method. * TODO: Write javadoc for this method.
* @return * @return

View File

@@ -1,7 +1,5 @@
package forge.gui.deckeditor.views; package forge.gui.deckeditor.views;
import javax.swing.JLabel;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import forge.gui.deckeditor.controllers.CDeckgen; import forge.gui.deckeditor.controllers.CDeckgen;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
@@ -24,22 +22,22 @@ public enum VDeckgen implements IVDoc<CDeckgen> {
private final DragTab tab = new DragTab("Deck Generation"); private final DragTab tab = new DragTab("Deck Generation");
// Deckgen buttons // Deckgen buttons
private final JLabel btnRandCardpool = new FLabel.Builder() private final FLabel btnRandCardpool = new FLabel.Builder()
.tooltip("Generate random constructed cardpool in current deck area") .tooltip("Generate random constructed cardpool in current deck area")
.text("Random Cardpool").fontSize(14) .text("Random Cardpool").fontSize(14)
.opaque(true).hoverable(true).build(); .opaque(true).hoverable(true).build();
private final JLabel btnRandDeck2 = new FLabel.Builder() private final FLabel btnRandDeck2 = new FLabel.Builder()
.tooltip("Generate 2 color constructed deck in current deck area") .tooltip("Generate 2 color constructed deck in current deck area")
.text("Constructed (2 color)").fontSize(14) .text("Constructed (2 color)").fontSize(14)
.opaque(true).hoverable(true).build(); .opaque(true).hoverable(true).build();
private final JLabel btnRandDeck3 = new FLabel.Builder() private final FLabel btnRandDeck3 = new FLabel.Builder()
.tooltip("Generate 3 color constructed deck in current deck area") .tooltip("Generate 3 color constructed deck in current deck area")
.text("Constructed (3 color)").fontSize(14) .text("Constructed (3 color)").fontSize(14)
.opaque(true).hoverable(true).build(); .opaque(true).hoverable(true).build();
private final JLabel btnRandDeck5 = new FLabel.Builder() private final FLabel btnRandDeck5 = new FLabel.Builder()
.tooltip("Generate 5 color constructed deck in current deck area") .tooltip("Generate 5 color constructed deck in current deck area")
.text("Constructed (5 color)").fontSize(14) .text("Constructed (5 color)").fontSize(14)
.opaque(true).hoverable(true).build(); .opaque(true).hoverable(true).build();
@@ -106,22 +104,22 @@ public enum VDeckgen implements IVDoc<CDeckgen> {
//========== Retrieval methods //========== Retrieval methods
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public JLabel getBtnRandCardpool() { public FLabel getBtnRandCardpool() {
return btnRandCardpool; return btnRandCardpool;
} }
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public JLabel getBtnRandDeck2() { public FLabel getBtnRandDeck2() {
return btnRandDeck2; return btnRandDeck2;
} }
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public JLabel getBtnRandDeck3() { public FLabel getBtnRandDeck3() {
return btnRandDeck3; return btnRandDeck3;
} }
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public JLabel getBtnRandDeck5() { public FLabel getBtnRandDeck5() {
return btnRandDeck5; return btnRandDeck5;
} }
} }

View File

@@ -62,7 +62,6 @@ public enum VEditorPreferences implements IVDoc<CEditorPreferences> {
private JCheckBox chbDeckPower = new FCheckBox("Power"); private JCheckBox chbDeckPower = new FCheckBox("Power");
private JCheckBox chbDeckToughness = new FCheckBox("Toughness"); private JCheckBox chbDeckToughness = new FCheckBox("Toughness");
private JCheckBox chbDeckStats = new FCheckBox("Show stats in current deck");
private JCheckBox chbElasticColumns = new FCheckBox("Use elastic resizing when changing column widths"); private JCheckBox chbElasticColumns = new FCheckBox("Use elastic resizing when changing column widths");
private JCheckBox chbCardDisplayUnique = new FCheckBox("Show unique cards only (only affects Constructed)"); private JCheckBox chbCardDisplayUnique = new FCheckBox("Show unique cards only (only affects Constructed)");
@@ -98,16 +97,13 @@ public enum VEditorPreferences implements IVDoc<CEditorPreferences> {
FSkin.get(chbDeckPower).setFont(font); FSkin.get(chbDeckPower).setFont(font);
FSkin.get(chbDeckToughness).setFont(font); FSkin.get(chbDeckToughness).setFont(font);
FSkin.get(chbDeckStats).setFont(font);
FSkin.get(chbElasticColumns).setFont(font); FSkin.get(chbElasticColumns).setFont(font);
chbDeckStats.setSelected(true);
chbElasticColumns.setSelected(false); chbElasticColumns.setSelected(false);
FSkin.get(chbCardDisplayUnique).setFont(font); FSkin.get(chbCardDisplayUnique).setFont(font);
chbCardDisplayUnique.setSelected(false); chbCardDisplayUnique.setSelected(false);
pnl.add(lblStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1"); pnl.add(lblStats, "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"); pnl.add(chbElasticColumns, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1");
final String constraints = "w 75px, h 25px!, gap 5px 5px 5px 5px, ax center"; final String constraints = "w 75px, h 25px!, gap 5px 5px 5px 5px, ax center";
@@ -279,11 +275,6 @@ public enum VEditorPreferences implements IVDoc<CEditorPreferences> {
return chbDeckToughness; return chbDeckToughness;
} }
/** @return {@link javax.swing.JCheckBox} */
public JCheckBox getChbDeckStats() {
return chbDeckStats;
}
/** @return {@link javax.swing.JCheckBox} */ /** @return {@link javax.swing.JCheckBox} */
public JCheckBox getChbElasticColumns() { public JCheckBox getChbElasticColumns() {
return chbElasticColumns; return chbElasticColumns;

View File

@@ -37,12 +37,12 @@ public enum VProbabilities implements IVDoc<CProbabilities> {
private final DragTab tab = new DragTab("Draw Order"); private final DragTab tab = new DragTab("Draw Order");
// Title labels // Title labels
private final JLabel lblReshuffle = new FLabel.Builder() private final FLabel lblReshuffle = new FLabel.Builder()
.hoverable(true).text("CLICK HERE TO RE-SHUFFLE").tooltip("See a new sample shuffle") .hoverable(true).text("CLICK HERE TO RE-SHUFFLE").tooltip("See a new sample shuffle")
.fontSize(16).build(); .fontSize(16).build();
private final JLabel lblSampleHand = new FLabel.Builder().fontStyle(Font.BOLD) private final FLabel lblSampleHand = new FLabel.Builder().fontStyle(Font.BOLD)
.fontSize(12).text("SAMPLE HAND").opaque(true).build(); .fontSize(12).text("SAMPLE HAND").opaque(true).build();
private final JLabel lblRemainingDraws = new FLabel.Builder().fontStyle(Font.BOLD) private final FLabel lblRemainingDraws = new FLabel.Builder().fontStyle(Font.BOLD)
.fontSize(12).text("REMAINING DRAWS").opaque(true).build(); .fontSize(12).text("REMAINING DRAWS").opaque(true).build();
// private final JLabel lblExplanation = new FLabel.Builder() // private final JLabel lblExplanation = new FLabel.Builder()
// .fontSize(11).text("XX % = frequency that card will appear at that position").build(); // .fontSize(11).text("XX % = frequency that card will appear at that position").build();
@@ -64,7 +64,7 @@ public enum VProbabilities implements IVDoc<CProbabilities> {
scroller.getViewport().setBorder(null); scroller.getViewport().setBorder(null);
scroller.getVerticalScrollBar().setUnitIncrement(16); scroller.getVerticalScrollBar().setUnitIncrement(16);
FSkin.JLabelSkin<JLabel> labelSkin = FSkin.get(lblSampleHand); FSkin.JLabelSkin<FLabel> labelSkin = FSkin.get(lblSampleHand);
labelSkin.setMatteBorder(1, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS)); labelSkin.setMatteBorder(1, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS));
labelSkin.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); labelSkin.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
@@ -134,7 +134,7 @@ public enum VProbabilities implements IVDoc<CProbabilities> {
//========== Retrieval methods //========== Retrieval methods
/** @return {@link javax.swing.JLabel} */ /** @return {@link javax.swing.JLabel} */
public JLabel getLblReshuffle() { public FLabel getLblReshuffle() {
return lblReshuffle; return lblReshuffle;
} }

View File

@@ -25,7 +25,6 @@ import forge.gui.toolbox.FSkin.SkinFont;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class FComboBox<E> extends JComboBox<E> { public class FComboBox<E> extends JComboBox<E> {
public enum TextAlignment { public enum TextAlignment {
LEFT (SwingConstants.LEFT), LEFT (SwingConstants.LEFT),
RIGHT (SwingConstants.RIGHT), RIGHT (SwingConstants.RIGHT),
@@ -102,7 +101,6 @@ public class FComboBox<E> extends JComboBox<E> {
} }
private class FComboBoxUI extends BasicComboBoxUI { private class FComboBoxUI extends BasicComboBoxUI {
@Override @Override
protected LayoutManager createLayoutManager() { protected LayoutManager createLayoutManager() {
return super.createLayoutManager(); return super.createLayoutManager();
@@ -134,7 +132,6 @@ public class FComboBox<E> extends JComboBox<E> {
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
private class CustomCellRenderer<E> implements ListCellRenderer<E> { private class CustomCellRenderer<E> implements ListCellRenderer<E> {
private DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer(); private DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
@Override @Override

View File

@@ -8,6 +8,7 @@ import java.util.ArrayList;
import java.util.Vector; import java.util.Vector;
import javax.swing.ComboBoxModel; import javax.swing.ComboBoxModel;
import javax.swing.JComponent;
import javax.swing.ListCellRenderer; import javax.swing.ListCellRenderer;
import forge.gui.toolbox.FComboBox.TextAlignment; import forge.gui.toolbox.FComboBox.TextAlignment;
@@ -136,6 +137,10 @@ public class FComboBoxWrapper<E> {
container.add(this.comboBox, constraints0); container.add(this.comboBox, constraints0);
this.constraints = constraints0; this.constraints = constraints0;
} }
public JComponent getComponent() { //disguise as component for sake of rare places that need to access component in wrapper
return this.comboBox;
}
private void refreshSkin() { private void refreshSkin() {
this.comboBox = refreshComboBoxSkin(this.comboBox, this.constraints); this.comboBox = refreshComboBoxSkin(this.comboBox, this.constraints);

View File

@@ -360,10 +360,21 @@ public class FLabel extends JLabel implements ILocalRepaint {
}; };
//========== Methods //========== Methods
/** @param b0 &emsp; boolean */
// Must be public.
@Override
public void setEnabled(final boolean b0) {
super.setEnabled(b0);
if (!this.hoverable) { return; }
if (!b0) { this.removeMouseListener(madEvents); }
else { this.addMouseListener(madEvents); }
}
/** @param b0 &emsp; boolean */ /** @param b0 &emsp; boolean */
// Must be public. // Must be public.
public void setHoverable(final boolean b0) { public void setHoverable(final boolean b0) {
this.hoverable = b0; this.hoverable = b0;
if (!this.isEnabled()) { return; }
if (!b0) { this.removeMouseListener(madEvents); } if (!b0) { this.removeMouseListener(madEvents); }
else { this.addMouseListener(madEvents); } else { this.addMouseListener(madEvents); }
} }
@@ -387,7 +398,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
this.alphaStrong = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f); this.alphaStrong = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
} }
private void setFontSize(final int i0) { public void setFontSize(final int i0) {
switch(this.fontStyle) { switch(this.fontStyle) {
case Font.BOLD: skin.setFont(FSkin.getBoldFont(i0)); break; case Font.BOLD: skin.setFont(FSkin.getBoldFont(i0)); break;
case Font.ITALIC: skin.setFont(FSkin.getItalicFont(i0)); break; case Font.ITALIC: skin.setFont(FSkin.getItalicFont(i0)); break;
@@ -397,7 +408,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
/** @param i0 &emsp; Font.PLAIN, .BOLD, or .ITALIC */ /** @param i0 &emsp; Font.PLAIN, .BOLD, or .ITALIC */
// NOT public; must be set when label is built. // NOT public; must be set when label is built.
private void setFontStyle(final int i0) { public void setFontStyle(final int i0) {
if (i0 != Font.PLAIN && i0 != Font.BOLD && i0 != Font.ITALIC) { if (i0 != Font.PLAIN && i0 != Font.BOLD && i0 != Font.ITALIC) {
throw new IllegalArgumentException("FLabel$setFontStyle " throw new IllegalArgumentException("FLabel$setFontStyle "
+ "must be passed either Font.PLAIN, Font.BOLD, or Font.ITALIC."); + "must be passed either Font.PLAIN, Font.BOLD, or Font.ITALIC.");
@@ -407,7 +418,7 @@ public class FLabel extends JLabel implements ILocalRepaint {
/** @param i0 &emsp; SwingConstants.CENTER, .LEFT or .RIGHT */ /** @param i0 &emsp; SwingConstants.CENTER, .LEFT or .RIGHT */
// NOT public; must be set when label is built. // NOT public; must be set when label is built.
private void setFontAlign(final int i0) { public void setFontAlign(final int i0) {
if (i0 != SwingConstants.CENTER && i0 != SwingConstants.LEFT && i0 != SwingConstants.RIGHT) { if (i0 != SwingConstants.CENTER && i0 != SwingConstants.LEFT && i0 != SwingConstants.RIGHT) {
throw new IllegalArgumentException("FLabel$setFontStyle " throw new IllegalArgumentException("FLabel$setFontStyle "
+ "must be passed either SwingConstants.CENTER, " + "must be passed either SwingConstants.CENTER, "
@@ -513,10 +524,12 @@ public class FLabel extends JLabel implements ILocalRepaint {
else if (opaque) { else if (opaque) {
if (selected) { if (selected) {
paintDown(g2d, w, h); paintDown(g2d, w, h);
} else { }
else {
paintUp(g2d, w, h); paintUp(g2d, w, h);
} }
} else if (selectable) { }
else if (selectable) {
if (selected) { if (selected) {
paintDown(g2d, w, h); paintDown(g2d, w, h);
} else { } else {

View File

@@ -1644,6 +1644,10 @@ public enum FSkin {
return this.font.getSize(); return this.font.getSize();
} }
public int measureTextWidth(Graphics g, String text) {
return g.getFontMetrics(this.font).stringWidth(text);
}
private void updateFont() { private void updateFont() {
this.font = baseFont.deriveFont(this.style, this.size); this.font = baseFont.deriveFont(this.style, this.size);
} }

View File

@@ -1,5 +1,6 @@
package forge.gui.toolbox; package forge.gui.toolbox;
import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
@@ -9,6 +10,8 @@ import java.awt.event.FocusEvent;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AttributeSet; import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument; import javax.swing.text.PlainDocument;
@@ -47,7 +50,7 @@ public class FTextField extends JTextField {
public Builder showGhostTextWithFocus(boolean b0) { showGhostTextWithFocus = b0; return this; } public Builder showGhostTextWithFocus(boolean b0) { showGhostTextWithFocus = b0; return this; }
public Builder showGhostTextWithFocus() { return showGhostTextWithFocus(true); } public Builder showGhostTextWithFocus() { return showGhostTextWithFocus(true); }
} }
public static final int HEIGHT = 25; //TODO: calculate this somehow instead of hard-coding it public static final int HEIGHT = 25; //TODO: calculate this somehow instead of hard-coding it
private final FSkin.JTextComponentSkin<FTextField> skin; private final FSkin.JTextComponentSkin<FTextField> skin;
@@ -61,11 +64,11 @@ public class FTextField extends JTextField {
skin.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT)); skin.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT));
this.setMargin(new Insets(3, 3, 2, 3)); this.setMargin(new Insets(3, 3, 2, 3));
this.setOpaque(true); this.setOpaque(true);
if (builder.maxLength > 0) { if (builder.maxLength > 0) {
this.setDocument(new _LengthLimitedDocument(builder.maxLength)); this.setDocument(new _LengthLimitedDocument(builder.maxLength));
} }
this.setEditable(!builder.readonly); this.setEditable(!builder.readonly);
this.setText(builder.text); this.setText(builder.text);
this.setToolTipText(builder.toolTip); this.setToolTipText(builder.toolTip);
@@ -102,13 +105,17 @@ public class FTextField extends JTextField {
this.ghostText = builder.ghostText; this.ghostText = builder.ghostText;
if (this.ghostText == "") { this.ghostText = null; } //don't allow empty string to make other logic easier if (this.ghostText == "") { this.ghostText = null; } //don't allow empty string to make other logic easier
} }
public boolean isEmpty() public boolean isEmpty() {
{
String text = this.getText(); String text = this.getText();
return (text == null || text.isEmpty()); return (text == null || text.isEmpty());
} }
public int getAutoSizeWidth() {
FontMetrics metrics = getGraphics().getFontMetrics(this.getFont());
return metrics.stringWidth(this.getText()) + 12;
}
@Override @Override
public void paint(Graphics g) { public void paint(Graphics g) {
super.paint(g); super.paint(g);
@@ -123,14 +130,12 @@ public class FTextField extends JTextField {
g2d.dispose(); g2d.dispose();
} }
} }
public String getGhostText() public String getGhostText() {
{
return this.ghostText; return this.ghostText;
} }
public void setGhostText(String ghostText0) public void setGhostText(String ghostText0) {
{
if (ghostText0 == "") { ghostText0 = null; } //don't allow empty string to make other logic easier if (ghostText0 == "") { ghostText0 = null; } //don't allow empty string to make other logic easier
if (this.ghostText == ghostText0) { return; } if (this.ghostText == ghostText0) { return; }
this.ghostText = ghostText0; this.ghostText = ghostText0;
@@ -138,14 +143,12 @@ public class FTextField extends JTextField {
this.repaint(); this.repaint();
} }
} }
public boolean getShowGhostTextWithFocus() public boolean getShowGhostTextWithFocus() {
{
return this.showGhostTextWithFocus; return this.showGhostTextWithFocus;
} }
public void setShowGhostTextWithFocus(boolean showGhostTextWithFocus0) public void setShowGhostTextWithFocus(boolean showGhostTextWithFocus0) {
{
if (this.showGhostTextWithFocus == showGhostTextWithFocus0) { return; } if (this.showGhostTextWithFocus == showGhostTextWithFocus0) { return; }
this.showGhostTextWithFocus = showGhostTextWithFocus0; this.showGhostTextWithFocus = showGhostTextWithFocus0;
if (this.isEmpty() && this.hasFocus()) { if (this.isEmpty() && this.hasFocus()) {
@@ -155,7 +158,7 @@ public class FTextField extends JTextField {
private static class _LengthLimitedDocument extends PlainDocument { private static class _LengthLimitedDocument extends PlainDocument {
private final int _limit; private final int _limit;
_LengthLimitedDocument(int limit) { _limit = limit; } _LengthLimitedDocument(int limit) { _limit = limit; }
// called each time a character is typed or a string is pasted // called each time a character is typed or a string is pasted
@@ -172,4 +175,27 @@ public class FTextField extends JTextField {
super.insertString(offset, s, attributeSet); super.insertString(offset, s, attributeSet);
} }
} }
public void addChangeListener(ChangeListener listener) {
this.getDocument().addDocumentListener(listener);
}
public static abstract class ChangeListener implements DocumentListener {
@Override
public void changedUpdate(DocumentEvent e) {
textChanged();
}
@Override
public void removeUpdate(DocumentEvent e) {
textChanged();
}
@Override
public void insertUpdate(DocumentEvent e) {
textChanged();
}
public abstract void textChanged();
}
} }

View File

@@ -9,7 +9,7 @@ import javax.swing.JComponent;
public final class LayoutHelper { public final class LayoutHelper {
private final int parentWidth, parentHeight; private final int parentWidth, parentHeight;
private int x, y, lineBottom; private int x, y, lineBottom;
public LayoutHelper(JComponent parent) { public LayoutHelper(JComponent parent) {
parentWidth = parent.getWidth(); parentWidth = parent.getWidth();
parentHeight = parent.getHeight(); parentHeight = parent.getHeight();
@@ -30,12 +30,22 @@ public final class LayoutHelper {
* @param height * @param height
*/ */
public void fillLine(final JComponent comp, int height) { public void fillLine(final JComponent comp, int height) {
fillLine(comp, height, 0);
}
/**
* Layout component to fill remaining horizontal space of current line
* @param comp
* @param height
* @param rightPadding
*/
public void fillLine(final JComponent comp, int height, int rightPadding) {
if (x >= parentWidth) { if (x >= parentWidth) {
newLine(); newLine();
} }
include(comp, parentWidth - x, height); include(comp, parentWidth - x - rightPadding, height);
} }
/** /**
* Include component in layout with a percentage width and fixed height * Include component in layout with a percentage width and fixed height
* @param comp * @param comp
@@ -101,7 +111,7 @@ public final class LayoutHelper {
x += dx; x += dx;
y += dy; y += dy;
} }
/** /**
* Start new line of layout * Start new line of layout
*/ */
@@ -111,4 +121,27 @@ public final class LayoutHelper {
y = lineBottom + 3; y = lineBottom + 3;
lineBottom = y; lineBottom = y;
} }
/**
* Start new line of layout
*/
public void newLine(int dy) {
x = 0;
y = lineBottom + 3 + dy;
lineBottom = y;
}
/**
* @return width of parent
*/
public int getParentWidth() {
return parentWidth;
}
/**
* @return width of parent
*/
public int getParentHeight() {
return parentHeight;
}
} }

View File

@@ -1,16 +1,12 @@
package forge.gui.toolbox.itemmanager; package forge.gui.toolbox.itemmanager;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.swing.JMenu; import javax.swing.JMenu;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import forge.Singletons; import forge.Singletons;
import forge.game.GameFormat; import forge.game.GameFormat;
import forge.gui.GuiUtils; import forge.gui.GuiUtils;
import forge.gui.home.quest.DialogChooseSets; import forge.gui.home.quest.DialogChooseSets;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes;
import forge.gui.toolbox.itemmanager.filters.CardCMCFilter; import forge.gui.toolbox.itemmanager.filters.CardCMCFilter;
import forge.gui.toolbox.itemmanager.filters.CardColorFilter; import forge.gui.toolbox.itemmanager.filters.CardColorFilter;
import forge.gui.toolbox.itemmanager.filters.CardFormatFilter; import forge.gui.toolbox.itemmanager.filters.CardFormatFilter;
@@ -30,17 +26,19 @@ import forge.quest.QuestWorld;
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public final class CardManager extends ItemManager<PaperCard> { public final class CardManager extends ItemManager<PaperCard> {
public CardManager(boolean wantUnique0) {
super(PaperCard.class, wantUnique0);
public CardManager(Map<StatTypes, FLabel> statLabels0, boolean wantUnique0) { this.lockFiltering = true; //temporary lock filtering for improved performance
super(PaperCard.class, statLabels0, wantUnique0);
this.addFilter(new CardColorFilter(this)); this.addFilter(new CardColorFilter(this));
this.addFilter(new CardTypeFilter(this)); this.addFilter(new CardTypeFilter(this));
this.lockFiltering = false;
buildFilterPredicate();
} }
@Override @Override
protected ItemFilter<PaperCard> createSearchFilter(String text) { protected ItemFilter<PaperCard> createSearchFilter() {
return new CardSearchFilter(this, text); return new CardSearchFilter(this);
} }
@Override @Override
@@ -70,7 +68,7 @@ public final class CardManager extends ItemManager<PaperCard> {
public void run() { public void run() {
List<String> sets = dialog.getSelectedSets(); List<String> sets = dialog.getSelectedSets();
if (!sets.isEmpty()) { if (!sets.isEmpty()) {
addFilter(new CardSetFilter(CardManager.this, sets)); addFilter(new CardSetFilter(CardManager.this, sets, dialog.getWantReprints()));
} }
} }
}); });

View File

@@ -1,11 +1,7 @@
package forge.gui.toolbox.itemmanager; package forge.gui.toolbox.itemmanager;
import java.util.Map;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes;
import forge.gui.toolbox.itemmanager.filters.ItemFilter; import forge.gui.toolbox.itemmanager.filters.ItemFilter;
import forge.item.InventoryItem; import forge.item.InventoryItem;
@@ -15,13 +11,12 @@ import forge.item.InventoryItem;
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public final class InventoryItemManager extends ItemManager<InventoryItem> { public final class InventoryItemManager extends ItemManager<InventoryItem> {
public InventoryItemManager(boolean wantUnique0) {
public InventoryItemManager(Map<StatTypes, FLabel> statLabels0, boolean wantUnique0) { super(InventoryItem.class, wantUnique0);
super(InventoryItem.class, statLabels0, wantUnique0);
} }
@Override @Override
protected ItemFilter<InventoryItem> createSearchFilter(String text) { protected ItemFilter<InventoryItem> createSearchFilter() {
return null; return null;
} }

View File

@@ -18,6 +18,9 @@
package forge.gui.toolbox.itemmanager; package forge.gui.toolbox.itemmanager;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -25,26 +28,30 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import javax.swing.JCheckBox;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import net.miginfocom.swing.MigLayout;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import forge.Command; import forge.Command;
import forge.gui.GuiUtils; import forge.gui.GuiUtils;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FTextField; import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.LayoutHelper; import forge.gui.toolbox.LayoutHelper;
import forge.gui.toolbox.ToolTipListener; import forge.gui.toolbox.ToolTipListener;
import forge.gui.toolbox.FSkin.Colors;
import forge.gui.toolbox.itemmanager.filters.ItemFilter; import forge.gui.toolbox.itemmanager.filters.ItemFilter;
import forge.gui.toolbox.itemmanager.table.ItemTable; import forge.gui.toolbox.itemmanager.table.ItemTable;
import forge.gui.toolbox.itemmanager.table.ItemTableModel; import forge.gui.toolbox.itemmanager.table.ItemTableModel;
@@ -73,16 +80,33 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
private boolean alwaysNonUnique = false; private boolean alwaysNonUnique = false;
private boolean allowMultipleSelections = false; private boolean allowMultipleSelections = false;
private final Class<T> genericType; private final Class<T> genericType;
private final Map<SItemManagerUtil.StatTypes, FLabel> statLabels;
private final ArrayList<ListSelectionListener> selectionListeners = new ArrayList<ListSelectionListener>(); private final ArrayList<ListSelectionListener> selectionListeners = new ArrayList<ListSelectionListener>();
private final FLabel btnAddFilter = new FLabel.ButtonBuilder() private final JCheckBox chkEnableFilters = new JCheckBox();
.text("Add")
.tooltip("Click to add filters to the list") private final FTextField txtFilterLogic = new FTextField.Builder()
.reactOnMouseDown().build(); .tooltip("Use '&','|','!' symbols (AND,OR,NOT) in combination with filter numbers and optional grouping \"()\" to build Boolean expression evaluated when applying filters")
private final FTextField txtSearch = new FTextField.Builder().ghostText("Search").build(); .readonly() //TODO: Support editing filter logic
.build();
private ItemFilter<T> mainSearchFilter;
private final JPanel pnlButtons = new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3"));
private final FLabel btnFilters = new FLabel.ButtonBuilder()
.text("Filters")
.tooltip("Click to configure filters")
.reactOnMouseDown()
.build();
private final FLabel lblRatio = new FLabel.Builder()
.tooltip("Number of cards shown / Total available cards")
.fontAlign(SwingConstants.LEFT)
.fontSize(11)
.build();
private final ItemTable<T> table; private final ItemTable<T> table;
private final JScrollPane tableScroller; private final JScrollPane tableScroller;
protected boolean lockFiltering;
/** /**
* ItemManager Constructor. * ItemManager Constructor.
@@ -91,9 +115,8 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
* @param statLabels0 stat labels for this item manager * @param statLabels0 stat labels for this item manager
* @param wantUnique0 whether this table should display only one item with the same name * @param wantUnique0 whether this table should display only one item with the same name
*/ */
protected ItemManager(final Class<T> genericType0, Map<SItemManagerUtil.StatTypes, FLabel> statLabels0, final boolean wantUnique0) { protected ItemManager(final Class<T> genericType0, final boolean wantUnique0) {
this.genericType = genericType0; this.genericType = genericType0;
this.statLabels = statLabels0;
this.wantUnique = wantUnique0; this.wantUnique = wantUnique0;
this.model = new ItemManagerModel<T>(this, genericType0); this.model = new ItemManagerModel<T>(this, genericType0);
@@ -107,13 +130,65 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
this.tableScroller.getViewport().setBorder(null); this.tableScroller.getViewport().setBorder(null);
this.tableScroller.getVerticalScrollBar().addAdjustmentListener(new ToolTipListener()); this.tableScroller.getVerticalScrollBar().addAdjustmentListener(new ToolTipListener());
//build enable filters checkbox
ItemFilter.layoutCheckbox(this.chkEnableFilters);
this.chkEnableFilters.setText("(*)");
this.chkEnableFilters.setSelected(true);
this.chkEnableFilters.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
lockFiltering = true;
boolean enabled = chkEnableFilters.isSelected();
for (ItemFilter<T> filter : orderedFilters) {
filter.setEnabled(enabled);
}
txtFilterLogic.setEnabled(enabled);
btnFilters.setEnabled(enabled);
mainSearchFilter.setEnabled(enabled);
mainSearchFilter.updateEnabled(); //need to call updateEnabled since no listener for filter checkbox
lockFiltering = false;
buildFilterPredicate();
}
});
//build display //build display
this.setOpaque(false); this.setOpaque(false);
this.setLayout(null); this.setLayout(null);
this.add(this.btnAddFilter); this.add(this.chkEnableFilters);
this.add(this.txtSearch); this.add(this.txtFilterLogic);
this.mainSearchFilter = createSearchFilter();
this.add(mainSearchFilter.getWidget());
this.pnlButtons.setOpaque(false);
FSkin.get(this.pnlButtons).setMatteBorder(1, 0, 1, 0, FSkin.getColor(Colors.CLR_TEXT));
this.add(this.pnlButtons);
this.add(this.btnFilters);
this.add(this.lblRatio);
this.add(this.tableScroller); this.add(this.tableScroller);
final Runnable cmdAddCurrentSearch = new Runnable() {
@Override
public void run() {
ItemFilter<T> searchFilter = mainSearchFilter.createCopy();
if (searchFilter != null) {
lockFiltering = true; //prevent updating filtering from this change
addFilter(searchFilter);
mainSearchFilter.reset();
lockFiltering = false;
}
}
};
this.mainSearchFilter.getMainComponent().addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
if (e.isControlDown() || e.isMetaDown()) {
cmdAddCurrentSearch.run();
}
}
}
});
//setup command for btnAddFilter //setup command for btnAddFilter
final Command addFilterCommand = new Command() { final Command addFilterCommand = new Command() {
@Override @Override
@@ -121,34 +196,35 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
JPopupMenu menu = new JPopupMenu("FilterMenu"); JPopupMenu menu = new JPopupMenu("FilterMenu");
GuiUtils.addMenuItem(menu, "Current text search", GuiUtils.addMenuItem(menu, "Current text search",
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
new Runnable() { cmdAddCurrentSearch, !mainSearchFilter.isEmpty());
@Override
public void run() {
ItemFilter<T> searchFilter = createSearchFilter(txtSearch.getText());
if (searchFilter != null) {
addFilter(searchFilter);
}
}
}, !txtSearch.isEmpty());
buildFilterMenu(menu); buildFilterMenu(menu);
menu.show(btnAddFilter, 0, btnAddFilter.getHeight()); menu.show(btnFilters, 0, btnFilters.getHeight());
} }
}; };
this.btnAddFilter.setCommand(addFilterCommand); this.btnFilters.setCommand(addFilterCommand);
this.btnAddFilter.setRightClickCommand(addFilterCommand); //show menu on right-click too this.btnFilters.setRightClickCommand(addFilterCommand); //show menu on right-click too
} }
@Override @Override
public void doLayout() { public void doLayout() {
//int number = 0; int number = 0;
StringBuilder logicBuilder = new StringBuilder();
LayoutHelper helper = new LayoutHelper(this); LayoutHelper helper = new LayoutHelper(this);
/*for (ItemFilter<T> filter : this.orderedFilters) { for (ItemFilter<T> filter : this.orderedFilters) {
filter.updatePanelTitle(++number); filter.setNumber(++number);
logicBuilder.append(number + "&");
helper.fillLine(filter.getPanel(), ItemFilter.PANEL_HEIGHT); helper.fillLine(filter.getPanel(), ItemFilter.PANEL_HEIGHT);
} }
this.txtFilterLogic.setText(logicBuilder.toString());
helper.newLine(); helper.newLine();
helper.include(this.btnAddFilter, 30, FTextField.HEIGHT); helper.include(this.chkEnableFilters, 41, FTextField.HEIGHT);
helper.include(this.txtSearch, 0.5f, FTextField.HEIGHT);*/ helper.offset(-1, 0); //ensure widgets line up
helper.include(this.txtFilterLogic, this.txtFilterLogic.getAutoSizeWidth(), FTextField.HEIGHT);
helper.fillLine(this.mainSearchFilter.getWidget(), ItemFilter.PANEL_HEIGHT);
helper.newLine(-3);
helper.fillLine(this.pnlButtons, this.pnlButtons.getComponentCount() > 0 ? 32: 1); //just show border if no bottoms
helper.include(this.btnFilters, 61, FTextField.HEIGHT);
helper.fillLine(this.lblRatio, FTextField.HEIGHT);
helper.fill(this.tableScroller); helper.fill(this.tableScroller);
} }
@@ -356,17 +432,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
return this.model.getItems(); return this.model.getItems();
} }
/** protected abstract ItemFilter<T> createSearchFilter();
*
* getStatLabel.
*
* @param s
*/
public FLabel getStatLabel(SItemManagerUtil.StatTypes s) {
return this.statLabels.get(s);
}
protected abstract ItemFilter<T> createSearchFilter(String text);
protected abstract void buildFilterMenu(JPopupMenu menu); protected abstract void buildFilterMenu(JPopupMenu menu);
protected <F extends ItemFilter<T>> F getFilter(Class<F> filterClass) { protected <F extends ItemFilter<T>> F getFilter(Class<F> filterClass) {
@@ -374,7 +440,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void addFilter(ItemFilter<T> filter) { public void addFilter(final ItemFilter<T> filter) {
final Class<? extends ItemFilter<T>> filterClass = (Class<? extends ItemFilter<T>>) filter.getClass(); final Class<? extends ItemFilter<T>> filterClass = (Class<? extends ItemFilter<T>>) filter.getClass();
List<ItemFilter<T>> classFilters = this.filters.get(filterClass); List<ItemFilter<T>> classFilters = this.filters.get(filterClass);
if (classFilters == null) { if (classFilters == null) {
@@ -385,10 +451,20 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
//if filter with the same class already exists, try to merge if allowed //if filter with the same class already exists, try to merge if allowed
//NOTE: can always use first filter for these checks since if //NOTE: can always use first filter for these checks since if
//merge is supported, only one will ever exist //merge is supported, only one will ever exist
ItemFilter<T> existingFilter = classFilters.get(0); final ItemFilter<T> existingFilter = classFilters.get(0);
if (existingFilter.merge(filter)) { if (existingFilter.merge(filter)) {
//if new filter merged with existing filter, just update layout //if new filter merged with existing filter, just refresh the widget
this.revalidate(); existingFilter.refreshWidget();
if (!this.lockFiltering) { //apply filters and focus existing filter's main component if filtering not locked
buildFilterPredicate();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
existingFilter.getMainComponent().requestFocusInWindow();
}
});
}
return; return;
} }
} }
@@ -396,6 +472,16 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
orderedFilters.add(filter); orderedFilters.add(filter);
this.add(filter.getPanel()); this.add(filter.getPanel());
this.revalidate(); this.revalidate();
if (!this.lockFiltering) { //apply filters and focus filter's main component if filtering not locked
buildFilterPredicate();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
filter.getMainComponent().requestFocusInWindow();
}
});
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -409,15 +495,28 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
orderedFilters.remove(filter); orderedFilters.remove(filter);
this.remove(filter.getPanel()); this.remove(filter.getPanel());
this.revalidate(); this.revalidate();
buildFilterPredicate();
} }
} }
public void buildFilterPredicate() { public void buildFilterPredicate() {
/* if (this.lockFiltering) { return; }
this.filterPredicate = ?;
List<Predicate<? super T>> predicates = new ArrayList<Predicate<? super T>>();
predicates.add(Predicates.instanceOf(this.genericType));
for (ItemFilter<T> filter : this.orderedFilters) { //TODO: Support custom filter logic
if (filter.isEnabled() && !filter.isEmpty()) {
predicates.add(filter.buildPredicate());
}
}
if (!this.mainSearchFilter.isEmpty()) {
predicates.add(mainSearchFilter.buildPredicate());
}
this.filterPredicate = predicates.size() == 0 ? null : Predicates.and(predicates);
if (this.pool != null) { if (this.pool != null) {
this.updateView(true); this.updateView(true);
}*/ }
} }
/** /**
@@ -429,19 +528,6 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
return this.filterPredicate == null; return this.filterPredicate == null;
} }
/**
*
* setFilterPredicate.
*
* @param filterToSet
*/
public void setFilterPredicate(final Predicate<T> filterPredicate0) {
this.filterPredicate = filterPredicate0;
if (this.pool != null) {
this.updateView(true);
}
}
/** /**
* *
* updateView. * updateView.
@@ -459,18 +545,34 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
Predicate<Entry<T, Integer>> filterForPool = Predicates.compose(this.filterPredicate, this.pool.FN_GET_KEY); Predicate<Entry<T, Integer>> filterForPool = Predicates.compose(this.filterPredicate, this.pool.FN_GET_KEY);
Iterable<Entry<T, Integer>> items = Aggregates.uniqueByLast(Iterables.filter(this.pool, filterForPool), this.pool.FN_GET_NAME); Iterable<Entry<T, Integer>> items = Aggregates.uniqueByLast(Iterables.filter(this.pool, filterForPool), this.pool.FN_GET_NAME);
this.model.addItems(items); this.model.addItems(items);
} else if (useFilter) { }
else if (useFilter) {
Predicate<Entry<T, Integer>> pred = Predicates.compose(this.filterPredicate, this.pool.FN_GET_KEY); Predicate<Entry<T, Integer>> pred = Predicates.compose(this.filterPredicate, this.pool.FN_GET_KEY);
this.model.addItems(Iterables.filter(this.pool, pred)); this.model.addItems(Iterables.filter(this.pool, pred));
} else if (this.wantUnique) { }
else if (this.wantUnique) {
Iterable<Entry<T, Integer>> items = Aggregates.uniqueByLast(this.pool, this.pool.FN_GET_NAME); Iterable<Entry<T, Integer>> items = Aggregates.uniqueByLast(this.pool, this.pool.FN_GET_NAME);
this.model.addItems(items); this.model.addItems(items);
} else if (!useFilter && bForceFilter) { }
else if (!useFilter && bForceFilter) {
this.model.addItems(this.pool); this.model.addItems(this.pool);
} }
this.table.getTableModel().refreshSort(); this.table.getTableModel().refreshSort();
for (ItemFilter<T> filter : this.orderedFilters) {
filter.afterFiltersApplied();
}
int total;
if (this.wantUnique) {
total = Aggregates.uniqueCount(this.pool, this.pool.FN_GET_NAME);
}
else {
total = this.pool.countAll();
}
this.lblRatio.setText(this.getFilteredItems().countAll() + " / " + total);
//select first row if no row already selected //select first row if no row already selected
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
@@ -482,6 +584,16 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
}); });
} }
/**
*
* getPnlButtons.
*
* @return panel to put any custom buttons on
*/
public JPanel getPnlButtons() {
return this.pnlButtons;
}
/** /**
* *
* getWantUnique. * getWantUnique.
@@ -553,6 +665,15 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
this.table.requestFocusInWindow(); this.table.requestFocusInWindow();
} }
/**
*
* focusSearch.
*
*/
public void focusSearch() {
this.mainSearchFilter.getMainComponent().requestFocusInWindow();
}
public void addSelectionListener(ListSelectionListener listener) { public void addSelectionListener(ListSelectionListener listener) {
selectionListeners.remove(listener); //ensure listener not added multiple times selectionListeners.remove(listener); //ensure listener not added multiple times
selectionListeners.add(listener); selectionListeners.add(listener);

View File

@@ -4,8 +4,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
@@ -13,12 +11,8 @@ import forge.card.CardRules;
import forge.card.CardRulesPredicates; import forge.card.CardRulesPredicates;
import forge.card.CardRulesPredicates.Presets; import forge.card.CardRulesPredicates.Presets;
import forge.card.MagicColor; import forge.card.MagicColor;
import forge.gui.deckeditor.views.VCardCatalog;
import forge.gui.deckeditor.views.VCardCatalog.RangeTypes;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSpinner;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.util.ComparableOp;
import forge.util.PredicateString.StringOp; import forge.util.PredicateString.StringOp;
/** /**
@@ -139,39 +133,7 @@ public class SFilterUtil {
return Predicates.compose(textFilter, PaperCard.FN_GET_RULES); return Predicates.compose(textFilter, PaperCard.FN_GET_RULES);
} }
private static Predicate<CardRules> getCardRulesFieldPredicate(int min, int max, CardRulesPredicates.LeafNumber.CardField field) { public static <T> Predicate<T> optimizedAnd(Predicate<T> p1, Predicate<T> p2) {
boolean hasMin = 0 != min;
boolean hasMax = 10 != 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);
}
private static <T> Predicate<T> optimizedAnd(Predicate<T> p1, Predicate<T> p2) {
return p1 == null ? p2 : (p2 == null ? p1 : Predicates.and(p1, p2)); return p1 == null ? p2 : (p2 == null ? p1 : Predicates.and(p1, p2));
} }
/**
* builds a filter for an interval on a card field
*/
public static Predicate<PaperCard> buildIntervalFilter(
Map<RangeTypes, Pair<FSpinner, FSpinner>> spinners, VCardCatalog.RangeTypes field) {
Pair<FSpinner, FSpinner> sPair = spinners.get(field);
Predicate<CardRules> fieldFilter = getCardRulesFieldPredicate(
Integer.valueOf(sPair.getLeft().getValue().toString()),
Integer.valueOf(sPair.getRight().getValue().toString()), field.cardField);
if (null != fieldFilter && VCardCatalog.RangeTypes.CMC != field)
{
fieldFilter = Predicates.and(fieldFilter, CardRulesPredicates.Presets.IS_CREATURE);
}
if (fieldFilter == null) {
return Predicates.alwaysTrue();
} else {
return Predicates.compose(fieldFilter, PaperCard.FN_GET_RULES);
}
}
} }

View File

@@ -44,7 +44,6 @@ public class SItemManagerIO {
/** Preferences (must match with PREFS file). */ /** Preferences (must match with PREFS file). */
public enum EditorPreference { public enum EditorPreference {
stats_deck,
display_unique_only, display_unique_only,
elastic_columns elastic_columns
} }

View File

@@ -1,19 +1,14 @@
package forge.gui.toolbox.itemmanager; package forge.gui.toolbox.itemmanager;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import forge.card.CardRules; import forge.card.CardRules;
import forge.card.CardRulesPredicates; import forge.card.CardRulesPredicates;
import forge.gui.deckeditor.controllers.ACEditorBase;
import forge.gui.deckeditor.views.VCardCatalog; import forge.gui.deckeditor.views.VCardCatalog;
import forge.gui.deckeditor.views.VCurrentDeck; import forge.gui.deckeditor.views.VCurrentDeck;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FSkin.SkinImage; import forge.gui.toolbox.FSkin.SkinImage;
import forge.item.PaperCard;
import forge.item.InventoryItem;
import forge.util.Aggregates;
import forge.util.ItemPoolView;
import forge.util.TextUtil; import forge.util.TextUtil;
@@ -76,40 +71,13 @@ public final class SItemManagerUtil {
return (int) Math.round((double) (x0 * 100) / (double) y0); return (int) Math.round((double) (x0 * 100) / (double) y0);
} }
private static final Predicate<Object> totalPred = Predicates.instanceOf(PaperCard.class);
private static final Predicate<Object> packPred = Predicates.not(totalPred);
/**
* setStats.
*
* @param <T> &emsp; the generic type
* @param itemManager &emsp; {@link forge.gui.toolbox.itemmanager.ItemManager<T>}
*/
public static <T extends InventoryItem> void setStats(final ItemManager<T> itemManager) {
final ItemPoolView<T> items = itemManager.getFilteredItems();
for (StatTypes s : StatTypes.values()) {
switch (s) {
case TOTAL:
itemManager.getStatLabel(s).setText(String.valueOf(
Aggregates.sum(Iterables.filter(items, Predicates.compose(totalPred, items.FN_GET_KEY)), items.FN_GET_COUNT)));
break;
case PACK:
itemManager.getStatLabel(s).setText(String.valueOf(
Aggregates.sum(Iterables.filter(items, Predicates.compose(packPred, items.FN_GET_KEY)), items.FN_GET_COUNT)));
break;
default:
itemManager.getStatLabel(s).setText(String.valueOf(items.countAll(Predicates.compose(s.predicate, PaperCard.FN_GET_RULES), PaperCard.class)));
}
}
}
/** /**
* Resets components that may have been changed * Resets components that may have been changed
* by various configurations of the deck editor. * by various configurations of the deck editor.
*/ */
public static void resetUI() { public static void resetUI(ACEditorBase<?, ?> editor) {
VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setVisible(true); editor.getBtnAdd4().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setVisible(true); editor.getBtnRemove4().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnSave().setVisible(true); VCurrentDeck.SINGLETON_INSTANCE.getBtnSave().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs().setVisible(true); VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs().setVisible(true);
@@ -126,7 +94,7 @@ public final class SItemManagerUtil {
VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText("Card Catalog"); VCardCatalog.SINGLETON_INSTANCE.getTabLabel().setText("Card Catalog");
VCurrentDeck.SINGLETON_INSTANCE.getBtnPrintProxies().setVisible(true); VCurrentDeck.SINGLETON_INSTANCE.getBtnPrintProxies().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getBtnDoSideboard().setVisible(false); editor.getBtnCycleSection().setVisible(false);
VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setVisible(true); VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setVisible(true);
VCurrentDeck.SINGLETON_INSTANCE.getLblTitle().setText("Title:"); VCurrentDeck.SINGLETON_INSTANCE.getLblTitle().setText("Title:");

View File

@@ -1,7 +1,10 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import javax.swing.JPanel; import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.card.CardRules;
import forge.card.CardRulesPredicates;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -10,23 +13,26 @@ import forge.item.PaperCard;
* *
*/ */
public class CardCMCFilter extends ValueRangeFilter<PaperCard> { public class CardCMCFilter extends ValueRangeFilter<PaperCard> {
public CardCMCFilter(ItemManager<PaperCard> itemManager0) { public CardCMCFilter(ItemManager<PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@Override @Override
protected String getTitle() { public ItemFilter<PaperCard> createCopy() {
return "Card CMC"; return new CardCMCFilter(itemManager);
} }
@Override @Override
protected void buildPanel(JPanel panel) { protected String getCaption() {
return "CMC";
} }
@Override @Override
protected void onRemoved() { public Predicate<PaperCard> buildPredicate() {
Predicate<CardRules> predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.CMC);
if (predicate == null) {
return Predicates.alwaysTrue();
}
return Predicates.compose(predicate, PaperCard.FN_GET_RULES);
} }
} }

View File

@@ -2,7 +2,15 @@ package forge.gui.toolbox.itemmanager.filters;
import javax.swing.JPanel; import javax.swing.JPanel;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.card.CardRules;
import forge.card.CardRulesPredicates;
import forge.card.MagicColor;
import forge.card.CardRulesPredicates.Presets;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.SFilterUtil;
import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes; import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -10,29 +18,77 @@ import forge.item.PaperCard;
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public class CardColorFilter extends ToggleButtonsFilter<PaperCard> { public class CardColorFilter extends StatTypeFilter<PaperCard> {
public CardColorFilter(ItemManager<PaperCard> itemManager0) { public CardColorFilter(ItemManager<PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@Override @Override
protected String getTitle() { public ItemFilter<PaperCard> createCopy() {
return "Card Color"; return new CardColorFilter(itemManager);
} }
@Override @Override
protected void buildPanel(JPanel panel) { protected void buildWidget(JPanel widget) {
addToggleButton(panel, StatTypes.WHITE); addToggleButton(widget, StatTypes.WHITE);
addToggleButton(panel, StatTypes.BLUE); addToggleButton(widget, StatTypes.BLUE);
addToggleButton(panel, StatTypes.BLACK); addToggleButton(widget, StatTypes.BLACK);
addToggleButton(panel, StatTypes.RED); addToggleButton(widget, StatTypes.RED);
addToggleButton(panel, StatTypes.GREEN); addToggleButton(widget, StatTypes.GREEN);
addToggleButton(panel, StatTypes.COLORLESS); addToggleButton(widget, StatTypes.COLORLESS);
addToggleButton(panel, StatTypes.MULTICOLOR); addToggleButton(widget, StatTypes.MULTICOLOR);
} }
@Override @Override
protected void onRemoved() { public final Predicate<PaperCard> buildPredicate() {
byte colors = 0;
if (buttonMap.get(StatTypes.WHITE).getSelected()) {
colors |= MagicColor.WHITE;
}
if (buttonMap.get(StatTypes.BLUE).getSelected()) {
colors |= MagicColor.BLUE;
}
if (buttonMap.get(StatTypes.BLACK).getSelected()) {
colors |= MagicColor.BLACK;
}
if (buttonMap.get(StatTypes.RED).getSelected()) {
colors |= MagicColor.RED;
}
if (buttonMap.get(StatTypes.GREEN).getSelected()) {
colors |= MagicColor.GREEN;
}
boolean wantColorless = buttonMap.get(StatTypes.COLORLESS).getSelected();
boolean wantMulticolor = buttonMap.get(StatTypes.MULTICOLOR).getSelected();
Predicate<CardRules> preFinal = null;
if (wantMulticolor) {
if (colors == 0) { //handle showing all multi-color cards if all 5 colors are filtered
preFinal = Presets.IS_MULTICOLOR;
if (wantColorless) {
preFinal = Predicates.or(preFinal, Presets.IS_COLORLESS);
}
}
else if (colors != MagicColor.ALL_COLORS) {
preFinal = CardRulesPredicates.canCastWithAvailable(colors);
}
}
else if (colors != MagicColor.ALL_COLORS) {
preFinal = Predicates.and(CardRulesPredicates.canCastWithAvailable(colors), Predicates.not(Presets.IS_MULTICOLOR));
}
if (!wantColorless) {
if (colors != 0 && colors != MagicColor.ALL_COLORS) {
//if colorless filtered out ensure phyrexian cards don't appear
//unless at least one of their colors is selected
preFinal = Predicates.and(preFinal, CardRulesPredicates.isColor(colors));
}
preFinal = SFilterUtil.optimizedAnd(preFinal, Predicates.not(Presets.IS_COLORLESS));
}
if (preFinal == null) {
return Predicates.alwaysTrue();
}
return Predicates.compose(preFinal, PaperCard.FN_GET_RULES);
} }
} }

View File

@@ -1,10 +1,15 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.swing.JPanel; import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.Singletons;
import forge.card.CardEdition;
import forge.game.GameFormat; import forge.game.GameFormat;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -14,17 +19,104 @@ import forge.item.PaperCard;
* *
*/ */
public class CardFormatFilter extends ListLabelFilter<PaperCard> { public class CardFormatFilter extends ListLabelFilter<PaperCard> {
private final Set<GameFormat> formats = new HashSet<GameFormat>(); protected boolean allowReprints = true;
protected final Set<GameFormat> formats = new HashSet<GameFormat>();
public CardFormatFilter(ItemManager<PaperCard> itemManager0) {
super(itemManager0);
}
public CardFormatFilter(ItemManager<PaperCard> itemManager0, GameFormat format0) { public CardFormatFilter(ItemManager<PaperCard> itemManager0, GameFormat format0) {
super(itemManager0); super(itemManager0);
this.formats.add(format0); this.formats.add(format0);
} }
@Override
protected String getTooltip() {
Set<String> sets = new HashSet<String>();
Set<String> bannedCards = new HashSet<String>();
for (GameFormat format : this.formats) {
List<String> formatSets = format.getAllowedSetCodes();
if (formatSets != null) {
sets.addAll(formatSets);
}
List<String> formatBannedCards = format.getBannedCardNames();
if (formatBannedCards != null) {
bannedCards.addAll(formatBannedCards);
}
}
//use HTML tooltips so we can insert line breaks
int lastLen = 0;
int lineLen = 0;
StringBuilder tooltip = new StringBuilder("<html>Sets:");
if (sets.isEmpty()) {
tooltip.append(" All");
}
else {
CardEdition.Collection editions = Singletons.getMagicDb().getEditions();
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());
if (this.allowReprints) {
tooltip.append("<br><br>Allowing identical cards from other sets");
}
}
if (!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 tooltip.toString();
}
@Override
public void reset() {
this.formats.clear();
}
@Override
public ItemFilter<PaperCard> createCopy() {
CardFormatFilter copy = new CardFormatFilter(itemManager);
copy.formats.addAll(this.formats);
return copy;
}
public static boolean canAddFormat(GameFormat format, ItemFilter<PaperCard> existingFilter) { public static boolean canAddFormat(GameFormat format, ItemFilter<PaperCard> existingFilter) {
return existingFilter == null || !((CardFormatFilter)existingFilter).formats.contains(format); return existingFilter == null || !((CardFormatFilter)existingFilter).formats.contains(format);
} }
/** /**
* Merge the given filter with this filter if possible * Merge the given filter with this filter if possible
* @param filter * @param filter
@@ -35,22 +127,18 @@ public class CardFormatFilter extends ListLabelFilter<PaperCard> {
public boolean merge(ItemFilter filter) { public boolean merge(ItemFilter filter) {
CardFormatFilter cardFormatFilter = (CardFormatFilter)filter; CardFormatFilter cardFormatFilter = (CardFormatFilter)filter;
this.formats.addAll(cardFormatFilter.formats); this.formats.addAll(cardFormatFilter.formats);
this.allowReprints = cardFormatFilter.allowReprints;
return true; return true;
} }
@Override @Override
protected String getTitle() { protected String getCaption() {
return "Card Format"; return "Format";
} }
@Override @Override
protected void buildPanel(JPanel panel) { protected int getCount() {
return this.formats.size();
}
@Override
protected void onRemoved() {
} }
@Override @Override
@@ -61,4 +149,13 @@ public class CardFormatFilter extends ListLabelFilter<PaperCard> {
} }
return strings; return strings;
} }
@Override
public final Predicate<PaperCard> buildPredicate() {
List<Predicate<PaperCard>> predicates = new ArrayList<Predicate<PaperCard>>();
for (GameFormat f : this.formats) {
predicates.add(allowReprints ? f.getFilterRules() : f.getFilterPrinted());
}
return Predicates.or(predicates);
}
} }

View File

@@ -1,7 +1,10 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import javax.swing.JPanel; import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.card.CardRules;
import forge.card.CardRulesPredicates;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -15,17 +18,22 @@ public class CardPowerFilter extends ValueRangeFilter<PaperCard> {
} }
@Override @Override
protected String getTitle() { public ItemFilter<PaperCard> createCopy() {
return "Card Power"; return new CardPowerFilter(itemManager);
} }
@Override @Override
protected void buildPanel(JPanel panel) { protected String getCaption() {
return "Power";
} }
@Override @Override
protected void onRemoved() { public Predicate<PaperCard> buildPredicate() {
Predicate<CardRules> predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.POWER);
if (predicate == null) {
return Predicates.alwaysTrue();
}
predicate = Predicates.and(predicate, CardRulesPredicates.Presets.IS_CREATURE);
return Predicates.compose(predicate, PaperCard.FN_GET_RULES);
} }
} }

View File

@@ -3,9 +3,8 @@ package forge.gui.toolbox.itemmanager.filters;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.swing.JPanel;
import forge.Singletons; import forge.Singletons;
import forge.game.GameFormat;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.quest.QuestWorld; import forge.quest.QuestWorld;
@@ -14,14 +13,34 @@ import forge.quest.QuestWorld;
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public class CardQuestWorldFilter extends ListLabelFilter<PaperCard> { public class CardQuestWorldFilter extends CardFormatFilter {
private final Set<QuestWorld> questWorlds = new HashSet<QuestWorld>(); private final Set<QuestWorld> questWorlds = new HashSet<QuestWorld>();
public CardQuestWorldFilter(ItemManager<PaperCard> itemManager0) {
super(itemManager0);
}
public CardQuestWorldFilter(ItemManager<PaperCard> itemManager0, QuestWorld questWorld0) { public CardQuestWorldFilter(ItemManager<PaperCard> itemManager0, QuestWorld questWorld0) {
super(itemManager0); super(itemManager0);
this.questWorlds.add(questWorld0); this.questWorlds.add(questWorld0);
this.formats.add(getQuestWorldFormat(questWorld0));
} }
@Override
public ItemFilter<PaperCard> createCopy() {
CardQuestWorldFilter copy = new CardQuestWorldFilter(itemManager);
copy.questWorlds.addAll(this.questWorlds);
for (QuestWorld w : this.questWorlds) {
copy.formats.add(getQuestWorldFormat(w));
}
return copy;
}
@Override
public void reset() {
this.questWorlds.clear();
super.reset();
}
public static boolean canAddQuestWorld(QuestWorld questWorld, ItemFilter<PaperCard> existingFilter) { public static boolean canAddQuestWorld(QuestWorld questWorld, ItemFilter<PaperCard> existingFilter) {
if (questWorld.getFormat() == null && Singletons.getModel().getQuest().getMainFormat() == null) { if (questWorld.getFormat() == null && Singletons.getModel().getQuest().getMainFormat() == null) {
return false; //must have format return false; //must have format
@@ -29,11 +48,6 @@ public class CardQuestWorldFilter extends ListLabelFilter<PaperCard> {
return existingFilter == null || !((CardQuestWorldFilter)existingFilter).questWorlds.contains(questWorld); return existingFilter == null || !((CardQuestWorldFilter)existingFilter).questWorlds.contains(questWorld);
} }
@Override
protected String getTitle() {
return "Quest World";
}
/** /**
* Merge the given filter with this filter if possible * Merge the given filter with this filter if possible
* @param filter * @param filter
@@ -44,19 +58,22 @@ public class CardQuestWorldFilter extends ListLabelFilter<PaperCard> {
public boolean merge(ItemFilter filter) { public boolean merge(ItemFilter filter) {
CardQuestWorldFilter cardQuestWorldFilter = (CardQuestWorldFilter)filter; CardQuestWorldFilter cardQuestWorldFilter = (CardQuestWorldFilter)filter;
this.questWorlds.addAll(cardQuestWorldFilter.questWorlds); this.questWorlds.addAll(cardQuestWorldFilter.questWorlds);
for (QuestWorld w : cardQuestWorldFilter.questWorlds) {
this.formats.add(getQuestWorldFormat(w));
}
return true; return true;
} }
@Override @Override
protected void buildPanel(JPanel panel) { protected String getCaption() {
return "Quest World";
} }
@Override @Override
protected void onRemoved() { protected int getCount() {
return this.questWorlds.size();
} }
@Override @Override
protected Iterable<String> getList() { protected Iterable<String> getList() {
Set<String> strings = new HashSet<String>(); Set<String> strings = new HashSet<String>();
@@ -65,4 +82,13 @@ public class CardQuestWorldFilter extends ListLabelFilter<PaperCard> {
} }
return strings; return strings;
} }
private GameFormat getQuestWorldFormat(QuestWorld w) {
GameFormat format = w.getFormat();
if (format == null) {
//assumes that no world other than the main world will have a null format
format = Singletons.getModel().getQuest().getMainFormat();
}
return format;
}
} }

View File

@@ -1,8 +1,19 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JPanel; import javax.swing.JPanel;
import com.google.common.base.Predicate;
import forge.Command;
import forge.gui.toolbox.FComboBoxWrapper;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.LayoutHelper;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.SFilterUtil;
import forge.item.PaperCard; import forge.item.PaperCard;
/** /**
@@ -10,22 +21,101 @@ import forge.item.PaperCard;
* *
*/ */
public class CardSearchFilter extends TextSearchFilter<PaperCard> { public class CardSearchFilter extends TextSearchFilter<PaperCard> {
public CardSearchFilter(ItemManager<PaperCard> itemManager0, String text0) { private FComboBoxWrapper<String> cbSearchMode;
super(itemManager0, text0); private FLabel btnName, btnType, btnText;
public CardSearchFilter(ItemManager<PaperCard> itemManager0) {
super(itemManager0);
} }
@Override @Override
protected String getTitle() { public ItemFilter<PaperCard> createCopy() {
return "Card Search"; CardSearchFilter copy = new CardSearchFilter(itemManager);
copy.getWidget(); //initialize widget
copy.txtSearch.setText(this.txtSearch.getText());
copy.cbSearchMode.setSelectedIndex(this.cbSearchMode.getSelectedIndex());
copy.btnName.setSelected(this.btnName.getSelected());
copy.btnType.setSelected(this.btnType.getSelected());
copy.btnText.setSelected(this.btnText.getSelected());
return copy;
} }
@Override @Override
protected void buildPanel(JPanel panel) { public void reset() {
super.reset();
this.cbSearchMode.setSelectedIndex(0);
this.btnName.setSelected(true);
this.btnType.setSelected(true);
this.btnText.setSelected(true);
}
/**
* Merge the given filter with this filter if possible
* @param filter
* @return true if filter merged in or to suppress adding a new filter, false to allow adding new filter
*/
@Override
@SuppressWarnings("rawtypes")
public boolean merge(ItemFilter filter) {
return false;
} }
@Override @Override
protected void onRemoved() { protected final void buildWidget(JPanel widget) {
super.buildWidget(widget);
cbSearchMode = new FComboBoxWrapper<String>();
cbSearchMode.addItem("in");
cbSearchMode.addItem("not in");
cbSearchMode.addTo(widget);
cbSearchMode.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
if (!txtSearch.isEmpty()) {
applyChange();
}
}
});
btnName = addButton(widget, "Name");
btnType = addButton(widget, "Type");
btnText = addButton(widget, "Text");
}
@Override
protected void doWidgetLayout(LayoutHelper helper) {
final int comboBoxWidth = 61;
final int buttonWidth = 51;
helper.fillLine(txtSearch, FTextField.HEIGHT, comboBoxWidth + buttonWidth * 3 + 12); //leave space for combo box and buttons
helper.include(cbSearchMode.getComponent(), comboBoxWidth, FTextField.HEIGHT);
helper.include(btnName, buttonWidth, FTextField.HEIGHT);
helper.include(btnType, buttonWidth, FTextField.HEIGHT);
helper.include(btnText, buttonWidth, FTextField.HEIGHT);
}
@SuppressWarnings("serial")
private FLabel addButton(JPanel widget, String text) {
FLabel button = new FLabel.Builder().text(text).hoverable().selectable().selected().build();
button.setCommand(new Command() {
@Override
public void run() {
applyChange();
}
});
widget.add(button);
return button;
}
@Override
public Predicate<PaperCard> buildPredicate() {
return SFilterUtil.buildTextFilter(
txtSearch.getText(),
cbSearchMode.getSelectedIndex() != 0,
btnName.getSelected(),
btnType.getSelected(),
btnText.getSelected());
} }
} }

View File

@@ -4,8 +4,7 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.swing.JPanel; import forge.game.GameFormat;
import forge.gui.home.quest.DialogChooseSets; import forge.gui.home.quest.DialogChooseSets;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -14,19 +13,27 @@ import forge.item.PaperCard;
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public class CardSetFilter extends ListLabelFilter<PaperCard> { public class CardSetFilter extends CardFormatFilter {
private final Set<String> sets = new HashSet<String>(); private final Set<String> sets = new HashSet<String>();
public CardSetFilter(ItemManager<PaperCard> itemManager0, Collection<String> sets) { public CardSetFilter(ItemManager<PaperCard> itemManager0, Collection<String> sets0, boolean allowReprints0) {
super(itemManager0); super(itemManager0);
this.sets.addAll(sets); this.sets.addAll(sets0);
this.formats.add(new GameFormat(null, this.sets, null));
this.allowReprints = allowReprints0;
} }
@Override @Override
protected String getTitle() { public ItemFilter<PaperCard> createCopy() {
return "Card Set"; return new CardSetFilter(itemManager, this.sets, this.allowReprints);
} }
@Override
public void reset() {
this.sets.clear();
super.reset();
}
/** /**
* Merge the given filter with this filter if possible * Merge the given filter with this filter if possible
* @param filter * @param filter
@@ -37,9 +44,12 @@ public class CardSetFilter extends ListLabelFilter<PaperCard> {
public boolean merge(ItemFilter filter) { public boolean merge(ItemFilter filter) {
CardSetFilter cardSetFilter = (CardSetFilter)filter; CardSetFilter cardSetFilter = (CardSetFilter)filter;
this.sets.addAll(cardSetFilter.sets); this.sets.addAll(cardSetFilter.sets);
this.allowReprints = cardSetFilter.allowReprints;
this.formats.clear();
this.formats.add(new GameFormat(null, this.sets, null));
return true; return true;
} }
public void edit() { public void edit() {
final DialogChooseSets dialog = new DialogChooseSets(this.sets, null, true); final DialogChooseSets dialog = new DialogChooseSets(this.sets, null, true);
dialog.setOkCallback(new Runnable() { dialog.setOkCallback(new Runnable() {
@@ -47,18 +57,21 @@ public class CardSetFilter extends ListLabelFilter<PaperCard> {
public void run() { public void run() {
sets.clear(); sets.clear();
sets.addAll(dialog.getSelectedSets()); sets.addAll(dialog.getSelectedSets());
allowReprints = dialog.getWantReprints();
formats.clear();
formats.add(new GameFormat(null, sets, null));
} }
}); });
} }
@Override @Override
protected void buildPanel(JPanel panel) { protected String getCaption() {
return "Set";
} }
@Override @Override
protected void onRemoved() { protected int getCount() {
return this.sets.size();
} }
@Override @Override

View File

@@ -1,7 +1,10 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import javax.swing.JPanel; import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.card.CardRules;
import forge.card.CardRulesPredicates;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -15,17 +18,22 @@ public class CardToughnessFilter extends ValueRangeFilter<PaperCard> {
} }
@Override @Override
protected String getTitle() { public ItemFilter<PaperCard> createCopy() {
return "Card Toughness"; return new CardToughnessFilter(itemManager);
} }
@Override @Override
protected void buildPanel(JPanel panel) { protected String getCaption() {
return "Toughness";
} }
@Override @Override
protected void onRemoved() { public Predicate<PaperCard> buildPredicate() {
Predicate<CardRules> predicate = getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField.TOUGHNESS);
if (predicate == null) {
return Predicates.alwaysTrue();
}
predicate = Predicates.and(predicate, CardRulesPredicates.Presets.IS_CREATURE);
return Predicates.compose(predicate, PaperCard.FN_GET_RULES);
} }
} }

View File

@@ -1,8 +1,16 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel; import javax.swing.JPanel;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.card.CardRules;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes; import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -10,29 +18,40 @@ import forge.item.PaperCard;
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public class CardTypeFilter extends ToggleButtonsFilter<PaperCard> { public class CardTypeFilter extends StatTypeFilter<PaperCard> {
public CardTypeFilter(ItemManager<PaperCard> itemManager0) { public CardTypeFilter(ItemManager<PaperCard> itemManager0) {
super(itemManager0); super(itemManager0);
} }
@Override @Override
protected String getTitle() { public ItemFilter<PaperCard> createCopy() {
return "Card Type"; return new CardTypeFilter(itemManager);
} }
@Override @Override
protected void buildPanel(JPanel panel) { protected void buildWidget(JPanel widget) {
addToggleButton(panel, StatTypes.LAND); addToggleButton(widget, StatTypes.LAND);
addToggleButton(panel, StatTypes.ARTIFACT); addToggleButton(widget, StatTypes.ARTIFACT);
addToggleButton(panel, StatTypes.CREATURE); addToggleButton(widget, StatTypes.CREATURE);
addToggleButton(panel, StatTypes.ENCHANTMENT); addToggleButton(widget, StatTypes.ENCHANTMENT);
addToggleButton(panel, StatTypes.PLANESWALKER); addToggleButton(widget, StatTypes.PLANESWALKER);
addToggleButton(panel, StatTypes.INSTANT); addToggleButton(widget, StatTypes.INSTANT);
addToggleButton(panel, StatTypes.SORCERY); addToggleButton(widget, StatTypes.SORCERY);
} }
@Override @Override
protected void onRemoved() { public final Predicate<PaperCard> buildPredicate() {
final List<Predicate<CardRules>> types = new ArrayList<Predicate<CardRules>>();
for (SItemManagerUtil.StatTypes s : buttonMap.keySet()) {
if (buttonMap.get(s).getSelected()) {
types.add(s.predicate);
}
}
if (types.size() == 7) {
return Predicates.alwaysTrue();
}
return Predicates.compose(Predicates.or(types), PaperCard.FN_GET_RULES);
} }
} }

View File

@@ -1,12 +1,31 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import java.awt.BasicStroke;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JCheckBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout; import com.google.common.base.Predicate;
import forge.Command;
import forge.gui.toolbox.FLabel; import forge.gui.framework.ILocalRepaint;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FSkin.Colors;
import forge.gui.toolbox.FSkin.JComponentSkin;
import forge.gui.toolbox.FSkin.JLabelSkin;
import forge.gui.toolbox.FSkin.SkinColor;
import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.LayoutHelper;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.InventoryItem; import forge.item.InventoryItem;
@@ -15,55 +34,101 @@ import forge.item.InventoryItem;
* *
*/ */
public abstract class ItemFilter<T extends InventoryItem> { public abstract class ItemFilter<T extends InventoryItem> {
private final ItemManager<T> itemManager; public final static int PANEL_HEIGHT = 28;
private JPanel panel;
private JLabel lblPanelTitle; public static void layoutCheckbox(JCheckBox cb) {
JComponentSkin<JCheckBox> skin = FSkin.get(cb);
public static int PANEL_HEIGHT = 30; skin.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
skin.setFont(FSkin.getFont(12));
cb.setOpaque(false);
cb.setFocusable(false);
}
protected final ItemManager<T> itemManager;
private FilterPanel panel;
private Widget widget;
private final JCheckBox chkEnable = new JCheckBox();
private RemoveButton btnRemove;
protected ItemFilter(ItemManager<T> itemManager0) { protected ItemFilter(ItemManager<T> itemManager0) {
this.itemManager = itemManager0; this.itemManager = itemManager0;
this.chkEnable.setSelected(true); //enable by default
} }
@SuppressWarnings("serial")
public JPanel getPanel() { public JPanel getPanel() {
if (this.panel == null) { if (this.panel == null) {
this.panel = new JPanel(new MigLayout("insets 0, gap 2")); this.panel = new FilterPanel();
this.panel.setOpaque(false);
FSkin.get(this.panel).setMatteBorder(1, 2, 1, 2, FSkin.getColor(FSkin.Colors.CLR_TEXT)); layoutCheckbox(this.chkEnable);
this.chkEnable.addItemListener(new ItemListener() {
this.lblPanelTitle = new FLabel.Builder().fontSize(10).build(); @Override
this.panel.add(this.lblPanelTitle, "top"); public void itemStateChanged(ItemEvent arg0) {
updateEnabled();
//add button to remove filter applyChange();
this.panel.add(new FLabel.Builder() }
.text("X") });
.fontSize(10) this.panel.add(this.chkEnable);
.hoverable(true)
.tooltip("Remove filter") getWidget(); //initialize widget
.cmdClick(new Command() { if (!isEnabled()) {
@Override updateEnabled();
public void run() { }
itemManager.removeFilter(ItemFilter.this); this.panel.add(this.widget);
ItemFilter.this.onRemoved();
} this.btnRemove = new RemoveButton();
}).build(), "top"); this.panel.add(this.btnRemove);
this.buildPanel(panel);
} }
return this.panel; return this.panel;
} }
public void updatePanelTitle(int number) { public JPanel getWidget() {
this.lblPanelTitle.setText(number + ". " + this.getTitle()); if (this.widget == null) {
this.widget = new Widget();
this.buildWidget(this.widget);
}
return this.widget;
} }
protected abstract String getTitle(); public void refreshWidget() {
if (this.widget == null) { return; }
this.widget.removeAll();
this.buildWidget(this.widget);
}
public Component getMainComponent() {
return getWidget();
}
public void setNumber(int number) {
this.chkEnable.setText("(" + number + ")");
}
public boolean isEnabled() {
return this.chkEnable.isSelected();
}
public void setEnabled(boolean enabled0) {
this.chkEnable.setSelected(enabled0);
}
public void updateEnabled() {
boolean enabled = this.isEnabled();
for (Component comp : this.widget.getComponents()) {
comp.setEnabled(enabled);
}
}
protected void applyChange() { protected void applyChange() {
this.itemManager.buildFilterPredicate(); this.itemManager.buildFilterPredicate();
} }
public abstract ItemFilter<T> createCopy();
public abstract boolean isEmpty();
public abstract void reset();
public abstract Predicate<T> buildPredicate();
public void afterFiltersApplied() {
}
/** /**
* Merge the given filter with this filter if possible * Merge the given filter with this filter if possible
* @param filter * @param filter
@@ -71,7 +136,127 @@ public abstract class ItemFilter<T extends InventoryItem> {
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public abstract boolean merge(ItemFilter filter); public abstract boolean merge(ItemFilter filter);
protected abstract void buildPanel(JPanel panel); protected abstract void buildWidget(JPanel widget);
protected abstract void onRemoved(); protected abstract void doWidgetLayout(LayoutHelper helper);
@SuppressWarnings("serial")
private class FilterPanel extends JPanel {
private FilterPanel() {
setLayout(null);
setOpaque(false);
FSkin.get(this).setMatteBorder(0, 0, 1, 0, FSkin.getColor(Colors.CLR_TEXT));
}
@Override
public void doLayout() {
LayoutHelper helper = new LayoutHelper(this);
int removeButtonSize = 17;
helper.include(chkEnable, 43, FTextField.HEIGHT);
helper.offset(-3, 0); //avoid extra padding between checkbox and widget
helper.fillLine(widget, PANEL_HEIGHT, removeButtonSize); //leave room for remove button
helper.offset(-3, (PANEL_HEIGHT - removeButtonSize) / 2 - 1); //shift position of remove button
helper.include(btnRemove, removeButtonSize, removeButtonSize);
}
}
@SuppressWarnings("serial")
private class Widget extends JPanel {
private Widget() {
setLayout(null);
setOpaque(false);
}
@Override
public void doLayout() {
LayoutHelper helper = new LayoutHelper(this);
ItemFilter.this.doWidgetLayout(helper);
}
}
@SuppressWarnings("serial")
private class RemoveButton extends JLabel implements ILocalRepaint {
protected JLabelSkin<RemoveButton> skin = FSkin.get(this);
private final SkinColor iconColor = FSkin.getColor(Colors.CLR_TEXT);
private boolean pressed, hovered;
private RemoveButton() {
setToolTipText("Remove filter");
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (!RemoveButton.this.isEnabled()) { return; }
if (SwingUtilities.isLeftMouseButton(e)) {
pressed = true;
repaintSelf();
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (pressed && SwingUtilities.isLeftMouseButton(e)) {
pressed = false;
if (hovered) { //only handle click if mouse released over button
repaintSelf();
itemManager.focus();
itemManager.removeFilter(ItemFilter.this);
}
}
}
@Override
public void mouseEntered(MouseEvent e) {
if (!RemoveButton.this.isEnabled()) { return; }
hovered = true;
repaintSelf();
}
@Override
public void mouseExited(MouseEvent e) {
if (hovered) {
hovered = false;
repaintSelf();
}
}
});
}
@Override
public void setEnabled(boolean enabled0) {
if (!enabled0 && hovered) {
hovered = false; //ensure hovered reset if disabled
}
super.setEnabled(enabled0);
}
@Override
public void repaintSelf() {
final Dimension d = this.getSize();
repaint(0, 0, d.width, d.height);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int thickness = 2;
int offset = 4;
int x1 = offset;
int y1 = offset;
int x2 = getWidth() - offset - 1;
int y2 = getHeight() - offset - 1;
Graphics2D g2d = (Graphics2D) g;
if (hovered) {
if (pressed) {
g.translate(1, 1); //translate icon to give pressed button look
}
skin.setGraphicsColor(g2d, iconColor);
}
else {
skin.setGraphicsColor(g2d, iconColor.alphaColor(150));
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(thickness));
g2d.drawLine(x1, y1, x2, y2);
g2d.drawLine(x2, y1, x1, y2);
}
}
} }

View File

@@ -1,38 +1,62 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.LayoutHelper;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.util.TextUtil;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public abstract class ListLabelFilter<T extends InventoryItem> extends ItemFilter<T> { public abstract class ListLabelFilter<T extends InventoryItem> extends ItemFilter<T> {
private FLabel label;
protected ListLabelFilter(ItemManager<T> itemManager0) { protected ListLabelFilter(ItemManager<T> itemManager0) {
super(itemManager0); super(itemManager0);
} }
protected abstract String getCaption();
protected abstract Iterable<String> getList(); protected abstract Iterable<String> getList();
protected abstract String getTooltip();
public void buildPanel() { protected abstract int getCount();
StringBuilder label = new StringBuilder();
boolean truncated = false; @Override
for (String str : getList()) { public final boolean isEmpty() {
// don't let the full label get too long return getCount() == 0;
if (label.length() < 32) { }
label.append(" ").append(str).append(";");
} else { @Override
truncated = true; protected final void buildWidget(JPanel widget) {
break; StringBuilder labelBuilder = new StringBuilder();
} labelBuilder.append(getCaption());
} switch (getCount()) {
case 0:
// chop off last semicolons labelBuilder.append(": All");
label.delete(label.length() - 1, label.length()); break;
case 1:
if (truncated) { labelBuilder.append(": " + getList().iterator().next());
label.append("..."); break;
default:
labelBuilder.append("s: " + TextUtil.join(getList(), ", "));
break;
} }
label = new FLabel.Builder()
.text(labelBuilder.toString())
.tooltip(getTooltip())
.fontAlign(SwingConstants.LEFT)
.fontSize(12)
.build();
widget.add(label);
}
@Override
protected void doWidgetLayout(LayoutHelper helper) {
helper.fillLine(label, FTextField.HEIGHT);
} }
} }

View File

@@ -0,0 +1,89 @@
package forge.gui.toolbox.itemmanager.filters;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JPanel;
import com.google.common.base.Predicates;
import forge.Command;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes;
import forge.item.InventoryItem;
import forge.item.PaperCard;
import forge.util.ItemPoolView;
public abstract class StatTypeFilter<T extends InventoryItem> extends ToggleButtonsFilter<T> {
protected final Map<SItemManagerUtil.StatTypes, FLabel> buttonMap;
public StatTypeFilter(ItemManager<T> itemManager0) {
super(itemManager0);
buttonMap = new HashMap<SItemManagerUtil.StatTypes, FLabel>();
}
@SuppressWarnings("serial")
protected void addToggleButton(JPanel widget, final StatTypes st) {
final FLabel button = addToggleButton(widget, st.toLabelString(), st.img);
buttonMap.put(st, button);
//hook so right-clicking a button toggles itself on and toggles off all other buttons
button.setRightClickCommand(new Command() {
@Override
public void run() {
lockFiltering = true;
boolean foundSelected = false;
for (Map.Entry<SItemManagerUtil.StatTypes, FLabel> btn : buttonMap.entrySet()) {
if (btn.getKey() != st) {
if (btn.getKey() == StatTypes.MULTICOLOR) {
switch (st) {
case WHITE:
case BLUE:
case BLACK:
case RED:
case GREEN:
//ensure multicolor filter selected after right-clicking a color filter
if (!btn.getValue().getSelected()) {
btn.getValue().setSelected(true);
}
continue;
default:
break;
}
}
if (btn.getValue().getSelected()) {
foundSelected = true;
btn.getValue().setSelected(false);
}
}
}
if (!button.getSelected()) {
button.setSelected(true);
}
else if (!foundSelected) {
//if statLabel only label in group selected, re-select all other labels in group
for (Map.Entry<SItemManagerUtil.StatTypes, FLabel> btn : buttonMap.entrySet()) {
if (btn.getKey() != st) {
if (!btn.getValue().getSelected()) {
btn.getValue().setSelected(true);
}
}
}
}
lockFiltering = false;
applyChange();
}
});
}
@Override
public void afterFiltersApplied() {
final ItemPoolView<T> items = itemManager.getFilteredItems();
for (Map.Entry<SItemManagerUtil.StatTypes, FLabel> btn : buttonMap.entrySet()) {
int count = items.countAll(Predicates.compose(btn.getKey().predicate, PaperCard.FN_GET_RULES), PaperCard.class);
btn.getValue().setText(String.valueOf(count));
}
getWidget().revalidate();
}
}

View File

@@ -1,8 +1,16 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.Timer;
import forge.gui.toolbox.FTextField; import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.LayoutHelper;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.item.InventoryItem; import forge.item.InventoryItem;
@@ -11,13 +19,27 @@ import forge.item.InventoryItem;
* *
*/ */
public abstract class TextSearchFilter<T extends InventoryItem> extends ItemFilter<T> { public abstract class TextSearchFilter<T extends InventoryItem> extends ItemFilter<T> {
private String text; protected FTextField txtSearch;
protected TextSearchFilter(ItemManager<T> itemManager0, String text0) { protected TextSearchFilter(ItemManager<T> itemManager0) {
super(itemManager0); super(itemManager0);
this.text = text0;
} }
@Override
public boolean isEmpty() {
return txtSearch.isEmpty();
}
@Override
public void reset() {
txtSearch.setText("");
}
@Override
public Component getMainComponent() {
return txtSearch;
}
/** /**
* Merge the given filter with this filter if possible * Merge the given filter with this filter if possible
* @param filter * @param filter
@@ -28,9 +50,62 @@ public abstract class TextSearchFilter<T extends InventoryItem> extends ItemFilt
public boolean merge(ItemFilter filter) { public boolean merge(ItemFilter filter) {
return false; return false;
} }
@Override @Override
protected void buildPanel(JPanel panel) { protected void buildWidget(JPanel widget) {
panel.add(new FTextField.Builder().text(this.text).build()); txtSearch = new FTextField.Builder().ghostText("Search").build();
widget.add(txtSearch);
txtSearch.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
case KeyEvent.VK_DOWN:
case KeyEvent.VK_PAGE_UP:
case KeyEvent.VK_PAGE_DOWN:
//set focus to item manager when certain keys pressed
if (changeTimer.isRunning()) {
applyChange(); //apply change now if currently delayed
}
itemManager.focus();
break;
case KeyEvent.VK_ENTER:
if (e.getModifiers() == 0) {
if (changeTimer.isRunning()) {
applyChange(); //apply change now if currently delayed
}
}
break;
}
}
});
txtSearch.addChangeListener(new FTextField.ChangeListener() {
@Override
public void textChanged() {
changeTimer.restart();
}
});
} }
@Override
protected void doWidgetLayout(LayoutHelper helper) {
helper.offset(0, 3); //add padding above text field
helper.fillLine(txtSearch, FTextField.HEIGHT);
}
@Override
protected void applyChange() {
changeTimer.stop(); //ensure change timer stopped before applying change
super.applyChange();
}
private Timer changeTimer = new Timer(200, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
applyChange();
}
});
} }

View File

@@ -1,15 +1,18 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import java.awt.Dimension; import java.awt.Graphics;
import java.util.ArrayList; import java.util.ArrayList;
import javax.swing.Icon;
import javax.swing.JPanel; import javax.swing.JPanel;
import forge.Command; import forge.Command;
import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FSkin.SkinFont;
import forge.gui.toolbox.FSkin.SkinImage; import forge.gui.toolbox.FSkin.SkinImage;
import forge.gui.toolbox.LayoutHelper;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes;
import forge.item.InventoryItem; import forge.item.InventoryItem;
/** /**
@@ -18,50 +21,80 @@ import forge.item.InventoryItem;
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
public abstract class ToggleButtonsFilter<T extends InventoryItem> extends ItemFilter<T> { public abstract class ToggleButtonsFilter<T extends InventoryItem> extends ItemFilter<T> {
private static final Dimension BUTTON_SIZE = new Dimension(60, 24); protected boolean lockFiltering;
private final ArrayList<FLabel> buttons = new ArrayList<FLabel>(); private final ArrayList<FLabel> buttons = new ArrayList<FLabel>();
protected ToggleButtonsFilter(ItemManager<T> itemManager0) { protected ToggleButtonsFilter(ItemManager<T> itemManager0) {
super(itemManager0); super(itemManager0);
} }
protected void addToggleButton(JPanel panel, StatTypes s) { protected FLabel addToggleButton(JPanel widget, String filterName, SkinImage icon) {
addToggleButton(panel, s.toLabelString(), s.img);
}
protected void addToggleButton(JPanel panel, String filterName, SkinImage icon) {
final FLabel button = new FLabel.Builder() final FLabel button = new FLabel.Builder()
.icon(icon).iconScaleAuto(false) .icon(icon).iconScaleAuto(false)
.fontSize(11) .fontSize(11)
.tooltip(filterName + " (click to toggle the filter, right-click to show only " + filterName.toLowerCase() + ")") .tooltip(filterName + " (click to toggle the filter, right-click to show only " + filterName.toLowerCase() + ")")
.hoverable().selectable(true).selected(true) .hoverable().selectable(true).selected(true)
.build(); .build();
button.setPreferredSize(BUTTON_SIZE);
button.setMinimumSize(BUTTON_SIZE);
button.setCommand(new Command() { button.setCommand(new Command() {
@Override @Override
public void run() { public void run() {
if (lockFiltering) { return; }
applyChange(); applyChange();
} }
}); });
//hook so right-clicking a button toggles itself on and toggles off all other buttons
button.setRightClickCommand(new Command() {
@Override
public void run() {
for(FLabel btn : buttons) {
btn.setSelected(false);
}
button.setSelected(true);
applyChange();
}
});
this.buttons.add(button); this.buttons.add(button);
panel.add(button); widget.add(button);
return button;
}
@Override
protected void doWidgetLayout(LayoutHelper helper) {
int availableWidth = helper.getParentWidth() - (buttons.size() - 1) * 2; //account for gaps
int buttonWidth = availableWidth / buttons.size();
Graphics g = buttons.get(0).getGraphics();
if (buttonWidth <= 0 || g == null) {
return;
}
int maxTextWidth = buttonWidth - 8; //account for padding
for (FLabel btn : buttons) {
if (!btn.getText().isEmpty()) {
int max = maxTextWidth;
Icon icon = btn.getIcon();
if (icon != null) {
max -= icon.getIconWidth() + 4;
}
for (int fs = 11; fs > 5; fs--) {
SkinFont skinFont = FSkin.getFont(fs);
if (skinFont.measureTextWidth(g, btn.getText()) <= max) {
FSkin.get(btn).setFont(skinFont);
break;
}
}
helper.include(btn, buttonWidth, 25);
helper.offset(-1, 0); //keep buttons tighter together
}
}
}
@Override
public final boolean isEmpty() {
for (FLabel button : buttons) { //consider filter empty if any button isn't selected
if (!button.getSelected()) {
return false;
}
}
return true;
}
@Override
public void reset() {
for (FLabel button : buttons) {
button.setSelected(true);
}
} }
/** /**

View File

@@ -1,18 +1,127 @@
package forge.gui.toolbox.itemmanager.filters; package forge.gui.toolbox.itemmanager.filters;
import java.awt.Component;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import com.google.common.base.Predicate;
import forge.card.CardRules;
import forge.card.CardRulesPredicates;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSpinner;
import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.LayoutHelper;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.SFilterUtil;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.util.ComparableOp;
/** /**
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public abstract class ValueRangeFilter<T extends InventoryItem> extends ItemFilter<T> { public abstract class ValueRangeFilter<T extends InventoryItem> extends ItemFilter<T> {
private FLabel label;
private FSpinner lowerBound, upperBound;
protected ValueRangeFilter(ItemManager<T> itemManager0) { protected ValueRangeFilter(ItemManager<T> itemManager0) {
super(itemManager0); super(itemManager0);
} }
protected abstract String getCaption();
protected int minValue() {
return 0;
}
protected int maxValue() {
return 20;
}
@Override
public final boolean isEmpty() {
return lowerBound.getValue().equals(minValue()) && upperBound.getValue().equals(maxValue());
}
@Override
public void reset() {
lowerBound.setValue(minValue());
upperBound.setValue(maxValue());
}
@Override
public Component getMainComponent() {
return ((JSpinner.DefaultEditor)lowerBound.getEditor()).getTextField();
}
@Override
protected final void buildWidget(JPanel widget) {
lowerBound = addSpinner(widget, true);
String text = " <= " + this.getCaption() + " <= ";
label = new FLabel.Builder().text(text).fontSize(12).build();
widget.add(label);
upperBound = addSpinner(widget, false);
lowerBound.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent arg0) {
if (Integer.parseInt(upperBound.getValue().toString()) <
Integer.parseInt(lowerBound.getValue().toString()))
{
upperBound.setValue(lowerBound.getValue());
}
applyChange();
}
});
upperBound.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent arg0) {
if (Integer.parseInt(lowerBound.getValue().toString()) >
Integer.parseInt(upperBound.getValue().toString()))
{
lowerBound.setValue(upperBound.getValue());
}
applyChange();
}
});
}
@Override
protected void doWidgetLayout(LayoutHelper helper) {
helper.include(lowerBound, 45, FTextField.HEIGHT);
helper.include(label, 125, 26);
helper.include(upperBound, 45, FTextField.HEIGHT);
}
private FSpinner addSpinner(JPanel widget, boolean lowerBound) {
FSpinner spinner = new FSpinner.Builder()
.minValue(this.minValue())
.maxValue(this.maxValue())
.initialValue(lowerBound ? this.minValue() : this.maxValue())
.build();
spinner.setFocusable(false); //only the spinner text field should be focusable, not the up/down widget
widget.add(spinner);
return spinner;
}
protected Predicate<CardRules> getCardRulesFieldPredicate(CardRulesPredicates.LeafNumber.CardField field) {
int lowerValue = Integer.parseInt(lowerBound.getValue().toString());
int upperValue = Integer.parseInt(upperBound.getValue().toString());
boolean hasMin = lowerValue != minValue();
boolean hasMax = upperValue != maxValue();
Predicate<CardRules> pLower = hasMin ? new CardRulesPredicates.LeafNumber(field, ComparableOp.GT_OR_EQUAL, lowerValue) : null;
Predicate<CardRules> pUpper = hasMax ? new CardRulesPredicates.LeafNumber(field, ComparableOp.LT_OR_EQUAL, upperValue) : null;
return SFilterUtil.optimizedAnd(pLower, pUpper);
}
/** /**
* Merge the given filter with this filter if possible * Merge the given filter with this filter if possible
* @param filter * @param filter

View File

@@ -33,8 +33,6 @@ import java.util.List;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.JViewport; import javax.swing.JViewport;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableColumnModel; import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.JTableHeader; import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer; import javax.swing.table.TableCellRenderer;
@@ -43,7 +41,6 @@ import javax.swing.table.TableColumn;
import forge.gui.toolbox.FSkin; import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.ItemManagerModel; import forge.gui.toolbox.itemmanager.ItemManagerModel;
import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.item.InventoryItem; import forge.item.InventoryItem;
@@ -62,7 +59,7 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
public ItemManager<T> getItemManager() { public ItemManager<T> getItemManager() {
return this.itemManager; return this.itemManager;
} }
public ItemTableModel<T> getTableModel() { public ItemTableModel<T> getTableModel() {
return this.tableModel; return this.tableModel;
} }
@@ -88,7 +85,7 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
skin.setSelectionBackground(FSkin.getColor(FSkin.Colors.CLR_INACTIVE)); skin.setSelectionBackground(FSkin.getColor(FSkin.Colors.CLR_INACTIVE));
} }
} }
@Override @Override
public void focusGained(FocusEvent e) { public void focusGained(FocusEvent e) {
skin.setSelectionBackground(FSkin.getColor(FSkin.Colors.CLR_ACTIVE)); skin.setSelectionBackground(FSkin.getColor(FSkin.Colors.CLR_ACTIVE));
@@ -98,24 +95,17 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
} }
} }
}); });
skin.setFont(FSkin.getFont(12)); skin.setFont(FSkin.getFont(12));
setBorder(null); setBorder(null);
getTableHeader().setBorder(null); getTableHeader().setBorder(null);
setRowHeight(18); setRowHeight(18);
setWantElasticColumns(false); setWantElasticColumns(false);
// prevent tables from intercepting tab focus traversals // prevent tables from intercepting tab focus traversals
setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null); setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null); setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
} }
private final TableModelListener tableModelListener = new TableModelListener() {
@Override
public void tableChanged(final TableModelEvent ev) {
SItemManagerUtil.setStats(ItemTable.this.itemManager);
}
};
/** /**
* Applies a EditorTableModel and a model listener to this instance's JTable. * Applies a EditorTableModel and a model listener to this instance's JTable.
@@ -124,7 +114,7 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
*/ */
public void setup(final List<TableColumnInfo<InventoryItem>> cols) { public void setup(final List<TableColumnInfo<InventoryItem>> cols) {
final DefaultTableColumnModel colmodel = new DefaultTableColumnModel(); final DefaultTableColumnModel colmodel = new DefaultTableColumnModel();
//ensure columns ordered properly //ensure columns ordered properly
Collections.sort(cols, new Comparator<TableColumnInfo<InventoryItem>>() { Collections.sort(cols, new Comparator<TableColumnInfo<InventoryItem>>() {
@Override @Override
@@ -146,16 +136,12 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
this.tableModel.refreshSort(); this.tableModel.refreshSort();
getTableHeader().setBackground(new Color(200, 200, 200)); getTableHeader().setBackground(new Color(200, 200, 200));
// Update stats each time table changes
this.tableModel.removeTableModelListener(tableModelListener); //ensure listener not added multiple times
this.tableModel.addTableModelListener(tableModelListener);
} }
private String _getCellTooltip(TableCellRenderer renderer, int row, int col, Object val) { private String _getCellTooltip(TableCellRenderer renderer, int row, int col, Object val) {
Component cell = renderer.getTableCellRendererComponent( Component cell = renderer.getTableCellRendererComponent(
this, val, false, false, row, col); this, val, false, false, row, col);
// if we're conditionally showing the tooltip, check to see // if we're conditionally showing the tooltip, check to see
// if we shouldn't show it // if we shouldn't show it
if (!(cell instanceof AlwaysShowToolTip)) if (!(cell instanceof AlwaysShowToolTip))
@@ -185,7 +171,7 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
// otherwise, show the full text in the tooltip // otherwise, show the full text in the tooltip
return String.valueOf(val); return String.valueOf(val);
} }
// column headers // column headers
@Override @Override
protected JTableHeader createDefaultTableHeader() { protected JTableHeader createDefaultTableHeader() {
@@ -198,36 +184,36 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
if (null == headerRenderer) { if (null == headerRenderer) {
headerRenderer = getDefaultRenderer(); headerRenderer = getDefaultRenderer();
} }
return _getCellTooltip( return _getCellTooltip(
headerRenderer, -1, col, tableColumn.getHeaderValue()); headerRenderer, -1, col, tableColumn.getHeaderValue());
} }
}; };
} }
// cell data // cell data
@Override @Override
public String getToolTipText(MouseEvent e) { public String getToolTipText(MouseEvent e) {
Point p = e.getPoint(); Point p = e.getPoint();
int row = rowAtPoint(p); int row = rowAtPoint(p);
int col = columnAtPoint(p); int col = columnAtPoint(p);
if (col >= getColumnCount() || row >= getRowCount()) { if (col >= getColumnCount() || row >= getRowCount()) {
return null; return null;
} }
Object val = getValueAt(row, col); Object val = getValueAt(row, col);
if (null == val) { if (null == val) {
return null; return null;
} }
return _getCellTooltip(getCellRenderer(row, col), row, col, val); return _getCellTooltip(getCellRenderer(row, col), row, col, val);
} }
private int lastTooltipRow = -1; private int lastTooltipRow = -1;
private int lastTooltipCol = -1; private int lastTooltipCol = -1;
private Point lastTooltipPt; private Point lastTooltipPt;
@Override @Override
public Point getToolTipLocation(MouseEvent e) { public Point getToolTipLocation(MouseEvent e) {
Point p = e.getPoint(); Point p = e.getPoint();
@@ -265,19 +251,19 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
if (0 > rowLastSelected) { if (0 > rowLastSelected) {
return; return;
} }
// 3 cases: 0 items left, select the same row, select prev row // 3 cases: 0 items left, select the same row, select prev row
int numRows = getRowCount(); int numRows = getRowCount();
if (numRows == 0) { if (numRows == 0) {
return; return;
} }
int newRow = rowLastSelected; int newRow = rowLastSelected;
if (numRows <= newRow) { if (numRows <= newRow) {
// move selection away from the last, already missing, option // move selection away from the last, already missing, option
newRow = numRows - 1; newRow = numRows - 1;
} }
selectAndScrollTo(newRow); selectAndScrollTo(newRow);
} }
@@ -291,7 +277,7 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
final int iRow = getSelectedRow(); final int iRow = getSelectedRow();
return iRow >= 0 ? this.tableModel.rowToItem(iRow).getKey() : null; return iRow >= 0 ? this.tableModel.rowToItem(iRow).getKey() : null;
} }
/** /**
* *
* getSelectedItems. * getSelectedItems.
@@ -322,7 +308,7 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
public void setWantElasticColumns(boolean value) { public void setWantElasticColumns(boolean value) {
setAutoResizeMode(value ? JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS : JTable.AUTO_RESIZE_OFF); setAutoResizeMode(value ? JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS : JTable.AUTO_RESIZE_OFF);
} }
public void selectAndScrollTo(int rowIdx) { public void selectAndScrollTo(int rowIdx) {
if (!(getParent() instanceof JViewport)) { if (!(getParent() instanceof JViewport)) {
return; return;
@@ -342,7 +328,7 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
// target is above is, move to position 3 rows above target // target is above is, move to position 3 rows above target
targetRect.setLocation(targetRect.x, targetRect.y - (targetRect.height * 3)); targetRect.setLocation(targetRect.x, targetRect.y - (targetRect.height * 3));
} }
scrollRectToVisible(targetRect); scrollRectToVisible(targetRect);
setRowSelectionInterval(rowIdx, rowIdx); setRowSelectionInterval(rowIdx, rowIdx);
} }

View File

@@ -29,7 +29,6 @@ import forge.gui.toolbox.itemmanager.CardManager;
import forge.gui.toolbox.itemmanager.SItemManagerIO; import forge.gui.toolbox.itemmanager.SItemManagerIO;
import forge.gui.toolbox.itemmanager.SItemManagerIO.EditorPreference; import forge.gui.toolbox.itemmanager.SItemManagerIO.EditorPreference;
import forge.gui.toolbox.itemmanager.table.ItemTable; import forge.gui.toolbox.itemmanager.table.ItemTable;
import forge.gui.workshop.controllers.CWorkshopCatalog;
import forge.gui.workshop.menus.CWorkshopUIMenus; import forge.gui.workshop.menus.CWorkshopUIMenus;
import forge.gui.workshop.views.VWorkshopCatalog; import forge.gui.workshop.views.VWorkshopCatalog;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -78,7 +77,6 @@ public enum CWorkshopUI implements ICDoc, IMenuProvider {
boolean wantUnique = SItemManagerIO.getPref(EditorPreference.display_unique_only); boolean wantUnique = SItemManagerIO.getPref(EditorPreference.display_unique_only);
cardTable.setWantElasticColumns(wantElastic); cardTable.setWantElasticColumns(wantElastic);
cardManager.setWantUnique(wantUnique); cardManager.setWantUnique(wantUnique);
CWorkshopCatalog.SINGLETON_INSTANCE.applyCurrentFilter();
} }
/* (non-Javadoc) /* (non-Javadoc)

View File

@@ -1,54 +1,13 @@
package forge.gui.workshop.controllers; package forge.gui.workshop.controllers;
import java.awt.Toolkit;
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.List;
import java.util.Map;
import java.util.Set;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSpinner;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.Command; import forge.Command;
import forge.Singletons;
import forge.card.CardEdition;
import forge.game.GameFormat;
import forge.gui.GuiUtils;
import forge.gui.workshop.views.VWorkshopCatalog; import forge.gui.workshop.views.VWorkshopCatalog;
import forge.gui.deckeditor.views.VCardCatalog.RangeTypes;
import forge.gui.framework.ICDoc; import forge.gui.framework.ICDoc;
import forge.gui.home.quest.DialogChooseSets;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSpinner;
import forge.gui.toolbox.itemmanager.SFilterUtil;
import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.gui.toolbox.itemmanager.SItemManagerUtil.StatTypes;
import forge.gui.toolbox.itemmanager.table.SColumnUtil; import forge.gui.toolbox.itemmanager.table.SColumnUtil;
import forge.gui.toolbox.itemmanager.table.TableColumnInfo; import forge.gui.toolbox.itemmanager.table.TableColumnInfo;
import forge.gui.toolbox.itemmanager.table.SColumnUtil.ColumnName; import forge.gui.toolbox.itemmanager.table.SColumnUtil.ColumnName;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.item.PaperCard;
import forge.item.ItemPredicate;
import forge.quest.QuestWorld;
import forge.quest.data.GameFormatQuest;
/** /**
* Controls the "card catalog" panel in the workshop UI. * Controls the "card catalog" panel in the workshop UI.
@@ -60,13 +19,6 @@ public enum CWorkshopCatalog implements ICDoc {
/** */ /** */
SINGLETON_INSTANCE; SINGLETON_INSTANCE;
private final Set<Predicate<PaperCard>> activePredicates = new HashSet<Predicate<PaperCard>>();
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 CWorkshopCatalog() { private CWorkshopCatalog() {
} }
@@ -84,279 +36,7 @@ public enum CWorkshopCatalog implements ICDoc {
* @see forge.gui.framework.ICDoc#initialize() * @see forge.gui.framework.ICDoc#initialize()
*/ */
@Override @Override
@SuppressWarnings("serial") public void initialize() {
public void initialize() {
final Command updateFilterCommand = new Command() {
@Override
public void run() {
if (!disableFiltering) {
applyCurrentFilter();
}
}
};
for (Map.Entry<SItemManagerUtil.StatTypes, FLabel> entry : VWorkshopCatalog.SINGLETON_INSTANCE.getStatLabels().entrySet()) {
final FLabel statLabel = entry.getValue();
statLabel.setCommand(updateFilterCommand);
//hook so right-clicking a filter in a group toggles itself off and toggles on all other filters in group
final SItemManagerUtil.StatTypes st = entry.getKey();
final int group = st.group;
if (group > 0) {
statLabel.setRightClickCommand(new Command() {
@SuppressWarnings("incomplete-switch")
@Override
public void run() {
if (!disableFiltering) {
disableFiltering = true;
boolean foundSelected = false;
for (SItemManagerUtil.StatTypes s : SItemManagerUtil.StatTypes.values()) {
if (s.group == group && s != st) {
FLabel lbl = VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().getStatLabel(s);
if (s == StatTypes.MULTICOLOR) {
switch (st) {
case WHITE:
case BLUE:
case BLACK:
case RED:
case GREEN:
//ensure multicolor filter selected after right-clicking a color filter
if (!lbl.getSelected()) {
lbl.setSelected(true);
}
continue;
}
}
if (lbl.getSelected()) {
foundSelected = true;
lbl.setSelected(false);
}
}
}
if (!statLabel.getSelected()) {
statLabel.setSelected(true);
}
else if (!foundSelected) {
//if statLabel only label in group selected, re-select all other labels in group
for (SItemManagerUtil.StatTypes s : SItemManagerUtil.StatTypes.values()) {
if (s.group == group && s != st) {
FLabel lbl = VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().getStatLabel(s);
if (!lbl.getSelected()) {
lbl.setSelected(true);
}
}
}
}
disableFiltering = false;
applyCurrentFilter();
}
}
});
}
}
VWorkshopCatalog.SINGLETON_INSTANCE.getStatLabels().get(SItemManagerUtil.StatTypes.TOTAL).setCommand(new Command() {
private boolean lastToggle = true;
@Override
public void run() {
disableFiltering = true;
lastToggle = !lastToggle;
for (SItemManagerUtil.StatTypes s : SItemManagerUtil.StatTypes.values()) {
if (SItemManagerUtil.StatTypes.TOTAL != s) {
VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().getStatLabel(s).setSelected(lastToggle);
}
}
disableFiltering = false;
applyCurrentFilter();
}
});
// assemble add restriction menu
final Command addRestrictionCommand = new Command() {
@Override
public void run() {
JPopupMenu popup = new JPopupMenu("RestrictionPopupMenu");
GuiUtils.addMenuItem(popup, "Current text search",
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
new Runnable() {
@Override
public void run() {
addRestriction(buildSearchRestriction(), null, null);
}
}, canSearch());
JMenu fmt = new JMenu("Format");
for (final GameFormat f : Singletons.getModel().getFormats()) {
GuiUtils.addMenuItem(fmt, f.getName(), null, new Runnable() {
@Override
public void run() {
addRestriction(buildFormatRestriction(f.toString(), f, true), activeFormats, f);
}
}, !isActive(activeFormats, f));
}
popup.add(fmt);
GuiUtils.addMenuItem(popup, "Sets...", null, new Runnable() {
@Override
public void run() {
final DialogChooseSets dialog = new DialogChooseSets(null, null, true);
dialog.setOkCallback(new Runnable() {
@Override
public void run() {
List<String> setCodes = dialog.getSelectedSets();
if (setCodes.isEmpty()) {
return;
}
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(buildSetRestriction(label.toString(), setCodes, dialog.getWantReprints()), null, null);
}
});
}
});
JMenu range = new JMenu("Value range");
for (final RangeTypes t : RangeTypes.values()) {
GuiUtils.addMenuItem(range, t.toLabelString() + " restriction", null, new Runnable() {
@Override
public void run() {
addRestriction(buildRangeRestriction(t), activeRanges, t);
}
}, !isActive(activeRanges, t));
}
popup.add(range);
JMenu world = new JMenu("Quest world");
for (final QuestWorld w : Singletons.getModel().getWorlds()) {
GameFormatQuest format = w.getFormat();
if (null == format) {
// assumes that no world other than the main world will have a null format
format = Singletons.getModel().getQuest().getMainFormat();
}
final GameFormatQuest f = format;
GuiUtils.addMenuItem(world, w.getName(), null, new Runnable() {
@Override
public void run() {
addRestriction(buildFormatRestriction(w.getName(), f, true), activeWorlds, w);
}
}, !isActive(activeWorlds, w) && null != f);
}
popup.add(world);
popup.show(VWorkshopCatalog.SINGLETON_INSTANCE.getBtnAddRestriction(), 0,
VWorkshopCatalog.SINGLETON_INSTANCE.getBtnAddRestriction().getHeight());
}
};
FLabel btnAddRestriction = VWorkshopCatalog.SINGLETON_INSTANCE.getBtnAddRestriction();
btnAddRestriction.setCommand(addRestrictionCommand);
btnAddRestriction.setRightClickCommand(addRestrictionCommand); //show menu on right-click too
VWorkshopCatalog.SINGLETON_INSTANCE.getCbSearchMode().addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent arg0) {
applyCurrentFilter();
}
});
Runnable addSearchRestriction = new Runnable() {
@Override
public void run() {
if (canSearch()) {
addRestriction(buildSearchRestriction(), null, null);
}
}
};
// add search restriction on ctrl-enter from either the textbox or combobox
VWorkshopCatalog.SINGLETON_INSTANCE.getCbSearchMode().addKeyListener(new _OnCtrlEnter(addSearchRestriction));
VWorkshopCatalog.SINGLETON_INSTANCE.getTxfSearch().addKeyListener(new _OnCtrlEnter(addSearchRestriction) {
private boolean keypressPending;
@Override
public void keyReleased(KeyEvent e) {
if (KeyEvent.VK_ENTER == e.getKeyCode() && 0 == e.getModifiers()) {
// set focus to table when a plain enter is typed into the text filter box
VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().getTable().requestFocusInWindow();
} else if (keypressPending) {
// do this in keyReleased instead of keyTyped since the textbox text isn't updated until the key is released
// but depend on keypressPending since otherwise we pick up hotkeys and other unwanted stuff
applyCurrentFilter();
}
}
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
keypressPending = KeyEvent.VK_ENTER != e.getKeyCode();
}
});
VWorkshopCatalog.SINGLETON_INSTANCE.getLblName().setCommand(updateFilterCommand);
VWorkshopCatalog.SINGLETON_INSTANCE.getLblType().setCommand(updateFilterCommand);
VWorkshopCatalog.SINGLETON_INSTANCE.getLblText().setCommand(updateFilterCommand);
// ensure mins can's exceed maxes and maxes can't fall below mins
for (Pair<FSpinner, FSpinner> sPair : VWorkshopCatalog.SINGLETON_INSTANCE.getSpinners().values()) {
final FSpinner min = sPair.getLeft();
final FSpinner max = sPair.getRight();
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();
}
});
}
}
private class _OnCtrlEnter extends KeyAdapter {
private final Runnable action;
_OnCtrlEnter(Runnable action) {
this.action = action;
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
if (e.isControlDown() || e.isMetaDown()) {
action.run();
}
}
}
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -369,202 +49,4 @@ public enum CWorkshopCatalog implements ICDoc {
VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().getTable().setup(lstCatalogCols); VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().getTable().setup(lstCatalogCols);
//TODO: Restore previously selected card //TODO: Restore previously selected card
} }
public void applyCurrentFilter() {
// The main trick here is to apply a CardPrinted predicate
// to the table. CardRules will lead to difficulties.
List<Predicate<? super PaperCard>> cardPredicates = new ArrayList<Predicate<? super PaperCard>>();
cardPredicates.add(Predicates.instanceOf(PaperCard.class));
cardPredicates.add(SFilterUtil.buildColorAndTypeFilter(VWorkshopCatalog.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(VWorkshopCatalog.SINGLETON_INSTANCE.getSpinners(), t));
}
}
// get the current contents of the search box
cardPredicates.add(SFilterUtil.buildTextFilter(
VWorkshopCatalog.SINGLETON_INSTANCE.getTxfSearch().getText(),
0 != VWorkshopCatalog.SINGLETON_INSTANCE.getCbSearchMode().getSelectedIndex(),
VWorkshopCatalog.SINGLETON_INSTANCE.getLblName().getSelected(),
VWorkshopCatalog.SINGLETON_INSTANCE.getLblType().getSelected(),
VWorkshopCatalog.SINGLETON_INSTANCE.getLblText().getSelected()));
Predicate<PaperCard> cardFilter = Predicates.and(cardPredicates);
// show packs and decks in the card shop according to the toggle setting
// this is special-cased apart from the buildColorAndTypeFilter() above
if (VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().getStatLabel(StatTypes.PACK).getSelected()) {
List<Predicate<? super PaperCard>> itemPredicates = new ArrayList<Predicate<? super PaperCard>>();
itemPredicates.add(cardFilter);
itemPredicates.add(ItemPredicate.Presets.IS_PACK);
itemPredicates.add(ItemPredicate.Presets.IS_DECK);
cardFilter = Predicates.or(itemPredicates);
}
// Apply to table
VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().setFilterPredicate(cardFilter);
}
private boolean canSearch() {
return !VWorkshopCatalog.SINGLETON_INSTANCE.getTxfSearch().getText().isEmpty() &&
(VWorkshopCatalog.SINGLETON_INSTANCE.getLblName().getSelected() ||
VWorkshopCatalog.SINGLETON_INSTANCE.getLblType().getSelected() ||
VWorkshopCatalog.SINGLETON_INSTANCE.getLblText().getSelected());
}
private <T> boolean isActive(Set<T> activeSet, T key) {
return activeSet.contains(key);
}
@SuppressWarnings("serial")
private <T> void addRestriction(Pair<? extends JComponent, Predicate<PaperCard>> restriction, final Set<T> activeSet, final T key) {
final Predicate<PaperCard> predicate = restriction.getRight();
if (null != predicate && activePredicates.contains(predicate)) {
return;
}
VWorkshopCatalog.SINGLETON_INSTANCE.addRestrictionWidget(restriction.getLeft(), new Command() {
@Override
public void run() {
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<JPanel, Predicate<PaperCard>> buildRangeRestriction(RangeTypes t) {
final Pair<FSpinner, FSpinner> s = VWorkshopCatalog.SINGLETON_INSTANCE.getSpinners().get(t);
s.getLeft().setValue(0);
s.getRight().setValue(10);
// set focus to lower bound widget
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
((JSpinner.DefaultEditor)s.getLeft().getEditor()).getTextField().requestFocusInWindow();
}
});
return Pair.of(VWorkshopCatalog.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<FLabel, Predicate<PaperCard>> buildSearchRestriction() {
boolean isInverse =
VWorkshopCatalog.SEARCH_MODE_INVERSE_INDEX == VWorkshopCatalog.SINGLETON_INSTANCE.getCbSearchMode().getSelectedIndex();
String text = VWorkshopCatalog.SINGLETON_INSTANCE.getTxfSearch().getText();
boolean wantName = VWorkshopCatalog.SINGLETON_INSTANCE.getLblName().getSelected();
boolean wantType = VWorkshopCatalog.SINGLETON_INSTANCE.getLblType().getSelected();
boolean wantText = VWorkshopCatalog.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);
}
VWorkshopCatalog.SINGLETON_INSTANCE.getTxfSearch().setText("");
return Pair.of(
VWorkshopCatalog.SINGLETON_INSTANCE.buildPlainRestrictionWidget(shortText, fullText),
SFilterUtil.buildTextFilter(text, isInverse, wantName, wantType, wantText));
}
private Pair<FLabel, Predicate<PaperCard>> buildFormatRestriction(String displayName, GameFormat format, boolean allowReprints) {
CardEdition.Collection editions = Singletons.getMagicDb().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 = 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());
if (allowReprints) {
tooltip.append("<br><br>Allowing identical cards from other sets");
}
}
List<String> bannedCards = 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 Pair.of(
VWorkshopCatalog.SINGLETON_INSTANCE.buildPlainRestrictionWidget(displayName, tooltip.toString()),
allowReprints ? format.getFilterRules() : format.getFilterPrinted());
}
private Pair<FLabel, Predicate<PaperCard>> buildSetRestriction(String displayName, List<String> setCodes, boolean allowReprints) {
return buildFormatRestriction(displayName, new GameFormat(null, setCodes, null), allowReprints);
}
} }

View File

@@ -1,42 +1,22 @@
package forge.gui.workshop.views; package forge.gui.workshop.views;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import forge.Command;
import forge.Singletons; import forge.Singletons;
import forge.gui.WrapLayout;
import forge.gui.deckeditor.views.VCardCatalog.RangeTypes;
import forge.gui.framework.DragCell; import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab; import forge.gui.framework.DragTab;
import forge.gui.framework.EDocID; import forge.gui.framework.EDocID;
import forge.gui.framework.IVDoc; import forge.gui.framework.IVDoc;
import forge.gui.match.controllers.CDetail; import forge.gui.match.controllers.CDetail;
import forge.gui.match.controllers.CPicture; import forge.gui.match.controllers.CPicture;
import forge.gui.toolbox.FComboBoxWrapper;
import forge.gui.toolbox.FLabel;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FSpinner;
import forge.gui.toolbox.FTextField;
import forge.gui.toolbox.itemmanager.CardManager; import forge.gui.toolbox.itemmanager.CardManager;
import forge.gui.toolbox.itemmanager.ItemManagerContainer; import forge.gui.toolbox.itemmanager.ItemManagerContainer;
import forge.gui.toolbox.itemmanager.SItemManagerUtil;
import forge.gui.workshop.controllers.CCardScript; import forge.gui.workshop.controllers.CCardScript;
import forge.gui.workshop.controllers.CWorkshopCatalog; import forge.gui.workshop.controllers.CWorkshopCatalog;
import forge.item.PaperCard; import forge.item.PaperCard;
@@ -57,76 +37,13 @@ public enum VWorkshopCatalog implements IVDoc<CWorkshopCatalog> {
// Fields used with interface IVDoc // Fields used with interface IVDoc
private DragCell parentCell; private DragCell parentCell;
private final DragTab tab = new DragTab("Card Catalog"); private final DragTab tab = new DragTab("Card Catalog");
// Total and color count labels/filter toggles
private final Dimension labelSize = new Dimension(60, 24);
private final JPanel pnlStats = new JPanel(new WrapLayout(FlowLayout.LEFT));
private final Map<SItemManagerUtil.StatTypes, FLabel> statLabels =
new HashMap<SItemManagerUtil.StatTypes, FLabel>();
// restriction button and search widgets
private final JPanel pnlSearch = new JPanel(new MigLayout("insets 0, gap 5px, center"));
private final FLabel btnAddRestriction = new FLabel.ButtonBuilder()
.text("Add filter")
.tooltip("Click to add custom filters to the card list")
.reactOnMouseDown().build();
private final FComboBoxWrapper<String> cbSearchMode = new FComboBoxWrapper<String>();
private final JTextField txfSearch = new FTextField.Builder().ghostText("Search").build();
private final FLabel lblName = new FLabel.Builder().text("Name").hoverable().selectable().selected().build();
private final FLabel lblType = new FLabel.Builder().text("Type").hoverable().selectable().selected().build();
private final FLabel lblText = new FLabel.Builder().text("Text").hoverable().selectable().selected().build();
private final JPanel pnlRestrictions = new JPanel(new WrapLayout(FlowLayout.LEFT, 10, 5));
private final ItemManagerContainer cardManagerContainer = new ItemManagerContainer(); private final ItemManagerContainer cardManagerContainer = new ItemManagerContainer();
private final CardManager cardManager; private final CardManager cardManager;
private final Map<RangeTypes, Pair<FSpinner, FSpinner>> spinners = new HashMap<RangeTypes, Pair<FSpinner, FSpinner>>();
//========== Constructor //========== Constructor
/** */ /** */
private VWorkshopCatalog() { private VWorkshopCatalog() {
pnlStats.setOpaque(false); this.cardManager = new CardManager(true);
for (SItemManagerUtil.StatTypes s : SItemManagerUtil.StatTypes.values()) {
FLabel label = buildToggleLabel(s, SItemManagerUtil.StatTypes.TOTAL != s);
statLabels.put(s, label);
JComponent component = label;
if (SItemManagerUtil.StatTypes.TOTAL == s) {
label.setToolTipText("Total cards (click to toggle all filters)");
} else if (SItemManagerUtil.StatTypes.PACK == s) {
// wrap in a constant-size panel so we can change its visibility without affecting layout
component = new JPanel(new MigLayout("insets 0, gap 0"));
component.setPreferredSize(labelSize);
component.setMinimumSize(labelSize);
component.setOpaque(false);
label.setVisible(false);
component.add(label);
}
pnlStats.add(component);
}
pnlSearch.setOpaque(false);
pnlSearch.add(btnAddRestriction, "center, w pref+8, h pref+8");
pnlSearch.add(txfSearch, "pushx, growx");
cbSearchMode.addItem("in");
cbSearchMode.addItem("not in");
cbSearchMode.addTo(pnlSearch, "center");
pnlSearch.add(lblName, "w pref+8, h pref+8");
pnlSearch.add(lblType, "w pref+8, h pref+8");
pnlSearch.add(lblText, "w pref+8, h pref+8");
pnlRestrictions.setOpaque(false);
// fill spinner map
for (RangeTypes t : RangeTypes.values()) {
FSpinner lowerBound = new FSpinner.Builder().maxValue(10).build();
FSpinner upperBound = new FSpinner.Builder().maxValue(10).build();
_setupSpinner(lowerBound);
_setupSpinner(upperBound);
spinners.put(t, Pair.of(lowerBound, upperBound));
}
this.cardManager = new CardManager(this.statLabels, true);
Iterable<PaperCard> allCards = Iterables.concat(Singletons.getMagicDb().getCommonCards(), Singletons.getMagicDb().getVariantCards()); Iterable<PaperCard> allCards = Iterables.concat(Singletons.getMagicDb().getCommonCards(), Singletons.getMagicDb().getVariantCards());
this.cardManager.setPool(ItemPool.createFrom(allCards, PaperCard.class), true); this.cardManager.setPool(ItemPool.createFrom(allCards, PaperCard.class), true);
this.cardManagerContainer.setItemManager(this.cardManager); this.cardManagerContainer.setItemManager(this.cardManager);
@@ -142,10 +59,6 @@ public enum VWorkshopCatalog implements IVDoc<CWorkshopCatalog> {
}); });
} }
private void _setupSpinner (JSpinner spinner) {
spinner.setFocusable(false); // only the spinner text field should be focusable, not the up/down widget
}
//========== Overridden from IVDoc //========== Overridden from IVDoc
@Override @Override
@@ -176,98 +89,11 @@ public enum VWorkshopCatalog implements IVDoc<CWorkshopCatalog> {
@Override @Override
public void populate() { public void populate() {
JPanel parentBody = parentCell.getBody(); JPanel parentBody = parentCell.getBody();
parentBody.setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3")); parentBody.setLayout(new MigLayout("insets 5, gap 0, wrap, hidemode 3"));
parentBody.add(pnlStats, "w 100:520:520, center"); parentBody.add(cardManagerContainer, "push, grow");
parentBody.add(pnlSearch, "w 96%, gap 1% 1%");
parentBody.add(pnlRestrictions, "w 96%, gapleft 1%, gapright push");
parentBody.add(cardManagerContainer, "w 98%!, h 100% - 35, gap 1% 0 0 1%");
} }
//========== Accessor/mutator methods
public FLabel getLblName() { return lblName; }
public FLabel getLblType() { return lblType; }
public FLabel getLblText() { return lblText; }
public FLabel getBtnAddRestriction() { return btnAddRestriction; }
public FComboBoxWrapper<String> getCbSearchMode() { return cbSearchMode; }
public JTextField getTxfSearch() { return txfSearch; }
public CardManager getCardManager() { public CardManager getCardManager() {
return cardManager; return cardManager;
} }
public Map<SItemManagerUtil.StatTypes, FLabel> getStatLabels() {
return statLabels;
}
public Map<RangeTypes, Pair<FSpinner, FSpinner>> getSpinners() {
return spinners;
}
//========== Other methods
private FLabel buildToggleLabel(SItemManagerUtil.StatTypes s, boolean selectable) {
String tooltip;
if (selectable) { //construct tooltip for selectable toggle labels, indicating click and right-click behavior
String labelString = s.toLabelString();
tooltip = labelString + " (click to toggle the filter, right-click to show only " + labelString.toLowerCase() + ")";
}
else { tooltip = ""; }
FLabel label = new FLabel.Builder()
.icon(s.img).iconScaleAuto(false)
.fontSize(11)
.tooltip(tooltip)
.hoverable().selectable(selectable).selected(selectable)
.build();
label.setPreferredSize(labelSize);
label.setMinimumSize(labelSize);
return label;
}
@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);
FSkin.get(pnl).setMatteBorder(1, 2, 1, 2, FSkin.getColor(FSkin.Colors.CLR_TEXT));
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 run() {
pnlRestrictions.remove(pnl);
refreshRestrictionWidgets();
onRemove.run();
}
}).build(), "top");
pnlRestrictions.add(pnl, "h 30!");
refreshRestrictionWidgets();
}
public void refreshRestrictionWidgets() {
Container parent = pnlRestrictions.getParent();
pnlRestrictions.validate();
parent.validate();
parent.repaint();
}
public JPanel 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.getLeft(), "w 45!, h 26!, center");
pnl.add(new FLabel.Builder().text("<=").fontSize(11).build(), "h 26!, center");
pnl.add(new FLabel.Builder().text(t.toLabelString()).fontSize(11).build(), "h 26!, center");
pnl.add(new FLabel.Builder().text("<=").fontSize(11).build(), "h 26!, center");
pnl.add(s.getRight(), "w 45!, h 26!, center");
return pnl;
}
public FLabel buildPlainRestrictionWidget(String label, String tooltip) {
return new FLabel.Builder().text(label).tooltip(tooltip).fontSize(11).build();
}
} }