From 22bfc9f1e3a4d605381bde0403d78397dd2d22e1 Mon Sep 17 00:00:00 2001 From: drdev Date: Sun, 20 Sep 2015 16:32:37 +0000 Subject: [PATCH] Support editing individual filters via menu --- .../filters/AdvancedSearchFilter.java | 30 ++++- .../src/forge/menu/FMenuItem.java | 13 ++- .../forge/itemmanager/AdvancedSearch.java | 104 ++++++++++-------- 3 files changed, 98 insertions(+), 49 deletions(-) diff --git a/forge-gui-mobile/src/forge/itemmanager/filters/AdvancedSearchFilter.java b/forge-gui-mobile/src/forge/itemmanager/filters/AdvancedSearchFilter.java index 8c77983d7cc..f70142488ee 100644 --- a/forge-gui-mobile/src/forge/itemmanager/filters/AdvancedSearchFilter.java +++ b/forge-gui-mobile/src/forge/itemmanager/filters/AdvancedSearchFilter.java @@ -5,10 +5,12 @@ import com.google.common.base.Predicate; import forge.Forge; import forge.assets.FSkinImage; +import forge.assets.TextRenderer; import forge.interfaces.IButton; import forge.item.InventoryItem; import forge.itemmanager.AdvancedSearch; import forge.itemmanager.ItemManager; +import forge.itemmanager.AdvancedSearch.IFilterControl; import forge.menu.FMenuItem; import forge.menu.FPopupMenu; import forge.menu.FTooltip; @@ -81,6 +83,15 @@ public class AdvancedSearchFilter extends ItemFilter label.setSize(width, height); } + private final Runnable onFilterChange = new Runnable() { + @Override + public void run() { + //update expression when edit screen closed or a single filter is changed + model.updateExpression(); + itemManager.applyNewOrModifiedFilter(AdvancedSearchFilter.this); + } + }; + private class FiltersLabel extends FLabel { private String toolTipText; @@ -103,13 +114,24 @@ public class AdvancedSearchFilter extends ItemFilter FPopupMenu menu = new FPopupMenu() { @Override protected void buildMenu() { - addItem(new FMenuItem("Edit Advanced Search", FSkinImage.EDIT, new FEventHandler() { + //add a menu item for each filter to allow easily editing just that filter + for (final IFilterControl control : model.getControls()) { + FMenuItem item = new FMenuItem(control.getFilter().toString(), FSkinImage.EDIT, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + model.editFilterControl(control, onFilterChange); + } + }); + item.setTextRenderer(new TextRenderer()); //ensure symbols are displayed + addItem(item); + } + addItem(new FMenuItem("Edit Expression", FSkinImage.EDIT, new FEventHandler() { @Override public void handleEvent(FEvent e) { edit(); } })); - addItem(new FMenuItem("Clear Advanced Search", FSkinImage.DELETE, new FEventHandler() { + addItem(new FMenuItem("Remove Filter", FSkinImage.DELETE, new FEventHandler() { @Override public void handleEvent(FEvent e) { reset(); @@ -161,9 +183,7 @@ public class AdvancedSearchFilter extends ItemFilter @Override public void onClose(Callback canCloseCallback) { - //update expression when screen closed - model.updateExpression(); - itemManager.applyNewOrModifiedFilter(AdvancedSearchFilter.this); + onFilterChange.run(); super.onClose(canCloseCallback); } diff --git a/forge-gui-mobile/src/forge/menu/FMenuItem.java b/forge-gui-mobile/src/forge/menu/FMenuItem.java index 7acdb267640..c9d31517d3d 100644 --- a/forge-gui-mobile/src/forge/menu/FMenuItem.java +++ b/forge-gui-mobile/src/forge/menu/FMenuItem.java @@ -9,6 +9,7 @@ import forge.UiCommand; import forge.assets.FImage; import forge.assets.FSkinColor; import forge.assets.FSkinFont; +import forge.assets.TextRenderer; import forge.assets.FSkinColor.Colors; import forge.assets.FSkinProp; import forge.interfaces.IButton; @@ -36,6 +37,7 @@ public class FMenuItem extends FDisplayObject implements IButton { private final FEventHandler handler; private boolean pressed, allowForIcon, selected, tabMode; private float textWidth; + private TextRenderer textRenderer; public FMenuItem(String text0, FEventHandler handler0) { this(text0, null, handler0, true); @@ -71,6 +73,10 @@ public class FMenuItem extends FDisplayObject implements IButton { tabMode = tabMode0; } + public void setTextRenderer(TextRenderer textRenderer0) { + textRenderer = textRenderer0; + } + public float getMinWidth() { //pretend there's a divot even if there isn't to provide extra right padding and allow menu items to line up nicer float width = textWidth + DIVOT_WIDTH + 4 * GAP_X; @@ -128,7 +134,12 @@ public class FMenuItem extends FDisplayObject implements IButton { x += ICON_SIZE + GAP_X; } - g.drawText(text, FONT, FORE_COLOR, x, 0, w - x - GAP_X, h, false, HAlignment.LEFT, true); + if (textRenderer == null) { + g.drawText(text, FONT, FORE_COLOR, x, 0, w - x - GAP_X, h, false, HAlignment.LEFT, true); + } + else { + textRenderer.drawText(g, text, FONT, FORE_COLOR, x, 0, w - x - GAP_X, h, 0, h, false, HAlignment.LEFT, true); + } //draw separator line if (tabMode) { diff --git a/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java b/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java index d4656042da5..3b31c462d7a 100644 --- a/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java +++ b/forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java @@ -837,21 +837,26 @@ public class AdvancedSearch { } @SuppressWarnings("unchecked") - public static Filter getFilter(Class type, Filter editFilter) { - //build list of filter options based on ItemManager type - List options = new ArrayList(); - if (editFilter != null) { - options.add(FilterOption.NONE); //provide option to clear existing filter - } - for (FilterOption opt : FilterOption.values()) { - if (opt.type == type) { - options.add(opt); - } - } - + public static Filter getFilter(Class type, Filter editFilter, boolean reselectOption) { + final FilterOption option; final FilterOption defaultOption = editFilter == null ? null : editFilter.option; - final FilterOption option = SGuiChoose.oneOrNone("Select a filter type", options, defaultOption, null); - if (option == null) { return editFilter; } + if (defaultOption == null || reselectOption) { + //build list of filter options based on ItemManager type + List options = new ArrayList(); + if (editFilter != null) { + options.add(FilterOption.NONE); //provide option to clear existing filter + } + for (FilterOption opt : FilterOption.values()) { + if (opt.type == type) { + options.add(opt); + } + } + option = SGuiChoose.oneOrNone("Select a filter type", options, defaultOption, null); + if (option == null) { return editFilter; } + } + else { + option = defaultOption; + } if (option == FilterOption.NONE) { return null; } //allow user to clear filter by selecting "(none)" @@ -928,6 +933,8 @@ public class AdvancedSearch { } public static class Model { + private static final String EMPTY_FILTER_TEXT = "Select Filter..."; + private final List expression = new ArrayList(); private final List> controls = new ArrayList>(); private IButton label; @@ -1002,42 +1009,16 @@ public class AdvancedSearch { @SuppressWarnings("serial") public void addFilterControl(final IFilterControl control) { - final String emptyFilterText = "Select Filter..."; - control.getBtnFilter().setText(emptyFilterText); + control.getBtnFilter().setText(EMPTY_FILTER_TEXT); control.getBtnFilter().setCommand(new UiCommand() { @Override public void run() { - FThreads.invokeInBackgroundThread(new Runnable() { - @Override - public void run() { - final Filter filter = getFilter(control.getGenericType(), control.getFilter()); - if (control.getFilter() != filter) { - FThreads.invokeInEdtLater(new Runnable() { - @Override - public void run() { - control.setFilter(filter); - if (filter != null) { - control.getBtnFilter().setText(GuiBase.getInterface().encodeSymbols(filter.toString(), false)); - } - else { - control.getBtnFilter().setText(emptyFilterText); - } - if (filter.getOption() == FilterOption.CARD_KEYWORDS) { - //the first time the user selects keywords, preload keywords for all cards - Runnable preloadTask = Keyword.getPreloadTask(); - if (preloadTask != null) { - GuiBase.getInterface().runBackgroundTask("Loading keywords...", preloadTask); - } - } - } - }); - } - } - }); + editFilterControl(control, null); } }); controls.add(control); } + public void removeFilterControl(IFilterControl control) { int index = controls.indexOf(control); if (index > 0) { @@ -1048,6 +1029,43 @@ public class AdvancedSearch { controls.remove(index); } + public void editFilterControl(final IFilterControl control, final Runnable onChange) { + FThreads.invokeInBackgroundThread(new Runnable() { + @Override + public void run() { + final Filter filter = getFilter(control.getGenericType(), control.getFilter(), onChange == null); //reselect option if no change handler passed + if (control.getFilter() != filter) { + FThreads.invokeInEdtLater(new Runnable() { + @Override + public void run() { + control.setFilter(filter); + if (filter != null) { + control.getBtnFilter().setText(GuiBase.getInterface().encodeSymbols(filter.toString(), false)); + } + else { + control.getBtnFilter().setText(EMPTY_FILTER_TEXT); + } + if (filter.getOption() == FilterOption.CARD_KEYWORDS) { + //the first time the user selects keywords, preload keywords for all cards + Runnable preloadTask = Keyword.getPreloadTask(); + if (preloadTask != null) { + GuiBase.getInterface().runBackgroundTask("Loading keywords...", preloadTask); + } + } + if (onChange != null) { + onChange.run(); + } + } + }); + } + } + }); + } + + public Iterable> getControls() { + return controls; + } + public void setLabel(IButton label0) { label = label0; updateLabel();