mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +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/home.xml svneol=native#text/xml
|
||||||
forge-gui/res/defaults/match.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/window.xml -text
|
||||||
|
forge-gui/res/defaults/workshop.xml -text
|
||||||
forge-gui/res/draft/cube_juzamjedi.draft -text
|
forge-gui/res/draft/cube_juzamjedi.draft -text
|
||||||
forge-gui/res/draft/cube_skiera.draft -text
|
forge-gui/res/draft/cube_skiera.draft -text
|
||||||
forge-gui/res/draft/rankings.txt -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/PhaseLabel.java -text
|
||||||
forge-gui/src/main/java/forge/gui/toolbox/special/PlayerDetailsPanel.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/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/BoosterPack.java -text
|
||||||
forge-gui/src/main/java/forge/item/FatPack.java -text
|
forge-gui/src/main/java/forge/item/FatPack.java -text
|
||||||
forge-gui/src/main/java/forge/item/IPaperCard.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;
|
package forge.card;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import forge.card.mana.ManaCost;
|
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 final Map<String, CardInSet> setsPrinted = new TreeMap<String, CardInSet>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
|
||||||
private CardAiHints aiHints;
|
private CardAiHints aiHints;
|
||||||
|
|
||||||
private ColorSet colorIdentity = null;
|
private ColorSet colorIdentity = null;
|
||||||
|
private File sourceFile;
|
||||||
|
|
||||||
public CardRules(ICardFace[] faces, CardSplitType altMode, CardAiHints cah) {
|
public CardRules(ICardFace[] faces, CardSplitType altMode, CardAiHints cah) {
|
||||||
splitType = altMode;
|
splitType = altMode;
|
||||||
@@ -65,8 +67,7 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
colorIdentity = ColorSet.fromMask(colMask);
|
colorIdentity = ColorSet.fromMask(colMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte calculateColorIdentity(ICardFace face)
|
private byte calculateColorIdentity(ICardFace face) {
|
||||||
{
|
|
||||||
byte res = face.getColor().getColor();
|
byte res = face.getColor().getColor();
|
||||||
boolean isReminder = false;
|
boolean isReminder = false;
|
||||||
boolean isSymbol = false;
|
boolean isSymbol = false;
|
||||||
@@ -216,7 +217,14 @@ public final class CardRules implements ICardCharacteristics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ColorSet getColorIdentity() {
|
public ColorSet getColorIdentity() {
|
||||||
return colorIdentity;
|
return this.colorIdentity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getSourceFile() {
|
||||||
|
return this.sourceFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceFile(File sourceFile0) {
|
||||||
|
this.sourceFile = sourceFile0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,8 +47,6 @@ public class CardRulesReader {
|
|||||||
private boolean removedFromRandomDecks = false;
|
private boolean removedFromRandomDecks = false;
|
||||||
private DeckHints hints = null;
|
private DeckHints hints = null;
|
||||||
private DeckHints needs = null;
|
private DeckHints needs = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Reset all fields to parse next card (to avoid allocating new
|
// Reset all fields to parse next card (to avoid allocating new
|
||||||
// CardRulesReader N times)
|
// CardRulesReader N times)
|
||||||
|
|||||||
@@ -329,15 +329,17 @@ public class CardStorageReader {
|
|||||||
*
|
*
|
||||||
* @return a new Card instance
|
* @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;
|
FileInputStream fileInputStream = null;
|
||||||
try {
|
try {
|
||||||
fileInputStream = new FileInputStream(pathToTxtFile);
|
fileInputStream = new FileInputStream(file);
|
||||||
return this.loadCard(reader, fileInputStream);
|
CardRules rules = this.loadCard(reader, fileInputStream);
|
||||||
|
rules.setSourceFile(file);
|
||||||
|
return rules;
|
||||||
} catch (final FileNotFoundException ex) {
|
} 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 "
|
throw new RuntimeException("CardReader : run error -- file exception -- filename is "
|
||||||
+ pathToTxtFile.getPath(), ex);
|
+ file.getPath(), ex);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
fileInputStream.close();
|
fileInputStream.close();
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ import javax.swing.PopupFactory;
|
|||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.Timer;
|
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.CharUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
@@ -85,7 +87,7 @@ public enum CDeckEditorUI implements ICDoc, IMenuProvider {
|
|||||||
SINGLETON_INSTANCE;
|
SINGLETON_INSTANCE;
|
||||||
|
|
||||||
private final HashMap<FScreen, ACEditorBase<? extends InventoryItem, ? extends DeckBase>> screenChildControllers;
|
private final HashMap<FScreen, ACEditorBase<? extends InventoryItem, ? extends DeckBase>> screenChildControllers;
|
||||||
private ACEditorBase<? extends InventoryItem, ? extends DeckBase> childController;
|
private ACEditorBase<? extends InventoryItem, ? extends DeckBase> childController;
|
||||||
private boolean isFindingAsYouType = false;
|
private boolean isFindingAsYouType = false;
|
||||||
|
|
||||||
private CDeckEditorUI() {
|
private CDeckEditorUI() {
|
||||||
@@ -358,7 +360,7 @@ public enum CDeckEditorUI implements ICDoc, IMenuProvider {
|
|||||||
removeSelectedCards(toAlternate, qty);
|
removeSelectedCards(toAlternate, qty);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
catTable.addMouseListener(new FMouseAdapter() {
|
catTable.addMouseListener(new FMouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onLeftDoubleClick(MouseEvent e) {
|
public void onLeftDoubleClick(MouseEvent e) {
|
||||||
@@ -407,6 +409,24 @@ public enum CDeckEditorUI implements ICDoc, IMenuProvider {
|
|||||||
catTable.addKeyListener(catFind);
|
catTable.addKeyListener(catFind);
|
||||||
deckTable.addKeyListener(deckFind);
|
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;
|
childController.listenersHooked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ import forge.gui.match.views.VMessage;
|
|||||||
import forge.gui.match.views.VPicture;
|
import forge.gui.match.views.VPicture;
|
||||||
import forge.gui.match.views.VPlayers;
|
import forge.gui.match.views.VPlayers;
|
||||||
import forge.gui.match.views.VStack;
|
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.
|
* These are the identifiers for tabs found in the drag layout.
|
||||||
@@ -59,6 +62,10 @@ public enum EDocID { /** */
|
|||||||
EDITOR_CATALOG (VCardCatalog.SINGLETON_INSTANCE), /** */
|
EDITOR_CATALOG (VCardCatalog.SINGLETON_INSTANCE), /** */
|
||||||
EDITOR_CURRENTDECK (VCurrentDeck.SINGLETON_INSTANCE), /** */
|
EDITOR_CURRENTDECK (VCurrentDeck.SINGLETON_INSTANCE), /** */
|
||||||
EDITOR_DECKGEN (VDeckgen.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_QUESTCHALLENGES (VSubmenuChallenges.SINGLETON_INSTANCE), /** */
|
||||||
HOME_QUESTDUELS (VSubmenuDuels.SINGLETON_INSTANCE), /** */
|
HOME_QUESTDUELS (VSubmenuDuels.SINGLETON_INSTANCE), /** */
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import forge.gui.match.CMatchUI;
|
|||||||
import forge.gui.match.VMatchUI;
|
import forge.gui.match.VMatchUI;
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
import forge.gui.toolbox.FSkin.SkinImage;
|
import forge.gui.toolbox.FSkin.SkinImage;
|
||||||
|
import forge.gui.workshop.CWorkshopUI;
|
||||||
|
import forge.gui.workshop.VWorkshopUI;
|
||||||
import forge.properties.FileLocation;
|
import forge.properties.FileLocation;
|
||||||
import forge.properties.NewConstants;
|
import forge.properties.NewConstants;
|
||||||
|
|
||||||
@@ -35,10 +37,18 @@ public enum FScreen {
|
|||||||
VMatchUI.SINGLETON_INSTANCE,
|
VMatchUI.SINGLETON_INSTANCE,
|
||||||
CMatchUI.SINGLETON_INSTANCE,
|
CMatchUI.SINGLETON_INSTANCE,
|
||||||
"Game",
|
"Game",
|
||||||
FSkin.getIcon(FSkin.DockIcons.ICO_ALPHASTRIKE),
|
FSkin.getIcon(FSkin.DockIcons.ICO_ALPHASTRIKE), //TODO: Create icon for match screen
|
||||||
true,
|
true,
|
||||||
"Concede Game",
|
"Concede Game",
|
||||||
NewConstants.MATCH_LAYOUT_FILE),
|
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(
|
DECK_EDITOR_CONSTRUCTED(
|
||||||
VDeckEditorUI.SINGLETON_INSTANCE,
|
VDeckEditorUI.SINGLETON_INSTANCE,
|
||||||
CDeckEditorUI.SINGLETON_INSTANCE,
|
CDeckEditorUI.SINGLETON_INSTANCE,
|
||||||
|
|||||||
@@ -106,6 +106,13 @@ public enum CSubmenuPreferences implements ICDoc {
|
|||||||
CSubmenuPreferences.this.resetDeckEditorLayout();
|
CSubmenuPreferences.this.resetDeckEditorLayout();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
view.getBtnDeleteWorkshopUI().setCommand(new Command() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CSubmenuPreferences.this.resetWorkshopLayout();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
view.getBtnDeleteMatchUI().setCommand(new Command() {
|
view.getBtnDeleteMatchUI().setCommand(new Command() {
|
||||||
@Override
|
@Override
|
||||||
@@ -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() {
|
private void resetMatchScreenLayout() {
|
||||||
String userPrompt =
|
String userPrompt =
|
||||||
"This will reset the layout of the Match screen.\n" +
|
"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 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 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 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 FLabel btnPlayerName = new FLabel.Builder().opaque(true).hoverable(true).text("").build();
|
||||||
|
|
||||||
private final JCheckBox cbRemoveSmall = new OptionsCheckBox("Remove Small Creatures");
|
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 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";
|
final String regularConstraints = "w 80%!, h 22px!, gap 10% 0 0 10px, span 2 1";
|
||||||
|
|
||||||
|
|
||||||
// Troubleshooting
|
// Troubleshooting
|
||||||
pnlPrefs.add(new SectionLabel("Troubleshooting"), sectionConstraints);
|
pnlPrefs.add(new SectionLabel("Troubleshooting"), sectionConstraints);
|
||||||
|
|
||||||
//pnlPrefs.add(new SectionLabel(" "), sectionConstraints);
|
// Reset buttons
|
||||||
pnlPrefs.add(btnReset, regularConstraints + ", h 30px!");
|
final String twoButtonConstraints1 = "w 38%!, h 30px!, gap 10% 0 0 10px";
|
||||||
|
final String twoButtonConstraints2 = "w 38%!, h 30px!, gap 0 0 0 10px";
|
||||||
final String twoButtonConstraints = "w 38%!, h 30px!, gap 10% 0 0 10px";
|
pnlPrefs.add(btnReset, twoButtonConstraints1);
|
||||||
pnlPrefs.add(btnDeleteMatchUI, twoButtonConstraints);
|
pnlPrefs.add(btnDeleteMatchUI, twoButtonConstraints2);
|
||||||
pnlPrefs.add(btnDeleteEditorUI, "w 38%!, h 30px!, gap 0 0 0 10px");
|
pnlPrefs.add(btnDeleteEditorUI, twoButtonConstraints1);
|
||||||
// Reset button
|
pnlPrefs.add(btnDeleteWorkshopUI, twoButtonConstraints2);
|
||||||
|
|
||||||
|
|
||||||
// General Configuration
|
// General Configuration
|
||||||
pnlPrefs.add(new SectionLabel("General Configuration"), sectionConstraints + ", gaptop 2%");
|
pnlPrefs.add(new SectionLabel("General Configuration"), sectionConstraints + ", gaptop 2%");
|
||||||
@@ -508,6 +507,10 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
|||||||
public final FLabel getBtnDeleteEditorUI() {
|
public final FLabel getBtnDeleteEditorUI() {
|
||||||
return btnDeleteEditorUI;
|
return btnDeleteEditorUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final FLabel getBtnDeleteWorkshopUI() {
|
||||||
|
return btnDeleteWorkshopUI;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see forge.gui.framework.IVDoc#getDocumentID()
|
* @see forge.gui.framework.IVDoc#getDocumentID()
|
||||||
|
|||||||
@@ -74,8 +74,6 @@ public enum VSubmenuReleaseNotes implements IVSubmenu<CSubmenuReleaseNotes> {
|
|||||||
|
|
||||||
scroller = new JScrollPane(tar);
|
scroller = new JScrollPane(tar);
|
||||||
pnlMain.add(scroller, "w 100%!, h 100%!");
|
pnlMain.add(scroller, "w 100%!, h 100%!");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ 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.event.ListSelectionListener;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
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 final List<ItemFilter<T>> orderedFilters = new ArrayList<ItemFilter<T>>();
|
||||||
private boolean wantUnique = false;
|
private boolean wantUnique = false;
|
||||||
private boolean alwaysNonUnique = false;
|
private boolean alwaysNonUnique = false;
|
||||||
|
private boolean allowMultipleSelections = false;
|
||||||
private final Class<T> genericType;
|
private final Class<T> genericType;
|
||||||
private final Map<SItemManagerUtil.StatTypes, FLabel> statLabels;
|
private final Map<SItemManagerUtil.StatTypes, FLabel> statLabels;
|
||||||
|
private final ArrayList<ListSelectionListener> selectionListeners = new ArrayList<ListSelectionListener>();
|
||||||
|
|
||||||
private final FLabel btnAddFilter = new FLabel.ButtonBuilder()
|
private final FLabel btnAddFilter = new FLabel.ButtonBuilder()
|
||||||
.text("Add")
|
.text("Add")
|
||||||
@@ -94,6 +98,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
|||||||
|
|
||||||
//build table view
|
//build table view
|
||||||
this.table = new ItemTable<T>(this, this.model);
|
this.table = new ItemTable<T>(this, this.model);
|
||||||
|
this.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
this.tableScroller = new JScrollPane(this.table);
|
this.tableScroller = new JScrollPane(this.table);
|
||||||
this.tableScroller.setOpaque(false);
|
this.tableScroller.setOpaque(false);
|
||||||
this.tableScroller.getViewport().setOpaque(false);
|
this.tableScroller.getViewport().setOpaque(false);
|
||||||
@@ -133,8 +138,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doLayout()
|
public void doLayout() {
|
||||||
{
|
|
||||||
//int number = 0;
|
//int number = 0;
|
||||||
LayoutHelper helper = new LayoutHelper(this);
|
LayoutHelper helper = new LayoutHelper(this);
|
||||||
/*for (ItemFilter<T> filter : this.orderedFilters) {
|
/*for (ItemFilter<T> filter : this.orderedFilters) {
|
||||||
@@ -240,7 +244,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
|||||||
*
|
*
|
||||||
* @return InventoryItem
|
* @return InventoryItem
|
||||||
*/
|
*/
|
||||||
public InventoryItem getSelectedItem() {
|
public T getSelectedItem() {
|
||||||
return this.table.getSelectedItem();
|
return this.table.getSelectedItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +254,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
|||||||
*
|
*
|
||||||
* @return List<InventoryItem>
|
* @return List<InventoryItem>
|
||||||
*/
|
*/
|
||||||
public List<InventoryItem> getSelectedItems() {
|
public List<T> getSelectedItems() {
|
||||||
return this.table.getSelectedItems();
|
return this.table.getSelectedItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,7 +475,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
|||||||
*
|
*
|
||||||
* setWantUnique.
|
* 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) {
|
public void setWantUnique(boolean unique) {
|
||||||
this.wantUnique = this.alwaysNonUnique ? false : unique;
|
this.wantUnique = this.alwaysNonUnique ? false : unique;
|
||||||
@@ -481,7 +485,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
|||||||
*
|
*
|
||||||
* getAlwaysNonUnique.
|
* 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() {
|
public boolean getAlwaysNonUnique() {
|
||||||
return this.alwaysNonUnique;
|
return this.alwaysNonUnique;
|
||||||
@@ -491,11 +495,33 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
|||||||
*
|
*
|
||||||
* setAlwaysNonUnique.
|
* 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) {
|
public void setAlwaysNonUnique(boolean nonUniqueOnly) {
|
||||||
this.alwaysNonUnique = 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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -509,4 +535,17 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel {
|
|||||||
this.table.changeSelection(0, 0, false, false);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
|
|||||||
private final FSkin.JTableSkin<ItemTable<T>> skin;
|
private final FSkin.JTableSkin<ItemTable<T>> skin;
|
||||||
private final ItemManager<T> itemManager;
|
private final ItemManager<T> itemManager;
|
||||||
private final ItemTableModel<T> tableModel;
|
private final ItemTableModel<T> tableModel;
|
||||||
|
|
||||||
|
public ItemManager<T> getItemManager() {
|
||||||
|
return this.itemManager;
|
||||||
|
}
|
||||||
|
|
||||||
public ItemTableModel<T> getTableModel() {
|
public ItemTableModel<T> getTableModel() {
|
||||||
return this.tableModel;
|
return this.tableModel;
|
||||||
@@ -283,7 +287,7 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
|
|||||||
*
|
*
|
||||||
* @return InventoryItem
|
* @return InventoryItem
|
||||||
*/
|
*/
|
||||||
public InventoryItem getSelectedItem() {
|
public T getSelectedItem() {
|
||||||
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;
|
||||||
}
|
}
|
||||||
@@ -294,8 +298,8 @@ public final class ItemTable<T extends InventoryItem> extends JTable {
|
|||||||
*
|
*
|
||||||
* @return List<InventoryItem>
|
* @return List<InventoryItem>
|
||||||
*/
|
*/
|
||||||
public List<InventoryItem> getSelectedItems() {
|
public List<T> getSelectedItems() {
|
||||||
List<InventoryItem> items = new ArrayList<InventoryItem>();
|
List<T> items = new ArrayList<T>();
|
||||||
for (int row : getSelectedRows()) {
|
for (int row : getSelectedRows()) {
|
||||||
items.add(tableModel.rowToItem(row).getKey());
|
items.add(tableModel.rowToItem(row).getKey());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import java.util.Enumeration;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.swing.JTable;
|
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
import javax.swing.event.TableModelEvent;
|
import javax.swing.event.TableModelEvent;
|
||||||
@@ -38,7 +37,6 @@ import javax.swing.table.TableColumnModel;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import forge.gui.deckeditor.CDeckEditorUI;
|
|
||||||
import forge.gui.toolbox.FMouseAdapter;
|
import forge.gui.toolbox.FMouseAdapter;
|
||||||
import forge.gui.toolbox.itemmanager.ItemManagerModel;
|
import forge.gui.toolbox.itemmanager.ItemManagerModel;
|
||||||
import forge.gui.toolbox.itemmanager.SItemManagerIO;
|
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;
|
return (row >= 0) && (row < model.size()) ? model.get(row) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void onSelectionChange(final ItemTable<T> table) {
|
||||||
* Show selected card.
|
|
||||||
*
|
|
||||||
* @param table
|
|
||||||
* the table
|
|
||||||
*/
|
|
||||||
public void showSelectedItem(final JTable table) {
|
|
||||||
final int row = table.getSelectedRow();
|
final int row = table.getSelectedRow();
|
||||||
if (row != -1) {
|
if (row != -1) {
|
||||||
Entry<T, Integer> card = this.rowToItem(row);
|
ListSelectionEvent event = new ListSelectionEvent(table.getItemManager(), row, row, false);
|
||||||
CDeckEditorUI.SINGLETON_INSTANCE.setCard(null != card ? card.getKey() : null);
|
for (ListSelectionListener listener : table.getItemManager().getSelectionListeners()) {
|
||||||
|
listener.valueChanged(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +137,7 @@ public final class ItemTableModel<T extends InventoryItem> extends AbstractTable
|
|||||||
@Override
|
@Override
|
||||||
public void valueChanged(final ListSelectionEvent arg0) {
|
public void valueChanged(final ListSelectionEvent arg0) {
|
||||||
if (table.isFocusOwner()) {
|
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() {
|
private final FocusAdapter focusAdapter = new FocusAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void focusGained(final FocusEvent e) {
|
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 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 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 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 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/");
|
public static final FileLocation GAUNTLET_DIR = new FileLocation(_DEFAULTS_DIR, USER_DIR, "gauntlet/");
|
||||||
|
|
||||||
|
|||||||
@@ -115,15 +115,22 @@ public final class FileUtil {
|
|||||||
} // writeAllDecks()
|
} // writeAllDecks()
|
||||||
|
|
||||||
public static String readFileToString(String filename) {
|
public static String readFileToString(String filename) {
|
||||||
|
return readFileToString(new File(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readFileToString(File file) {
|
||||||
StringBuilder s = new StringBuilder();
|
StringBuilder s = new StringBuilder();
|
||||||
for (String line : readFile(filename)) {
|
for (String line : readFile(file)) {
|
||||||
s.append(line).append('\n');
|
if (s.length() > 0) {
|
||||||
|
s.append('\n');
|
||||||
|
}
|
||||||
|
s.append(line);
|
||||||
}
|
}
|
||||||
return s.toString();
|
return s.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> readFile(final String filename) {
|
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
|
// 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.HOME_SCREEN);
|
||||||
addNavigationTab(FScreen.DECK_EDITOR_CONSTRUCTED);
|
addNavigationTab(FScreen.DECK_EDITOR_CONSTRUCTED);
|
||||||
|
addNavigationTab(FScreen.WORKSHOP_SCREEN);
|
||||||
|
|
||||||
super.addControls();
|
super.addControls();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user