diff --git a/forge-gui-mobile/src/forge/itemmanager/ItemManager.java b/forge-gui-mobile/src/forge/itemmanager/ItemManager.java index dc0bfed154f..4ade3447e0d 100644 --- a/forge-gui-mobile/src/forge/itemmanager/ItemManager.java +++ b/forge-gui-mobile/src/forge/itemmanager/ItemManager.java @@ -532,6 +532,16 @@ public abstract class ItemManager extends FContainer im updateView(false, items); } + public void addItemsFlat(Iterable itemsToAdd) { + pool.addAllFlat(itemsToAdd); + if (isUnfiltered()) { + for (T item : itemsToAdd) { + model.addItem(item, 1); + } + } + updateView(false, itemsToAdd); + } + public void setItems(Iterable> items) { pool.clear(); model.clear(); @@ -560,6 +570,18 @@ public abstract class ItemManager extends FContainer im updateView(false, itemsToSelect); } + public void removeItemsFlat(Iterable itemsToRemove) { + final Iterable itemsToSelect = currentView == listView ? getSelectedItems() : null; + + pool.removeAllFlat(itemsToRemove); + if (isUnfiltered()) { + for (T item : itemsToRemove) { + model.removeItem(item, 1); + } + } + updateView(false, itemsToSelect); + } + public void removeAllItems() { pool.clear(); model.clear(); diff --git a/forge-gui-mobile/src/forge/itemmanager/views/ItemView.java b/forge-gui-mobile/src/forge/itemmanager/views/ItemView.java index b832a38947e..5d9a3241604 100644 --- a/forge-gui-mobile/src/forge/itemmanager/views/ItemView.java +++ b/forge-gui-mobile/src/forge/itemmanager/views/ItemView.java @@ -120,17 +120,21 @@ public abstract class ItemView { protected abstract void onRefresh(); protected void fixSelection(final Iterable itemsToSelect, final int backupIndexToSelect, final float scrollValueToRestore) { if (itemsToSelect == null) { - if (maxSelections <= 1 || minSelections > 0) { - setSelectedIndex(0, false); //select first item if no items to select - } - else { //if in multi-select mode, clear selection instead + if (itemManager.getMultiSelectMode()) { //if in multi-select mode, clear selection setSelectedIndex(-1, false); } + else { //otherwise select first item if no items to select + setSelectedIndex(0, false); + } setScrollValue(0); //ensure scrolled to top } else { if (!setSelectedItems(itemsToSelect)) { setSelectedIndex(backupIndexToSelect); + + if (itemManager.getMultiSelectMode()) { //in multi-select mode, clear selection after scrolling into view + setSelectedIndex(-1, false); + } } } } @@ -245,8 +249,7 @@ public abstract class ItemView { } protected void onSelectionChange() { - final int index = getSelectedIndex(); - if (index != -1) { + if (getSelectedIndex() != -1 || itemManager.getMultiSelectMode()) { if (itemManager.getSelectionChangedHandler() != null) { itemManager.getSelectionChangedHandler().handleEvent(new FEvent(itemManager, FEventType.CHANGE)); } diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCollectionScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCollectionScreen.java index 9c17883b6fc..c9779a8f893 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCollectionScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestCollectionScreen.java @@ -1,8 +1,10 @@ package forge.screens.planarconquest; +import java.util.Collection; import java.util.Map.Entry; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; import forge.FThreads; import forge.assets.FImage; @@ -34,12 +36,62 @@ import forge.toolbox.FEvent.FEventHandler; public class ConquestCollectionScreen extends TabPageScreen { private final FLabel lblShards = add(new FLabel.Builder().font(ConquestAEtherScreen.LABEL_FONT).parseSymbols().build()); private final FLabel lblInfo = add(new FLabel.Builder().font(FSkinFont.get(11)).build()); + private final FLabel btnExileMultiple = add(new FLabel.ButtonBuilder().font(ConquestAEtherScreen.LABEL_FONT).parseSymbols().build()); public ConquestCollectionScreen() { super("", ConquestMenu.getMenu(), new CollectionTab[] { new CollectionTab("Collection", FSkinImage.SPELLBOOK), new CollectionTab("Exile", FSkinImage.EXILE) }); + btnExileMultiple.setVisible(false); //hide unless in multi-select mode + btnExileMultiple.setCommand(new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + final ConquestData model = FModel.getConquest().getModel(); + + FThreads.invokeInBackgroundThread(new Runnable() { + @Override + public void run() { + if (getSelectedPage() == tabPages[0]) { + int value = 0; + final Collection cards = getCollectionTab().list.getSelectedItems(); + for (PaperCard card : cards) { + value += ConquestUtil.getShardValue(card, CQPref.AETHER_BASE_EXILE_VALUE); + } + if (model.exileCards(cards, value)) { + FThreads.invokeInEdtLater(new Runnable() { + @Override + public void run() { + updateShards(); + getCollectionTab().list.removeItemsFlat(cards); + getExileTab().list.addItemsFlat(cards); + updateTabCaptions(); + } + }); + } + } + else { + int cost = 0; + final Collection cards = getExileTab().list.getSelectedItems(); + for (PaperCard card : cards) { + cost += ConquestUtil.getShardValue(card, CQPref.AETHER_BASE_RETRIEVE_COST); + } + if (model.retrieveCardsFromExile(cards, cost)) { + FThreads.invokeInEdtLater(new Runnable() { + @Override + public void run() { + updateShards(); + getCollectionTab().list.addItemsFlat(cards); + getExileTab().list.removeItemsFlat(cards); + updateTabCaptions(); + } + }); + } + } + } + }); + } + }); } @Override @@ -83,6 +135,38 @@ public class ConquestCollectionScreen extends TabPageScreen cards; + if (getSelectedPage() == tabPages[0]) { + action = "Exile"; + baseValuePref = CQPref.AETHER_BASE_EXILE_VALUE; + cards = getCollectionTab().list.getSelectedItems(); + } + else { + action = "Retrieve"; + baseValuePref = CQPref.AETHER_BASE_RETRIEVE_COST; + cards = getExileTab().list.getSelectedItems(); + } + + int count = cards.size(); + String caption = action; + if (count > 0) { + if (count > 1) { + caption += " " + count + " cards"; + } + int total = 0; + for (PaperCard card : cards) { + total += ConquestUtil.getShardValue(card, baseValuePref); + } + caption += " for {AE}" + total; + } + + btnExileMultiple.setText(caption); + btnExileMultiple.setEnabled(count > 0); + } + private CollectionTab getCollectionTab() { return (CollectionTab)tabPages[0]; } @@ -104,6 +188,9 @@ public class ConquestCollectionScreen extends TabPageScreen { @@ -125,7 +212,15 @@ public class ConquestCollectionScreen extends TabPageScreen value, float x, float y) { toggleMultiSelectMode(index); + + //hide tabs and show Exile/Retrieve button while in multi-select mode boolean multiSelectMode = getMultiSelectMode(); - + if (multiSelectMode) { + parentScreen.updateExileButtonCaption(); + } + parentScreen.btnExileMultiple.setVisible(multiSelectMode); + parentScreen.tabHeader.setVisible(!multiSelectMode); } } diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestData.java b/forge-gui/src/main/java/forge/planarconquest/ConquestData.java index 803e653d9e7..14e92eac8a3 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestData.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestData.java @@ -35,6 +35,7 @@ import forge.util.gui.SOptionPane; import java.io.File; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -256,34 +257,51 @@ public final class ConquestData { return exiledCards; } - public boolean exileCard(PaperCard card, int value) { - final String title = "Exile Card"; - if (planeswalker == card) { - SOptionPane.showMessageDialog("Current planeswalker cannot be exiled.", title, SOptionPane.INFORMATION_ICON); - return false; - } - String commandersUsingCard = ""; - ConquestCommander commanderBeingExiled = null; - for (ConquestCommander commander : commanders) { - if (commander.getCard() == card) { - if (!commander.getDeck().getMain().isEmpty()) { - SOptionPane.showMessageDialog("Cannot exile a commander with a defined deck.", title, SOptionPane.INFORMATION_ICON); - return false; + public boolean exileCards(Collection cards, int value) { + int count = cards.size(); + if (count == 0) { return false; } + + String title = count == 1 ? "Exile Card" : "Exile " + count + " Cards"; + String cardStr = (count == 1 ? "card" : "cards"); + + List commandersBeingExiled = null; + + String message = "Exile the following " + cardStr + " to receive {AE}" + value + "?\n"; + for (PaperCard card : cards) { + if (planeswalker == card) { + SOptionPane.showMessageDialog("Current planeswalker cannot be exiled.", title, SOptionPane.INFORMATION_ICON); + return false; + } + + String commandersUsingCard = ""; + for (ConquestCommander commander : commanders) { + if (commander.getCard() == card) { + if (!commander.getDeck().getMain().isEmpty()) { + SOptionPane.showMessageDialog("Cannot exile a commander with a defined deck.", title, SOptionPane.INFORMATION_ICON); + return false; + } + if (commandersBeingExiled == null) { + commandersBeingExiled = new ArrayList(); + } + commandersBeingExiled.add(commander); //cache commander to make it easier to remove later + } + if (commander.getDeck().getMain().contains(card)) { + commandersUsingCard += "\n" + commander.getName(); } - commanderBeingExiled = commander; //cache commander to make it easier to remove later } - if (commander.getDeck().getMain().contains(card)) { - commandersUsingCard += "\n" + commander.getName(); + + if (!commandersUsingCard.isEmpty()) { + SOptionPane.showMessageDialog(card.getName() + " is in use by the following commanders and cannot be exiled:\n" + commandersUsingCard, title, SOptionPane.INFORMATION_ICON); + return false; } + + message += "\n" + card.getName(); } - if (!commandersUsingCard.isEmpty()) { - SOptionPane.showMessageDialog("Card is in use by the following commanders and cannot be exiled:\n" + commandersUsingCard, title, SOptionPane.INFORMATION_ICON); - return false; - } - if (SOptionPane.showConfirmDialog("Exile the following card to receive {AE}" + value + "?\n\n" + card.getName(), title, "OK", "Cancel")) { - if (exiledCards.add(card)) { - if (commanderBeingExiled != null) { - commanders.remove(commanderBeingExiled); + + if (SOptionPane.showConfirmDialog(message, title, "OK", "Cancel")) { + if (exiledCards.addAll(cards)) { + if (commandersBeingExiled != null) { + commanders.removeAll(commandersBeingExiled); } rewardAEtherShards(value); saveData(); @@ -293,16 +311,27 @@ public final class ConquestData { return false; } - public boolean retrieveCardFromExile(PaperCard card, int cost) { - final String title = "Retrieve Card"; + public boolean retrieveCardsFromExile(Collection cards, int cost) { + int count = cards.size(); + if (count == 0) { return false; } + + String title = count == 1 ? "Retrieve Card" : "Retrieve " + count + " Cards"; + String cardStr = (count == 1 ? "card" : "cards"); if (aetherShards < cost) { - SOptionPane.showMessageDialog("Not enough shards to retrieve card.", title, SOptionPane.INFORMATION_ICON); + SOptionPane.showMessageDialog("Not enough shards to retrieve " + cardStr + ".", title, SOptionPane.INFORMATION_ICON); return false; } - if (SOptionPane.showConfirmDialog("Spend {AE}" + cost + " to retrieve the following card from exile?\n\n" + card.getName(), title, "OK", "Cancel")) { - if (exiledCards.remove(card)) { - if (card.getRules().canBeCommander()) { //add back commander for card if needed - commanders.add(new ConquestCommander(card)); + + String message = "Spend {AE}" + cost + " to retrieve the following " + cardStr + " from exile?\n"; + for (PaperCard card : cards) { + message += "\n" + card.getName(); + } + if (SOptionPane.showConfirmDialog(message, title, "OK", "Cancel")) { + if (exiledCards.removeAll(cards)) { + for (PaperCard card : cards) { + if (card.getRules().canBeCommander()) { //add back commander for card if needed + commanders.add(new ConquestCommander(card)); + } } spendAEtherShards(cost); saveData();