diff --git a/.gitattributes b/.gitattributes index 88d48815517..1651b5886cc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11351,8 +11351,15 @@ src/main/java/forge/gui/home/draft/VSubmenuDraft.java -text src/main/java/forge/gui/home/draft/VSubmenuSealed.java -text src/main/java/forge/gui/home/draft/package-info.java svneol=native#text/plain src/main/java/forge/gui/home/package-info.java svneol=native#text/plain +src/main/java/forge/gui/home/quest/CSubmenuChallenges.java -text src/main/java/forge/gui/home/quest/CSubmenuDuels.java -text +src/main/java/forge/gui/home/quest/CSubmenuQuestData.java -text +src/main/java/forge/gui/home/quest/CSubmenuQuestPrefs.java -text +src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java -text +src/main/java/forge/gui/home/quest/VSubmenuChallenges.java -text src/main/java/forge/gui/home/quest/VSubmenuDuels.java -text +src/main/java/forge/gui/home/quest/VSubmenuQuestData.java -text +src/main/java/forge/gui/home/quest/VSubmenuQuestPrefs.java -text src/main/java/forge/gui/home/quest/package-info.java svneol=native#text/plain src/main/java/forge/gui/home/settings/CSubmenuAvatars.java -text src/main/java/forge/gui/home/settings/CSubmenuPreferences.java -text diff --git a/res/skins/default/sprite_icons.png b/res/skins/default/sprite_icons.png index 609d1f0078a..27c68b0f6a0 100644 Binary files a/res/skins/default/sprite_icons.png and b/res/skins/default/sprite_icons.png differ diff --git a/src/main/java/forge/gui/home/constructed/SubmenuConstructedUtil.java b/src/main/java/forge/gui/home/constructed/SubmenuConstructedUtil.java index a685089a864..a3d62996010 100644 --- a/src/main/java/forge/gui/home/constructed/SubmenuConstructedUtil.java +++ b/src/main/java/forge/gui/home/constructed/SubmenuConstructedUtil.java @@ -44,7 +44,7 @@ import forge.view.toolbox.FSkin; /** * Utilities for the constructed submenu, all over the MVC spectrum. - * + * If a piece of code can be reused, it's dumped here. */ public class SubmenuConstructedUtil { /** @@ -337,9 +337,6 @@ public class SubmenuConstructedUtil { /** @param lists0   {@link java.util.List}<{@link javax.swing.JList}> */ public static void startGame(final List lists0) { - final Deck deckHuman = generateDeck(lists0.get(0), PlayerType.HUMAN); - final Deck deckAI = generateDeck(lists0.get(1), PlayerType.COMPUTER); - final FOverlay overlay = Singletons.getView().getOverlay(); overlay.setLayout(new MigLayout("insets 0, gap 0, align center")); @@ -355,7 +352,9 @@ public class SubmenuConstructedUtil { overlay.add(pnl, "h 300px!, w 400px!"); overlay.showOverlay(); - GameNew.newGame(deckHuman, deckAI); + GameNew.newGame( + generateDeck(lists0.get(0), PlayerType.HUMAN), + generateDeck(lists0.get(1), PlayerType.COMPUTER)); overlay.hideOverlay(); } diff --git a/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java b/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java new file mode 100644 index 00000000000..50a02be9e0e --- /dev/null +++ b/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java @@ -0,0 +1,81 @@ +package forge.gui.home.quest; + +import java.awt.Color; +import java.util.List; + +import javax.swing.SwingConstants; +import javax.swing.border.EmptyBorder; + +import forge.AllZone; +import forge.Command; +import forge.Singletons; +import forge.gui.home.ICSubmenu; +import forge.gui.home.quest.SubmenuQuestUtil.SelectablePanel; +import forge.quest.data.QuestChallenge; +import forge.view.toolbox.FLabel; + +/** + * TODO: Write javadoc for this type. + * + */ +public enum CSubmenuChallenges implements ICSubmenu { + /** */ + SINGLETON_INSTANCE; + + /* (non-Javadoc) + * @see forge.control.home.IControlSubmenu#getMenuCommand() + */ + @Override + public Command getMenuCommand() { + return null; + } + + /* (non-Javadoc) + * @see forge.control.home.IControlSubmenu#initialize() + */ + @Override + public void initialize() { + /// TEMPORARY + VSubmenuDuels.SINGLETON_INSTANCE.populate(); + CSubmenuDuels.SINGLETON_INSTANCE.update(); + ///////////// + + VSubmenuChallenges.SINGLETON_INSTANCE.populate(); + CSubmenuChallenges.SINGLETON_INSTANCE.update(); + } + + /* (non-Javadoc) + * @see forge.control.home.IControlSubmenu#update() + */ + @Override + public void update() { + SubmenuQuestUtil.updateStatsAndPet(); + + final VSubmenuChallenges view = VSubmenuChallenges.SINGLETON_INSTANCE; + VSubmenuDuels.SINGLETON_INSTANCE.getBtnStart().setEnabled(false); + + if (AllZone.getQuestData() != null) { + VSubmenuDuels.SINGLETON_INSTANCE.getLblTitle().setText("Challenges: " + AllZone.getQuestData().getRank()); + + view.getPnlChallenges().removeAll(); + final List challenges = + Singletons.getModel().getQuestEventManager().generateChallenges(AllZone.getQuestData()); + + for (final QuestChallenge c : challenges) { + final SelectablePanel temp = new SelectablePanel(c); + view.getPnlChallenges().add(temp, "w 96%!, h 86px!, gap 2% 0 5px 5px"); + } + + if (challenges.size() == 0) { + final FLabel lbl = new FLabel.Builder() + .text(VSubmenuDuels.SINGLETON_INSTANCE.getLblNextChallengeInWins().getText()) + .fontAlign(SwingConstants.CENTER).build(); + lbl.setForeground(Color.red); + lbl.setBackground(Color.white); + lbl.setBorder(new EmptyBorder(10, 10, 10, 10)); + lbl.setOpaque(true); + view.getPnlChallenges().add(lbl, "w 50%!, h 30px!, gap 25% 0 50px 0"); + } + } + } +} diff --git a/src/main/java/forge/gui/home/quest/CSubmenuDuels.java b/src/main/java/forge/gui/home/quest/CSubmenuDuels.java index bdc3e16ee72..34da4fc6870 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuDuels.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuDuels.java @@ -1,16 +1,15 @@ package forge.gui.home.quest; -import java.io.File; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; import forge.AllZone; import forge.Command; import forge.Singletons; import forge.gui.home.ICSubmenu; -import forge.properties.ForgeProps; -import forge.properties.NewConstants; -import forge.quest.data.QuestData; -import forge.quest.data.QuestDataIO; -import forge.quest.data.QuestPreferences.QPref; +import forge.gui.home.quest.SubmenuQuestUtil.SelectablePanel; +import forge.quest.data.QuestDuel; /** * TODO: Write javadoc for this type. @@ -31,10 +30,23 @@ public enum CSubmenuDuels implements ICSubmenu { /* (non-Javadoc) * @see forge.control.home.IControlSubmenu#initialize() */ + @SuppressWarnings("serial") @Override public void initialize() { VSubmenuDuels.SINGLETON_INSTANCE.populate(); CSubmenuDuels.SINGLETON_INSTANCE.update(); + + VSubmenuDuels.SINGLETON_INSTANCE.getBtnSpellShop().setCommand( + new Command() { @Override + public void execute() { SubmenuQuestUtil.showSpellShop(); } }); + + VSubmenuDuels.SINGLETON_INSTANCE.getBtnSpellShop().setCommand( + new Command() { @Override + public void execute() { SubmenuQuestUtil.showBazaar(); } }); + + VSubmenuDuels.SINGLETON_INSTANCE.getBtnStart().addActionListener( + new ActionListener() { @Override + public void actionPerformed(final ActionEvent e) { SubmenuQuestUtil.startGame(); } }); } /* (non-Javadoc) @@ -42,16 +54,21 @@ public enum CSubmenuDuels implements ICSubmenu { */ @Override public void update() { - QuestData qData = AllZone.getQuestData(); - if (qData == null) { - final String questname = Singletons.getModel() - .getQuestPreferences().getPreference(QPref.CURRENT_QUEST); + SubmenuQuestUtil.updateStatsAndPet(); - qData = QuestDataIO.loadData(new File( - ForgeProps.getFile(NewConstants.Quest.DATA_DIR) + questname + ".dat")); - System.out.println("asdf current quest data and credits: " + questname + " " + qData.getCredits()); + final VSubmenuDuels view = VSubmenuDuels.SINGLETON_INSTANCE; + + if (AllZone.getQuestData() != null) { + view.getLblTitle().setText("Duels: " + AllZone.getQuestData().getRank()); + + view.getPnlDuels().removeAll(); + final List duels = + Singletons.getModel().getQuestEventManager().generateDuels(); + + for (final QuestDuel d : duels) { + final SelectablePanel temp = new SelectablePanel(d); + view.getPnlDuels().add(temp, "w 96%!, h 86px!, gap 2% 0 5px 5px"); + } } - - //lblTitle.setText("Duels: " + control.getRankString()); } } diff --git a/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java b/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java new file mode 100644 index 00000000000..c0ce07ff03c --- /dev/null +++ b/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java @@ -0,0 +1,179 @@ +package forge.gui.home.quest; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JOptionPane; + +import forge.AllZone; +import forge.Command; +import forge.Singletons; +import forge.gui.GuiUtils; +import forge.gui.home.ICSubmenu; +import forge.properties.ForgeProps; +import forge.properties.NewConstants; +import forge.quest.data.QuestData; +import forge.quest.data.QuestDataIO; +import forge.quest.data.QuestPreferences.QPref; + +/** + * TODO: Write javadoc for this type. + * + */ +public enum CSubmenuQuestData implements ICSubmenu { + /** */ + SINGLETON_INSTANCE; + + private final Map arrQuests = new HashMap(); + + /* (non-Javadoc) + * @see forge.control.home.IControlSubmenu#update() + */ + @SuppressWarnings("serial") + @Override + public void initialize() { + VSubmenuQuestData.SINGLETON_INSTANCE.populate(); + CSubmenuQuestData.SINGLETON_INSTANCE.update(); + + VSubmenuQuestData.SINGLETON_INSTANCE.getBtnEmbark().setCommand( + new Command() { @Override public void execute() { newQuest(); } }); + } + + /* (non-Javadoc) + * @see forge.control.home.IControlSubmenu#getCommand() + */ + @Override + public Command getMenuCommand() { + return null; + } + + /* (non-Javadoc) + * @see forge.control.home.IControlSubmenu#update() + */ + @Override + public void update() { + refreshQuests(); + } + + /** + * The actuator for new quests. + */ + private void newQuest() { + final VSubmenuQuestData view = VSubmenuQuestData.SINGLETON_INSTANCE; + int difficulty = 0; + QuestData newdata = new QuestData(); + + final String mode = view.getRadFantasy().isSelected() + ? forge.quest.data.QuestData.FANTASY + : forge.quest.data.QuestData.CLASSIC; + + if (view.getRadEasy().isSelected()) { + difficulty = 0; + } else if (view.getRadMedium().isSelected()) { + difficulty = 1; + } else if (view.getRadHard().isSelected()) { + difficulty = 2; + } else if (view.getRadExpert().isSelected()) { + difficulty = 3; + } else { + throw new IllegalStateException( + "ControlQuest() > newQuest(): Error starting new quest!"); + } + + final Object o = JOptionPane.showInputDialog(null, "Poets will remember your quest as:", "Quest Name", JOptionPane.OK_CANCEL_OPTION); + + if (o == null) { return; } + + final String questName = GuiUtils.cleanString(o.toString()); + + if (getAllQuests().get(questName) != null || questName.equals("")) { + JOptionPane.showMessageDialog(null, "Please pick another quest name, a quest already has that name."); + return; + } + + // Give the user a few cards to build a deck + newdata.newGame(difficulty, mode, view.getCbStandardStart().isSelected()); + newdata.setName(questName); + newdata.saveData(); + + // Save in preferences. + Singletons.getModel().getQuestPreferences().setPreference(QPref.CURRENT_QUEST, questName + ".dat"); + Singletons.getModel().getQuestPreferences().save(); + + Singletons.getView().getViewHome().resetQuest(); + } // New Quest + + /** Changes between quest data files. */ + private void changeQuest() { + AllZone.setQuestData(VSubmenuQuestData.SINGLETON_INSTANCE + .getLstQuests().getSelectedQuest()); + + // Save in preferences. + Singletons.getModel().getQuestPreferences().setPreference(QPref.CURRENT_QUEST, + AllZone.getQuestData().getName() + ".dat"); + Singletons.getModel().getQuestPreferences().save(); + + //refreshDecks(); + //refreshStats(); + } + + /** Resets quests, then retrieves and sets current quest. */ + public void refreshQuests() { + final VSubmenuQuestData view = VSubmenuQuestData.SINGLETON_INSTANCE; + File dirQuests = ForgeProps.getFile(NewConstants.Quest.DATA_DIR); + + // Temporary transition code between v1.2.2 and v1.2.3. + // Can be safely deleted after release of 1.2.3. + if (!dirQuests.exists()) { + dirQuests.mkdirs(); + } + File olddata = new File("res/quest/questData.dat"); + File newpath = new File(dirQuests.getPath() + "/questData.dat"); + + if (olddata.exists()) { olddata.renameTo(newpath); } + // end block which can be deleted + + // Iterate over files and load quest datas for each. + FilenameFilter takeDatFiles = new FilenameFilter() { + @Override + public boolean accept(final File dir, final String name) { + return name.endsWith(".dat"); + } + }; + File[] arrFiles = dirQuests.listFiles(takeDatFiles); + arrQuests.clear(); + for (File f : arrFiles) { + arrQuests.put(f.getName(), QuestDataIO.loadData(f)); + } + + // Populate list with available quest datas. + view.getLstQuests().setQuests(arrQuests.values().toArray(new QuestData[0])); + + // If there are quests available, force select. + if (arrQuests.size() > 0) { + final String questname = Singletons.getModel().getQuestPreferences() + .getPreference(QPref.CURRENT_QUEST); + + // Attempt to select previous quest. + if (arrQuests.get(questname) != null) { + view.getLstQuests().setSelectedQuestData(arrQuests.get(questname)); + } + else { + view.getLstQuests().setSelectedIndex(0); + } + + // Drop into AllZone. + AllZone.setQuestData(view.getLstQuests().getSelectedQuest()); + } + else { + AllZone.setQuestData(null); + } + } + + /** @return */ + private Map getAllQuests() { + return arrQuests; + } +} diff --git a/src/main/java/forge/gui/home/quest/CSubmenuQuestPrefs.java b/src/main/java/forge/gui/home/quest/CSubmenuQuestPrefs.java new file mode 100644 index 00000000000..74cc46413b7 --- /dev/null +++ b/src/main/java/forge/gui/home/quest/CSubmenuQuestPrefs.java @@ -0,0 +1,165 @@ +package forge.gui.home.quest; + +import forge.Command; +import forge.Singletons; +import forge.gui.home.ICSubmenu; +import forge.gui.home.quest.VSubmenuQuestPrefs.PrefInput; +import forge.quest.data.QuestPreferences; +import forge.quest.data.QuestPreferences.QPref; + +/** + * TODO: Write javadoc for this type. + * + */ +public enum CSubmenuQuestPrefs implements ICSubmenu { + /** */ + SINGLETON_INSTANCE; + + /* (non-Javadoc) + * @see forge.control.home.IControlSubmenu#update() + */ + @Override + public void initialize() { + VSubmenuQuestPrefs.SINGLETON_INSTANCE.populate(); + CSubmenuQuestPrefs.SINGLETON_INSTANCE.update(); + } + + /* (non-Javadoc) + * @see forge.control.home.IControlSubmenu#getCommand() + */ + @Override + public Command getMenuCommand() { + return null; + } + + /* (non-Javadoc) + * @see forge.control.home.IControlSubmenu#update() + */ + @Override + public void update() { + + } + + /** + * Checks validity of values entered into prefInputs. + * @param i0   a PrefInput object + */ + public static void validateAndSave(PrefInput i0) { + if (i0.getText().equals(i0.getPreviousText())) { return; } + final QuestPreferences prefs = Singletons.getModel().getQuestPreferences(); + int temp1, temp2; + + int val = Integer.parseInt(i0.getText()); + resetErrors(); + + switch (i0.getQPref()) { + case STARTING_CREDITS_EASY: case STARTING_CREDITS_MEDIUM: + case STARTING_CREDITS_HARD: case STARTING_CREDITS_EXPERT: + case REWARDS_MILLED: case REWARDS_MULLIGAN0: + case REWARDS_ALTERNATIVE: case REWARDS_TURN5: + if (val > 500) { + showError(i0, "Value too large (maximum 500)."); + return; + } + break; + case BOOSTER_COMMONS: + temp1 = prefs.getPreferenceInt(QPref.BOOSTER_UNCOMMONS); + temp2 = prefs.getPreferenceInt(QPref.BOOSTER_RARES); + + if (temp1 + temp2 + val > 15) { + showError(i0, "Booster packs must have maximum 15 cards."); + return; + } + break; + case BOOSTER_UNCOMMONS: + temp1 = prefs.getPreferenceInt(QPref.BOOSTER_COMMONS); + temp2 = prefs.getPreferenceInt(QPref.BOOSTER_RARES); + + if (temp1 + temp2 + val > 15) { + showError(i0, "Booster packs must have maximum 15 cards."); + return; + } + break; + case BOOSTER_RARES: + temp1 = prefs.getPreferenceInt(QPref.BOOSTER_COMMONS); + temp2 = prefs.getPreferenceInt(QPref.BOOSTER_UNCOMMONS); + + if (temp1 + temp2 + val > 15) { + showError(i0, "Booster packs must have maximum 15 cards."); + return; + } + break; + case REWARDS_TURN1: + if (val > 2000) { + showError(i0, "Value too large (maximum 2000)."); + return; + } + break; + case SHOP_STARTING_PACKS: + case SHOP_SINGLES_COMMON: case SHOP_SINGLES_UNCOMMON: case SHOP_SINGLES_RARE: + if (val < 0) { + showError(i0, "Value too small (minimum 0)."); + return; + } else if (val > 15) { + showError(i0, "Value too large (maximum 15)."); + return; + } + break; + case SHOP_WINS_FOR_ADDITIONAL_PACK: case SHOP_MAX_PACKS: + if (val < 1) { + showError(i0, "Value too small (minimum 1)."); + return; + } else if (val > 25) { + showError(i0, "Value too large (maximum 25)."); + return; + } + break; + default: + if (val > 100) { + showError(i0, "Value too large (maximum 100)."); + return; + } + break; + } + + prefs.setPreference(i0.getQPref(), i0.getText()); + prefs.save(); + i0.setPreviousText(i0.getText()); + } + + private static void showError(PrefInput i0, String s0) { + final VSubmenuQuestPrefs view = VSubmenuQuestPrefs.SINGLETON_INSTANCE; + String s = "Save failed: " + s0; + switch(i0.getErrType()) { + case BOOSTER: + view.getLblErrBooster().setVisible(true); + view.getLblErrBooster().setText(s); + break; + case DIFFICULTY: + view.getLblErrDifficulty().setVisible(true); + view.getLblErrDifficulty().setText(s); + break; + case REWARDS: + view.getLblErrRewards().setVisible(true); + view.getLblErrRewards().setText(s); + break; + case SHOP: + view.getLblErrShop().setVisible(true); + view.getLblErrShop().setText(s); + break; + default: + } + + i0.setText(i0.getPreviousText()); + } + + /** */ + public static void resetErrors() { + final VSubmenuQuestPrefs view = VSubmenuQuestPrefs.SINGLETON_INSTANCE; + + view.getLblErrBooster().setVisible(false); + view.getLblErrDifficulty().setVisible(false); + view.getLblErrRewards().setVisible(false); + view.getLblErrShop().setVisible(false); + } +} diff --git a/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java b/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java new file mode 100644 index 00000000000..7386c92abc2 --- /dev/null +++ b/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java @@ -0,0 +1,295 @@ +package forge.gui.home.quest; + +import java.io.File; +import java.util.Set; + +import javax.swing.ImageIcon; + +import net.miginfocom.swing.MigLayout; +import forge.AllZone; +import forge.Command; +import forge.Constant; +import forge.Singletons; +import forge.control.FControl; +import forge.deck.Deck; +import forge.game.GameNew; +import forge.game.GameType; +import forge.gui.deckeditor.QuestCardShop; +import forge.properties.ForgeProps; +import forge.properties.NewConstants; +import forge.quest.data.QuestChallenge; +import forge.quest.data.QuestData; +import forge.quest.data.QuestDataIO; +import forge.quest.data.QuestEvent; +import forge.quest.data.QuestPreferences.QPref; +import forge.quest.data.QuestUtil; +import forge.quest.data.item.QuestItemZeppelin; +import forge.quest.data.pet.QuestPetAbstract; +import forge.view.toolbox.FLabel; +import forge.view.toolbox.FOverlay; +import forge.view.toolbox.FPanel; +import forge.view.toolbox.FSkin; +import forge.view.toolbox.FTextArea; + +/** + * Utilities for the quest submenu, all over the MVC spectrum. + * If a piece of code can be reused, it's dumped here. + */ +public class SubmenuQuestUtil { + private static SelectablePanel selectedOpponent; + private static Deck currentDeck; + + /** + *

