From 952e3d93f03892cdb5a43d7cdba02f02eec81f4e Mon Sep 17 00:00:00 2001 From: drdev Date: Fri, 8 Aug 2014 04:05:18 +0000 Subject: [PATCH] Create Gauntlets screen --- .gitattributes | 1 + .../src/main/java/forge/util/Localizer.java | 2 +- .../home/gauntlet/QuickGauntletLister.java | 1 - .../src/forge/deck/FDeckChooser.java | 60 ++-- .../screens/gauntlet/GauntletScreen.java | 290 +++++++++++++++++- .../screens/gauntlet/NewGauntletScreen.java | 15 + .../src/forge/screens/home/HomeScreen.java | 26 +- .../forge/screens/quest/LoadQuestScreen.java | 11 +- 8 files changed, 363 insertions(+), 43 deletions(-) create mode 100644 forge-gui-mobile/src/forge/screens/gauntlet/NewGauntletScreen.java diff --git a/.gitattributes b/.gitattributes index 5d8e059b5f0..9423fb67e08 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1186,6 +1186,7 @@ forge-gui-mobile/src/forge/screens/constructed/ConstructedScreen.java -text forge-gui-mobile/src/forge/screens/draft/DraftScreen.java -text forge-gui-mobile/src/forge/screens/draft/DraftingProcessScreen.java -text forge-gui-mobile/src/forge/screens/gauntlet/GauntletScreen.java -text +forge-gui-mobile/src/forge/screens/gauntlet/NewGauntletScreen.java -text forge-gui-mobile/src/forge/screens/home/HomeScreen.java -text forge-gui-mobile/src/forge/screens/match/FControl.java -text forge-gui-mobile/src/forge/screens/match/MatchScreen.java -text diff --git a/forge-core/src/main/java/forge/util/Localizer.java b/forge-core/src/main/java/forge/util/Localizer.java index 9deece39604..290d33d2ee7 100644 --- a/forge-core/src/main/java/forge/util/Localizer.java +++ b/forge-core/src/main/java/forge/util/Localizer.java @@ -92,7 +92,7 @@ public class Localizer { e.printStackTrace(); } - System.out.println("Language '" + resourceBundle.getBaseBundleName() + "' loaded successfully."); + System.out.println("Language '" + resourceBundle.toString() + "' loaded successfully."); notifyObservers(); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/QuickGauntletLister.java b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/QuickGauntletLister.java index 4ec84d82291..e61c11c3d73 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/QuickGauntletLister.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/gauntlet/QuickGauntletLister.java @@ -56,7 +56,6 @@ public class QuickGauntletLister extends JPanel { icoEdit = FSkin.getIcon(FSkinProp.ICO_EDIT); icoEditOver = FSkin.getIcon(FSkinProp.ICO_EDIT_OVER); } - /** @param gd0   {@link forge.gauntlet.GauntletData}[] */ public void setGauntlets(List gd0) { diff --git a/forge-gui-mobile/src/forge/deck/FDeckChooser.java b/forge-gui-mobile/src/forge/deck/FDeckChooser.java index 5cfdde2345f..19b2beaafe7 100644 --- a/forge-gui-mobile/src/forge/deck/FDeckChooser.java +++ b/forge-gui-mobile/src/forge/deck/FDeckChooser.java @@ -1,5 +1,6 @@ package forge.deck; +import forge.FThreads; import forge.Forge; import forge.deck.Deck; import forge.deck.FDeckEditor.EditorType; @@ -51,6 +52,20 @@ public class FDeckChooser extends FScreen { private final ForgePreferences prefs = FModel.getPreferences(); private FPref stateSetting = null; + //Show dialog to select a deck + public static void promptForDeck(String title, GameType gameType, boolean forAi, final Callback callback) { + FThreads.assertExecutedByEdt(true); + final FDeckChooser chooser = new FDeckChooser(gameType, forAi, null) { + @Override + public void onClose(Callback canCloseCallback) { + super.onClose(canCloseCallback); + callback.run(getDeck()); + } + }; + chooser.setHeaderCaption(title); + Forge.openScreen(chooser); + } + public FDeckChooser(GameType gameType0, boolean isAi0, FEventHandler selectionChangedHandler) { super(""); lstDecks = new DeckManager(gameType0); @@ -67,9 +82,6 @@ public class FDeckChooser extends FScreen { public void handleEvent(FEvent e) { EditorType editorType; switch (lstDecks.getGameType()) { - case Constructed: - editorType = EditorType.Constructed; - break; case Commander: editorType = EditorType.Commander; break; @@ -80,7 +92,8 @@ public class FDeckChooser extends FScreen { editorType = EditorType.Planechase; break; default: - return; + editorType = EditorType.Constructed; + break; } FDeckEditor editor; switch (selectedDeckType) { @@ -131,8 +144,16 @@ public class FDeckChooser extends FScreen { } } }); - if (gameType0 != GameType.Constructed) { //delay initialize for constructed until saved decks can be reloaded + switch (lstDecks.getGameType()) { + case Constructed: + break; //delay initialize for constructed until saved decks can be reloaded + case Commander: + case Gauntlet: + initialize(null, DeckType.CUSTOM_DECK); + break; + default: initialize(null, DeckType.RANDOM_DECK); + break; } lstDecks.setSelectionChangedHandler(selectionChangedHandler); } @@ -143,9 +164,6 @@ public class FDeckChooser extends FScreen { needRefreshOnActivate = false; updateCustom(); switch (lstDecks.getGameType()) { - case Constructed: - lstDecks.setSelectedString(DeckPreferences.getCurrentDeck()); - break; case Commander: lstDecks.setSelectedString(DeckPreferences.getCommanderDeck()); break; @@ -156,7 +174,8 @@ public class FDeckChooser extends FScreen { lstDecks.setSelectedString(DeckPreferences.getPlanarDeck()); break; default: - return; + lstDecks.setSelectedString(DeckPreferences.getCurrentDeck()); + break; } } } @@ -197,10 +216,6 @@ public class FDeckChooser extends FScreen { private void editDeck(DeckProxy deck) { EditorType editorType; switch (lstDecks.getGameType()) { - case Constructed: - editorType = EditorType.Constructed; - DeckPreferences.setCurrentDeck(deck.getName()); - break; case Commander: editorType = EditorType.Commander; DeckPreferences.setCommanderDeck(deck.getName()); @@ -214,7 +229,9 @@ public class FDeckChooser extends FScreen { DeckPreferences.setPlanarDeck(deck.getName()); break; default: - return; + editorType = EditorType.Constructed; + DeckPreferences.setCurrentDeck(deck.getName()); + break; } needRefreshOnActivate = true; Forge.openScreen(new FDeckEditor(editorType, deck, true)); @@ -226,17 +243,20 @@ public class FDeckChooser extends FScreen { if (cmbDeckTypes == null) { //initialize components with delayed initialization the first time this is populated cmbDeckTypes = new FComboBox(); - if (lstDecks.getGameType() == GameType.Constructed) { + switch (lstDecks.getGameType()) { + case Constructed: + case Gauntlet: cmbDeckTypes.addItem(DeckType.CUSTOM_DECK); cmbDeckTypes.addItem(DeckType.PRECONSTRUCTED_DECK); cmbDeckTypes.addItem(DeckType.QUEST_OPPONENT_DECK); cmbDeckTypes.addItem(DeckType.COLOR_DECK); cmbDeckTypes.addItem(DeckType.THEME_DECK); cmbDeckTypes.addItem(DeckType.RANDOM_DECK); - } - else { + break; + default: cmbDeckTypes.addItem(DeckType.CUSTOM_DECK); cmbDeckTypes.addItem(DeckType.RANDOM_DECK); + break; } cmbDeckTypes.setAlignment(HAlignment.CENTER); restoreSavedState(); @@ -303,10 +323,6 @@ public class FDeckChooser extends FScreen { lstDecks.setSelectionSupport(1, 1); switch (lstDecks.getGameType()) { - case Constructed: - lstDecks.setPool(DeckProxy.getAllConstructedDecks()); - lstDecks.setup(ItemManagerConfig.CONSTRUCTED_DECKS); - break; case Commander: lstDecks.setPool(DeckProxy.getAllCommanderDecks()); lstDecks.setup(ItemManagerConfig.COMMANDER_DECKS); @@ -320,6 +336,8 @@ public class FDeckChooser extends FScreen { lstDecks.setup(ItemManagerConfig.PLANAR_DECKS); break; default: + lstDecks.setPool(DeckProxy.getAllConstructedDecks()); + lstDecks.setup(ItemManagerConfig.CONSTRUCTED_DECKS); break; } diff --git a/forge-gui-mobile/src/forge/screens/gauntlet/GauntletScreen.java b/forge-gui-mobile/src/forge/screens/gauntlet/GauntletScreen.java index a79d1e1dbde..c549616ed9d 100644 --- a/forge-gui-mobile/src/forge/screens/gauntlet/GauntletScreen.java +++ b/forge-gui-mobile/src/forge/screens/gauntlet/GauntletScreen.java @@ -1,22 +1,306 @@ package forge.screens.gauntlet; +import java.io.File; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; + +import forge.FThreads; +import forge.Forge; +import forge.Graphics; +import forge.GuiBase; +import forge.assets.FSkinColor; +import forge.assets.FSkinColor.Colors; +import forge.assets.FSkinFont; +import forge.card.CardRenderer; +import forge.deck.Deck; +import forge.deck.FDeckChooser; import forge.game.GameType; +import forge.game.player.RegisteredPlayer; +import forge.gauntlet.GauntletData; +import forge.gauntlet.GauntletIO; +import forge.model.FModel; +import forge.quest.QuestUtil; import forge.screens.LaunchScreen; +import forge.screens.settings.SettingsScreen; +import forge.toolbox.FButton; +import forge.toolbox.FEvent; +import forge.toolbox.FList; +import forge.toolbox.FOptionPane; +import forge.toolbox.FEvent.FEventHandler; +import forge.util.Callback; +import forge.util.ThreadUtil; +import forge.util.Utils; +import forge.util.gui.SOptionPane; public class GauntletScreen extends LaunchScreen { + private static final float PADDING = Utils.AVG_FINGER_HEIGHT * 0.1f; + private static final FSkinColor SEL_COLOR = FSkinColor.get(Colors.CLR_ACTIVE); + + private final GauntletFileLister lstGauntlets = add(new GauntletFileLister()); + private final FButton btnNewGauntlet = add(new FButton("New")); + private final FButton btnRenameGauntlet = add(new FButton("Rename")); + private final FButton btnDeleteGauntlet = add(new FButton("Delete")); + public GauntletScreen() { super("Gauntlets"); + + btnNewGauntlet.setFont(FSkinFont.get(16)); + btnNewGauntlet.setCommand(new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + Forge.openScreen(new NewGauntletScreen()); + } + }); + btnRenameGauntlet.setFont(btnNewGauntlet.getFont()); + btnRenameGauntlet.setCommand(new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + renameGauntlet(lstGauntlets.getSelectedGauntlet()); + } + }); + btnDeleteGauntlet.setFont(btnNewGauntlet.getFont()); + btnDeleteGauntlet.setCommand(new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + deleteGauntlet(lstGauntlets.getSelectedGauntlet()); + } + }); + + final File[] files = GauntletIO.getGauntletFilesUnlocked(); + final List data = new ArrayList(); + + for (final File f : files) { + data.add(GauntletIO.loadGauntlet(f)); + } + + lstGauntlets.setGauntlets(data); + lstGauntlets.setSelectedIndex(0); } @Override protected void doLayoutAboveBtnStart(float startY, float width, float height) { - // TODO Auto-generated method stub - + float buttonWidth = (width - 2 * PADDING) / 3; + float buttonHeight = btnNewGauntlet.getAutoSizeBounds().height * 1.2f; + + float y = startY; + lstGauntlets.setBounds(0, y, width, height - y - buttonHeight - PADDING); + y += lstGauntlets.getHeight() + PADDING; + + float x = 0; + btnNewGauntlet.setBounds(x, y, buttonWidth, buttonHeight); + x += buttonWidth + PADDING; + btnRenameGauntlet.setBounds(x, y, buttonWidth, buttonHeight); + x += buttonWidth + PADDING; + btnDeleteGauntlet.setBounds(x, y, buttonWidth, buttonHeight); + } + + @Override + protected void startMatch() { + final GauntletData gauntlet = lstGauntlets.getSelectedGauntlet(); + if (gauntlet == null) { + FOptionPane.showMessageDialog("You must create and select a gauntlet."); + return; + } + FModel.setGauntletData(gauntlet); + Deck userDeck = gauntlet.getUserDeck(); + if (userDeck == null) { + //give user a chance to select a deck if none saved with gauntlet + FDeckChooser.promptForDeck("Select Deck for Gauntlet", GameType.Gauntlet, false, new Callback() { + @Override + public void run(Deck result) { + if (result != null) { + gauntlet.setUserDeck(result); + GauntletIO.saveGauntlet(gauntlet); + startMatch(); + } + } + }); + return; + } + super.startMatch(); } @Override protected boolean buildLaunchParams(LaunchParams launchParams) { + final GauntletData gauntlet = FModel.getGauntletData(); launchParams.gameType = GameType.Gauntlet; - return false; //TODO: Support launching match + launchParams.players.add(new RegisteredPlayer(gauntlet.getUserDeck()).setPlayer(GuiBase.getInterface().getGuiPlayer())); + launchParams.players.add(new RegisteredPlayer(gauntlet.getDecks().get(gauntlet.getCompleted())).setPlayer(GuiBase.getInterface().createAiPlayer())); + return true; + } + + private void renameGauntlet(final GauntletData gauntlet) { + if (gauntlet == null) { return; } + + ThreadUtil.invokeInGameThread(new Runnable() { + @Override + public void run() { + String gauntletName; + String oldGauntletName = gauntlet.getName(); + while (true) { + gauntletName = SOptionPane.showInputDialog("Enter new name for gauntlet:", "Rename Gauntlet", null, oldGauntletName); + if (gauntletName == null) { return; } + + gauntletName = QuestUtil.cleanString(gauntletName); + if (gauntletName.equals(oldGauntletName)) { return; } //quit if chose same name + + if (gauntletName.isEmpty()) { + SOptionPane.showMessageDialog("Please specify a gauntlet name."); + continue; + } + + boolean exists = false; + for (GauntletData gauntletData : lstGauntlets) { + if (gauntletData.getName().equalsIgnoreCase(gauntletName)) { + exists = true; + break; + } + } + if (exists) { + SOptionPane.showMessageDialog("A gauntlet already exists with that name. Please pick another gauntlet name."); + continue; + } + break; + } + final String newGauntletName = gauntletName; + FThreads.invokeInEdtLater(new Runnable() { + @Override + public void run() { + gauntlet.rename(newGauntletName); + lstGauntlets.refresh(); + lstGauntlets.setSelectedGauntlet(gauntlet); + } + }); + } + }); + } + + private void deleteGauntlet(final GauntletData gauntlet) { + if (gauntlet == null) { return; } + + ThreadUtil.invokeInGameThread(new Runnable() { + @Override + public void run() { + if (!SOptionPane.showConfirmDialog( + "Are you sure you want to delete '" + gauntlet.getName() + "'?", + "Delete Gauntlet", "Delete", "Cancel")) { + return; + } + + GauntletIO.getGauntletFile(gauntlet).delete(); + + lstGauntlets.removeItem(gauntlet); + } + }); + } + + private class GauntletFileLister extends FList { + private int selectedIndex = 0; + private List gauntlets; + + private GauntletFileLister() { + setListItemRenderer(new ListItemRenderer() { + @Override + public boolean tap(Integer index, GauntletData value, float x, float y, int count) { + if (count == 2) { + startMatch(); + } + else { + selectedIndex = index; + } + return true; + } + + @Override + public float getItemHeight() { + return CardRenderer.getCardListItemHeight(false); + } + + @Override + public void drawValue(Graphics g, Integer index, GauntletData value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { + float offset = w * SettingsScreen.INSETS_FACTOR - FList.PADDING; //increase padding for settings items + x += offset; + y += offset; + w -= 2 * offset; + h -= 2 * offset; + + float totalHeight = h; + String name = value.getName(); + h = font.getMultiLineBounds(name).height + SettingsScreen.SETTING_PADDING; + + int completed = value.getCompleted(); + int opponents = value.getDecks().size(); + NumberFormat percent = NumberFormat.getPercentInstance(); + String progress = completed + " / " + opponents + " (" + percent.format((double)completed / (double)opponents) + ")"; + float progressWidth = font.getBounds(progress).width + SettingsScreen.SETTING_PADDING; + + g.drawText(name, font, foreColor, x, y, w - progressWidth, h, false, HAlignment.LEFT, false); + g.drawText(progress, font, foreColor, x, y, w, h, false, HAlignment.RIGHT, false); + + h += SettingsScreen.SETTING_PADDING; + y += h; + h = totalHeight - h + w * SettingsScreen.INSETS_FACTOR; + + String timestamp = value.getTimestamp(); + font = FSkinFont.get(12); + float timestampWidth = font.getBounds(timestamp).width + SettingsScreen.SETTING_PADDING; + g.drawText(value.getUserDeck() == null ? "(none)" : value.getUserDeck().getName(), font, SettingsScreen.DESC_COLOR, x, y, w - timestampWidth, h, false, HAlignment.LEFT, false); + g.drawText(timestamp, font, SettingsScreen.DESC_COLOR, x + w - timestampWidth + SettingsScreen.SETTING_PADDING, y, w, h, false, HAlignment.LEFT, false); + } + }); + } + + @Override + protected FSkinColor getItemFillColor(int index) { + if (index == selectedIndex) { + return SEL_COLOR; + } + return null; + } + + public void setGauntlets(List gauntlets0) { + gauntlets = gauntlets0; + refresh(); + } + + public void refresh() { + List sorted = new ArrayList(); + for (GauntletData gauntlet : gauntlets) { + sorted.add(gauntlet); + } + Collections.sort(sorted, new Comparator() { + @Override + public int compare(final GauntletData x, final GauntletData y) { + return x.getName().toLowerCase().compareTo(y.getName().toLowerCase()); + } + }); + setListData(sorted); + } + + public boolean setSelectedIndex(int i0) { + if (i0 >= getCount()) { return false; } + selectedIndex = i0; + return true; + } + + public GauntletData getSelectedGauntlet() { + if (selectedIndex == -1) { return null; } + return getItemAt(selectedIndex); + } + + public boolean setSelectedGauntlet(GauntletData gauntlet) { + for (int i = 0; i < getCount(); i++) { + if (getItemAt(i) == gauntlet) { + selectedIndex = i; + return true; + } + } + return false; + } } } diff --git a/forge-gui-mobile/src/forge/screens/gauntlet/NewGauntletScreen.java b/forge-gui-mobile/src/forge/screens/gauntlet/NewGauntletScreen.java new file mode 100644 index 00000000000..844f93a6123 --- /dev/null +++ b/forge-gui-mobile/src/forge/screens/gauntlet/NewGauntletScreen.java @@ -0,0 +1,15 @@ +package forge.screens.gauntlet; + +import forge.screens.FScreen; + +public class NewGauntletScreen extends FScreen { + + public NewGauntletScreen() { + super("New Gauntlet"); + } + + @Override + protected void doLayout(float startY, float width, float height) { + + } +} diff --git a/forge-gui-mobile/src/forge/screens/home/HomeScreen.java b/forge-gui-mobile/src/forge/screens/home/HomeScreen.java index 3ba78a5bcb9..e135e80b0be 100644 --- a/forge-gui-mobile/src/forge/screens/home/HomeScreen.java +++ b/forge-gui-mobile/src/forge/screens/home/HomeScreen.java @@ -3,6 +3,7 @@ package forge.screens.home; import java.util.ArrayList; import forge.screens.FScreen; +import forge.screens.LoadingOverlay; import forge.Forge; import forge.Graphics; import forge.assets.FSkinImage; @@ -31,43 +32,46 @@ public class HomeScreen extends FScreen { public void handleEvent(FEvent e) { Forge.openScreen(new ConstructedScreen()); } - }, true); + }); addButton("Booster Draft", new FEventHandler() { @Override public void handleEvent(FEvent e) { Forge.openScreen(new DraftScreen()); } - }, true); + }); addButton("Sealed Deck", new FEventHandler() { @Override public void handleEvent(FEvent e) { Forge.openScreen(new SealedScreen()); } - }, true); + }); addButton("Quest Mode", new FEventHandler() { @Override public void handleEvent(FEvent e) { QuestMenu.launchQuestMode(LaunchReason.StartQuestMode); } - }, true); + }); addButton("Gauntlets", new FEventHandler() { @Override public void handleEvent(FEvent e) { - Forge.openScreen(new GauntletScreen()); + LoadingOverlay.show("Loading gauntlets...", new Runnable() { + @Override + public void run() { + Forge.openScreen(new GauntletScreen()); + } + }); } - }, false); + }); addButton("Settings", new FEventHandler() { @Override public void handleEvent(FEvent e) { SettingsScreen.show(); } - }, true); + }); } - private void addButton(String caption, FEventHandler command, boolean enabled) { - FButton button = add(new FButton(caption, command)); - button.setEnabled(enabled); - buttons.add(button); + private void addButton(String caption, FEventHandler command) { + buttons.add(add(new FButton(caption, command))); } @Override diff --git a/forge-gui-mobile/src/forge/screens/quest/LoadQuestScreen.java b/forge-gui-mobile/src/forge/screens/quest/LoadQuestScreen.java index 62a366221db..9eafe5572be 100644 --- a/forge-gui-mobile/src/forge/screens/quest/LoadQuestScreen.java +++ b/forge-gui-mobile/src/forge/screens/quest/LoadQuestScreen.java @@ -33,7 +33,6 @@ import forge.screens.settings.SettingsScreen; import forge.toolbox.FButton; import forge.toolbox.FEvent; import forge.toolbox.FList; -import forge.toolbox.FOptionPane; import forge.toolbox.FTextArea; import forge.toolbox.FEvent.FEventHandler; import forge.util.ThreadUtil; @@ -187,7 +186,7 @@ public class LoadQuestScreen extends FScreen { if (questName.equals(oldQuestName)) { return; } //quit if chose same name if (questName.isEmpty()) { - FOptionPane.showMessageDialog("Please specify a quest name."); + SOptionPane.showMessageDialog("Please specify a quest name."); continue; } @@ -199,7 +198,7 @@ public class LoadQuestScreen extends FScreen { } } if (exists) { - FOptionPane.showMessageDialog("A quest already exists with that name. Please pick another quest name."); + SOptionPane.showMessageDialog("A quest already exists with that name. Please pick another quest name."); continue; } break; @@ -304,10 +303,10 @@ public class LoadQuestScreen extends FScreen { Collections.sort(sorted, new Comparator() { @Override public int compare(final QuestData x, final QuestData y) { - return x.getName().compareTo(y.getName()); + return x.getName().toLowerCase().compareTo(y.getName().toLowerCase()); } }); - lstQuests.setListData(sorted); + setListData(sorted); } public boolean setSelectedIndex(int i0) { @@ -318,7 +317,7 @@ public class LoadQuestScreen extends FScreen { public QuestData getSelectedQuest() { if (selectedIndex == -1) { return null; } - return lstQuests.getItemAt(selectedIndex); + return getItemAt(selectedIndex); } public boolean setSelectedQuest(QuestData qd0) {