Refactor so Image View shares sort order of List View

This commit is contained in:
drdev
2014-02-01 21:16:12 +00:00
parent da3b2c1dc1
commit c3d7a9f075
6 changed files with 165 additions and 205 deletions

1
.gitattributes vendored
View File

@@ -15698,7 +15698,6 @@ forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/ManaCostRenderer.jav
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/SColumnUtil.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/SColumnUtil.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/SetCodeRenderer.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/SetCodeRenderer.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/StarRenderer.java -text forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/StarRenderer.java -text
forge-gui/src/main/java/forge/gui/toolbox/itemmanager/views/TableSorterCascade.java -text
forge-gui/src/main/java/forge/gui/toolbox/package-info.java svneol=native#text/plain forge-gui/src/main/java/forge/gui/toolbox/package-info.java svneol=native#text/plain
forge-gui/src/main/java/forge/gui/toolbox/special/CardViewer.java -text forge-gui/src/main/java/forge/gui/toolbox/special/CardViewer.java -text
forge-gui/src/main/java/forge/gui/toolbox/special/CardZoomer.java -text forge-gui/src/main/java/forge/gui/toolbox/special/CardZoomer.java -text

View File

@@ -18,12 +18,17 @@
package forge.gui.toolbox.itemmanager; package forge.gui.toolbox.itemmanager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import forge.gui.toolbox.itemmanager.views.ItemColumn;
import forge.gui.toolbox.itemmanager.views.ItemColumn.SortState;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.util.ItemPool; import forge.util.ItemPool;
import forge.util.ItemPoolSorter;
/** /**
* <p> * <p>
@@ -36,8 +41,11 @@ import forge.util.ItemPool;
* @version $Id: ItemManagerModel.java 19857 2013-02-24 08:49:52Z Max mtg $ * @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 final ItemPool<T> data; private final ItemPool<T> data;
private boolean infiniteSupply; private boolean infiniteSupply;
private final CascadeManager cascadeManager = new CascadeManager();
/** /**
* Instantiates a new list view model * Instantiates a new list view model
@@ -152,4 +160,136 @@ public final class ItemManagerModel<T extends InventoryItem> {
public boolean isInfinite() { public boolean isInfinite() {
return infiniteSupply; return infiniteSupply;
} }
public CascadeManager getCascadeManager() {
return cascadeManager;
}
/**
* Resort.
*/
public void refreshSort() {
if (this.getOrderedList().isEmpty()) { return; }
Collections.sort(this.getOrderedList(), new MyComparator());
}
/**
* Manages sorting orders for multiple depths of sorting.
*/
public final class CascadeManager {
private final List<ItemColumn> colsToSort = new ArrayList<ItemColumn>(3);
private Sorter sorter = null;
// Adds a column to sort cascade list.
// If column is first in the cascade, inverts direction of sort.
// Otherwise, sorts in ascending direction.
public void add(final ItemColumn col0, boolean forSetup) {
this.sorter = null;
if (forSetup) { //just add column unmodified if setting up sort columns
this.colsToSort.add(0, (ItemColumn) col0);
}
else {
if (colsToSort.size() > 0 && colsToSort.get(0).equals(col0)) { //if column already at top level, just invert
col0.setSortPriority(1);
col0.setSortState(col0.getSortState() == SortState.ASC ? SortState.DESC : SortState.ASC);
}
else { //otherwise move column to top level and move others down
this.colsToSort.remove(col0);
col0.setSortPriority(1);
col0.setSortState(col0.getDefaultSortState());
this.colsToSort.add(0, (ItemColumn) col0);
}
//decrement sort priority on remaining columns
for (int i = 1; i < maxSortDepth; i++) {
if (colsToSort.size() == i) { break; }
if (colsToSort.get(i).getSortPriority() != 0) {
colsToSort.get(i).setSortPriority(i + 1);
}
}
}
//unset and remove boundary columns.
if (this.colsToSort.size() > maxSortDepth) {
this.colsToSort.get(maxSortDepth).setSortPriority(0);
this.colsToSort.remove(maxSortDepth);
}
}
public Sorter getSorter() {
if (this.sorter == null) {
this.sorter = createSorter();
}
return this.sorter;
}
public void reset() {
this.colsToSort.clear();
this.sorter = null;
}
private Sorter createSorter() {
final List<ItemPoolSorter<InventoryItem>> oneColSorters
= new ArrayList<ItemPoolSorter<InventoryItem>>(maxSortDepth);
for (final ItemColumn col : this.colsToSort) {
oneColSorters.add(new ItemPoolSorter<InventoryItem>(
col.getFnSort(),
col.getSortState().equals(SortState.ASC) ? true : false));
}
return new Sorter(oneColSorters);
}
public class Sorter implements Comparator<Entry<InventoryItem, Integer>> {
private final List<ItemPoolSorter<InventoryItem>> sorters;
private final int cntFields;
/**
*
* Sorter Constructor.
*
* @param sorters0
* a List<TableSorter<InventoryItem>>
*/
public Sorter(final List<ItemPoolSorter<InventoryItem>> sorters0) {
this.sorters = sorters0;
this.cntFields = sorters0.size();
}
/*
* (non-Javadoc)
*
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public final int compare(final Entry<InventoryItem, Integer> arg0, final Entry<InventoryItem, Integer> arg1) {
int lastCompare = 0;
int iField = -1;
while ((++iField < this.cntFields) && (lastCompare == 0)) { // reverse
// iteration
final ItemPoolSorter<InventoryItem> sorter = this.sorters.get(iField);
if (sorter == null) {
break;
}
lastCompare = sorter.compare(arg0, arg1);
}
return lastCompare;
}
}
}
private class MyComparator implements Comparator<Entry<T, Integer>> {
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public int compare(Entry<T, Integer> o1, Entry<T, Integer> o2) {
return cascadeManager.getSorter().compare((Entry<InventoryItem, Integer>)o1, (Entry<InventoryItem, Integer>)o2);
}
}
} // ItemManagerModel } // ItemManagerModel

View File

@@ -13,8 +13,6 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter; import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
@@ -46,16 +44,14 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
} }
private final CardViewDisplay display; private final CardViewDisplay display;
private final ItemManagerModel<T> model;
private List<Integer> selectedIndices = new ArrayList<Integer>(); private List<Integer> selectedIndices = new ArrayList<Integer>();
private int imageScaleFactor = 3; private int imageScaleFactor = 3;
private boolean allowMultipleSelections; private boolean allowMultipleSelections;
private LayoutType layoutType = LayoutType.Spreadsheet; private LayoutType layoutType = LayoutType.Spreadsheet;
public ImageView(ItemManager<T> itemManager0, ItemManagerModel<T> model0) { public ImageView(ItemManager<T> itemManager0, ItemManagerModel<T> model0) {
super(itemManager0); super(itemManager0, model0);
this.display = new CardViewDisplay(); this.display = new CardViewDisplay();
this.model = model0;
this.display.addMouseListener(new FMouseAdapter() { this.display.addMouseListener(new FMouseAdapter() {
@Override @Override
public void onLeftMouseDown(MouseEvent e) { public void onLeftMouseDown(MouseEvent e) {
@@ -64,13 +60,13 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
@Override @Override
public void onLeftDoubleClick(MouseEvent e) { public void onLeftDoubleClick(MouseEvent e) {
getItemManager().activateSelectedItems(); itemManager.activateSelectedItems();
} }
@Override @Override
public void onRightClick(MouseEvent e) { public void onRightClick(MouseEvent e) {
selectItem(e); selectItem(e);
getItemManager().showContextMenu(e); itemManager.showContextMenu(e);
} }
private void selectItem(MouseEvent e) { private void selectItem(MouseEvent e) {
@@ -192,7 +188,7 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
@Override @Override
protected SkinImage getIcon() { protected SkinImage getIcon() {
if (getItemManager().getGenericType().equals(DeckProxy.class)) { if (itemManager.getGenericType().equals(DeckProxy.class)) {
return FSkin.getImage(FSkin.EditorImages.IMG_PACK).resize(18, 18); return FSkin.getImage(FSkin.EditorImages.IMG_PACK).resize(18, 18);
} }
return FSkin.getIcon(FSkin.InterfaceIcons.ICO_CARD_IMAGE); return FSkin.getIcon(FSkin.InterfaceIcons.ICO_CARD_IMAGE);
@@ -291,8 +287,9 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
private Integer index; private Integer index;
private boolean selected; private boolean selected;
private ItemInfo(T item0) { private ItemInfo(T item0, int index0) {
this.item = item0; this.item = item0;
this.index = index0;
} }
@Override @Override
@@ -315,21 +312,13 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
} }
private void refresh() { private void refresh() {
int index = 0;
this.items.clear(); this.items.clear();
for (Entry<T, Integer> itemEntry : model.getItems()) { for (Entry<T, Integer> itemEntry : model.getOrderedList()) {
for (int i = 0; i < itemEntry.getValue(); i++) { for (int i = 0; i < itemEntry.getValue(); i++) {
this.items.add(new ItemInfo(itemEntry.getKey())); this.items.add(new ItemInfo(itemEntry.getKey(), index++));
} }
} }
Collections.sort(this.items, new Comparator<ItemInfo>() {
@Override
public int compare(ItemInfo arg0, ItemInfo arg1) {
return arg0.item.getName().compareTo(arg1.item.getName());
}
});
for (int i = 0; i < this.items.size(); i++) {
this.items.get(i).index = i;
}
this.refreshSections(); this.refreshSections();
} }

View File

@@ -66,9 +66,7 @@ import forge.gui.toolbox.FSkin.SkinnedTableHeader;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.ItemManagerModel; import forge.gui.toolbox.itemmanager.ItemManagerModel;
import forge.gui.toolbox.itemmanager.SItemManagerIO; import forge.gui.toolbox.itemmanager.SItemManagerIO;
import forge.gui.toolbox.itemmanager.views.ItemColumn.SortState;
import forge.item.InventoryItem; import forge.item.InventoryItem;
import forge.util.ItemPoolSorter;
/** /**
@@ -104,7 +102,7 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
* @param model0 * @param model0
*/ */
public ItemListView(ItemManager<T> itemManager0, ItemManagerModel<T> model0) { public ItemListView(ItemManager<T> itemManager0, ItemManagerModel<T> model0) {
super(itemManager0); super(itemManager0, model0);
this.tableModel = new ItemTableModel(model0); this.tableModel = new ItemTableModel(model0);
// use different selection highlight colors for focused vs. unfocused tables // use different selection highlight colors for focused vs. unfocused tables
@@ -112,12 +110,12 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
@Override @Override
public void onLeftDoubleClick(MouseEvent e) { public void onLeftDoubleClick(MouseEvent e) {
if (e.isConsumed()) { return; } //don't activate if inline button double clicked if (e.isConsumed()) { return; } //don't activate if inline button double clicked
getItemManager().activateSelectedItems(); itemManager.activateSelectedItems();
} }
@Override @Override
public void onRightClick(MouseEvent e) { public void onRightClick(MouseEvent e) {
getItemManager().showContextMenu(e); itemManager.showContextMenu(e);
} }
}); });
@@ -274,7 +272,6 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
@Override @Override
protected void onRefresh() { protected void onRefresh() {
this.tableModel.refreshSort();
this.tableModel.fireTableDataChanged(); this.tableModel.fireTableDataChanged();
} }
@@ -444,8 +441,6 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
public final class ItemTableModel extends AbstractTableModel { public final class ItemTableModel extends AbstractTableModel {
private final ItemManagerModel<T> model; private final ItemManagerModel<T> model;
private final CascadeManager cascadeManager = new CascadeManager();
private final int maxSortDepth = 3;
/** /**
* Instantiates a new table model. * Instantiates a new table model.
@@ -469,12 +464,12 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
} }
} }
cascadeManager.reset(); model.getCascadeManager().reset();
for (int i = sortcols.length - 1; i >= 0; i--) { for (int i = sortcols.length - 1; i >= 0; i--) {
ItemColumn col = sortcols[i]; ItemColumn col = sortcols[i];
if (col != null) { if (col != null) {
cascadeManager.add(col, true); model.getCascadeManager().add(col, true);
} }
} }
} }
@@ -537,17 +532,17 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
} }
// This will invert if needed // This will invert if needed
ItemTableModel.this.cascadeManager.add((ItemColumn) table.getColumnModel().getColumn(columnModelIndex), false); model.getCascadeManager().add((ItemColumn) table.getColumnModel().getColumn(columnModelIndex), false);
ItemTableModel.this.refreshSort(); model.refreshSort();
table.tableChanged(new TableModelEvent(ItemTableModel.this)); table.tableChanged(new TableModelEvent(ItemTableModel.this));
table.repaint(); table.repaint();
ItemListView.this.setSelectedIndex(0); ItemListView.this.setSelectedIndex(0);
SItemManagerIO.savePreferences(getItemManager()); SItemManagerIO.savePreferences(itemManager);
} }
@Override @Override
public void onLeftMouseDragDrop(MouseEvent e) { //save preferences after column moved/resized public void onLeftMouseDragDrop(MouseEvent e) { //save preferences after column moved/resized
SItemManagerIO.savePreferences(getItemManager()); SItemManagerIO.savePreferences(itemManager);
} }
}; };
@@ -568,15 +563,6 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
table.getTableHeader().addMouseListener(headerMouseAdapter); table.getTableHeader().addMouseListener(headerMouseAdapter);
} }
/**
* Resort.
*/
private void refreshSort() {
if (this.model.getOrderedList().size() == 0) { return; }
Collections.sort(this.model.getOrderedList(), new MyComparator());
}
//========== Overridden from AbstractTableModel //========== Overridden from AbstractTableModel
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
@@ -614,87 +600,5 @@ public final class ItemListView<T extends InventoryItem> extends ItemView<T> {
//========= Custom class handling //========= Custom class handling
/**
* Manages sorting orders for multiple depths of sorting.
*/
private final class CascadeManager {
private final List<ItemColumn> colsToSort = new ArrayList<ItemColumn>(3);
private TableSorterCascade<InventoryItem> sorter = null;
// Adds a column to sort cascade list.
// If column is first in the cascade, inverts direction of sort.
// Otherwise, sorts in ascending direction.
public void add(final ItemColumn col0, boolean forSetup) {
this.sorter = null;
if (forSetup) { //just add column unmodified if setting up sort columns
this.colsToSort.add(0, (ItemColumn) col0);
}
else {
if (colsToSort.size() > 0 && colsToSort.get(0).equals(col0)) { //if column already at top level, just invert
col0.setSortPriority(1);
col0.setSortState(col0.getSortState() == SortState.ASC ? SortState.DESC : SortState.ASC);
}
else { //otherwise move column to top level and move others down
this.colsToSort.remove(col0);
col0.setSortPriority(1);
col0.setSortState(col0.getDefaultSortState());
this.colsToSort.add(0, (ItemColumn) col0);
}
//decrement sort priority on remaining columns
for (int i = 1; i < maxSortDepth; i++) {
if (colsToSort.size() == i) { break; }
if (colsToSort.get(i).getSortPriority() != 0) {
colsToSort.get(i).setSortPriority(i + 1);
}
}
}
//unset and remove boundary columns.
if (this.colsToSort.size() > maxSortDepth) {
this.colsToSort.get(maxSortDepth).setSortPriority(0);
this.colsToSort.remove(maxSortDepth);
}
}
public TableSorterCascade<InventoryItem> getSorter() {
if (this.sorter == null) {
this.sorter = createSorter();
}
return this.sorter;
}
public void reset() {
this.colsToSort.clear();
this.sorter = null;
}
private TableSorterCascade<InventoryItem> createSorter() {
final List<ItemPoolSorter<InventoryItem>> oneColSorters
= new ArrayList<ItemPoolSorter<InventoryItem>>(maxSortDepth);
for (final ItemColumn col : this.colsToSort) {
oneColSorters.add(new ItemPoolSorter<InventoryItem>(
col.getFnSort(),
col.getSortState().equals(SortState.ASC) ? true : false));
}
return new TableSorterCascade<InventoryItem>(oneColSorters);
}
}
private class MyComparator implements Comparator<Entry<T, Integer>> {
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@SuppressWarnings("unchecked")
@Override
public int compare(Entry<T, Integer> o1, Entry<T, Integer> o2) {
return ItemTableModel.this.cascadeManager.getSorter().compare(
(Entry<InventoryItem, Integer>) o1, (Entry<InventoryItem, Integer>) o2);
}
}
} }
} }

