mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Add Workshop screen
This commit is contained in:
10
.gitattributes
vendored
10
.gitattributes
vendored
@@ -13468,6 +13468,7 @@ forge-gui/res/defaults/gauntlet/LOCKED_Swimming[!!-~]With[!!-~]Sharks.dat -text
|
||||
forge-gui/res/defaults/home.xml svneol=native#text/xml
|
||||
forge-gui/res/defaults/match.xml svneol=native#text/xml
|
||||
forge-gui/res/defaults/window.xml -text
|
||||
forge-gui/res/defaults/workshop.xml -text
|
||||
forge-gui/res/draft/cube_juzamjedi.draft -text
|
||||
forge-gui/res/draft/cube_skiera.draft -text
|
||||
forge-gui/res/draft/rankings.txt -text
|
||||
@@ -15457,6 +15458,15 @@ forge-gui/src/main/java/forge/gui/toolbox/special/PhaseIndicator.java -text
|
||||
forge-gui/src/main/java/forge/gui/toolbox/special/PhaseLabel.java -text
|
||||
forge-gui/src/main/java/forge/gui/toolbox/special/PlayerDetailsPanel.java -text
|
||||
forge-gui/src/main/java/forge/gui/toolbox/special/package-info.java -text
|
||||
forge-gui/src/main/java/forge/gui/workshop/CWorkshopUI.java -text
|
||||
forge-gui/src/main/java/forge/gui/workshop/SWorkshopIO.java -text
|
||||
forge-gui/src/main/java/forge/gui/workshop/VWorkshopUI.java -text
|
||||
forge-gui/src/main/java/forge/gui/workshop/controllers/CCardDesigner.java -text
|
||||
forge-gui/src/main/java/forge/gui/workshop/controllers/CCardScript.java -text
|
||||
forge-gui/src/main/java/forge/gui/workshop/controllers/CWorkshopCatalog.java -text
|
||||
forge-gui/src/main/java/forge/gui/workshop/views/VCardDesigner.java -text
|
||||
forge-gui/src/main/java/forge/gui/workshop/views/VCardScript.java -text
|
||||
forge-gui/src/main/java/forge/gui/workshop/views/VWorkshopCatalog.java -text
|
||||
forge-gui/src/main/java/forge/item/BoosterPack.java -text
|
||||
forge-gui/src/main/java/forge/item/FatPack.java -text
|
||||
forge-gui/src/main/java/forge/item/IPaperCard.java -text
|
||||
|
||||
18
forge-gui/res/defaults/workshop.xml
Normal file
18
forge-gui/res/defaults/workshop.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0"?>
|
||||
<layout>
|
||||
<cell x="0.0" y="0.0" w="0.38722" h="0.62302">
|
||||
<doc>WORKSHOP_CATALOG</doc>
|
||||
</cell>
|
||||
<cell x="0.38722" y="0.0" w="0.38722" h="0.62302">
|
||||
<doc>WORKSHOP_CARDDESIGNER</doc>
|
||||
</cell>
|
||||
<cell x="0.0" y="0.62302" w="0.77444" h="0.37698">
|
||||
<doc>WORKSHOP_CARDSCRIPT</doc>
|
||||
</cell>
|
||||
<cell x="0.77444" y="0.0" w="0.22556" h="0.37698">
|
||||
<doc>CARD_DETAIL</doc>
|
||||
</cell>
|
||||
<cell x="0.77444" y="0.37698" w="0.22556" h="0.62302">
|
||||
<doc>CARD_PICTURE</doc>
|
||||
</cell>
|
||||
</layout>
|
||||
@@ -17,7 +17,9 @@
|
||||
*/
|
||||
package forge.card;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import forge.card.mana.ManaCost;
|
||||
|
||||
/**
|
||||
@@ -34,8 +36,8 @@ public final class CardRules implements ICardCharacteristics {
|
||||
//private final Map<String, CardInSet> setsPrinted = new TreeMap<String, CardInSet>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
private CardAiHints aiHints;
|
||||
|
||||
private ColorSet colorIdentity = null;
|
||||
private File sourceFile;
|
||||
|
||||
public CardRules(ICardFace[] faces, CardSplitType altMode, CardAiHints cah) {
|
||||
splitType = altMode;
|
||||
@@ -65,8 +67,7 @@ public final class CardRules implements ICardCharacteristics {
|
||||
colorIdentity = ColorSet.fromMask(colMask);
|
||||
}
|
||||
|
||||
private byte calculateColorIdentity(ICardFace face)
|
||||
{
|
||||
private byte calculateColorIdentity(ICardFace face) {
|
||||
byte res = face.getColor().getColor();
|
||||
boolean isReminder = false;
|
||||
boolean isSymbol = false;
|
||||
@@ -216,7 +217,14 @@ public final class CardRules implements ICardCharacteristics {
|
||||
}
|
||||
|
||||
public ColorSet getColorIdentity() {
|
||||
return colorIdentity;
|
||||
return this.colorIdentity;
|
||||
}
|
||||
|
||||
public File getSourceFile() {
|
||||
return this.sourceFile;
|
||||
}
|
||||
|
||||
public void setSourceFile(File sourceFile0) {
|
||||
this.sourceFile = sourceFile0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,8 +48,6 @@ public class CardRulesReader {
|
||||
private DeckHints hints = null;
|
||||
private DeckHints needs = null;
|
||||
|
||||
|
||||
|
||||
// Reset all fields to parse next card (to avoid allocating new
|
||||
// CardRulesReader N times)
|
||||
/**
|
||||
|
||||
@@ -329,15 +329,17 @@ public class CardStorageReader {
|
||||
*
|
||||
* @return a new Card instance
|
||||
*/
|
||||
protected final CardRules loadCard(final CardRulesReader reader, final File pathToTxtFile) {
|
||||
protected final CardRules loadCard(final CardRulesReader reader, final File file) {
|
||||
FileInputStream fileInputStream = null;
|
||||
try {
|
||||
fileInputStream = new FileInputStream(pathToTxtFile);
|
||||
return this.loadCard(reader, fileInputStream);
|
||||
fileInputStream = new FileInputStream(file);
|
||||
CardRules rules = this.loadCard(reader, fileInputStream);
|
||||
rules.setSourceFile(file);
|
||||
return rules;
|
||||
} catch (final FileNotFoundException ex) {
|
||||
BugReporter.reportException(ex, "File \"%s\" exception", pathToTxtFile.getAbsolutePath());
|
||||
BugReporter.reportException(ex, "File \"%s\" exception", file.getAbsolutePath());
|
||||
throw new RuntimeException("CardReader : run error -- file exception -- filename is "
|
||||
+ pathToTxtFile.getPath(), ex);
|
||||
+ file.getPath(), ex);
|
||||
} finally {
|
||||
try {
|
||||
fileInputStream.close();
|
||||
|
||||
@@ -40,6 +40,8 @@ import javax.swing.PopupFactory;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import org.apache.commons.lang.CharUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@@ -407,6 +409,24 @@ public enum CDeckEditorUI implements ICDoc, IMenuProvider {
|
||||
catTable.addKeyListener(catFind);
|
||||
deckTable.addKeyListener(deckFind);
|
||||
|
||||
//set card when selection changes
|
||||
catView.addSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
setCard(catView.getSelectedItem());
|
||||
}
|
||||
});
|
||||
|
||||
deckView.addSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
setCard(deckView.getSelectedItem());
|
||||
}
|
||||
});
|
||||
|
||||
catView.setAllowMultipleSelections(true);
|
||||
deckView.setAllowMultipleSelections(true);
|
||||
|
||||
childController.listenersHooked = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@ import forge.gui.match.views.VMessage;
|
||||
import forge.gui.match.views.VPicture;
|
||||
import forge.gui.match.views.VPlayers;
|
||||
import forge.gui.match.views.VStack;
|
||||
import forge.gui.workshop.views.VCardDesigner;
|
||||
import forge.gui.workshop.views.VCardScript;
|
||||
import forge.gui.workshop.views.VWorkshopCatalog;
|
||||
|
||||
/**
|
||||
* These are the identifiers for tabs found in the drag layout.
|
||||
@@ -60,6 +63,10 @@ public enum EDocID { /** */
|
||||
EDITOR_CURRENTDECK (VCurrentDeck.SINGLETON_INSTANCE), /** */
|
||||
EDITOR_DECKGEN (VDeckgen.SINGLETON_INSTANCE), /** */
|
||||
|
||||
WORKSHOP_CATALOG (VWorkshopCatalog.SINGLETON_INSTANCE), /** */
|
||||
WORKSHOP_CARDDESIGNER (VCardDesigner.SINGLETON_INSTANCE), /** */
|
||||
WORKSHOP_CARDSCRIPT (VCardScript.SINGLETON_INSTANCE), /** */
|
||||
|
||||
HOME_QUESTCHALLENGES (VSubmenuChallenges.SINGLETON_INSTANCE), /** */
|
||||
HOME_QUESTDUELS (VSubmenuDuels.SINGLETON_INSTANCE), /** */
|
||||
HOME_QUESTDATA (VSubmenuQuestData.SINGLETON_INSTANCE), /** */
|
||||
|
||||
@@ -15,6 +15,8 @@ import forge.gui.match.CMatchUI;
|
||||
import forge.gui.match.VMatchUI;
|
||||
import forge.gui.toolbox.FSkin;
|
||||
import forge.gui.toolbox.FSkin.SkinImage;
|
||||
import forge.gui.workshop.CWorkshopUI;
|
||||
import forge.gui.workshop.VWorkshopUI;
|
||||
import forge.properties.FileLocation;
|
||||
import forge.properties.NewConstants;
|
||||
|
||||
@@ -35,10 +37,18 @@ public enum FScreen {
|
||||
VMatchUI.SINGLETON_INSTANCE,
|
||||
CMatchUI.SINGLETON_INSTANCE,
|
||||
"Game",
|
||||
FSkin.getIcon(FSkin.DockIcons.ICO_ALPHASTRIKE),
|
||||
FSkin.getIcon(FSkin.DockIcons.ICO_ALPHASTRIKE), //TODO: Create icon for match screen
|
||||
true,
|
||||
"Concede Game",
|
||||
NewConstants.MATCH_LAYOUT_FILE),
|
||||
WORKSHOP_SCREEN(
|
||||
VWorkshopUI.SINGLETON_INSTANCE,
|
||||
CWorkshopUI.SINGLETON_INSTANCE,
|
||||
"Workshop",
|
||||
FSkin.getIcon(FSkin.DockIcons.ICO_SETTINGS), //TODO: Create icon for workshop screen
|
||||
false,
|
||||
"Back to Home",
|
||||
NewConstants.WORKSHOP_LAYOUT_FILE),
|
||||
DECK_EDITOR_CONSTRUCTED(
|
||||
VDeckEditorUI.SINGLETON_INSTANCE,
|
||||
CDeckEditorUI.SINGLETON_INSTANCE,
|
||||
|
||||
@@ -107,6 +107,13 @@ public enum CSubmenuPreferences implements ICDoc {
|
||||
}
|
||||
});
|
||||
|
||||
view.getBtnDeleteWorkshopUI().setCommand(new Command() {
|
||||
@Override
|
||||
public void run() {
|
||||
CSubmenuPreferences.this.resetWorkshopLayout();
|
||||
}
|
||||
});
|
||||
|
||||
view.getBtnDeleteMatchUI().setCommand(new Command() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -178,6 +185,19 @@ public enum CSubmenuPreferences implements ICDoc {
|
||||
}
|
||||
}
|
||||
|
||||
private void resetWorkshopLayout() {
|
||||
String userPrompt =
|
||||
"This will reset the Workshop screen layout.\n" +
|
||||
"All tabbed views will be restored to their default positions.\n\n" +
|
||||
"Reset layout?";
|
||||
int reply = JOptionPane.showConfirmDialog(JOptionPane.getRootFrame(), userPrompt, "Reset Workshop Layout", JOptionPane.YES_NO_OPTION);
|
||||
if (reply == JOptionPane.YES_OPTION) {
|
||||
if (FScreen.WORKSHOP_SCREEN.deleteLayoutFile()) {
|
||||
JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Workshop layout has been reset.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetMatchScreenLayout() {
|
||||
String userPrompt =
|
||||
"This will reset the layout of the Match screen.\n" +
|
||||
|
||||
@@ -62,6 +62,7 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
||||
private final FLabel btnReset = new FLabel.Builder().opaque(true).hoverable(true).text("Reset to Default Settings").build();
|
||||
private final FLabel btnDeleteMatchUI = new FLabel.Builder().opaque(true).hoverable(true).text("Reset Match Layout").build();
|
||||
private final FLabel btnDeleteEditorUI = new FLabel.Builder().opaque(true).hoverable(true).text("Reset Editor Layout").build();
|
||||
private final FLabel btnDeleteWorkshopUI = new FLabel.Builder().opaque(true).hoverable(true).text("Reset Workshop Layout").build();
|
||||
private final FLabel btnPlayerName = new FLabel.Builder().opaque(true).hoverable(true).text("").build();
|
||||
|
||||
private final JCheckBox cbRemoveSmall = new OptionsCheckBox("Remove Small Creatures");
|
||||
@@ -103,18 +104,16 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
||||
final String sectionConstraints = "w 80%!, h 42px!, gap 10% 0 10px 10px, span 2 1";
|
||||
final String regularConstraints = "w 80%!, h 22px!, gap 10% 0 0 10px, span 2 1";
|
||||
|
||||
|
||||
// Troubleshooting
|
||||
pnlPrefs.add(new SectionLabel("Troubleshooting"), sectionConstraints);
|
||||
|
||||
//pnlPrefs.add(new SectionLabel(" "), sectionConstraints);
|
||||
pnlPrefs.add(btnReset, regularConstraints + ", h 30px!");
|
||||
|
||||
final String twoButtonConstraints = "w 38%!, h 30px!, gap 10% 0 0 10px";
|
||||
pnlPrefs.add(btnDeleteMatchUI, twoButtonConstraints);
|
||||
pnlPrefs.add(btnDeleteEditorUI, "w 38%!, h 30px!, gap 0 0 0 10px");
|
||||
// Reset button
|
||||
|
||||
// Reset buttons
|
||||
final String twoButtonConstraints1 = "w 38%!, h 30px!, gap 10% 0 0 10px";
|
||||
final String twoButtonConstraints2 = "w 38%!, h 30px!, gap 0 0 0 10px";
|
||||
pnlPrefs.add(btnReset, twoButtonConstraints1);
|
||||
pnlPrefs.add(btnDeleteMatchUI, twoButtonConstraints2);
|
||||
pnlPrefs.add(btnDeleteEditorUI, twoButtonConstraints1);
|
||||
pnlPrefs.add(btnDeleteWorkshopUI, twoButtonConstraints2);
|
||||
|
||||
// General Configuration
|
||||
pnlPrefs.add(new SectionLabel("General Configuration"), sectionConstraints + ", gaptop 2%");
|
||||
@@ -509,6 +508,10 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
||||
return btnDeleteEditorUI;
|
||||
}
|
||||
|
||||
public final FLabel getBtnDeleteWorkshopUI() {
|
||||
return btnDeleteWorkshopUI;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getDocumentID()
|
||||
*/
|
||||
|
||||
@@ -74,8 +74,6 @@ public enum VSubmenuReleaseNotes implements IVSubmenu<CSubmenuReleaseNotes> {
|
||||
|
||||
scroller = new JScrollPane(tar);
|
||||
pnlMain.add(scroller, "w 100%!, h 100%!");
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -29,6 +29,8 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
@@ -68,8 +70,10 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
||||
private final List<ItemFilter<T>> orderedFilters = new ArrayList<ItemFilter<T>>();
|
||||
private boolean wantUnique = false;
|
||||
private boolean alwaysNonUnique = false;
|
||||
private boolean allowMultipleSelections = false;
|
||||
private final Class<T> genericType;
|
||||
private final Map<SItemManagerUtil.StatTypes, FLabel> statLabels;
|
||||
private final ArrayList<ListSelectionListener> selectionListeners = new ArrayList<ListSelectionListener>();
|
||||
|
||||
private final FLabel btnAddFilter = new FLabel.ButtonBuilder()
|
||||
.text("Add")
|
||||
@@ -94,6 +98,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
||||
|
||||
//build table view
|
||||
this.table = new ItemTable<T>(this, this.model);
|
||||
this.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
this.tableScroller = new JScrollPane(this.table);
|
||||
this.tableScroller.setOpaque(false);
|
||||
this.tableScroller.getViewport().setOpaque(false);
|
||||
@@ -133,8 +138,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doLayout()
|
||||
{
|
||||
public void doLayout() {
|
||||
//int number = 0;
|
||||
LayoutHelper helper = new LayoutHelper(this);
|
||||
/*for (ItemFilter<T> filter : this.orderedFilters) {
|
||||
@@ -240,7 +244,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
||||
*
|
||||
* @return InventoryItem
|
||||
*/
|
||||
public InventoryItem getSelectedItem() {
|
||||
public T getSelectedItem() {
|
||||
return this.table.getSelectedItem();
|
||||
}
|
||||
|
||||
@@ -250,7 +254,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
||||
*
|
||||
* @return List<InventoryItem>
|
||||
*/
|
||||
public List<InventoryItem> getSelectedItems() {
|
||||
public List<T> getSelectedItems() {
|
||||
return this.table.getSelectedItems();
|
||||
}
|
||||
|
||||
@@ -471,7 +475,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
||||
*
|
||||
* setWantUnique.
|
||||
*
|
||||
* @param unique if true, the editor will be set to the "unique item names only" mode.
|
||||
* @param unique - if true, the editor will be set to the "unique item names only" mode.
|
||||
*/
|
||||
public void setWantUnique(boolean unique) {
|
||||
this.wantUnique = this.alwaysNonUnique ? false : unique;
|
||||
@@ -481,7 +485,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
||||
*
|
||||
* getAlwaysNonUnique.
|
||||
*
|
||||
* @return if ture, this editor must always show non-unique items (e.g. quest editor).
|
||||
* @return if true, this editor must always show non-unique items (e.g. quest editor).
|
||||
*/
|
||||
public boolean getAlwaysNonUnique() {
|
||||
return this.alwaysNonUnique;
|
||||
@@ -491,12 +495,34 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
||||
*
|
||||
* setAlwaysNonUnique.
|
||||
*
|
||||
* @param nonUniqueOnly if true, this editor must always show non-unique items (e.g. quest editor).
|
||||
* @param nonUniqueOnly - if true, this editor must always show non-unique items (e.g. quest editor).
|
||||
*/
|
||||
public void setAlwaysNonUnique(boolean nonUniqueOnly) {
|
||||
this.alwaysNonUnique = nonUniqueOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getAllowMultipleSelections.
|
||||
*
|
||||
* @return if true, multiple items can be selected at once
|
||||
*/
|
||||
public boolean getAllowMultipleSelections() {
|
||||
return this.allowMultipleSelections;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getAllowMultipleSelections.
|
||||
*
|
||||
* @return allowMultipleSelections0 - if true, multiple items can be selected at once
|
||||
*/
|
||||
public void setAllowMultipleSelections(boolean allowMultipleSelections0) {
|
||||
if (this.allowMultipleSelections == allowMultipleSelections0) { return; }
|
||||
this.allowMultipleSelections = allowMultipleSelections0;
|
||||
this.table.setSelectionMode(allowMultipleSelections0 ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : ListSelectionModel.SINGLE_SELECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* focus.
|
||||
@@ -509,4 +535,17 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
||||
this.table.changeSelection(0, 0, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void addSelectionListener(ListSelectionListener listener) {
|
||||
selectionListeners.remove(listener); //ensure listener not added multiple times
|
||||
selectionListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeSelectionListener(ListSelectionListener listener) {
|
||||
selectionListeners.remove(listener);
|
||||
}
|
||||
|
||||
public Iterable<ListSelectionListener> getSelectionListeners() {
|
||||
return selectionListeners;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,10 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
|
||||
private final ItemManager<T> itemManager;
|
||||
private final ItemTableModel<T> tableModel;
|
||||
|
||||
public ItemManager<T> getItemManager() {
|
||||
return this.itemManager;
|
||||
}
|
||||
|
||||
public ItemTableModel<T> getTableModel() {
|
||||
return this.tableModel;
|
||||
}
|
||||
@@ -283,7 +287,7 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
|
||||
*
|
||||
* @return InventoryItem
|
||||
*/
|
||||
public InventoryItem getSelectedItem() {
|
||||
public T getSelectedItem() {
|
||||
final int iRow = getSelectedRow();
|
||||
return iRow >= 0 ? this.tableModel.rowToItem(iRow).getKey() : null;
|
||||
}
|
||||
@@ -294,8 +298,8 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
|
||||
*
|
||||
* @return List<InventoryItem>
|
||||
*/
|
||||
public List<InventoryItem> getSelectedItems() {
|
||||
List<InventoryItem> items = new ArrayList<InventoryItem>();
|
||||
public List<T> getSelectedItems() {
|
||||
List<T> items = new ArrayList<T>();
|
||||
for (int row : getSelectedRows()) {
|
||||
items.add(tableModel.rowToItem(row).getKey());
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.event.TableModelEvent;
|
||||
@@ -38,7 +37,6 @@ import javax.swing.table.TableColumnModel;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import forge.gui.deckeditor.CDeckEditorUI;
|
||||
import forge.gui.toolbox.FMouseAdapter;
|
||||
import forge.gui.toolbox.itemmanager.ItemManagerModel;
|
||||
import forge.gui.toolbox.itemmanager.SItemManagerIO;
|
||||
@@ -125,17 +123,13 @@ public final class ItemTableModel<T extends InventoryItem> extends AbstractTable
|
||||
return (row >= 0) && (row < model.size()) ? model.get(row) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show selected card.
|
||||
*
|
||||
* @param table
|
||||
* the table
|
||||
*/
|
||||
public void showSelectedItem(final JTable table) {
|
||||
public void onSelectionChange(final ItemTable<T> table) {
|
||||
final int row = table.getSelectedRow();
|
||||
if (row != -1) {
|
||||
Entry<T, Integer> card = this.rowToItem(row);
|
||||
CDeckEditorUI.SINGLETON_INSTANCE.setCard(null != card ? card.getKey() : null);
|
||||
ListSelectionEvent event = new ListSelectionEvent(table.getItemManager(), row, row, false);
|
||||
for (ListSelectionListener listener : table.getItemManager().getSelectionListeners()) {
|
||||
listener.valueChanged(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +137,7 @@ public final class ItemTableModel<T extends InventoryItem> extends AbstractTable
|
||||
@Override
|
||||
public void valueChanged(final ListSelectionEvent arg0) {
|
||||
if (table.isFocusOwner()) {
|
||||
ItemTableModel.this.showSelectedItem(table);
|
||||
ItemTableModel.this.onSelectionChange(table);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -151,7 +145,7 @@ public final class ItemTableModel<T extends InventoryItem> extends AbstractTable
|
||||
private final FocusAdapter focusAdapter = new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(final FocusEvent e) {
|
||||
ItemTableModel.this.showSelectedItem(table);
|
||||
ItemTableModel.this.onSelectionChange(table);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
89
forge-gui/src/main/java/forge/gui/workshop/CWorkshopUI.java
Normal file
89
forge-gui/src/main/java/forge/gui/workshop/CWorkshopUI.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Forge: Play Magic: the Gathering.
|
||||
* Copyright (C) 2011 Forge Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.gui.workshop;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JMenu;
|
||||
|
||||
import forge.Command;
|
||||
import forge.Singletons;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.gui.menus.IMenuProvider;
|
||||
import forge.gui.toolbox.itemmanager.CardManager;
|
||||
import forge.gui.toolbox.itemmanager.SItemManagerIO;
|
||||
import forge.gui.toolbox.itemmanager.SItemManagerIO.EditorPreference;
|
||||
import forge.gui.toolbox.itemmanager.table.ItemTable;
|
||||
import forge.gui.workshop.controllers.CWorkshopCatalog;
|
||||
import forge.gui.workshop.views.VWorkshopCatalog;
|
||||
import forge.item.PaperCard;
|
||||
|
||||
/**
|
||||
* Constructs instance of workshop UI controller, used as a single point of
|
||||
* top-level control for child UIs. Tasks targeting the view of individual
|
||||
* components are found in a separate controller for that component and
|
||||
* should not be included here.
|
||||
*
|
||||
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
|
||||
*/
|
||||
public enum CWorkshopUI implements ICDoc, IMenuProvider {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private CWorkshopUI() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.menubar.IMenuProvider#getMenus()
|
||||
*/
|
||||
@Override
|
||||
public List<JMenu> getMenus() {
|
||||
return null; //TODO: Create Workshop menus
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
*/
|
||||
@Override
|
||||
public Command getCommandOnSelect() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#initialize()
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
Singletons.getControl().getForgeMenu().setProvider(this);
|
||||
final CardManager cardManager = VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager();
|
||||
final ItemTable<PaperCard> cardTable = cardManager.getTable();
|
||||
|
||||
boolean wantElastic = SItemManagerIO.getPref(EditorPreference.elastic_columns);
|
||||
boolean wantUnique = SItemManagerIO.getPref(EditorPreference.display_unique_only);
|
||||
cardTable.setWantElasticColumns(wantElastic);
|
||||
cardManager.setWantUnique(wantUnique);
|
||||
CWorkshopCatalog.SINGLETON_INSTANCE.applyCurrentFilter();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#update()
|
||||
*/
|
||||
@Override
|
||||
public void update() { }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package forge.gui.workshop;
|
||||
|
||||
/**
|
||||
* Handles worksho saving and loading.
|
||||
*
|
||||
* <br><br><i>(S at beginning of class name denotes a static factory.)</i>
|
||||
*/
|
||||
public class SWorkshopIO {
|
||||
}
|
||||
62
forge-gui/src/main/java/forge/gui/workshop/VWorkshopUI.java
Normal file
62
forge-gui/src/main/java/forge/gui/workshop/VWorkshopUI.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package forge.gui.workshop;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.gui.framework.FScreen;
|
||||
import forge.gui.framework.IVTopLevelUI;
|
||||
import forge.gui.workshop.views.VWorkshopCatalog;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Top level view class; instantiates and assembles
|
||||
* tabs used in deck editor UI drag layout.<br>
|
||||
*
|
||||
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
|
||||
*
|
||||
*/
|
||||
public enum VWorkshopUI implements IVTopLevelUI {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
//========== Overridden methods
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVTopLevelUI#instantiate()
|
||||
*/
|
||||
@Override
|
||||
public void instantiate() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVTopLevelUI#populate()
|
||||
*/
|
||||
@Override
|
||||
public void populate() {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVTopLevelUI#onSwitching(forge.gui.framework.FScreen)
|
||||
*/
|
||||
@Override
|
||||
public boolean onSwitching(FScreen fromScreen, FScreen toScreen) {
|
||||
//TODO: ensure card saved before switching
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVTopLevelUI#onClosing()
|
||||
*/
|
||||
@Override
|
||||
public boolean onClosing(FScreen screen) {
|
||||
//don't close tab, but return to home screen if this called
|
||||
Singletons.getControl().setCurrentScreen(FScreen.HOME_SCREEN);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package forge.gui.workshop.controllers;
|
||||
|
||||
import forge.Command;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.gui.workshop.views.VCardDesigner;
|
||||
|
||||
|
||||
/**
|
||||
* Controls the "card designer" panel in the workshop UI.
|
||||
*
|
||||
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
|
||||
*
|
||||
*/
|
||||
public enum CCardDesigner implements ICDoc {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private CCardDesigner() {
|
||||
VCardDesigner.SINGLETON_INSTANCE.getBtnSaveCard().setCommand(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CCardScript.SINGLETON_INSTANCE.saveChanges();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//========== Overridden methods
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
*/
|
||||
@Override
|
||||
public Command getCommandOnSelect() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#initialize()
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#update()
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package forge.gui.workshop.controllers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import forge.Command;
|
||||
import forge.error.BugReporter;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.gui.workshop.views.VCardDesigner;
|
||||
import forge.gui.workshop.views.VCardScript;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.FileUtil;
|
||||
|
||||
|
||||
/**
|
||||
* Controls the "card script" panel in the workshop UI.
|
||||
*
|
||||
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
|
||||
*
|
||||
*/
|
||||
public enum CCardScript implements ICDoc {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private PaperCard currentCard;
|
||||
private String baseText;
|
||||
private boolean isTextDirty;
|
||||
|
||||
private CCardScript() {
|
||||
VCardScript.SINGLETON_INSTANCE.getTarScript().getDocument().addDocumentListener(new DocumentListener() {
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent arg0) {
|
||||
updateDirtyFlag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent arg0) {
|
||||
updateDirtyFlag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent arg0) {
|
||||
//Plain text components do not fire these events
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateDirtyFlag() {
|
||||
isTextDirty = !VCardScript.SINGLETON_INSTANCE.getTarScript().getText().equals(baseText);
|
||||
VCardDesigner.SINGLETON_INSTANCE.getBtnSaveCard().setEnabled(isTextDirty);
|
||||
VCardScript.SINGLETON_INSTANCE.getTabLabel().setText((isTextDirty ? "*" : "") + "Card Script");
|
||||
}
|
||||
|
||||
public void showCard(PaperCard card) {
|
||||
if (this.currentCard == card) { return; }
|
||||
this.currentCard = card;
|
||||
|
||||
String text = "";
|
||||
boolean editable = false;
|
||||
File sourceFile = card.getRules().getSourceFile();
|
||||
if (sourceFile != null) {
|
||||
try {
|
||||
text = FileUtil.readFileToString(sourceFile);
|
||||
editable = true;
|
||||
}
|
||||
catch (final Exception ex) {
|
||||
text = "Couldn't read file - " + sourceFile + "\n\nException:\n" + ex.toString();
|
||||
}
|
||||
}
|
||||
this.baseText = text;
|
||||
|
||||
JTextArea tarScript = VCardScript.SINGLETON_INSTANCE.getTarScript();
|
||||
tarScript.setText(text);
|
||||
tarScript.setEditable(editable);
|
||||
tarScript.setCaretPosition(0); //keep scrolled to top
|
||||
}
|
||||
|
||||
public void saveChanges() {
|
||||
if (this.currentCard == null || !this.isTextDirty) { return; } //not need if text hasn't been changed
|
||||
|
||||
File sourceFile = this.currentCard.getRules().getSourceFile();
|
||||
if (sourceFile == null) { return; }
|
||||
|
||||
try {
|
||||
String text = VCardScript.SINGLETON_INSTANCE.getTarScript().getText();
|
||||
|
||||
PrintWriter p = new PrintWriter(sourceFile);
|
||||
p.print(text);
|
||||
p.close();
|
||||
|
||||
this.baseText = text;
|
||||
updateDirtyFlag();
|
||||
} catch (final Exception ex) {
|
||||
BugReporter.reportException(ex);
|
||||
throw new RuntimeException("FileUtil : writeFile() error, problem writing file - " + sourceFile + " : " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
//========== Overridden methods
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
*/
|
||||
@Override
|
||||
public Command getCommandOnSelect() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#initialize()
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#update()
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,555 @@
|
||||
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.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.Singletons;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.EditionCollection;
|
||||
import forge.game.GameFormat;
|
||||
import forge.gui.GuiUtils;
|
||||
import forge.gui.workshop.views.VWorkshopCatalog;
|
||||
import forge.gui.deckeditor.views.VCardCatalog.RangeTypes;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.gui.home.quest.DialogChooseSets;
|
||||
import forge.gui.toolbox.FLabel;
|
||||
import forge.gui.toolbox.FSpinner;
|
||||
import forge.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.TableColumnInfo;
|
||||
import forge.gui.toolbox.itemmanager.table.SColumnUtil.ColumnName;
|
||||
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.
|
||||
*
|
||||
* <br><br><i>(C at beginning of class name denotes a control class.)</i>
|
||||
*
|
||||
*/
|
||||
public enum CWorkshopCatalog implements ICDoc {
|
||||
/** */
|
||||
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() {
|
||||
}
|
||||
|
||||
//========== Overridden methods
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
*/
|
||||
@Override
|
||||
public Command getCommandOnSelect() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#initialize()
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("serial")
|
||||
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() {
|
||||
@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 (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)
|
||||
* @see forge.gui.framework.ICDoc#update()
|
||||
*/
|
||||
@Override
|
||||
public void update() {
|
||||
final List<TableColumnInfo<InventoryItem>> lstCatalogCols = SColumnUtil.getCatalogDefaultColumns();
|
||||
lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY));
|
||||
VWorkshopCatalog.SINGLETON_INSTANCE.getCardManager().getTable().setup(lstCatalogCols);
|
||||
}
|
||||
|
||||
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) {
|
||||
EditionCollection editions = Singletons.getModel().getEditions();
|
||||
StringBuilder tooltip = new StringBuilder("<html>Sets:");
|
||||
|
||||
int lastLen = 0;
|
||||
int lineLen = 0;
|
||||
|
||||
// use HTML tooltips so we can insert line breaks
|
||||
List<String> sets = 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package forge.gui.workshop.views;
|
||||
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SpringLayout;
|
||||
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.IVDoc;
|
||||
import forge.gui.toolbox.FLabel;
|
||||
import forge.gui.toolbox.FSkin;
|
||||
import forge.gui.workshop.controllers.CCardDesigner;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of workshop card designer tab.
|
||||
*
|
||||
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
|
||||
*/
|
||||
public enum VCardDesigner implements IVDoc<CCardDesigner> {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
// Fields used with interface IVDoc
|
||||
private DragCell parentCell;
|
||||
private final DragTab tab = new DragTab("Card Designer");
|
||||
|
||||
private FLabel btnSaveCard = new FLabel.Builder()
|
||||
.opaque(true).hoverable(true)
|
||||
.text("Save and Apply Card Changes")
|
||||
.icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVE))
|
||||
.enabled(false) //disabled by default until card changes made
|
||||
.build();
|
||||
|
||||
//========== Constructor
|
||||
private VCardDesigner() {
|
||||
}
|
||||
|
||||
public FLabel getBtnSaveCard() {
|
||||
return btnSaveCard;
|
||||
}
|
||||
|
||||
//========== Overridden methods
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getDocumentID()
|
||||
*/
|
||||
@Override
|
||||
public EDocID getDocumentID() {
|
||||
return EDocID.WORKSHOP_CARDDESIGNER;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getTabLabel()
|
||||
*/
|
||||
@Override
|
||||
public DragTab getTabLabel() {
|
||||
return tab;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getLayoutControl()
|
||||
*/
|
||||
@Override
|
||||
public CCardDesigner getLayoutControl() {
|
||||
return CCardDesigner.SINGLETON_INSTANCE;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell)
|
||||
*/
|
||||
@Override
|
||||
public void setParentCell(final DragCell cell0) {
|
||||
this.parentCell = cell0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getParentCell()
|
||||
*/
|
||||
@Override
|
||||
public DragCell getParentCell() {
|
||||
return this.parentCell;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#populate()
|
||||
*/
|
||||
@Override
|
||||
public void populate() {
|
||||
JPanel body = parentCell.getBody();
|
||||
SpringLayout layout = new SpringLayout();
|
||||
body.setLayout(layout);
|
||||
layout.putConstraint(SpringLayout.SOUTH, btnSaveCard, -6, SpringLayout.SOUTH, body);
|
||||
layout.putConstraint(SpringLayout.WEST, btnSaveCard, 6, SpringLayout.WEST, body);
|
||||
layout.putConstraint(SpringLayout.EAST, btnSaveCard, -6, SpringLayout.EAST, body);
|
||||
btnSaveCard.setPreferredSize(new Dimension(60, 30));
|
||||
body.add(btnSaveCard);
|
||||
//body.setLayout(new MigLayout("insets 1, gap 0, wrap"));
|
||||
//body.add(btnSaveCard, "w 100% - 12, h 30px!, ay bottom, gap 6");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package forge.gui.workshop.views;
|
||||
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.IVDoc;
|
||||
import forge.gui.toolbox.FSkin;
|
||||
import forge.gui.workshop.controllers.CCardScript;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of workshop card script tab.
|
||||
*
|
||||
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
|
||||
*/
|
||||
public enum VCardScript implements IVDoc<CCardScript> {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
// Fields used with interface IVDoc
|
||||
private DragCell parentCell;
|
||||
private final DragTab tab = new DragTab("Card Script");
|
||||
|
||||
private final JTextArea tarScript = new JTextArea();
|
||||
private final JScrollPane scroller;
|
||||
|
||||
//========== Constructor
|
||||
private VCardScript() {
|
||||
FSkin.JTextComponentSkin<JTextArea> txtScriptSkin = FSkin.get(tarScript);
|
||||
txtScriptSkin.setFont(FSkin.getFixedFont(16));
|
||||
txtScriptSkin.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
|
||||
txtScriptSkin.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
|
||||
txtScriptSkin.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT));
|
||||
tarScript.setMargin(new Insets(3, 3, 3, 3));
|
||||
|
||||
scroller = new JScrollPane(tarScript);
|
||||
scroller.setBorder(null);
|
||||
scroller.setOpaque(false);
|
||||
}
|
||||
|
||||
public JTextArea getTarScript() {
|
||||
return tarScript;
|
||||
}
|
||||
|
||||
//========== Overridden methods
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getDocumentID()
|
||||
*/
|
||||
@Override
|
||||
public EDocID getDocumentID() {
|
||||
return EDocID.WORKSHOP_CARDSCRIPT;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getTabLabel()
|
||||
*/
|
||||
@Override
|
||||
public DragTab getTabLabel() {
|
||||
return tab;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getLayoutControl()
|
||||
*/
|
||||
@Override
|
||||
public CCardScript getLayoutControl() {
|
||||
return CCardScript.SINGLETON_INSTANCE;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell)
|
||||
*/
|
||||
@Override
|
||||
public void setParentCell(final DragCell cell0) {
|
||||
this.parentCell = cell0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#getParentCell()
|
||||
*/
|
||||
@Override
|
||||
public DragCell getParentCell() {
|
||||
return this.parentCell;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.IVDoc#populate()
|
||||
*/
|
||||
@Override
|
||||
public void populate() {
|
||||
JPanel body = parentCell.getBody();
|
||||
body.setLayout(new MigLayout("insets 1, gap 0, wrap"));
|
||||
body.add(scroller, "w 100%, h 100%");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
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.JSpinner;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import forge.Command;
|
||||
import forge.card.CardDb;
|
||||
import forge.gui.WrapLayout;
|
||||
import forge.gui.deckeditor.views.VCardCatalog.RangeTypes;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.IVDoc;
|
||||
import forge.gui.match.controllers.CDetail;
|
||||
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.ItemManagerContainer;
|
||||
import forge.gui.toolbox.itemmanager.SItemManagerUtil;
|
||||
import forge.gui.workshop.controllers.CCardScript;
|
||||
import forge.gui.workshop.controllers.CWorkshopCatalog;
|
||||
import forge.item.ItemPool;
|
||||
import forge.item.PaperCard;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of card catalog in workshop.
|
||||
*
|
||||
* <br><br><i>(V at beginning of class name denotes a view class.)</i>
|
||||
*
|
||||
*/
|
||||
public enum VWorkshopCatalog implements IVDoc<CWorkshopCatalog> {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
public static final int SEARCH_MODE_INVERSE_INDEX = 1;
|
||||
|
||||
// Fields used with interface IVDoc
|
||||
private DragCell parentCell;
|
||||
private final DragTab tab = new DragTab("Card Catalog");
|
||||
|
||||
// Total and color count labels/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 CardManager cardManager;
|
||||
|
||||
private final Map<RangeTypes, Pair<FSpinner, FSpinner>> spinners = new HashMap<RangeTypes, Pair<FSpinner, FSpinner>>();
|
||||
|
||||
//========== Constructor
|
||||
/** */
|
||||
private VWorkshopCatalog() {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
this.cardManager.setPool(ItemPool.createFrom(CardDb.instance().getAllCards(), PaperCard.class), true);
|
||||
this.cardManagerContainer.setItemManager(this.cardManager);
|
||||
|
||||
this.cardManager.addSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
PaperCard card = cardManager.getSelectedItem();
|
||||
CDetail.SINGLETON_INSTANCE.showCard(card);
|
||||
CPicture.SINGLETON_INSTANCE.showImage(card);
|
||||
CCardScript.SINGLETON_INSTANCE.showCard(card);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void _setupSpinner (JSpinner spinner) {
|
||||
spinner.setFocusable(false); // only the spinner text field should be focusable, not the up/down widget
|
||||
}
|
||||
|
||||
//========== Overridden from IVDoc
|
||||
|
||||
@Override
|
||||
public EDocID getDocumentID() {
|
||||
return EDocID.WORKSHOP_CATALOG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DragTab getTabLabel() {
|
||||
return tab;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CWorkshopCatalog getLayoutControl() {
|
||||
return CWorkshopCatalog.SINGLETON_INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentCell(DragCell cell0) {
|
||||
this.parentCell = cell0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DragCell getParentCell() {
|
||||
return this.parentCell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate() {
|
||||
JPanel parentBody = parentCell.getBody();
|
||||
parentBody.setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3"));
|
||||
parentBody.add(pnlStats, "w 100:520:520, center");
|
||||
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() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,7 @@ public final class NewConstants {
|
||||
public static final FileLocation EDITOR_PREFERENCES_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "editor.preferences");
|
||||
public static final FileLocation WINDOW_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "window.xml");
|
||||
public static final FileLocation MATCH_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "match.xml");
|
||||
public static final FileLocation WORKSHOP_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "workshop.xml");
|
||||
public static final FileLocation EDITOR_LAYOUT_FILE = new FileLocation(_DEFAULTS_DIR, USER_PREFS_DIR, "editor.xml");
|
||||
public static final FileLocation GAUNTLET_DIR = new FileLocation(_DEFAULTS_DIR, USER_DIR, "gauntlet/");
|
||||
|
||||
|
||||
@@ -115,15 +115,22 @@ public final class FileUtil {
|
||||
} // writeAllDecks()
|
||||
|
||||
public static String readFileToString(String filename) {
|
||||
return readFileToString(new File(filename));
|
||||
}
|
||||
|
||||
public static String readFileToString(File file) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (String line : readFile(filename)) {
|
||||
s.append(line).append('\n');
|
||||
for (String line : readFile(file)) {
|
||||
if (s.length() > 0) {
|
||||
s.append('\n');
|
||||
}
|
||||
s.append(line);
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public static List<String> readFile(final String filename) {
|
||||
return FileUtil.readFile(new File(filename));
|
||||
return readFile(new File(filename));
|
||||
}
|
||||
|
||||
// reads line by line and adds each line to the ArrayList
|
||||
|
||||
@@ -89,6 +89,7 @@ public class FNavigationBar extends FTitleBarBase {
|
||||
|
||||
addNavigationTab(FScreen.HOME_SCREEN);
|
||||
addNavigationTab(FScreen.DECK_EDITOR_CONSTRUCTED);
|
||||
addNavigationTab(FScreen.WORKSHOP_SCREEN);
|
||||
|
||||
super.addControls();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user