+ * nextChallengeInWins. + *

+ * + * @return a int. + */ + public static int nextChallengeInWins() { + final QuestData qData = AllZone.getQuestData(); + final int challengesPlayed = qData.getChallengesPlayed(); + + int mul = 5; + if (qData.getInventory().hasItem("Zeppelin")) { + mul = 3; + } else if (qData.getInventory().hasItem("Map")) { + mul = 4; + } + + final int delta = (qData.getWin() < 20 + ? 20 - qData.getWin() + : (challengesPlayed * mul) - qData.getWin()); + + return (delta > 0) ? delta : 0; + } + + /** Updates stats, pets panels for both duels and challenges. */ + public static void updateStatsAndPet() { + final QuestData qData; + final VSubmenuDuels view = VSubmenuDuels.SINGLETON_INSTANCE; + + ////////// TODO - THIS SHOULD NOT BE HERE AND WILL BE MOVED EVENTUALLY. + if (AllZone.getQuestData() == null) { + final String questname = Singletons.getModel() + .getQuestPreferences().getPreference(QPref.CURRENT_QUEST); + + qData = QuestDataIO.loadData(new File( + ForgeProps.getFile(NewConstants.Quest.DATA_DIR) + questname + ".dat")); + AllZone.setQuestData(qData); + } + else { + qData = AllZone.getQuestData(); + } + //////////////////////////////////////////////////////////////////////// + + // Stats panel + view.getLblCredits().setText("Credits: " + qData.getCredits()); + view.getLblLife().setText("Life: " + qData.getLife()); + view.getLblWins().setText("Wins: " + qData.getWin()); + view.getLblLosses().setText("Losses: " + qData.getLost()); + view.setCurrentDeckStatus(); + + final int num = SubmenuQuestUtil.nextChallengeInWins(); + if (num == 0) { + view.getLblNextChallengeInWins().setText("Next challenge available now."); + } + else { + view.getLblNextChallengeInWins().setText("Next challenge available in " + num + " wins."); + } + + view.getLblWinStreak().setText( + "Win streak: " + qData.getWinStreakCurrent() + + " (Best:" + qData.getWinStreakBest() + ")"); + + // Start panel: pet, plant, zep. + if (qData.getMode().equals(QuestData.FANTASY)) { + final Set petList = qData.getPetManager().getAvailablePetNames(); + final QuestPetAbstract currentPet = qData.getPetManager().getSelectedPet(); + + view.getCbxPet().removeAllItems(); + // Pet list visibility + if (petList.size() > 0) { + view.getCbxPet().setEnabled(true); + view.getCbxPet().addItem("Don't summon a pet"); + for (final String pet : petList) { + view.getCbxPet().addItem("Summon " + pet); + } + + if (currentPet != null) { view.getCbxPet().setSelectedItem("Summon " + currentPet.getName()); } + } else { + view.getCbxPet().setVisible(false); + } + + // Plant visiblity + if (qData.getPetManager().getPlant().getLevel() == 0) { + view.getCbPlant().setVisible(false); + } + else { + view.getCbPlant().setVisible(true); + view.getCbPlant().setSelected(qData.getPetManager().shouldPlantBeUsed()); + } + + // Zeppelin visibility + final QuestItemZeppelin zeppelin = (QuestItemZeppelin) qData.getInventory().getItem("Zeppelin"); + view.getCbZep().setVisible(zeppelin.hasBeenUsed()); + } + else { + view.getCbxPet().setVisible(false); + view.getCbPlant().setVisible(false); + view.getCbZep().setVisible(false); + } + } + + /** Selectable panels for duels and challenges. */ + @SuppressWarnings("serial") + public static class SelectablePanel extends FPanel { + private final QuestEvent event; + + /** @param e0   QuestEvent */ + public SelectablePanel(final QuestEvent e0) { + super(); + this.event = e0; + this.setSelectable(true); + this.setHoverable(true); + this.setLayout(new MigLayout("insets 0, gap 0")); + + this.setCommand(new Command() { + @Override + public void execute() { + if (selectedOpponent != null) { selectedOpponent.setSelected(false); } + else { VSubmenuDuels.SINGLETON_INSTANCE.getBtnStart().setEnabled(true); } + + selectedOpponent = SubmenuQuestUtil.SelectablePanel.this; + } + }); + + // Icon + final File base = ForgeProps.getFile(NewConstants.IMAGE_ICON); + final File file = new File(base, event.getIconFilename()); + + final FLabel lblIcon = new FLabel.Builder().iconScaleFactor(1).build(); + if (!file.exists()) { + lblIcon.setIcon(FSkin.getIcon(FSkin.ForgeIcons.ICO_UNKNOWN)); + } + else { + lblIcon.setIcon(new ImageIcon(file.toString())); + } + this.add(lblIcon, "h 60px!, w 60px!, gap 10px 10px 10px 0, span 1 2"); + + // Name + final FLabel lblName = new FLabel.Builder() + .text(event.getTitle() + ": " + event.getDifficulty()).hoverable(false).build(); + this.add(lblName, "h 31px!, gap 0 0 10px 5px, wrap"); + + // Description + final FTextArea tarDesc = new FTextArea(); + tarDesc.setText(event.getDescription()); + tarDesc.setFont(FSkin.getItalicFont(12)); + this.add(tarDesc, "w 80%!, h 30px!"); + } + + /** @return QuestEvent */ + public QuestEvent getEvent() { + return event; + } + } + + /** @return {@link forge.view.home.ViewQuest.SelectablePanel} */ + public static SelectablePanel getSelectedOpponent() { + return selectedOpponent; + } + + /** @param deck0   {@link forge.deck.Deck} */ + public static void setCurrentDeck(final Deck deck0) { + currentDeck = deck0; + } + + /** @return {@link forge.deck.Deck} */ + public static Deck getCurrentDeck() { + return currentDeck; + } + + /** */ + @SuppressWarnings("serial") + public static void showSpellShop() { + final Command exit = new Command() { + @Override + public void execute() { + AllZone.getQuestData().saveData(); + updateStatsAndPet(); + } + }; + + QuestCardShop g = new QuestCardShop(AllZone.getQuestData()); + g.show(exit); + g.setVisible(true); + } + + /** */ + public static void showBazaar() { + Singletons.getControl().changeState(FControl.QUEST_BAZAAR); + Singletons.getView().getFrame().validate(); + } + + /** */ + public static void startGame() { + final QuestData qData = AllZone.getQuestData(); + final QuestEvent event = selectedOpponent.getEvent(); + final FOverlay overlay = Singletons.getView().getOverlay(); + final FPanel pnl = new FPanel(); + + // Overlay layout + overlay.setLayout(new MigLayout("insets 0, gap 0, align center")); + + pnl.setLayout(new MigLayout("insets 0, gap 0, ax center, wrap")); + pnl.setBackground(FSkin.getColor(FSkin.Colors.CLR_ACTIVE)); + pnl.add(new FLabel.Builder().icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_LOGO)).build(), + "h 200px!, align center"); + pnl.add(new FLabel.Builder().text("Loading new game...") + .fontScaleAuto(false).fontSize(22).build(), "h 40px!, align center"); + + overlay.add(pnl, "h 300px!, w 400px!"); + overlay.showOverlay(); + + // Logic + final QuestItemZeppelin zeppelin = (QuestItemZeppelin) qData.getInventory().getItem("Zeppelin"); + zeppelin.setZeppelinUsed(false); + qData.randomizeOpponents(); + + Constant.Runtime.HUMAN_DECK[0] = currentDeck; + Constant.Runtime.COMPUTER_DECK[0] = event.getEventDeck(); + Constant.Quest.OPP_ICON_NAME[0] = event.getIconFilename(); + Constant.Runtime.setGameType(GameType.Quest); + AllZone.setQuestEvent(event); + qData.saveData(); + + if (qData.isFantasy()) { + Constant.Quest.FANTASY_QUEST[0] = true; + int lifeAI = 20; + int lifeHuman = 20; + + if (selectedOpponent.getEvent().getEventType().equals("challenge")) { + int extraLife = 0; + + if (qData.getInventory().getItemLevel("Gear") == 2) { + extraLife = 3; + } + lifeAI = ((QuestChallenge) event).getAILife(); + lifeHuman = qData.getLife() + extraLife; + } + + GameNew.newGame( + Constant.Runtime.HUMAN_DECK[0], Constant.Runtime.COMPUTER_DECK[0], + QuestUtil.getHumanStartingCards(qData), + QuestUtil.getComputerStartingCards(qData), + lifeHuman, lifeAI); + } // End isFantasy + else { + GameNew.newGame(currentDeck, event.getEventDeck()); + } + + // Start transisiton to match UI. + overlay.hideOverlay(); + } +} diff --git a/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java b/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java new file mode 100644 index 00000000000..20d3692f150 --- /dev/null +++ b/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java @@ -0,0 +1,68 @@ +package forge.gui.home.quest; + +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import net.miginfocom.swing.MigLayout; +import forge.gui.home.EMenuGroup; +import forge.gui.home.IVSubmenu; +import forge.view.toolbox.FPanel; +import forge.view.toolbox.FScrollPane; + +/** */ +public enum VSubmenuChallenges implements IVSubmenu { + /** */ + SINGLETON_INSTANCE; + + //========== INSTANTIATION + private final JPanel pnl = new JPanel(); + private final JPanel pnlChallenges = new JPanel(); + + /* (non-Javadoc) + * @see forge.view.home.IViewSubmenu#getPanel() + */ + @Override + public JPanel getPanel() { + return pnl; + } + + /* (non-Javadoc) + * @see forge.view.home.IViewSubmenu#getGroup() + */ + @Override + public EMenuGroup getGroup() { + return null; + } + + /* (non-Javadoc) + * @see forge.view.home.IViewSubmenu#populate() + */ + @Override + public void populate() { + // Note: "Challenges" submenu uses the instances of + // title, stats, and start panels from "Duels" submenu. + final FPanel pnlTitle = VSubmenuDuels.SINGLETON_INSTANCE.getPnlTitle(); + final JPanel pnlStats = VSubmenuDuels.SINGLETON_INSTANCE.getPnlStats(); + final JPanel pnlStart = VSubmenuDuels.SINGLETON_INSTANCE.getPnlStart(); + VSubmenuDuels.SINGLETON_INSTANCE.getBtnStart().setEnabled(false); + //// + + final FScrollPane scrChallenges = new FScrollPane(pnlChallenges, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrChallenges.setBorder(null); + pnlChallenges.setOpaque(false); + pnlChallenges.setLayout(new MigLayout("insets 0, gap 0, wrap")); + + pnl.setOpaque(false); + pnl.setLayout(new MigLayout("insets 0, gap 0, wrap")); + pnl.add(pnlTitle, "w 94%!, h 30px!, gap 3% 0 15px 15px"); + pnl.add(pnlStats, "w 94%!, gap 3% 0 0 20px"); + pnl.add(scrChallenges, "w 94%!, pushy, growy, gap 3% 0 0 0"); + pnl.add(pnlStart, "w 94%, gap 3% 0 15px 5%"); + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlChallenges() { + return pnlChallenges; + } +} diff --git a/src/main/java/forge/gui/home/quest/VSubmenuDuels.java b/src/main/java/forge/gui/home/quest/VSubmenuDuels.java index 2839c82fdb7..ba40c163e60 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuDuels.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuDuels.java @@ -1,5 +1,7 @@ package forge.gui.home.quest; +import java.awt.Color; + import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; @@ -18,10 +20,7 @@ import forge.view.toolbox.FPanel; import forge.view.toolbox.FScrollPane; import forge.view.toolbox.FSkin; -/** - * TODO: Write javadoc for this type. - * - */ +/** */ public enum VSubmenuDuels implements IVSubmenu { /** */ SINGLETON_INSTANCE; @@ -29,28 +28,37 @@ public enum VSubmenuDuels implements IVSubmenu { //========== INSTANTIATION private final JPanel pnl = new JPanel(); private final JPanel pnlDuels = new JPanel(); + private final FPanel pnlTitle = new FPanel(); + private final JPanel pnlStats = new JPanel(); + private final JPanel pnlStart = new JPanel(); + private final JButton btnStart = new StartButton(); private final JComboBox cbxPet = new JComboBox(); private final JCheckBox cbPlant = new FCheckBox("Summon Plant"); private final JCheckBox cbZep = new FCheckBox("Launch Zeppelin"); private final FLabel lblLife = new FLabel.Builder() - .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_LIFE)).build(); + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_LIFE)) + .fontScaleAuto(false).fontSize(15).build(); private final FLabel lblCredits = new FLabel.Builder() - .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_COINSTACK)).build(); + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_COINSTACK)) + .fontScaleAuto(false).fontSize(15).build(); private final FLabel lblWins = new FLabel.Builder() - .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_PLUS)).build(); + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_PLUS)) + .fontScaleAuto(false).fontSize(15).build(); private final FLabel lblLosses = new FLabel.Builder() - .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_MINUS)).build(); - private final FLabel lblNextChallengeInWins = new FLabel.Builder() - .text("No challenges available.").build(); + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_MINUS)) + .fontScaleAuto(false).fontSize(15).build(); private final FLabel lblWinStreak = new FLabel.Builder() - .build(); + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_PLUSPLUS)) + .fontScaleAuto(false).fontSize(15).build(); private final FLabel lblTitle = new FLabel.Builder() .text("Title Hasn't Been Set Yet").fontAlign(SwingConstants.CENTER) + .fontScaleAuto(false).fontSize(16).build(); + private final FLabel lblNextChallengeInWins = new FLabel.Builder() .fontScaleAuto(false).fontSize(15).build(); private final FLabel btnCurrentDeck = new FLabel.Builder() - .opaque(true).hoverable(true).build(); + .fontScaleAuto(false).fontSize(15).opaque(true).hoverable(true).build(); private final FLabel btnBazaar = new FLabel.Builder() .selectable(true).opaque(true).hoverable(true).text("Bazaar") .fontScaleAuto(false).fontSize(14).tooltip("Peruse the Bazaar").build(); @@ -79,29 +87,60 @@ public enum VSubmenuDuels implements IVSubmenu { */ @Override public void populate() { - final FPanel pnlTitle = new FPanel(); pnlTitle.setLayout(new MigLayout("insets 0, gap 0")); pnlTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); pnlTitle.add(lblTitle, "w 100%, h 100%, gap 0 0 0 0"); - final JPanel pnlStats = new JPanel(); - pnlStats.setOpaque(false); - populateStats(pnlStats); + populateStats(); + populateStart(); + btnStart.setEnabled(false); final FScrollPane scrDuels = new FScrollPane(pnlDuels, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrDuels.setBorder(null); pnlDuels.setOpaque(false); pnlDuels.setLayout(new MigLayout("insets 0, gap 0, wrap")); pnl.setOpaque(false); pnl.setLayout(new MigLayout("insets 0, gap 0, wrap")); - pnl.add(pnlTitle, "w 94%!, h 30px!, gap 3% 0 20px 20px"); + pnl.add(pnlTitle, "w 94%!, h 30px!, gap 3% 0 15px 15px"); pnl.add(pnlStats, "w 94%!, gap 3% 0 0 20px"); - pnl.add(scrDuels, "w 94%!, h 50%!, gap 3% 0 0 10px"); - pnl.add(cbxPet, "ax center, gap 3% 0 5px 0"); - pnl.add(cbPlant, "ax center, gap 3% 0 5px 0"); - pnl.add(cbZep, "ax center, gap 3% 0 5px 0"); - pnl.add(btnStart, "ax center, gap 3% 0 5px 10px"); + pnl.add(scrDuels, "w 94%!, pushy, growy, gap 3% 0 0 0"); + pnl.add(pnlStart, "w 94%, gap 3% 0 15px 5%"); + } + + /** */ + public void setCurrentDeckStatus() { + final JLabel btnCurrentDeck = VSubmenuDuels.SINGLETON_INSTANCE.getBtnCurrentDeck(); + if (SubmenuQuestUtil.getCurrentDeck() == null) { + btnCurrentDeck.setBackground(Color.red.darker()); + btnCurrentDeck.setText(" Build, then select a deck in the \"Decks\" submenu. "); + } + else { + btnCurrentDeck.setBackground(FSkin.getColor(FSkin.Colors.CLR_INACTIVE)); + btnCurrentDeck.setText("Current deck: " + + SubmenuQuestUtil.getCurrentDeck().getName()); + } + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlDuels() { + return pnlDuels; + } + + /** @return {@link javax.swing.JPanel} */ + public FPanel getPnlTitle() { + return pnlTitle; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlStats() { + return pnlStats; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlStart() { + return pnlStart; } /** @return {@link javax.swing.JLabel} */ @@ -173,31 +212,33 @@ public enum VSubmenuDuels implements IVSubmenu { return btnStart; } - /** Stats panel has different layout depending on classic/fantasy quest. */ - private void populateStats(final JPanel pnl0) { - pnl0.removeAll(); + private void populateStats() { + final String constraints = "w 23%!, h 35px!, gap 1% 1% 5px 5px"; + pnlStats.removeAll(); + pnlStats.setOpaque(false); + pnlStats.setLayout(new MigLayout("insets 0, gap 0, hidemode 0")); + pnlStats.add(btnBazaar, constraints); + pnlStats.add(lblWins, constraints); + pnlStats.add(lblLosses, constraints); + pnlStats.add(lblLife, constraints + ", wrap"); - if (true) { //(AllZone.getQuestData().isFantasy()) { - pnl0.setLayout(new MigLayout("insets 0, gap 0")); - pnl0.add(btnBazaar, "w 15%!, h 70px!, gap 0 4% 10px 10px, span 1 2"); - pnl0.add(lblWins, "w 30%!, h 25px!, gap 0 2% 12px 0"); - pnl0.add(lblLosses, "w 30%!, h 25px!, gap 0 4% 12px 0"); - pnl0.add(btnSpellShop, "w 14.5%!, h 70px!, gap 0 0 10px 10px, span 1 2, wrap"); - pnl0.add(lblCredits, "w 30%!, h 25px!, gap 0 2% 0 0"); - pnl0.add(lblLife, "w 30%!, h 25px!, gap 0 4% 0 0 0, wrap"); - pnl0.add(lblWinStreak, "h 20px!, align center, span 4 1, wrap"); - pnl0.add(lblNextChallengeInWins, "h 20px!, align center, span 4 1, wrap"); - pnl0.add(btnCurrentDeck, "w 40%!, h 26px!, align center, span 4 1, gap 0 0 0 5px"); - } - else { - pnl0.setLayout(new MigLayout("insets 0, gap 0, align center")); - pnl0.add(lblWins, "w 150px!, h 25px!, gap 0 50px 5px 5px, align center"); - pnl0.add(lblCredits, "w 150px!, h 25px!, gap 0 0 5px 5px, align center, wrap"); - pnl0.add(lblLosses, "w 150px!, h 25px!, gap 0 50px 0 5px, align center"); - pnl0.add(btnSpellShop, "w 150px!, h 25px!, gap 0 0 0 5px, align center, wrap"); - pnl0.add(lblWinStreak, "h 20px!, align center, span 4 1, wrap"); - pnl0.add(lblNextChallengeInWins, "h 20px!, align center, span 4 1, gap 0 0 10px 5px, wrap"); - pnl0.add(btnCurrentDeck, "w 40%!, h 26px!, align center, span 4 1, gap 0 0 0 5px"); - } + pnlStats.add(btnSpellShop, constraints); + pnlStats.add(lblWinStreak, "w 48%!, h 35px!, gap 1% 1% 5px 5px, span 2 1"); + pnlStats.add(lblCredits, constraints + ", wrap"); + + pnlStats.add(lblNextChallengeInWins, "span 4 1, h 20px!, gap 0 0 5px 5px, ax center, wrap"); + pnlStats.add(btnCurrentDeck, "span 4 1, w 350px!, h 30px!, gap 0 0 0 5px, ax center"); + } + + private void populateStart() { + final String constraints = "w 200px!, h 20px!, gap 0 10px 5px 5px"; + pnlStart.removeAll(); + pnlStart.setOpaque(false); + pnlStart.setLayout(new MigLayout("insets 0, gap 0, align center, hidemode 3")); + + pnlStart.add(cbxPet, constraints); + pnlStart.add(btnStart, "ax center, span 1 3, wrap"); + pnlStart.add(cbPlant, constraints + ", wrap"); + pnlStart.add(cbZep, constraints); } } diff --git a/src/main/java/forge/gui/home/quest/VSubmenuQuestData.java b/src/main/java/forge/gui/home/quest/VSubmenuQuestData.java new file mode 100644 index 00000000000..8e61312bc6a --- /dev/null +++ b/src/main/java/forge/gui/home/quest/VSubmenuQuestData.java @@ -0,0 +1,178 @@ +package forge.gui.home.quest; + +import javax.swing.ButtonGroup; +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.SwingConstants; + +import net.miginfocom.swing.MigLayout; +import forge.gui.home.EMenuGroup; +import forge.gui.home.IVSubmenu; +import forge.view.home.QuestFileLister; +import forge.view.toolbox.FCheckBox; +import forge.view.toolbox.FLabel; +import forge.view.toolbox.FPanel; +import forge.view.toolbox.FRadioButton; +import forge.view.toolbox.FScrollPane; +import forge.view.toolbox.FSkin; + +/** + * Singleton instance of "Colors" submenu in "Constructed" group. + * + */ +public enum VSubmenuQuestData implements IVSubmenu { + /** */ + SINGLETON_INSTANCE; + + /** */ + private final JPanel pnl = new JPanel(); + private final JPanel pnlViewport = new JPanel(); + private final QuestFileLister lstQuests = new QuestFileLister(); + + private final JRadioButton radEasy = new FRadioButton("Easy"); + private final JRadioButton radMedium = new FRadioButton("Medium"); + private final JRadioButton radHard = new FRadioButton("Hard"); + private final JRadioButton radExpert = new FRadioButton("Expert"); + private final JRadioButton radFantasy = new FRadioButton("Fantasy"); + private final JRadioButton radClassic = new FRadioButton("Classic"); + + private final JCheckBox cbStandardStart = new FCheckBox("Standard (Type 2) Starting Pool"); + private final FLabel btnEmbark = new FLabel.Builder().opaque(true).hoverable(true).text("Embark!").build(); + + /* (non-Javadoc) + * @see forge.view.home.IViewSubmenu#populate() + */ + @Override + public void populate() { + pnl.removeAll(); + pnl.setOpaque(false); + pnl.setLayout(new MigLayout("insets 0, gap 0")); + + // Load quest + final FPanel pnlTitleLoad = new FPanel(); + pnlTitleLoad.setLayout(new MigLayout("insets 0, align center")); + pnlTitleLoad.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + pnlTitleLoad.add(new FLabel.Builder().text("Load a previous Quest") + .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + + final FScrollPane scr = new FScrollPane(lstQuests); + scr.setBorder(null); + scr.getViewport().setBorder(null); + + // New quest + final FPanel pnlTitleNew = new FPanel(); + pnlTitleNew.setLayout(new MigLayout("insets 0, align center")); + pnlTitleNew.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + pnlTitleNew.add(new FLabel.Builder().text("Start a new Quest") + .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + + final ButtonGroup group1 = new ButtonGroup(); + group1.add(radEasy); + group1.add(radMedium); + group1.add(radHard); + group1.add(radExpert); + + radEasy.setSelected(true); + radClassic.setSelected(true); + + final ButtonGroup group2 = new ButtonGroup(); + group2.add(radFantasy); + group2.add(radClassic); + + final JPanel pnlOptions = new JPanel(); + pnlOptions.setOpaque(false); + pnlOptions.setLayout(new MigLayout("insets 0, gap 0")); + + final String constraints = "w 40%!, h 30px!"; + pnlOptions.add(radEasy, constraints + ", gap 7.5% 2.5% 0 0"); + pnlOptions.add(radFantasy, constraints + ", wrap"); + pnlOptions.add(radMedium, constraints + ", gap 7.5% 2.5% 0 0"); + pnlOptions.add(radClassic, constraints + ", wrap"); + pnlOptions.add(radHard, constraints + ", gap 7.5% 2.5% 0 0"); + pnlOptions.add(cbStandardStart, constraints + ", wrap"); + pnlOptions.add(radExpert, constraints + ", gap 7.5% 2.5% 0 0, wrap"); + + pnlOptions.add(btnEmbark, "w 40%!, h 30px!, gap 30% 0 20px 0, span 3 1"); + + // Final layout + pnlViewport.removeAll(); + pnlViewport.setOpaque(false); + pnlViewport.setLayout(new MigLayout("insets 0, gap 0, wrap")); + + pnlViewport.add(pnlTitleLoad, "w 96%, h 36px!, gap 2% 0 20px 10px"); + + pnlViewport.add(new FLabel.Builder().text("Old quest data? Put into " + + "res/quest/data, and restart Forge.") + .fontAlign(SwingConstants.CENTER).fontScaleAuto(false).fontSize(12) + .build(), "w 96%!, h 18px!, gap 2% 0 0 4px"); + + pnlViewport.add(scr, "w 96%!, pushy, growy, gap 2% 0 0 30px"); + + pnlViewport.add(pnlTitleNew, "w 96%, h 36px!, gap 2% 0 0 10px"); + pnlViewport.add(pnlOptions, "w 96%!, h 200px!, gap 2% 0 0 20px"); + + pnl.add(new FScrollPane(pnlViewport), "w 100%!, h 100%!"); + } + + /* (non-Javadoc) + * @see forge.view.home.IViewSubmenu#getGroup() + */ + @Override + public EMenuGroup getGroup() { + return null; + } + + /* (non-Javadoc) + * @see forge.view.home.IViewSubmenu#getPanel() + */ + @Override + public JPanel getPanel() { + return pnl; + } + + /** @return {@link forge.view.home.QuestFileLister} */ + public QuestFileLister getLstQuests() { + return this.lstQuests; + } + + /** @return {@link javax.swing.JRadioButton} */ + public JRadioButton getRadEasy() { + return radEasy; + } + + /** @return {@link javax.swing.JRadioButton} */ + public JRadioButton getRadMedium() { + return radMedium; + } + + /** @return {@link javax.swing.JRadioButton} */ + public JRadioButton getRadHard() { + return radHard; + } + + /** @return {@link javax.swing.JRadioButton} */ + public JRadioButton getRadExpert() { + return radExpert; + } + + /** @return {@link javax.swing.JRadioButton} */ + public JRadioButton getRadFantasy() { + return radFantasy; + } + + /** @return {@link javax.swing.JRadioButton} */ + public JRadioButton getRadClassic() { + return radClassic; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getCbStandardStart() { + return cbStandardStart; + } + + /** @return {@link forge.view.toolbox.FLabel} */ + public FLabel getBtnEmbark() { + return btnEmbark; + } +} diff --git a/src/main/java/forge/gui/home/quest/VSubmenuQuestPrefs.java b/src/main/java/forge/gui/home/quest/VSubmenuQuestPrefs.java new file mode 100644 index 00000000000..dde9eca82cd --- /dev/null +++ b/src/main/java/forge/gui/home/quest/VSubmenuQuestPrefs.java @@ -0,0 +1,420 @@ +package forge.gui.home.quest; + +import java.awt.Color; +import java.awt.Font; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +import net.miginfocom.swing.MigLayout; +import forge.Singletons; +import forge.gui.home.EMenuGroup; +import forge.gui.home.IVSubmenu; +import forge.quest.data.QuestPreferences; +import forge.quest.data.QuestPreferences.QPref; +import forge.view.toolbox.FLabel; +import forge.view.toolbox.FPanel; +import forge.view.toolbox.FScrollPane; +import forge.view.toolbox.FSkin; + +/** + * Singleton instance of "Colors" submenu in "Constructed" group. + * + */ +public enum VSubmenuQuestPrefs implements IVSubmenu { + /** */ + SINGLETON_INSTANCE; + + /** */ + private final JPanel pnl = new JPanel(); + private final JPanel pnlRewards = new JPanel(); + private final JPanel pnlDifficulty = new JPanel(); + private final JPanel pnlBooster = new JPanel(); + private final JPanel pnlShop = new JPanel(); + + private final FLabel lblErrRewards = new FLabel.Builder().text("Rewards Error").fontStyle(Font.BOLD).build(); + private final FLabel lblErrDifficulty = new FLabel.Builder().text("Difficulty Error").fontStyle(Font.BOLD).build(); + private final FLabel lblErrBooster = new FLabel.Builder().text("Booster Error").fontStyle(Font.BOLD).build(); + private final FLabel lblErrShop = new FLabel.Builder().text("Shop Error").fontStyle(Font.BOLD).build(); + + private final QuestPreferences prefs = Singletons.getModel().getQuestPreferences(); + + /** */ + public enum QuestPreferencesErrType { /** */ + REWARDS, /** */ + DIFFICULTY, /** */ + BOOSTER, /** */ + SHOP + } + + /* (non-Javadoc) + * @see forge.view.home.IViewSubmenu#populate() + */ + @Override + public void populate() { + final JPanel pnlContent = new JPanel(); + pnlContent.setOpaque(false); + pnlContent.setLayout(new MigLayout("insets 0, gap 0, wrap")); + + lblErrRewards.setForeground(Color.red); + lblErrDifficulty.setForeground(Color.red); + lblErrBooster.setForeground(Color.red); + lblErrShop.setForeground(Color.red); + + // Rewards panel + final FPanel pnlTitleRewards = new FPanel(); + pnlTitleRewards.setLayout(new MigLayout("insets 0, align center")); + pnlTitleRewards.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + pnlTitleRewards.add(new FLabel.Builder().text("Rewards") + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_COIN)) + .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + + pnlContent.add(pnlTitleRewards, "w 96%!, h 36px!, gap 2% 0 10px 20px"); + pnlContent.add(pnlRewards, "w 96%!, gap 2% 0 10px 20px"); + populateRewards(); + + // Booster panel + final FPanel pnlTitleBooster = new FPanel(); + pnlTitleBooster.setLayout(new MigLayout("insets 0, align center")); + pnlTitleBooster.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + pnlTitleBooster.add(new FLabel.Builder().text("Booster Pack Ratios") + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_BOOK)) + .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + pnlContent.add(pnlTitleBooster, "w 96%!, h 36px!, gap 2% 0 10px 10px"); + pnlContent.add(pnlBooster, "w 96%!, gap 2% 0 10px 20px"); + populateBooster(); + + // Difficulty table panel + final FPanel pnlTitleDifficulty = new FPanel(); + pnlTitleDifficulty.setLayout(new MigLayout("insets 0, align center")); + pnlTitleDifficulty.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + pnlTitleDifficulty.add(new FLabel.Builder().text("Difficulty Adjustments") + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_NOTES)) + .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + pnlContent.add(pnlTitleDifficulty, "w 96%!, h 36px!, gap 2% 0 10px 10px"); + pnlContent.add(pnlDifficulty, "w 96%!, gap 2% 0 10px 20px"); + populateDifficulty(); + + // Shop panel + final FPanel pnlTitleShop = new FPanel(); + pnlTitleShop.setLayout(new MigLayout("insets 0, align center")); + pnlTitleShop.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + pnlTitleShop.add(new FLabel.Builder().text("Shop Preferences") + .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_COIN)) + .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + pnlContent.add(pnlTitleShop, "w 96%!, h 36px!, gap 2% 0 10px 10px"); + pnlContent.add(pnlShop, "w 96%!, gap 2% 0 10px 20px"); + populateShop(); + + final FScrollPane scrContent = new FScrollPane(pnlContent, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrContent.setBorder(null); + + pnl.removeAll(); + pnl.setOpaque(false); + pnl.setLayout(new MigLayout("insets 0, gap 0")); + pnl.add(scrContent, "w 100%!, growy, pushy, gap 0 0 10px 10px"); + + CSubmenuQuestPrefs.resetErrors(); + } + + /* (non-Javadoc) + * @see forge.view.home.IViewSubmenu#getGroup() + */ + @Override + public EMenuGroup getGroup() { + return EMenuGroup.QUEST; + } + + /* (non-Javadoc) + * @see forge.view.home.IViewSubmenu#getPanel() + */ + @Override + public JPanel getPanel() { + return pnl; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblErrRewards() { + return lblErrRewards; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblErrShop() { + return lblErrShop; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblErrDifficulty() { + return lblErrDifficulty; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblErrBooster() { + return lblErrBooster; + } + + private void populateRewards() { + pnlRewards.setOpaque(false); + pnlRewards.setLayout(new MigLayout("insets 0, gap 0, wrap 2, hidemode 3")); + pnlRewards.removeAll(); + pnlRewards.add(lblErrRewards, "w 100%!, h 30px!, span 2 1"); + + final String constraints1 = "w 60px, h 26px!"; + final String constraints2 = "w 150px!, h 26px!"; + + pnlRewards.add(new FLabel.Builder().text("Base winnings").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_BASE, QuestPreferencesErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel.Builder().text("No losses").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_UNDEFEATED, QuestPreferencesErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel.Builder().text("Poison win").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_POISON, QuestPreferencesErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel.Builder().text("Milling win").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_MILLED, QuestPreferencesErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel.Builder().text("Mulligan 0 win").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_MULLIGAN0, QuestPreferencesErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel.Builder().text("Alternative win").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_ALTERNATIVE, QuestPreferencesErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel.Builder().text("Win by turn 15").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_TURN15, QuestPreferencesErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel.Builder().text("Win by turn 10").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_TURN10, QuestPreferencesErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel.Builder().text("Win by turn 5").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_TURN5, QuestPreferencesErrType.REWARDS), constraints1); + + pnlRewards.add(new FLabel.Builder().text("First turn win").build(), constraints2); + pnlRewards.add(new PrefInput(QPref.REWARDS_TURN1, QuestPreferencesErrType.REWARDS), constraints1); + } + + private void populateDifficulty() { + final String constraints1 = "w 60px!, h 26px!"; + final String constraints2 = "w 150px!, h 26px!"; + + pnlDifficulty.setOpaque(false); + pnlDifficulty.setLayout(new MigLayout("insets 0, gap 0, wrap 5, hidemode 3")); + pnlDifficulty.removeAll(); + pnlDifficulty.add(lblErrDifficulty, "w 100%!, h 30px!, span 5 1"); + + pnlDifficulty.add(new FLabel.Builder().text("").build(), constraints2); + pnlDifficulty.add(new FLabel.Builder().text("Easy").build(), constraints1); + pnlDifficulty.add(new FLabel.Builder().text("Medium").build(), constraints1); + pnlDifficulty.add(new FLabel.Builder().text("Hard").build(), constraints1); + pnlDifficulty.add(new FLabel.Builder().text("Expert").build(), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Wins For Booster").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_BOOSTER_EASY, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_BOOSTER_MEDIUM, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_BOOSTER_HARD, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_BOOSTER_EXPERT, QuestPreferencesErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Wins For Rank Increase").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_RANKUP_EASY, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_RANKUP_MEDIUM, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_RANKUP_HARD, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_RANKUP_EXPERT, QuestPreferencesErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Wins For Medium AI").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_MEDIUMAI_EASY, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_MEDIUMAI_MEDIUM, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_MEDIUMAI_HARD, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_MEDIUMAI_EXPERT, QuestPreferencesErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Wins For Hard AI").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_HARDAI_EASY, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_HARDAI_MEDIUM, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_HARDAI_HARD, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_HARDAI_EXPERT, QuestPreferencesErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Wins For Expert AI").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.WINS_EXPERTAI_EASY, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_EXPERTAI_MEDIUM, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_EXPERTAI_HARD, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.WINS_EXPERTAI_EXPERT, QuestPreferencesErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Starting commons").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_COMMONS_EASY, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_COMMONS_MEDIUM, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_COMMONS_HARD, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_COMMONS_EXPERT, QuestPreferencesErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Starting uncommons").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_UNCOMMONS_EASY, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_UNCOMMONS_MEDIUM, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_UNCOMMONS_HARD, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_UNCOMMONS_EXPERT, QuestPreferencesErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Starting rares").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_RARES_EASY, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_RARES_MEDIUM, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_RARES_HARD, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_RARES_EXPERT, QuestPreferencesErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Starting credits").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_CREDITS_EASY, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_CREDITS_MEDIUM, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_CREDITS_HARD, QuestPreferencesErrType.DIFFICULTY), constraints1); + pnlDifficulty.add(new PrefInput(QPref.STARTING_CREDITS_EXPERT, QuestPreferencesErrType.DIFFICULTY), constraints1); + + pnlDifficulty.add(new FLabel.Builder().text("Starting basic lands").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_BASIC_LANDS, QuestPreferencesErrType.DIFFICULTY), constraints1 + ", wrap"); + + pnlDifficulty.add(new FLabel.Builder().text("Starting snow lands").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.STARTING_SNOW_LANDS, QuestPreferencesErrType.DIFFICULTY), constraints1 + ", wrap"); + + pnlDifficulty.add(new FLabel.Builder().text("Penalty for loss").build(), constraints2); + pnlDifficulty.add(new PrefInput(QPref.PENALTY_LOSS, QuestPreferencesErrType.DIFFICULTY), constraints1 + ", wrap"); + } + + private void populateBooster() { + final String constraints1 = "w 60px!, h 26px!"; + final String constraints2 = "w 150px!, h 26px!"; + + pnlBooster.setOpaque(false); + pnlBooster.setLayout(new MigLayout("insets 0, gap 0, wrap 2, hidemode 3")); + pnlBooster.removeAll(); + pnlBooster.add(lblErrBooster, "w 100%!, h 30px!, span 2 1"); + + pnlBooster.add(new FLabel.Builder().text("Common").build(), constraints2); + pnlBooster.add(new PrefInput(QPref.BOOSTER_COMMONS, QuestPreferencesErrType.BOOSTER), constraints1); + + pnlBooster.add(new FLabel.Builder().text("Uncommon").build(), constraints2); + pnlBooster.add(new PrefInput(QPref.BOOSTER_UNCOMMONS, QuestPreferencesErrType.BOOSTER), constraints1); + + pnlBooster.add(new FLabel.Builder().text("Rare").build(), constraints2); + pnlBooster.add(new PrefInput(QPref.BOOSTER_RARES, QuestPreferencesErrType.BOOSTER), constraints1); + + } + + private void populateShop() { + final String constraints1 = "w 60px, h 26px!"; + final String constraints2 = "w 150px!, h 26px!"; + + pnlShop.setOpaque(false); + pnlShop.setLayout(new MigLayout("insets 0, gap 0, wrap 2, hidemode 3")); + pnlShop.removeAll(); + pnlShop.add(lblErrShop, "w 100%!, h 30px!, span 2 1"); + + pnlShop.add(new FLabel.Builder().text("Maximum Packs").build(), constraints2); + pnlShop.add(new PrefInput(QPref.SHOP_MAX_PACKS, QuestPreferencesErrType.SHOP), constraints1); + + pnlShop.add(new FLabel.Builder().text("Starting Packs").build(), constraints2); + pnlShop.add(new PrefInput(QPref.SHOP_STARTING_PACKS, QuestPreferencesErrType.SHOP), constraints1); + + pnlShop.add(new FLabel.Builder().text("Wins for Pack").build(), constraints2); + pnlShop.add(new PrefInput(QPref.SHOP_WINS_FOR_ADDITIONAL_PACK, QuestPreferencesErrType.SHOP), constraints1); + + pnlShop.add(new FLabel.Builder().text("Common Singles").build(), constraints2); + pnlShop.add(new PrefInput(QPref.SHOP_SINGLES_COMMON, QuestPreferencesErrType.SHOP), constraints1); + + pnlShop.add(new FLabel.Builder().text("Uncommon Singles").build(), constraints2); + pnlShop.add(new PrefInput(QPref.SHOP_SINGLES_UNCOMMON, QuestPreferencesErrType.SHOP), constraints1); + + pnlShop.add(new FLabel.Builder().text("Rare Singles").build(), constraints2); + pnlShop.add(new PrefInput(QPref.SHOP_SINGLES_RARE, QuestPreferencesErrType.SHOP), constraints1); + } + + /** */ + @SuppressWarnings("serial") + public class PrefInput extends JTextField { + private final QPref qpref; + private final QuestPreferencesErrType err; + private final Color clrHover, clrActive, clrText; + private boolean isFocus = false; + private String previousText = ""; + + /** + * @param qp0   {@link forge.quest.data.QuestPreferences.QPref} + * preferences ident enum + * @param e0   {@link forge.view.home.ViewQuestPreference.QuestPreferencesErrType} + * where error should display to + */ + public PrefInput(QPref qp0, QuestPreferencesErrType e0) { + super(); + + this.qpref = qp0; + this.err = e0; + this.clrHover = FSkin.getColor(FSkin.Colors.CLR_HOVER); + this.clrActive = FSkin.getColor(FSkin.Colors.CLR_ACTIVE); + this.clrText = FSkin.getColor(FSkin.Colors.CLR_TEXT); + + this.setOpaque(false); + this.setBorder(null); + this.setFont(FSkin.getFont(13)); + this.setForeground(clrText); + this.setCaretColor(clrText); + this.setBackground(clrHover); + this.setHorizontalAlignment(SwingConstants.CENTER); + this.setText(prefs.getPreference(qpref)); + this.setPreviousText(prefs.getPreference(qpref)); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + if (isFocus) { return; } + setOpaque(true); + repaint(); + } + + @Override + public void mouseExited(MouseEvent e) { + if (isFocus) { return; } + setOpaque(false); + repaint(); + } + }); + + this.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + isFocus = true; + setOpaque(true); + setBackground(clrActive); + } + + @Override + public void focusLost(FocusEvent e) { + isFocus = false; + setOpaque(false); + setBackground(clrHover); + + CSubmenuQuestPrefs.validateAndSave(PrefInput.this); + } + }); + } + + /** @return {@link forge.quest.data.QuestPreferences.QPref} */ + public QPref getQPref() { + return this.qpref; + } + + /** @return {@link forge.gui.home.quest.VSubmenuQuestPrefs.QuestPreferencesErrType} */ + public QuestPreferencesErrType getErrType() { + return this.err; + } + + /** @return {@link java.lang.String} */ + public String getPreviousText() { + return this.previousText; + } + + /** @param s0   {@link java.lang.String} */ + public void setPreviousText(String s0) { + this.previousText = s0; + } + } +} diff --git a/src/main/java/forge/view/toolbox/FSkin.java b/src/main/java/forge/view/toolbox/FSkin.java index f7783dbc3ea..e7861cddd31 100644 --- a/src/main/java/forge/view/toolbox/FSkin.java +++ b/src/main/java/forge/view/toolbox/FSkin.java @@ -243,7 +243,8 @@ public enum FSkin { ICO_BREW (new int[] {560, 560, 80, 80}), /** */ ICO_MINUS (new int[] {560, 640, 80, 80}), /** */ - ICO_PLUS (new int[] {480, 640, 80, 80}); + ICO_PLUS (new int[] {480, 640, 80, 80}), /** */ + ICO_PLUSPLUS (new int[] {480, 720, 80, 80}); private int[] coords; /** @param xy   int[] coordinates */