Support showing unowned cards in collection

This commit is contained in:
drdev
2015-12-07 03:02:39 +00:00
parent 85320926e7
commit c93418a526
7 changed files with 132 additions and 146 deletions

View File

@@ -90,18 +90,22 @@ public class ItemPool<T extends InventoryItem> implements Iterable<Entry<T, Inte
return result; return result;
} }
protected ItemPool(final Map<T, Integer> inMap, final Class<T> cls) { protected ItemPool(final Map<T, Integer> items0, final Class<T> cls) {
items = inMap; if (items0 != null) {
items = items0;
}
else {
items = new HashMap<T, Integer>(); //prevent items being null
}
myClass = cls; myClass = cls;
} }
// Data members // Data members
/** The items. */
protected final Map<T, Integer> items; protected final Map<T, Integer> items;
/** The my class. */ private final Class<T> myClass; //class does not keep this in runtime by itself
private final Class<T> myClass; // class does not keep this in runtime by
// itself private boolean allowZero; //whether to allow items with 0 count to remain in pool
@Override @Override
public final Iterator<Entry<T, Integer>> iterator() { public final Iterator<Entry<T, Integer>> iterator() {
@@ -109,14 +113,11 @@ public class ItemPool<T extends InventoryItem> implements Iterable<Entry<T, Inte
} }
public final boolean contains(final T item) { public final boolean contains(final T item) {
if (items == null) {
return false;
}
return items.containsKey(item); return items.containsKey(item);
} }
public final int count(final T item) { public final int count(final T item) {
if (items == null || item == null) { if (item == null) {
return 0; return 0;
} }
final Integer boxed = items.get(item); final Integer boxed = items.get(item);
@@ -133,15 +134,13 @@ public class ItemPool<T extends InventoryItem> implements Iterable<Entry<T, Inte
public final <U extends InventoryItem> int countAll(Predicate<U> condition, Class<U> cls) { public final <U extends InventoryItem> int countAll(Predicate<U> condition, Class<U> cls) {
int result = 0; int result = 0;
if (items != null) { final boolean isSameClass = cls == myClass;
final boolean isSameClass = cls == myClass; for (final Entry<T, Integer> kv : this) {
for (final Entry<T, Integer> kv : this) { final T key = kv.getKey();
final T key = kv.getKey(); @SuppressWarnings("unchecked")
@SuppressWarnings("unchecked") final U castKey = isSameClass || cls.isInstance(key) ? (U)key : null;
final U castKey = isSameClass || cls.isInstance(key) ? (U)key : null; if (null == condition || castKey != null && condition.apply(castKey))
if (null == condition || castKey != null && condition.apply(castKey)) result += kv.getValue();
result += kv.getValue();
}
} }
return result; return result;
} }
@@ -151,7 +150,7 @@ public class ItemPool<T extends InventoryItem> implements Iterable<Entry<T, Inte
} }
public final boolean isEmpty() { public final boolean isEmpty() {
return (items == null) || items.isEmpty(); return items.isEmpty();
} }
public final List<T> toFlatList() { public final List<T> toFlatList() {
@@ -176,6 +175,13 @@ public class ItemPool<T extends InventoryItem> implements Iterable<Entry<T, Inte
return myClass; return myClass;
} }
public boolean allowZero() {
return allowZero;
}
public void setAllowZero(boolean allowZero0) {
allowZero = allowZero0;
}
public ItemPool<T> getView() { public ItemPool<T> getView() {
return new ItemPool<T>(Collections.unmodifiableMap(items), getMyClass()); return new ItemPool<T>(Collections.unmodifiableMap(items), getMyClass());
} }
@@ -185,14 +191,21 @@ public class ItemPool<T extends InventoryItem> implements Iterable<Entry<T, Inte
} }
public void add(final T item, final int amount) { public void add(final T item, final int amount) {
if (item == null || amount <= 0) { if (item == null) { return; }
return;
if (amount <= 0) {
if (allowZero) {
if (!items.containsKey(item)) {
items.put(item, 0);
}
}
else { return; }
} }
items.put(item, Integer.valueOf(count(item) + amount)); items.put(item, count(item) + amount);
} }
public void addAllFlat(final Iterable<T> items) { public void addAllFlat(final Iterable<T> itms) {
for (T item : items) { for (T item : itms) {
add(item); add(item);
} }
} }
@@ -204,8 +217,8 @@ public class ItemPool<T extends InventoryItem> implements Iterable<Entry<T, Inte
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <U extends InventoryItem> void addAllOfTypeFlat(final Iterable<U> items) { public <U extends InventoryItem> void addAllOfTypeFlat(final Iterable<U> itms) {
for (U item : items) { for (U item : itms) {
if (myClass.isInstance(item)) { if (myClass.isInstance(item)) {
add((T) item); add((T) item);
} }
@@ -214,10 +227,9 @@ public class ItemPool<T extends InventoryItem> implements Iterable<Entry<T, Inte
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <U extends InventoryItem> void addAllOfType(final Iterable<Entry<U, Integer>> map) { public <U extends InventoryItem> void addAllOfType(final Iterable<Entry<U, Integer>> map) {
Class<T> myClass = this.getMyClass(); for (Entry<U, Integer> e : map) {
for (final Entry<U, Integer> e : map) {
if (myClass.isInstance(e.getKey())) { if (myClass.isInstance(e.getKey())) {
this.add((T) e.getKey(), e.getValue()); add((T) e.getKey(), e.getValue());
} }
} }
} }
@@ -228,12 +240,18 @@ public class ItemPool<T extends InventoryItem> implements Iterable<Entry<T, Inte
public boolean remove(final T item, final int amount) { public boolean remove(final T item, final int amount) {
final int count = count(item); final int count = count(item);
if ((count == 0) || (amount <= 0)) { if (count == 0 || amount <= 0) {
return false; return false;
} }
if (count <= amount) { if (count <= amount) {
items.remove(item); if (allowZero) {
} else { items.put(item, 0);
}
else {
items.remove(item);
}
}
else {
items.put(item, count - amount); items.put(item, count - amount);
} }
return true; return true;

View File

@@ -406,8 +406,9 @@ public abstract class ItemManager<T extends InventoryItem> extends FContainer im
setPool(pool0, false); setPool(pool0, false);
} }
public void setPool(final ItemPool<T> pool0, boolean infinite) { public void setPool(final ItemPool<T> pool0, boolean infinite) {
model.clear();
pool = pool0; pool = pool0;
model.clear();
model.setAllowZero(pool.allowZero());
model.addItems(pool); model.addItems(pool);
model.setInfinite(infinite); model.setInfinite(infinite);
updateView(true, null); updateView(true, null);

View File

@@ -366,8 +366,13 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
group = otherItems; group = otherItems;
} }
for (int i = 0; i < qty; i++) { if (qty > 0) {
group.add(new ItemInfo(item, group)); for (int i = 0; i < qty; i++) {
group.add(new ItemInfo(item, group, false));
}
}
else { //add single item for unowned item
group.add(new ItemInfo(item, group, true));
} }
} }
@@ -907,13 +912,15 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
private class ItemInfo extends FDisplayObject implements Entry<InventoryItem, Integer> { private class ItemInfo extends FDisplayObject implements Entry<InventoryItem, Integer> {
private final T item; private final T item;
private final Group group; private final Group group;
private final boolean unowned;
private int index; private int index;
private CardStackPosition pos; private CardStackPosition pos;
private boolean selected; private boolean selected;
private ItemInfo(T item0, Group group0) { private ItemInfo(T item0, Group group0, boolean unowned0) {
item = item0; item = item0;
group = group0; group = group0;
unowned = unowned0;
} }
@Override @Override
@@ -938,6 +945,10 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
@Override @Override
public void draw(Graphics g) { public void draw(Graphics g) {
if (unowned) {
g.setAlphaComposite(UNOWNED_ALPHA_COMPOSITE);
}
final float x = getLeft() - group.getScrollLeft(); final float x = getLeft() - group.getScrollLeft();
final float y = getTop() - group.getTop() - getScrollValue(); final float y = getTop() - group.getTop() - getScrollValue();
final float w = getWidth(); final float w = getWidth();
@@ -961,6 +972,10 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
g.drawText(item.getName(), GROUP_HEADER_FONT, Color.WHITE, x + PADDING, y + PADDING, w - 2 * PADDING, h - 2 * PADDING, true, HAlignment.CENTER, false); g.drawText(item.getName(), GROUP_HEADER_FONT, Color.WHITE, x + PADDING, y + PADDING, w - 2 * PADDING, h - 2 * PADDING, true, HAlignment.CENTER, false);
} }
} }
if (unowned) {
g.resetAlphaComposite();
}
} }
} }
} }

