mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Rework how advanced searches are built
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -17861,6 +17861,7 @@ forge-gui/src/main/java/forge/interfaces/ITextComponent.java -text
|
|||||||
forge-gui/src/main/java/forge/interfaces/ITextField.java -text
|
forge-gui/src/main/java/forge/interfaces/ITextField.java -text
|
||||||
forge-gui/src/main/java/forge/interfaces/IUpdateable.java -text
|
forge-gui/src/main/java/forge/interfaces/IUpdateable.java -text
|
||||||
forge-gui/src/main/java/forge/interfaces/IWinLoseView.java -text
|
forge-gui/src/main/java/forge/interfaces/IWinLoseView.java -text
|
||||||
|
forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java -text
|
||||||
forge-gui/src/main/java/forge/itemmanager/BooleanExpression.java -text
|
forge-gui/src/main/java/forge/itemmanager/BooleanExpression.java -text
|
||||||
forge-gui/src/main/java/forge/itemmanager/ColumnDef.java -text
|
forge-gui/src/main/java/forge/itemmanager/ColumnDef.java -text
|
||||||
forge-gui/src/main/java/forge/itemmanager/GroupDef.java -text
|
forge-gui/src/main/java/forge/itemmanager/GroupDef.java -text
|
||||||
|
|||||||
@@ -29,17 +29,7 @@ public enum ComparableOp {
|
|||||||
GREATER_THAN(">"),
|
GREATER_THAN(">"),
|
||||||
LESS_THAN("<"),
|
LESS_THAN("<"),
|
||||||
GT_OR_EQUAL(">="),
|
GT_OR_EQUAL(">="),
|
||||||
LT_OR_EQUAL("<="),
|
LT_OR_EQUAL("<=");
|
||||||
CONTAINS("contains"),
|
|
||||||
STARTS_WITH("starts with"),
|
|
||||||
ENDS_WITH("ends with");
|
|
||||||
|
|
||||||
public static final ComparableOp[] NUMBER_OPS = new ComparableOp[] {
|
|
||||||
EQUALS, NOT_EQUALS, GREATER_THAN, LESS_THAN, GT_OR_EQUAL, LT_OR_EQUAL
|
|
||||||
};
|
|
||||||
public static final ComparableOp[] STRING_OPS = new ComparableOp[] {
|
|
||||||
CONTAINS, STARTS_WITH, ENDS_WITH
|
|
||||||
};
|
|
||||||
|
|
||||||
private final String caption;
|
private final String caption;
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,8 @@ import forge.assets.FSkinImage;
|
|||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.itemmanager.BooleanExpression.Operator;
|
import forge.itemmanager.BooleanExpression.Operator;
|
||||||
import forge.itemmanager.ItemManager;
|
import forge.itemmanager.ItemManager;
|
||||||
import forge.menu.FMenuItem;
|
|
||||||
import forge.menu.FPopupMenu;
|
|
||||||
import forge.menu.FTooltip;
|
import forge.menu.FTooltip;
|
||||||
import forge.screens.FScreen;
|
import forge.screens.FScreen;
|
||||||
import forge.toolbox.FComboBox;
|
|
||||||
import forge.toolbox.FContainer;
|
import forge.toolbox.FContainer;
|
||||||
import forge.toolbox.FDisplayObject;
|
import forge.toolbox.FDisplayObject;
|
||||||
import forge.toolbox.FEvent;
|
import forge.toolbox.FEvent;
|
||||||
@@ -25,7 +22,6 @@ import forge.toolbox.FScrollPane;
|
|||||||
import forge.toolbox.FTextField;
|
import forge.toolbox.FTextField;
|
||||||
import forge.toolbox.FEvent.FEventHandler;
|
import forge.toolbox.FEvent.FEventHandler;
|
||||||
import forge.toolbox.FLabel;
|
import forge.toolbox.FLabel;
|
||||||
import forge.util.ComparableOp;
|
|
||||||
|
|
||||||
|
|
||||||
public class CardAdvancedFilter extends ItemFilter<PaperCard> {
|
public class CardAdvancedFilter extends ItemFilter<PaperCard> {
|
||||||
@@ -250,41 +246,9 @@ public class CardAdvancedFilter extends ItemFilter<PaperCard> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum FilterOption {
|
|
||||||
NONE("Filter...", null, null, -1, -1),
|
|
||||||
CMC("CMC", ComparableOp.NUMBER_OPS, ComparableOp.EQUALS, 0, 20),
|
|
||||||
COLORLESS_COST("Colorless Cost", ComparableOp.NUMBER_OPS, ComparableOp.EQUALS, 0, 20),
|
|
||||||
POWER("Power", ComparableOp.NUMBER_OPS, ComparableOp.EQUALS, 0, 20),
|
|
||||||
TOUGHNESS("Toughness", ComparableOp.NUMBER_OPS, ComparableOp.EQUALS, 0, 20),
|
|
||||||
NAME("Name", ComparableOp.STRING_OPS, ComparableOp.CONTAINS, -1, -1),
|
|
||||||
TYPE("Type", ComparableOp.STRING_OPS, ComparableOp.CONTAINS, -1, -1),
|
|
||||||
RULES_TEXT("Rules Text", ComparableOp.STRING_OPS, ComparableOp.CONTAINS, -1, -1),
|
|
||||||
MANA_COST("Mana Cost", ComparableOp.STRING_OPS, ComparableOp.EQUALS, -1, -1);
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final ComparableOp[] availableOps;
|
|
||||||
private final ComparableOp defaultOp;
|
|
||||||
private final int min, max;
|
|
||||||
|
|
||||||
private FilterOption(String name0, ComparableOp[] availableOps0, ComparableOp defaultOp0, int min0, int max0) {
|
|
||||||
name = name0;
|
|
||||||
availableOps = availableOps0;
|
|
||||||
defaultOp = defaultOp0;
|
|
||||||
min = min0;
|
|
||||||
max = max0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Filter extends FContainer {
|
private class Filter extends FContainer {
|
||||||
private final FLabel btnNotBeforeParen, btnOpenParen, btnNotAfterParen;
|
private final FLabel btnNotBeforeParen, btnOpenParen, btnNotAfterParen;
|
||||||
private final FComboBox<FilterOption> cbFilter;
|
private final FLabel btnFilter;
|
||||||
private final FComboBox<ComparableOp> cbFilterOperator;
|
|
||||||
private final FTextField txtFilterValue;
|
|
||||||
private final FLabel btnCloseParen, btnAnd, btnOr;
|
private final FLabel btnCloseParen, btnAnd, btnOr;
|
||||||
|
|
||||||
private Filter() {
|
private Filter() {
|
||||||
@@ -292,17 +256,11 @@ public class CardAdvancedFilter extends ItemFilter<PaperCard> {
|
|||||||
btnOpenParen = add(new FLabel.Builder().align(HAlignment.CENTER).text("(").selectable().build());
|
btnOpenParen = add(new FLabel.Builder().align(HAlignment.CENTER).text("(").selectable().build());
|
||||||
btnNotAfterParen = add(new FLabel.Builder().align(HAlignment.CENTER).text("NOT").selectable().build());
|
btnNotAfterParen = add(new FLabel.Builder().align(HAlignment.CENTER).text("NOT").selectable().build());
|
||||||
|
|
||||||
cbFilter = add(new FComboBox<FilterOption>(FilterOption.values()));
|
btnFilter = add(new FLabel.ButtonBuilder().text("Select Filter...").command(new FEventHandler() {
|
||||||
cbFilter.setChangedHandler(new FEventHandler() {
|
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
FilterOption filterOption = cbFilter.getSelectedItem();
|
|
||||||
cbFilterOperator.setItems(filterOption.availableOps, filterOption.defaultOp);
|
|
||||||
txtFilterValue.setText(filterOption.min == -1 ? "" : String.valueOf(filterOption.min));
|
|
||||||
}
|
}
|
||||||
});
|
}).build());
|
||||||
cbFilterOperator = add(new FComboBox<ComparableOp>());
|
|
||||||
txtFilterValue = add(new FTextField());
|
|
||||||
|
|
||||||
btnCloseParen = add(new FLabel.Builder().align(HAlignment.CENTER).selectable().text(")").build());
|
btnCloseParen = add(new FLabel.Builder().align(HAlignment.CENTER).selectable().text(")").build());
|
||||||
btnAnd = add(new FLabel.Builder().align(HAlignment.CENTER).text("AND").selectable().command(new FEventHandler() {
|
btnAnd = add(new FLabel.Builder().align(HAlignment.CENTER).text("AND").selectable().command(new FEventHandler() {
|
||||||
@@ -334,19 +292,28 @@ public class CardAdvancedFilter extends ItemFilter<PaperCard> {
|
|||||||
@Override
|
@Override
|
||||||
protected void doLayout(float width, float height) {
|
protected void doLayout(float width, float height) {
|
||||||
float padding = FList.PADDING;
|
float padding = FList.PADDING;
|
||||||
float controlWidth = (width - padding * 4) / 3;
|
float buttonWidth = (width - padding * 4) / 3;
|
||||||
float controlHeight = (height - padding * 3) / 3;
|
float buttonHeight = (height - padding * 3) / 3;
|
||||||
|
|
||||||
float x = padding;
|
float x = padding;
|
||||||
float y = padding;
|
float y = padding;
|
||||||
for (FDisplayObject obj : getChildren()) {
|
float dx = buttonWidth + padding;
|
||||||
obj.setBounds(x, y, controlWidth, controlHeight);
|
float dy = buttonHeight + padding;
|
||||||
x += controlWidth + padding;
|
|
||||||
if (x > width - controlWidth) {
|
btnNotBeforeParen.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
|
x += dx;
|
||||||
|
btnOpenParen.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
|
x += dx;
|
||||||
|
btnNotAfterParen.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
x = padding;
|
x = padding;
|
||||||
y += controlHeight + padding;
|
y += dy;
|
||||||
}
|
btnFilter.setBounds(x, y, width - 2 * padding, buttonHeight);
|
||||||
}
|
y += dy;
|
||||||
|
btnCloseParen.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
|
x += dx;
|
||||||
|
btnAnd.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
|
x += dx;
|
||||||
|
btnOr.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
105
forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java
Normal file
105
forge-gui/src/main/java/forge/itemmanager/AdvancedSearch.java
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package forge.itemmanager;
|
||||||
|
|
||||||
|
import forge.util.gui.SGuiChoose;
|
||||||
|
|
||||||
|
public class AdvancedSearch {
|
||||||
|
|
||||||
|
private enum FilterOption {
|
||||||
|
CARD_NAME("Name", FilterOperator.STRING_OPS, -1, -1),
|
||||||
|
CARD_RULES_TEXT("Name", FilterOperator.STRING_OPS, -1, -1),
|
||||||
|
CARD_TYPE("Name", FilterOperator.STRING_OPS, -1, -1),
|
||||||
|
CARD_SUBTYPE("Name", FilterOperator.STRING_OPS, -1, -1),
|
||||||
|
CARD_CMC("CMC", FilterOperator.NUMBER_OPS, 0, 20),
|
||||||
|
CARD_GENERIC_COST("Generic Cost", FilterOperator.NUMBER_OPS, 0, 20),
|
||||||
|
POWER("Power", FilterOperator.NUMBER_OPS, 0, 20),
|
||||||
|
TOUGHNESS("Toughness", FilterOperator.NUMBER_OPS, 0, 20),
|
||||||
|
TYPE("Type", FilterOperator.STRING_OPS, -1, -1),
|
||||||
|
RULES_TEXT("Rules Text", FilterOperator.STRING_OPS, -1, -1),
|
||||||
|
MANA_COST("Mana Cost", FilterOperator.STRING_OPS, -1, -1);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final FilterOperator[] availableOps;
|
||||||
|
private final int min, max;
|
||||||
|
|
||||||
|
private FilterOption(String name0, FilterOperator[] availableOps0, int min0, int max0) {
|
||||||
|
name = name0;
|
||||||
|
availableOps = availableOps0;
|
||||||
|
min = min0;
|
||||||
|
max = max0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum FilterOperator {
|
||||||
|
//Numeric operators
|
||||||
|
EQUALS("is equal to", "{0}=={1}", 1),
|
||||||
|
NOT_EQUALS("is not equal to", "{0}!={1}", 1),
|
||||||
|
GREATER_THAN("is greater than", "{0}>{1}", 1),
|
||||||
|
LESS_THAN("is less than", "{0}<{1}", 1),
|
||||||
|
GT_OR_EQUAL("is greater than or equal to", "{0}>={1}", 1),
|
||||||
|
LT_OR_EQUAL("is less than or equal to", "{0}<={1}", 1),
|
||||||
|
BETWEEN_INCLUSIVE("is between (inclusive)", "{1}<={0}<={2}", 2),
|
||||||
|
BETWEEN_EXCLUSIVE("is between (exclusive)", "{1}<{0}<{2}", 2),
|
||||||
|
|
||||||
|
//String operators
|
||||||
|
IS("is", "{0} is '{1}'", 1),
|
||||||
|
IS_NOT("is not", "{0} is not '{1}'", 1),
|
||||||
|
CONTAINS("contains", "{0} contains '{1}'", 1),
|
||||||
|
STARTS_WITH("starts with", "{0} starts with '{1}'", 1),
|
||||||
|
ENDS_WITH("ends with", "{0} ends with '{1}'", 1),
|
||||||
|
|
||||||
|
//Custom list operators
|
||||||
|
IS_EXACTLY("is exactly", "{0} is exactly '{X}'", -1),
|
||||||
|
IS_ANY("is any of", "{0} is '{X:or}'", -1),
|
||||||
|
IS_ALL("is all of", "{0} is '{X:and}'", -1),
|
||||||
|
IS_NONE("is none of", "{0} is not '{X:or}'", -1),
|
||||||
|
INCLUDES_ANY("includes any of", "{0} includes '{X:or}'", -1),
|
||||||
|
INCLUDES_ALL("includes all of", "{0} includes '{X:and}'", -1);
|
||||||
|
|
||||||
|
public static final FilterOperator[] NUMBER_OPS = new FilterOperator[] {
|
||||||
|
EQUALS, NOT_EQUALS, GREATER_THAN, LESS_THAN, GT_OR_EQUAL, LT_OR_EQUAL, BETWEEN_INCLUSIVE, BETWEEN_EXCLUSIVE
|
||||||
|
};
|
||||||
|
public static final FilterOperator[] STRING_OPS = new FilterOperator[] {
|
||||||
|
IS, IS_NOT, CONTAINS, STARTS_WITH, ENDS_WITH
|
||||||
|
};
|
||||||
|
public static final FilterOperator[] CUSTOM_LIST_OPS = new FilterOperator[] {
|
||||||
|
IS_EXACTLY, IS_ANY, IS_ALL, IS_NONE, INCLUDES_ANY, INCLUDES_ALL
|
||||||
|
};
|
||||||
|
|
||||||
|
private final String caption, formatStr;
|
||||||
|
private final int valueCount;
|
||||||
|
|
||||||
|
private FilterOperator(String caption0, String formatStr0, int valueCount0) {
|
||||||
|
caption = caption0;
|
||||||
|
formatStr = formatStr0;
|
||||||
|
valueCount = valueCount0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static abstract class FilterType<T> {
|
||||||
|
public abstract T getValue(String message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NumberFilterType extends FilterType<Integer> {
|
||||||
|
private final int min, max;
|
||||||
|
|
||||||
|
public NumberFilterType(int min0, int max0) {
|
||||||
|
min = min0;
|
||||||
|
max = max0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getValue(String message) {
|
||||||
|
return SGuiChoose.getInteger(message, min, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user