mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Add Advanced Search support for desktop
This commit is contained in:
@@ -163,7 +163,9 @@ public class CardManager extends ItemManager<PaperCard> {
|
|||||||
public void run() {
|
public void run() {
|
||||||
AdvancedSearchFilter<PaperCard> filter = itemManager.getFilter(AdvancedSearchFilter.class);
|
AdvancedSearchFilter<PaperCard> filter = itemManager.getFilter(AdvancedSearchFilter.class);
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
filter.edit();
|
if (filter.edit()) {
|
||||||
|
itemManager.applyNewOrModifiedFilter(filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
filter = new AdvancedSearchFilter<PaperCard>(itemManager);
|
filter = new AdvancedSearchFilter<PaperCard>(itemManager);
|
||||||
|
|||||||
@@ -232,7 +232,9 @@ public final class DeckManager extends ItemManager<DeckProxy> implements IHasGam
|
|||||||
public void run() {
|
public void run() {
|
||||||
AdvancedSearchFilter<DeckProxy> filter = getFilter(AdvancedSearchFilter.class);
|
AdvancedSearchFilter<DeckProxy> filter = getFilter(AdvancedSearchFilter.class);
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
filter.edit();
|
if (filter.edit()) {
|
||||||
|
applyNewOrModifiedFilter(filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
filter = new AdvancedSearchFilter<DeckProxy>(DeckManager.this);
|
filter = new AdvancedSearchFilter<DeckProxy>(DeckManager.this);
|
||||||
|
|||||||
@@ -820,7 +820,11 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel implem
|
|||||||
protected abstract void buildAddFilterMenu(JMenu menu);
|
protected abstract void buildAddFilterMenu(JMenu menu);
|
||||||
|
|
||||||
protected <F extends ItemFilter<? extends T>> F getFilter(final Class<F> filterClass) {
|
protected <F extends ItemFilter<? extends T>> F getFilter(final Class<F> filterClass) {
|
||||||
return ReflectionUtil.safeCast(this.filters.get(filterClass), filterClass);
|
List<ItemFilter<? extends T>> filters = this.filters.get(filterClass);
|
||||||
|
if (filters == null || filters.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ReflectionUtil.safeCast(filters.get(0), filterClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -856,7 +860,7 @@ public abstract class ItemManager<T extends InventoryItem> extends JPanel implem
|
|||||||
}
|
}
|
||||||
|
|
||||||
//apply filters and focus existing filter's main component if filtering not locked
|
//apply filters and focus existing filter's main component if filtering not locked
|
||||||
private void applyNewOrModifiedFilter(final ItemFilter<? extends T> filter) {
|
protected void applyNewOrModifiedFilter(final ItemFilter<? extends T> filter) {
|
||||||
if (this.lockFiltering) {
|
if (this.lockFiltering) {
|
||||||
filter.afterFiltersApplied(); //ensure this called even if filters currently locked
|
filter.afterFiltersApplied(); //ensure this called even if filters currently locked
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import forge.itemmanager.AdvancedSearch;
|
|||||||
import forge.itemmanager.ItemManager;
|
import forge.itemmanager.ItemManager;
|
||||||
import forge.toolbox.FLabel;
|
import forge.toolbox.FLabel;
|
||||||
import forge.toolbox.FOptionPane;
|
import forge.toolbox.FOptionPane;
|
||||||
import forge.toolbox.FScrollPanel;
|
import forge.toolbox.FScrollPane;
|
||||||
import forge.toolbox.FSkin.SkinnedPanel;
|
import forge.toolbox.FSkin.SkinnedPanel;
|
||||||
import forge.toolbox.FTextField;
|
import forge.toolbox.FTextField;
|
||||||
import forge.toolbox.LayoutHelper;
|
import forge.toolbox.LayoutHelper;
|
||||||
@@ -20,6 +20,7 @@ import javax.swing.*;
|
|||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
|
||||||
public class AdvancedSearchFilter<T extends InventoryItem> extends ItemFilter<T> {
|
public class AdvancedSearchFilter<T extends InventoryItem> extends ItemFilter<T> {
|
||||||
@@ -73,7 +74,7 @@ public class AdvancedSearchFilter<T extends InventoryItem> extends ItemFilter<T>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean merge(ItemFilter<?> filter) {
|
public boolean merge(ItemFilter<?> filter) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
@@ -81,11 +82,12 @@ public class AdvancedSearchFilter<T extends InventoryItem> extends ItemFilter<T>
|
|||||||
private static final int WIDTH = 400;
|
private static final int WIDTH = 400;
|
||||||
private static final int HEIGHT = 500;
|
private static final int HEIGHT = 500;
|
||||||
|
|
||||||
private final FScrollPanel scroller;
|
private final JPanel panel;
|
||||||
//private FOptionPane optionPane;
|
private final FScrollPane scroller;
|
||||||
|
private FOptionPane optionPane;
|
||||||
|
|
||||||
private EditDialog() {
|
private EditDialog() {
|
||||||
scroller = new FScrollPanel(null, false, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER) {
|
panel = new JPanel(null) {
|
||||||
@Override
|
@Override
|
||||||
public void doLayout() {
|
public void doLayout() {
|
||||||
int x = 0;
|
int x = 0;
|
||||||
@@ -93,22 +95,25 @@ public class AdvancedSearchFilter<T extends InventoryItem> extends ItemFilter<T>
|
|||||||
int w = getWidth();
|
int w = getWidth();
|
||||||
int h = 100;
|
int h = 100;
|
||||||
|
|
||||||
for (Component child : getInnerComponents()) {
|
for (Component child : getComponents()) {
|
||||||
child.setBounds(x, y, w, h);
|
child.setBounds(x, y, w, h);
|
||||||
y += h;
|
y += h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
panel.setOpaque(false);
|
||||||
|
scroller = new FScrollPane(panel, false, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
scroller.setMinimumSize(new Dimension(WIDTH, HEIGHT));
|
scroller.setMinimumSize(new Dimension(WIDTH, HEIGHT));
|
||||||
|
|
||||||
Filter filter = new Filter();
|
Filter filter = new Filter();
|
||||||
model.addFilterControl(filter);
|
model.addFilterControl(filter);
|
||||||
scroller.add(filter);
|
panel.add(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean show() {
|
private boolean show() {
|
||||||
FOptionPane.showMessageDialog("Coming Soon!", "Advanced Search", FOptionPane.INFORMATION_ICON);
|
optionPane = new FOptionPane(null, "Advanced Search", null, scroller, ImmutableList.of("OK", "Cancel"), 0);
|
||||||
/*optionPane = new FOptionPane(null, "Advanced Search", null, scroller, ImmutableList.of("OK", "Cancel"), 0);
|
scroller.revalidate();
|
||||||
|
scroller.repaint();
|
||||||
optionPane.setVisible(true);
|
optionPane.setVisible(true);
|
||||||
|
|
||||||
int result = optionPane.getResult();
|
int result = optionPane.getResult();
|
||||||
@@ -117,28 +122,29 @@ public class AdvancedSearchFilter<T extends InventoryItem> extends ItemFilter<T>
|
|||||||
if (result != 1) {
|
if (result != 1) {
|
||||||
model.updateExpression(); //update expression when dialog accepted
|
model.updateExpression(); //update expression when dialog accepted
|
||||||
return true;
|
return true;
|
||||||
}*/
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addNewFilter(Filter fromFilter) {
|
private void addNewFilter(Filter fromFilter) {
|
||||||
if (scroller.getComponent(scroller.getComponentCount() - 1) == fromFilter) {
|
if (panel.getComponent(panel.getComponentCount() - 1) == fromFilter) {
|
||||||
Filter filter = new Filter();
|
Filter filter = new Filter();
|
||||||
model.addFilterControl(filter);
|
model.addFilterControl(filter);
|
||||||
scroller.add(filter);
|
panel.add(filter);
|
||||||
scroller.revalidate();
|
panel.revalidate();
|
||||||
|
panel.repaint();
|
||||||
scroller.scrollToBottom();
|
scroller.scrollToBottom();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void removeNextFilter(Filter fromFilter) {
|
private void removeNextFilter(Filter fromFilter) {
|
||||||
int index = ArrayUtils.indexOf(scroller.getComponents(), fromFilter);
|
int index = ArrayUtils.indexOf(panel.getComponents(), fromFilter);
|
||||||
if (index < scroller.getComponentCount() - 1) {
|
if (index < panel.getComponentCount() - 1) {
|
||||||
Filter nextFilter = (Filter)scroller.getComponent(index + 1);
|
Filter nextFilter = (Filter)panel.getComponent(index + 1);
|
||||||
model.removeFilterControl(nextFilter);
|
model.removeFilterControl(nextFilter);
|
||||||
scroller.remove(nextFilter);
|
panel.remove(nextFilter);
|
||||||
scroller.revalidate();
|
panel.revalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,13 +156,14 @@ public class AdvancedSearchFilter<T extends InventoryItem> extends ItemFilter<T>
|
|||||||
|
|
||||||
private Filter() {
|
private Filter() {
|
||||||
super(null);
|
super(null);
|
||||||
|
setOpaque(false);
|
||||||
|
|
||||||
btnNotBeforeParen = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("NOT").selectable().build();
|
btnNotBeforeParen = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("NOT").hoverable().selectable().build();
|
||||||
btnOpenParen = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("(").selectable().build();
|
btnOpenParen = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("(").hoverable().selectable().build();
|
||||||
btnNotAfterParen = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("NOT").selectable().build();
|
btnNotAfterParen = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("NOT").hoverable().selectable().build();
|
||||||
btnFilter = new FLabel.ButtonBuilder().build();
|
btnFilter = new FLabel.ButtonBuilder().build();
|
||||||
btnCloseParen = new FLabel.Builder().fontAlign(SwingConstants.CENTER).selectable().text(")").build();
|
btnCloseParen = new FLabel.Builder().fontAlign(SwingConstants.CENTER).hoverable().selectable().text(")").build();
|
||||||
btnAnd = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("AND").selectable().cmdClick(new UiCommand() {
|
btnAnd = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("AND").hoverable().selectable().cmdClick(new UiCommand() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (btnAnd.isSelected()) {
|
if (btnAnd.isSelected()) {
|
||||||
@@ -168,7 +175,7 @@ public class AdvancedSearchFilter<T extends InventoryItem> extends ItemFilter<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).build();
|
}).build();
|
||||||
btnOr = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("OR").selectable().cmdClick(new UiCommand() {
|
btnOr = new FLabel.Builder().fontAlign(SwingConstants.CENTER).text("OR").hoverable().selectable().cmdClick(new UiCommand() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (btnOr.isSelected()) {
|
if (btnOr.isSelected()) {
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ All Net Deck categories should now find decks and won't stop returning decks whe
|
|||||||
A new "Download Achievement Images" button has been added to Content Downloaders for downloading awesome trophies for each achievement.
|
A new "Download Achievement Images" button has been added to Content Downloaders for downloading awesome trophies for each achievement.
|
||||||
|
|
||||||
|
|
||||||
|
- Advanced Search in Card and Deck managers -
|
||||||
|
"Filter" button replaced with smaller button with search icon
|
||||||
|
When click, Add Filter > Advanced... will open Advanced Search dialog which will allow configuring an advanced search filter using any combination of filter options and operators, connected in an easy to build boolean expression.
|
||||||
|
|
||||||
|
|
||||||
- Keyboard shortcuts for Auto Yield -
|
- Keyboard shortcuts for Auto Yield -
|
||||||
There are two new keyboard shortcuts now that can be used to quickly set up an
|
There are two new keyboard shortcuts now that can be used to quickly set up an
|
||||||
auto-yield for the current ability on stack without having to use the mouse.
|
auto-yield for the current ability on stack without having to use the mouse.
|
||||||
|
|||||||
Reference in New Issue
Block a user