View File

@@ -239,6 +239,10 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
@Override @Override
public void drawValue(Graphics g, Integer index, Entry<T, Integer> value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) { public void drawValue(Graphics g, Integer index, Entry<T, Integer> value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) {
boolean unowned = (value.getValue() == 0); //fade out item if item isn't owned
if (unowned) {
g.setAlphaComposite(UNOWNED_ALPHA_COMPOSITE);
}
if (maxSelections > 1) { if (maxSelections > 1) {
if (pressed) { //if multi-select mode, draw SEL_COLOR when pressed if (pressed) { //if multi-select mode, draw SEL_COLOR when pressed
g.fillRect(SEL_COLOR, x - FList.PADDING, y - FList.PADDING, w + 2 * FList.PADDING, h + 2 * FList.PADDING); g.fillRect(SEL_COLOR, x - FList.PADDING, y - FList.PADDING, w + 2 * FList.PADDING, h + 2 * FList.PADDING);
@@ -251,6 +255,9 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
w -= padding; w -= padding;
} }
renderer.drawValue(g, value, font, foreColor, backColor, pressed, x + 1, y, w - 2, h); //x + 1 and w - 2 to account for left and right borders renderer.drawValue(g, value, font, foreColor, backColor, pressed, x + 1, y, w - 2, h); //x + 1 and w - 2 to account for left and right borders
if (unowned) {
g.resetAlphaComposite();
}
} }
}); });
setFont(FSkinFont.get(14)); setFont(FSkinFont.get(14));
@@ -293,11 +300,6 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
public final class ItemListModel { public final class ItemListModel {
private final ItemManagerModel<T> model; private final ItemManagerModel<T> model;
/**
* Instantiates a new list model.
*
* @param model0 &emsp; {@link forge.gui.ItemManager.ItemManagerModel<T>}
*/
public ItemListModel(final ItemManagerModel<T> model0) { public ItemListModel(final ItemManagerModel<T> model0) {
model = model0; model = model0;
} }

View File

@@ -23,6 +23,7 @@ import java.util.Map;
import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Rectangle;
public abstract class ItemView<T extends InventoryItem> { public abstract class ItemView<T extends InventoryItem> {
protected static final float UNOWNED_ALPHA_COMPOSITE = 0.35f;
private static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_TEXT); private static final FSkinColor BORDER_COLOR = FSkinColor.get(Colors.CLR_TEXT);
protected final ItemManager<T> itemManager; protected final ItemManager<T> itemManager;

View File

@@ -29,16 +29,7 @@ import forge.itemmanager.ItemColumnConfig.SortState;
import forge.util.ItemPool; import forge.util.ItemPool;
import forge.util.ItemPoolSorter; import forge.util.ItemPoolSorter;
/**
* <p>
* ItemManagerModel class.
* </p>
*
* @param <T>
* the generic type
* @author Forge
* @version $Id: ItemManagerModel.java 19857 2013-02-24 08:49:52Z Max mtg $
*/
public final class ItemManagerModel<T extends InventoryItem> { public final class ItemManagerModel<T extends InventoryItem> {
private static final int maxSortDepth = 3; private static final int maxSortDepth = 3;
@@ -46,102 +37,71 @@ public final class ItemManagerModel<T extends InventoryItem> {
private boolean infiniteSupply; private boolean infiniteSupply;
private final CascadeManager cascadeManager = new CascadeManager(); private final CascadeManager cascadeManager = new CascadeManager();
/**
* Instantiates a new list view model
*
* @param ItemManager0
* @param genericType0
*/
public ItemManagerModel(final Class<T> genericType0) { public ItemManagerModel(final Class<T> genericType0) {
this.data = new ItemPool<T>(genericType0); data = new ItemPool<T>(genericType0);
} }
/**
* Clears all data in the model.
*/
public void clear() { public void clear() {
this.data.clear(); data.clear();
} }
// same thing as above, it was copied to provide sorting (needed by table // same thing as above, it was copied to provide sorting (needed by table
// views in deck editors) // views in deck editors)
/** The items ordered. */
private final transient List<Entry<T, Integer>> itemsOrdered = new ArrayList<Map.Entry<T, Integer>>(); private final transient List<Entry<T, Integer>> itemsOrdered = new ArrayList<Map.Entry<T, Integer>>();
/** Whether list is in sync. */
protected transient boolean isListInSync = false; protected transient boolean isListInSync = false;
public List<Entry<T, Integer>> getOrderedList() { public List<Entry<T, Integer>> getOrderedList() {
if (!this.isListInSync) { if (!isListInSync) {
this.rebuildOrderedList(); rebuildOrderedList();
} }
return this.itemsOrdered; return itemsOrdered;
} }
private void rebuildOrderedList() { private void rebuildOrderedList() {
this.itemsOrdered.clear(); itemsOrdered.clear();
if (this.data != null) { if (data != null) {
for (final Entry<T, Integer> e : this.data) { for (final Entry<T, Integer> e : data) {
this.itemsOrdered.add(e); itemsOrdered.add(e);
} }
} }
this.isListInSync = true; isListInSync = true;
} }
public int countDistinct() { public int countDistinct() {
return this.data.countDistinct(); return data.countDistinct();
} }
/**
* Gets all items in the model.
*
* @return ItemPoolView<T>
*/
public ItemPool<T> getItems() { public ItemPool<T> getItems() {
return this.data.getView(); return data.getView();
} }
/**
* Removes a item from the model.
*
* @param item0 &emsp; {@link forge.Item} object
*/
public void removeItem(final T item0, final int qty) { public void removeItem(final T item0, final int qty) {
if (isInfinite()) { return; } if (isInfinite()) { return; }
final boolean wasThere = this.data.count(item0) > 0; final boolean wasThere = data.count(item0) > 0;
if (wasThere) { if (wasThere) {
this.data.remove(item0, qty); data.remove(item0, qty);
isListInSync = false; isListInSync = false;
} }
} }
public void replaceAll(final T item0, final T replacement0) { public void replaceAll(final T item0, final T replacement0) {
final int count = this.data.count(item0); final int count = data.count(item0);
if (count > 0) { if (count > 0) {
this.data.removeAll(item0); data.removeAll(item0);
this.data.add(replacement0, count); data.add(replacement0, count);
isListInSync = false; isListInSync = false;
} }
} }
/**
* Adds a item to the model.
*
* @param item0 &emsp; {@link forge.Item} object.
*/
public void addItem(final T item0, final int qty) { public void addItem(final T item0, final int qty) {
this.data.add(item0, qty); data.add(item0, qty);
isListInSync = false; isListInSync = false;
} }
/**
* Adds multiple copies of multiple items to the model.
*
* @param items0 &emsp; {@link java.lang.Iterable}<Entry<T, Integer>>
*/
public void addItems(final Iterable<Entry<T, Integer>> items0) { public void addItems(final Iterable<Entry<T, Integer>> items0) {
this.data.addAll(items0); data.addAll(items0);
isListInSync = false; isListInSync = false;
} }
@@ -150,29 +110,31 @@ public final class ItemManagerModel<T extends InventoryItem> {
* items in the table have a limited number of copies. * items in the table have a limited number of copies.
*/ */
public void setInfinite(final boolean infinite) { public void setInfinite(final boolean infinite) {
this.infiniteSupply = infinite; infiniteSupply = infinite;
} }
public boolean isInfinite() { public boolean isInfinite() {
return infiniteSupply; return infiniteSupply;
} }
public boolean allowZero() {
return data.allowZero();
}
public void setAllowZero(boolean allowZero0) {
data.setAllowZero(allowZero0);
}
public CascadeManager getCascadeManager() { public CascadeManager getCascadeManager() {
return cascadeManager; return cascadeManager;
} }
/**
* Resort.
*/
public void refreshSort() { public void refreshSort() {
if (this.getOrderedList().isEmpty()) { return; } if (getOrderedList().isEmpty()) { return; }
Collections.sort(this.getOrderedList(), new MyComparator()); Collections.sort(getOrderedList(), new MyComparator());
} }
/** //Manages sorting orders for multiple depths of sorting
* Manages sorting orders for multiple depths of sorting.
*/
public final class CascadeManager { public final class CascadeManager {
private final List<ItemColumn> colsToSort = new ArrayList<ItemColumn>(3); private final List<ItemColumn> colsToSort = new ArrayList<ItemColumn>(3);
private Sorter sorter = null; private Sorter sorter = null;
@@ -181,20 +143,21 @@ public final class ItemManagerModel<T extends InventoryItem> {
// If column is first in the cascade, inverts direction of sort. // If column is first in the cascade, inverts direction of sort.
// Otherwise, sorts in ascending direction. // Otherwise, sorts in ascending direction.
public void add(final ItemColumn col0, final boolean forSetup) { public void add(final ItemColumn col0, final boolean forSetup) {
this.sorter = null; sorter = null;
if (forSetup) { //just add column unmodified if setting up sort columns if (forSetup) { //just add column unmodified if setting up sort columns
this.colsToSort.add(0, col0); colsToSort.add(0, col0);
} else { }
else {
if (colsToSort.size() > 0 && colsToSort.get(0).equals(col0)) { //if column already at top level, just invert if (colsToSort.size() > 0 && colsToSort.get(0).equals(col0)) { //if column already at top level, just invert
col0.getConfig().setSortPriority(1); col0.getConfig().setSortPriority(1);
col0.getConfig().setSortState(col0.getConfig().getSortState() == SortState.ASC ? SortState.DESC : SortState.ASC); col0.getConfig().setSortState(col0.getConfig().getSortState() == SortState.ASC ? SortState.DESC : SortState.ASC);
} }
else { //otherwise move column to top level and move others down else { //otherwise move column to top level and move others down
this.colsToSort.remove(col0); colsToSort.remove(col0);
col0.getConfig().setSortPriority(1); col0.getConfig().setSortPriority(1);
col0.getConfig().setSortState(col0.getConfig().getDefaultSortState()); col0.getConfig().setSortState(col0.getConfig().getDefaultSortState());
this.colsToSort.add(0, col0); colsToSort.add(0, col0);
} }
//decrement sort priority on remaining columns //decrement sort priority on remaining columns
@@ -208,28 +171,28 @@ public final class ItemManagerModel<T extends InventoryItem> {
} }
//unset and remove boundary columns. //unset and remove boundary columns.
if (this.colsToSort.size() > maxSortDepth) { if (colsToSort.size() > maxSortDepth) {
this.colsToSort.get(maxSortDepth).getConfig().setSortPriority(0); colsToSort.get(maxSortDepth).getConfig().setSortPriority(0);
this.colsToSort.remove(maxSortDepth); colsToSort.remove(maxSortDepth);
} }
} }
public Sorter getSorter() { public Sorter getSorter() {
if (this.sorter == null) { if (sorter == null) {
this.sorter = createSorter(); sorter = createSorter();
} }
return this.sorter; return sorter;
} }
public void reset() { public void reset() {
this.colsToSort.clear(); colsToSort.clear();
this.sorter = null; sorter = null;
} }
private Sorter createSorter() { private Sorter createSorter() {
final List<ItemPoolSorter<InventoryItem>> oneColSorters = new ArrayList<ItemPoolSorter<InventoryItem>>(maxSortDepth); final List<ItemPoolSorter<InventoryItem>> oneColSorters = new ArrayList<ItemPoolSorter<InventoryItem>>(maxSortDepth);
for (final ItemColumn col : this.colsToSort) { for (final ItemColumn col : colsToSort) {
oneColSorters.add(new ItemPoolSorter<InventoryItem>( oneColSorters.add(new ItemPoolSorter<InventoryItem>(
col.getFnSort(), col.getFnSort(),
col.getConfig().getSortState().equals(SortState.ASC) ? true : false)); col.getConfig().getSortState().equals(SortState.ASC) ? true : false));
@@ -242,30 +205,18 @@ public final class ItemManagerModel<T extends InventoryItem> {
private final List<ItemPoolSorter<InventoryItem>> sorters; private final List<ItemPoolSorter<InventoryItem>> sorters;
private final int cntFields; private final int cntFields;
/**
*
* Sorter Constructor.
*
* @param sorters0
* a List<TableSorter<InventoryItem>>
*/
public Sorter(final List<ItemPoolSorter<InventoryItem>> sorters0) { public Sorter(final List<ItemPoolSorter<InventoryItem>> sorters0) {
this.sorters = sorters0; sorters = sorters0;
this.cntFields = sorters0.size(); cntFields = sorters0.size();
} }
/*
* (non-Javadoc)
*
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override @Override
public final int compare(final Entry<InventoryItem, Integer> arg0, final Entry<InventoryItem, Integer> arg1) { public final int compare(final Entry<InventoryItem, Integer> arg0, final Entry<InventoryItem, Integer> arg1) {
int lastCompare = 0; int lastCompare = 0;
int iField = -1; int iField = -1;
while ((++iField < this.cntFields) && (lastCompare == 0)) { // reverse while ((++iField < cntFields) && (lastCompare == 0)) { // reverse
// iteration // iteration
final ItemPoolSorter<InventoryItem> sorter = this.sorters.get(iField); final ItemPoolSorter<InventoryItem> sorter = sorters.get(iField);
if (sorter == null) { if (sorter == null) {
break; break;
} }
@@ -277,13 +228,10 @@ public final class ItemManagerModel<T extends InventoryItem> {
} }
private final class MyComparator implements Comparator<Entry<T, Integer>> { private final class MyComparator implements Comparator<Entry<T, Integer>> {
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public int compare(final Entry<T, Integer> o1, final Entry<T, Integer> o2) { public int compare(final Entry<T, Integer> o1, final Entry<T, Integer> o2) {
return cascadeManager.getSorter().compare((Entry<InventoryItem, Integer>)o1, (Entry<InventoryItem, Integer>)o2); return cascadeManager.getSorter().compare((Entry<InventoryItem, Integer>)o1, (Entry<InventoryItem, Integer>)o2);
} }
} }
} // ItemManagerModel }

View File

@@ -130,7 +130,7 @@ public final class ConquestData {
if (collection == null) { if (collection == null) {
collection = new ConquestCollection(); collection = new ConquestCollection();
} }
manager.setPool(collection); manager.setPool(collection, true);
} }
public Iterable<PaperCard> getUnlockedCards() { public Iterable<PaperCard> getUnlockedCards() {
@@ -433,6 +433,7 @@ public final class ConquestData {
private class ConquestCollection extends ItemPool<PaperCard> { private class ConquestCollection extends ItemPool<PaperCard> {
private ConquestCollection() { private ConquestCollection() {
super(PaperCard.class); super(PaperCard.class);
setAllowZero(true);
//initialize to contain all available cards, with unlocked //initialize to contain all available cards, with unlocked
//having a count of 1 and the rest having a count of 0 //having a count of 1 and the rest having a count of 0