mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-11 16:26:22 +00:00
Merge pull request #8742 from Jetz72/fixes20250918
Refactor "Unique Cards Only" Setting for Mobile Editor
This commit is contained in:
@@ -85,7 +85,7 @@ public class AdventureDeckEditor extends FDeckEditor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemPool<PaperCard> getCardPool(boolean wantUnique) {
|
||||
public ItemPool<PaperCard> getCardPool() {
|
||||
ItemPool<PaperCard> pool = new ItemPool<>(PaperCard.class);
|
||||
pool.addAll(Current.player().getCards());
|
||||
return pool;
|
||||
@@ -163,7 +163,7 @@ public class AdventureDeckEditor extends FDeckEditor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemPool<PaperCard> getCardPool(boolean wantUnique) {
|
||||
public ItemPool<PaperCard> getCardPool() {
|
||||
return deckToPreview.getAllCardsInASinglePool(true, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
||||
return gameType == null ? null : gameType.getDeckFormat();
|
||||
}
|
||||
|
||||
public ItemPool<PaperCard> getCardPool(boolean wantUnique) {
|
||||
return wantUnique ? FModel.getUniqueCardsNoAlt() : FModel.getAllCardsNoAlt();
|
||||
public ItemPool<PaperCard> getCardPool() {
|
||||
return FModel.getAllCardsNoAlt();
|
||||
}
|
||||
protected Predicate<PaperCard> getCardFilter() { return null; }
|
||||
|
||||
@@ -172,10 +172,10 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
||||
@Override public boolean hasCommander() { return deckFormat.hasCommander(); }
|
||||
|
||||
@Override
|
||||
public ItemPool<PaperCard> getCardPool(boolean wantUnique) {
|
||||
public ItemPool<PaperCard> getCardPool() {
|
||||
if(this.itemPoolSupplier != null)
|
||||
return itemPoolSupplier.get();
|
||||
return super.getCardPool(wantUnique);
|
||||
return super.getCardPool();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1713,7 +1713,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
||||
|
||||
//Clone the pool to ensure we don't mutate it by adding to or removing from this page.
|
||||
//Can override this if that behavior is desired.
|
||||
ItemPool<PaperCard> cardPool = CardPool.createFrom(parentScreen.getEditorConfig().getCardPool(cardManager.getWantUnique()), PaperCard.class);
|
||||
ItemPool<PaperCard> cardPool = CardPool.createFrom(parentScreen.getEditorConfig().getCardPool(), PaperCard.class);
|
||||
|
||||
if(editorConfig.usePlayerInventory() && currentDeck != null) {
|
||||
//Remove any items from the pool that are in the deck.
|
||||
@@ -1886,8 +1886,8 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
||||
menu.addItem(new FCheckBoxMenuItem(Forge.getLocalizer().getMessage("lblUniqueCardsOnly"), cardManager.getWantUnique(), e -> {
|
||||
boolean wantUnique = !cardManager.getWantUnique();
|
||||
cardManager.setWantUnique(wantUnique);
|
||||
refresh();
|
||||
cardManager.getConfig().setUniqueCardsOnly(wantUnique);
|
||||
cardManager.refresh();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class FDeckImportDialog extends FDialog {
|
||||
boolean replacingDeck = !currentDeck.isEmpty() || usingInventory;
|
||||
this.currentDeck = currentDeck;
|
||||
this.editorConfig = editorConfig;
|
||||
ItemPool<PaperCard> cardPool = editorConfig.getCardPool(false);
|
||||
ItemPool<PaperCard> cardPool = editorConfig.getCardPool();
|
||||
controller = new DeckImportController(dateTimeCheck, monthDropdown, yearDropdown, replacingDeck);
|
||||
String contents = Forge.getClipboard().getContents();
|
||||
if (contents == null)
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
package forge.itemmanager;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import forge.Graphics;
|
||||
import forge.StaticData;
|
||||
import forge.assets.FSkinColor;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.CardRenderer;
|
||||
import forge.card.CardZoom;
|
||||
import forge.item.PaperCard;
|
||||
@@ -60,6 +68,77 @@ public class CardManager extends ItemManager<PaperCard> {
|
||||
return new AdvancedSearchFilter<>(itemManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<Entry<PaperCard, Integer>> getUnique(Iterable<Entry<PaperCard, Integer>> items) {
|
||||
//TO-maybe-DO: Share logic between this and identical method in desktop.
|
||||
ListMultimap<String, Entry<PaperCard, Integer>> entriesByName = Multimaps.newListMultimap(
|
||||
new TreeMap<>(String.CASE_INSENSITIVE_ORDER), Lists::newArrayList);
|
||||
for (Entry<PaperCard, Integer> item : items) {
|
||||
final String cardName = item.getKey().getName();
|
||||
entriesByName.put(cardName, item);
|
||||
}
|
||||
|
||||
// Now we're ready to go on with retrieving cards to be returned
|
||||
Map<PaperCard, Integer> cardsMap = new HashMap<>();
|
||||
for (String cardName : entriesByName.keySet()) {
|
||||
List<Entry<PaperCard, Integer>> entries = entriesByName.get(cardName);
|
||||
|
||||
ListMultimap<CardEdition, Entry<PaperCard, Integer>> entriesByEdition = Multimaps.newListMultimap(new HashMap<>(), Lists::newArrayList);
|
||||
for (Entry<PaperCard, Integer> entry : entries) {
|
||||
CardEdition ed = StaticData.instance().getCardEdition(entry.getKey().getEdition());
|
||||
if (ed != null)
|
||||
entriesByEdition.put(ed, entry);
|
||||
}
|
||||
if (entriesByEdition.isEmpty())
|
||||
continue; // skip card
|
||||
|
||||
// Try to retain only those editions accepted by the current Card Art Preference Policy
|
||||
Predicate<CardEdition> editionPredicate = ed -> StaticData.instance().getCardArtPreference().accept(ed);
|
||||
List<CardEdition> acceptedEditions = entriesByEdition.keySet().stream().filter(editionPredicate).collect(Collectors.toList());
|
||||
|
||||
// If policy too strict, fall back to getting all editions.
|
||||
if (acceptedEditions.isEmpty())
|
||||
// Policy is too strict for current PaperCard in Entry. Remove any filter
|
||||
acceptedEditions.addAll(entriesByEdition.keySet());
|
||||
|
||||
Entry<PaperCard, Integer> cardEntry = getCardEntryToAdd(entriesByEdition, acceptedEditions);
|
||||
if (cardEntry != null)
|
||||
cardsMap.put(cardEntry.getKey(), cardEntry.getValue());
|
||||
}
|
||||
return cardsMap.entrySet();
|
||||
}
|
||||
|
||||
// Select the Card Art Entry to add, based on current Card Art Preference Order.
|
||||
// This method will prefer the entry currently having an image. If that's not the case,
|
||||
private Entry<PaperCard, Integer> getCardEntryToAdd(ListMultimap<CardEdition, Entry<PaperCard, Integer>> entriesByEdition,
|
||||
List<CardEdition> acceptedEditions) {
|
||||
// Use standard sort + index, for better performance!
|
||||
Collections.sort(acceptedEditions);
|
||||
if (StaticData.instance().cardArtPreferenceIsLatest())
|
||||
Collections.reverse(acceptedEditions);
|
||||
Iterator<CardEdition> editionIterator = acceptedEditions.iterator();
|
||||
Entry<PaperCard, Integer> candidateEntry = null;
|
||||
Entry<PaperCard, Integer> firstCandidateEntryFound = null;
|
||||
while (editionIterator.hasNext() && candidateEntry == null){
|
||||
CardEdition cardEdition = editionIterator.next();
|
||||
// These are now the entries to add to Cards Map
|
||||
List<Entry<PaperCard, Integer>> cardEntries = entriesByEdition.get(cardEdition);
|
||||
Iterator<Entry<PaperCard, Integer>> entriesIterator = cardEntries.iterator();
|
||||
candidateEntry = entriesIterator.hasNext() ? entriesIterator.next() : null;
|
||||
if (candidateEntry != null && firstCandidateEntryFound == null)
|
||||
firstCandidateEntryFound = candidateEntry; // save reference to the first candidate entry found!
|
||||
while ((candidateEntry == null || !candidateEntry.getKey().hasImage()) && entriesIterator.hasNext()) {
|
||||
candidateEntry = entriesIterator.next();
|
||||
if (firstCandidateEntryFound == null)
|
||||
firstCandidateEntryFound = candidateEntry;
|
||||
}
|
||||
|
||||
if (candidateEntry != null && !candidateEntry.getKey().hasImage())
|
||||
candidateEntry = null; // resetting for next edition
|
||||
}
|
||||
return candidateEntry != null ? candidateEntry : firstCandidateEntryFound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemRenderer getListItemRenderer(final CompactModeHandler compactModeHandler) {
|
||||
return new CardListItemRenderer(compactModeHandler);
|
||||
|
||||
@@ -728,6 +728,10 @@ public abstract class ItemManager<T extends InventoryItem> extends FContainer im
|
||||
|
||||
protected abstract AdvancedSearchFilter<? extends T> createAdvancedSearchFilter();
|
||||
|
||||
protected Iterable<Entry<T, Integer>> getUnique(final Iterable<Entry<T, Integer>> items) {
|
||||
return Aggregates.uniqueByLast(items, from -> from.getKey().getName());
|
||||
}
|
||||
|
||||
public void addFilter(final ItemFilter<? extends T> filter) {
|
||||
filters.get().add(filter);
|
||||
add(filter.getWidget());
|
||||
@@ -908,19 +912,29 @@ public abstract class ItemManager<T extends InventoryItem> extends FContainer im
|
||||
}
|
||||
|
||||
public void updateView(final boolean forceFilter, final Iterable<T> itemsToSelect) {
|
||||
//TO-maybe-DO: Share logic between this and identical method in desktop.
|
||||
final boolean useFilter = (forceFilter && (filterPredicate != null)) || !isUnfiltered();
|
||||
|
||||
if (useFilter || forceFilter) {
|
||||
model.clear();
|
||||
|
||||
Iterable<Entry<T, Integer>> items = pool;
|
||||
if (useFilter) {
|
||||
Predicate<Entry<T, Integer>> pred = x -> x != null && filterPredicate.test(x.getKey());
|
||||
items = IterableUtil.filter(pool, pred);
|
||||
}
|
||||
model.addItems(items);
|
||||
if (useFilter || this.wantUnique || forceFilter) {
|
||||
this.model.clear();
|
||||
}
|
||||
|
||||
if (useFilter && this.wantUnique) {
|
||||
final Predicate<Entry<T, Integer>> filterForPool = x -> this.filterPredicate.test(x.getKey());
|
||||
final Iterable<Entry<T, Integer>> items = getUnique(IterableUtil.filter(this.pool, filterForPool));
|
||||
this.model.addItems(items);
|
||||
}
|
||||
else if (useFilter) {
|
||||
final Predicate<Entry<T, Integer>> pred = x -> this.filterPredicate.test(x.getKey());
|
||||
this.model.addItems(IterableUtil.filter(this.pool, pred));
|
||||
}
|
||||
else if (this.wantUnique) {
|
||||
final Iterable<Entry<T, Integer>> items = getUnique(this.pool);
|
||||
this.model.addItems(items);
|
||||
}
|
||||
else if (forceFilter) {
|
||||
this.model.addItems(this.pool);
|
||||
}
|
||||
currentView.refresh(itemsToSelect, getSelectedIndex(), forceFilter ? 0 : currentView.getScrollValue());
|
||||
|
||||
//update ratio of # in filtered pool / # in total pool
|
||||
|
||||
Reference in New Issue
Block a user