View File

@@ -36,17 +36,20 @@ import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FSkin.SkinImage; import forge.gui.toolbox.FSkin.SkinImage;
import forge.gui.toolbox.ToolTipListener; import forge.gui.toolbox.ToolTipListener;
import forge.gui.toolbox.itemmanager.ItemManager; import forge.gui.toolbox.itemmanager.ItemManager;
import forge.gui.toolbox.itemmanager.ItemManagerModel;
import forge.item.InventoryItem; import forge.item.InventoryItem;
public abstract class ItemView<T extends InventoryItem> { public abstract class ItemView<T extends InventoryItem> {
private final ItemManager<T> itemManager; protected final ItemManager<T> itemManager;
protected final ItemManagerModel<T> model;
private final FScrollPane scroller; private final FScrollPane scroller;
private final FLabel button; private final FLabel button;
private int heightBackup; private int heightBackup;
private boolean isIncrementalSearchActive = false; private boolean isIncrementalSearchActive = false;
protected ItemView(ItemManager<T> itemManager0) { protected ItemView(ItemManager<T> itemManager0, ItemManagerModel<T> model0) {
this.itemManager = itemManager0; this.itemManager = itemManager0;
this.model = model0;
this.scroller = new FScrollPane(false); this.scroller = new FScrollPane(false);
this.scroller.setBorder(new FSkin.LineSkinBorder(FSkin.getColor(FSkin.Colors.CLR_TEXT))); this.scroller.setBorder(new FSkin.LineSkinBorder(FSkin.getColor(FSkin.Colors.CLR_TEXT)));
this.button = new FLabel.Builder().hoverable().selectable(true) this.button = new FLabel.Builder().hoverable().selectable(true)
@@ -90,10 +93,6 @@ public abstract class ItemView<T extends InventoryItem> {
}); });
} }
public ItemManager<T> getItemManager() {
return this.itemManager;
}
public FLabel getButton() { public FLabel getButton() {
return this.button; return this.button;
} }
@@ -107,6 +106,7 @@ public abstract class ItemView<T extends InventoryItem> {
} }
public void refresh(final Iterable<T> itemsToSelect, final int backupIndexToSelect) { public void refresh(final Iterable<T> itemsToSelect, final int backupIndexToSelect) {
this.model.refreshSort();
onRefresh(); onRefresh();
fixSelection(itemsToSelect, backupIndexToSelect); fixSelection(itemsToSelect, backupIndexToSelect);
} }
@@ -222,7 +222,7 @@ public abstract class ItemView<T extends InventoryItem> {
protected void onSelectionChange() { protected void onSelectionChange() {
final int index = getSelectedIndex(); final int index = getSelectedIndex();
if (index != -1) { if (index != -1) {
ListSelectionEvent event = new ListSelectionEvent(getItemManager(), index, index, false); ListSelectionEvent event = new ListSelectionEvent(itemManager, index, index, false);
for (ListSelectionListener listener : itemManager.getSelectionListeners()) { for (ListSelectionListener listener : itemManager.getSelectionListeners()) {
listener.valueChanged(event); listener.valueChanged(event);
} }

View File

@@ -1,72 +0,0 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.gui.toolbox.itemmanager.views;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
import forge.item.InventoryItem;
import forge.util.ItemPoolSorter;
/**
* <p>
* TableSorter class.
* </p>
*
* @param <T>
* extends InventoryItem
* @author Forge
* @version $Id: TableSorter.java 10146 2011-09-01 18:11:00Z Max mtg $
*/
public class TableSorterCascade<T extends InventoryItem> implements Comparator<Entry<T, Integer>> {
private final List<ItemPoolSorter<T>> sorters;
private final int cntFields;
/**
*
* TableSorterCascade Constructor.
*
* @param sortersCascade
* a List<TableSorter<T>>
*/
public TableSorterCascade(final List<ItemPoolSorter<T>> sortersCascade) {
this.sorters = sortersCascade;
this.cntFields = sortersCascade.size();
}
/*
* (non-Javadoc)
*
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public final int compare(final Entry<T, Integer> arg0, final Entry<T, Integer> arg1) {
int lastCompare = 0;
int iField = -1;
while ((++iField < this.cntFields) && (lastCompare == 0)) { // reverse
// iteration
final ItemPoolSorter<T> sorter = this.sorters.get(iField);
if (sorter == null) {
break;
}
lastCompare = sorter.compare(arg0, arg1);
}
return lastCompare;
}
}