diff --git a/.gitattributes b/.gitattributes index 181e30486ca..eabce020be3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -15688,6 +15688,7 @@ forge-gui/src/main/java/forge/gui/toolbox/itemmanager/package-info.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ColorSetRenderer.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ColumnDef.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/DeckQuantityRenderer.java -text +forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/GroupDef.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ImageView.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/IntegerRenderer.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ItemCellRenderer.java -text diff --git a/forge-gui/src/main/java/forge/gui/deckeditor/DeckProxy.java b/forge-gui/src/main/java/forge/gui/deckeditor/DeckProxy.java index 3145c671b4f..458cb13b4a2 100644 --- a/forge-gui/src/main/java/forge/gui/deckeditor/DeckProxy.java +++ b/forge-gui/src/main/java/forge/gui/deckeditor/DeckProxy.java @@ -13,6 +13,7 @@ import forge.Singletons; import forge.StaticData; import forge.card.CardEdition; import forge.card.ColorSet; +import forge.card.MagicColor; import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckGroup; @@ -44,6 +45,7 @@ public class DeckProxy implements InventoryItem { // cached values protected ColorSet color; + protected ColorSet colorIdentity; protected Iterable formats; private int mainSize = Integer.MIN_VALUE; private int sbSize = Integer.MIN_VALUE; @@ -103,6 +105,7 @@ public class DeckProxy implements InventoryItem { public void invalidateCache() { color = null; + colorIdentity = null; formats = null; edition = null; mainSize = Integer.MIN_VALUE; @@ -116,6 +119,28 @@ public class DeckProxy implements InventoryItem { return color; } + public ColorSet getColorIdentity() { + if (colorIdentity == null) { + byte colorProfile = MagicColor.COLORLESS; + + for (Entry deckEntry : getDeck()) { + switch (deckEntry.getKey()) { + case Main: + case Sideboard: + case Commander: + for (Entry poolEntry : deckEntry.getValue()) { + colorProfile |= poolEntry.getKey().getRules().getColorIdentity().getColor(); + } + break; + default: + break; //ignore other sections + } + } + colorIdentity = ColorSet.fromMask(colorProfile); + } + return colorIdentity; + } + public Iterable getFormats() { if (formats == null) { formats = Singletons.getModel().getFormats().getAllFormatsOfDeck(getDeck()); diff --git a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ColumnDef.java b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ColumnDef.java index 4b4e98f7149..8c066d5f7ca 100644 --- a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ColumnDef.java +++ b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ColumnDef.java @@ -42,13 +42,6 @@ import forge.item.InventoryItemFromSet; import forge.item.PaperCard; import forge.limited.DraftRankCache; -/** - * A column object in a EditorTableModel in the card editor. - * Requires a sorting function and a display function - * (to extract information as appropriate for table row data). - * - * @param a generic type - */ public enum ColumnDef { STRING("", "", 0, -1, -1, SortState.ASC, new ItemCellRenderer(), new Function, Comparable>() { diff --git a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/GroupDef.java b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/GroupDef.java new file mode 100644 index 00000000000..1d31c6d6cbd --- /dev/null +++ b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/GroupDef.java @@ -0,0 +1,182 @@ +package forge.gui.toolbox.itemmanager.views; + +import com.google.common.base.Function; + +import forge.card.CardType; +import forge.card.ColorSet; +import forge.gui.deckeditor.DeckProxy; +import forge.item.InventoryItem; +import forge.item.PaperCard; + +public enum GroupDef { + COLOR("Color", getColorGroups(), + new Function() { + @Override + public ColumnDef apply(final Integer groupIndex) { + return null; + } + }, + new Function() { + @Override + public Integer apply(final InventoryItem item) { + if (item instanceof PaperCard) { + return getColorGroup(((PaperCard) item).getRules().getColor()); + } + else if (item instanceof DeckProxy) { + return getColorGroup(((DeckProxy) item).getColor()); + } + return -1; + } + }), + COLOR_IDENTITY("Color", getColorGroups(), + new Function() { + @Override + public ColumnDef apply(final Integer groupIndex) { + return null; + } + }, + new Function() { + @Override + public Integer apply(final InventoryItem item) { + if (item instanceof PaperCard) { + return getColorGroup(((PaperCard) item).getRules().getColorIdentity()); + } + else if (item instanceof DeckProxy) { + return getColorGroup(((DeckProxy) item).getColorIdentity()); + } + return -1; + } + }), + CREATURE_SPELL_LAND("Creatures/Spells/Lands", + new String[] { "Creatures", "Spells", "Lands" }, + new Function() { + @Override + public ColumnDef apply(final Integer groupIndex) { + if (groupIndex == 2) { + return ColumnDef.NAME; //pile lands by name regardless + } + return null; + } + }, + new Function() { + @Override + public Integer apply(final InventoryItem item) { + if (item instanceof PaperCard) { + CardType type = ((PaperCard) item).getRules().getType(); + if (type.isCreature()) { + return 0; + } + if (type.isArtifact() || type.isEnchantment() || type.isPlaneswalker() || type.isInstant() || type.isSorcery()) { + return 1; + } + if (type.isLand()) { + return 2; + } + } + return -1; + } + }), + CARD_TYPE("Card Type", + new String[] { "Lands", "Artifacts", "Creatures", "Enchantments", "Planeswalkers", "Instants", "Sorceries" }, + new Function() { + @Override + public ColumnDef apply(final Integer groupIndex) { + if (groupIndex == 0) { + return ColumnDef.NAME; //pile lands by name regardless + } + return null; + } + }, + new Function() { + @Override + public Integer apply(final InventoryItem item) { + if (item instanceof PaperCard) { + CardType type = ((PaperCard) item).getRules().getType(); + if (type.isLand()) { + return 0; + } + if (type.isArtifact()) { + return 1; + } + if (type.isCreature()) { + return 2; + } + if (type.isEnchantment()) { + return 3; + } + if (type.isPlaneswalker()) { + return 4; + } + if (type.isInstant()) { + return 5; + } + if (type.isSorcery()) { + return 6; + } + } + return -1; + } + }); + + GroupDef(String name0, String[] groups0, Function fnGetPileByOverride0, Function fnGroupItem0) { + this.name = name0; + this.groups = groups0; + this.fnGetPileByOverride = fnGetPileByOverride0; + this.fnGroupItem = fnGroupItem0; + } + + private final String name; + private final String[] groups; + private final Function fnGetPileByOverride; + private final Function fnGroupItem; + + public String getName() { + return this.name; + } + + public String[] getGroups() { + return this.groups; + } + + public ColumnDef getGroupPileBy(int groupIndex, ColumnDef defaultPileBy) { + ColumnDef pileBy = this.fnGetPileByOverride.apply(groupIndex); + if (pileBy == null) { + return defaultPileBy; + } + return pileBy; + } + + public int getItemGroupIndex(InventoryItem item) { + return this.fnGroupItem.apply(item); + } + + private static String[] getColorGroups() { + //TODO: Support breaking up Multicolor into separate groups for each color combination + return new String[] { "Colorless", "White", "Blue", "Black", "Red", "Green", "Multicolor" }; + } + + private static Integer getColorGroup(ColorSet color) { + if (color.isColorless()) { + return 0; + } + if (color.isMulticolor()) { + return 6; + } + if (color.hasWhite()) { + return 1; + } + if (color.hasBlue()) { + return 2; + } + if (color.hasBlack()) { + return 3; + } + if (color.hasRed()) { + return 4; + } + if (color.hasGreen()) { + return 5; + } + return -1; //shouldn't happen + } +} diff --git a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ImageView.java b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ImageView.java index 0a8f5d310af..b77b9dc819b 100644 --- a/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ImageView.java +++ b/forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ImageView.java @@ -38,16 +38,12 @@ import forge.view.arcane.CardPanel; public class ImageView extends ItemView { private static final float GAP_SCALE_FACTOR = 0.04f; - public enum LayoutType { - Spreadsheet, - Piles - } - private final CardViewDisplay display; private List selectedIndices = new ArrayList(); private int imageScaleFactor = 3; private boolean allowMultipleSelections; - private LayoutType layoutType = LayoutType.Spreadsheet; + private ColumnDef pileBy = null; + private GroupDef groupBy = null; public ImageView(ItemManager itemManager0, ItemManagerModel model0) { super(itemManager0, model0); @@ -118,7 +114,7 @@ public class ImageView extends ItemView { @Override protected void onResize() { - if (this.layoutType == LayoutType.Spreadsheet) { + if (this.pileBy == null) { display.refresh(); //need to refresh to adjust wrapping of items } } @@ -275,7 +271,7 @@ public class ImageView extends ItemView { display.scrollRectToVisible(new Rectangle(x, y, width, height)); } } - private class Section extends DisplayArea { + private class Group extends DisplayArea { private final List piles = new ArrayList(); private boolean isCollapsed; } @@ -304,7 +300,7 @@ public class ImageView extends ItemView { private Point hoverScrollPos; private ItemInfo hoveredItem; private List items = new ArrayList(); - private List
sections = new ArrayList
(); + private List sections = new ArrayList(); private CardViewDisplay() { this.setOpaque(false); @@ -326,13 +322,11 @@ public class ImageView extends ItemView { this.sections.clear(); if (!this.items.isEmpty()) { - switch (ImageView.this.layoutType) { - case Spreadsheet: + if (ImageView.this.pileBy == null) { buildSpreadsheet(); - break; - case Piles: + } + else { buildPiles(); - break; } } @@ -342,10 +336,10 @@ public class ImageView extends ItemView { private ItemInfo getItemAtPoint(Point p) { for (int i = this.sections.size() - 1; i >= 0; i--) { - Section section = this.sections.get(i); - if (!section.isCollapsed && section.getBounds().contains(p)) { - for (int j = section.piles.size() - 1; j >= 0; j--) { - Pile pile = section.piles.get(j); + Group group = this.sections.get(i); + if (!group.isCollapsed && group.getBounds().contains(p)) { + for (int j = group.piles.size() - 1; j >= 0; j--) { + Pile pile = group.piles.get(j); if (pile.getBounds().contains(p)) { for (int k = pile.items.size() - 1; k >= 0; k--) { ItemInfo item = pile.items.get(k); @@ -378,7 +372,7 @@ public class ImageView extends ItemView { private void buildSpreadsheet() { ImageView.this.getScroller().setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - Section section = new Section(); + Group group = new Group(); final int itemAreaWidth = getVisibleSize().width; int itemWidth = 50 * imageScaleFactor; @@ -407,16 +401,16 @@ public class ImageView extends ItemView { if (pile.items.size() == 0) { pile.setBounds(0, y, itemAreaWidth, dy); - section.piles.add(pile); + group.piles.add(pile); } pile.items.add(itemInfo); x += dx; } - section.setBounds(0, 0, itemAreaWidth, y + itemHeight + CardArea.GUTTER_Y); - this.setPreferredSize(section.getBounds().getSize()); + group.setBounds(0, 0, itemAreaWidth, y + itemHeight + CardArea.GUTTER_Y); + this.setPreferredSize(group.getBounds().getSize()); - this.sections.add(section); + this.sections.add(group); } private void buildPiles() { @@ -458,26 +452,25 @@ public class ImageView extends ItemView { int sectionIdx = 0, pileIdx = 0; final int scrollTop = ImageView.this.getScroller().getVerticalScrollBar().getValue(); final int scrollBottom = scrollTop + getVisibleSize().height; - switch (ImageView.this.layoutType) { - case Spreadsheet: + if (ImageView.this.pileBy == null) { pileIdx = scrollTop / this.sections.get(0).piles.get(0).getBounds().height; - break; - case Piles: - break; + } + else { + } for (; sectionIdx < this.sections.size(); sectionIdx++, pileIdx = 0) { - Section section = this.sections.get(sectionIdx); - if (section.getBounds().y >= scrollBottom) { + Group group = this.sections.get(sectionIdx); + if (group.getBounds().y >= scrollBottom) { break; } if (this.sections.size() > 1) { - //TODO: Draw section name/border - if (section.isCollapsed) { + //TODO: Draw group name/border + if (group.isCollapsed) { continue; } } - for (; pileIdx < section.piles.size(); pileIdx++) { - Pile pile = section.piles.get(pileIdx); + for (; pileIdx < group.piles.size(); pileIdx++) { + Pile pile = group.piles.get(pileIdx); if (pile.getBounds().y >= scrollBottom) { break; }