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/IUpdateable.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/ColumnDef.java -text
|
||||
forge-gui/src/main/java/forge/itemmanager/GroupDef.java -text
|
||||
|
||||
@@ -29,17 +29,7 @@ public enum ComparableOp {
|
||||
GREATER_THAN(">"),
|
||||
LESS_THAN("<"),
|
||||
GT_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
|
||||
};
|
||||
LT_OR_EQUAL("<=");
|
||||
|
||||
private final String caption;
|
||||
|
||||
|
||||
@@ -12,11 +12,8 @@ import forge.assets.FSkinImage;
|
||||
import forge.item.PaperCard;
|
||||
import forge.itemmanager.BooleanExpression.Operator;
|
||||
import forge.itemmanager.ItemManager;
|
||||
import forge.menu.FMenuItem;
|
||||
import forge.menu.FPopupMenu;
|
||||
import forge.menu.FTooltip;
|
||||
import forge.screens.FScreen;
|
||||
import forge.toolbox.FComboBox;
|
||||
import forge.toolbox.FContainer;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.toolbox.FEvent;
|
||||
@@ -25,7 +22,6 @@ import forge.toolbox.FScrollPane;
|
||||
import forge.toolbox.FTextField;
|
||||
import forge.toolbox.FEvent.FEventHandler;
|
||||
import forge.toolbox.FLabel;
|
||||
import forge.util.ComparableOp;
|
||||
|
||||
|
||||
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 final FLabel btnNotBeforeParen, btnOpenParen, btnNotAfterParen;
|
||||
private final FComboBox<FilterOption> cbFilter;
|
||||
private final FComboBox<ComparableOp> cbFilterOperator;
|
||||
private final FTextField txtFilterValue;
|
||||
private final FLabel btnFilter;
|
||||
private final FLabel btnCloseParen, btnAnd, btnOr;
|
||||
|
||||
private Filter() {
|
||||
@@ -292,17 +256,11 @@ public class CardAdvancedFilter extends ItemFilter<PaperCard> {
|
||||
btnOpenParen = add(new FLabel.Builder().align(HAlignment.CENTER).text("(").selectable().build());
|
||||
btnNotAfterParen = add(new FLabel.Builder().align(HAlignment.CENTER).text("NOT").selectable().build());
|
||||
|
||||
cbFilter = add(new FComboBox<FilterOption>(FilterOption.values()));
|
||||
cbFilter.setChangedHandler(new FEventHandler() {
|
||||
btnFilter = add(new FLabel.ButtonBuilder().text("Select Filter...").command(new FEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(FEvent e) {
|
||||
FilterOption filterOption = cbFilter.getSelectedItem();
|
||||
cbFilterOperator.setItems(filterOption.availableOps, filterOption.defaultOp);
|
||||
txtFilterValue.setText(filterOption.min == -1 ? "" : String.valueOf(filterOption.min));
|
||||
}
|
||||
});
|
||||
cbFilterOperator = add(new FComboBox<ComparableOp>());
|
||||
txtFilterValue = add(new FTextField());
|
||||
}).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() {
|
||||
@@ -334,19 +292,28 @@ public class CardAdvancedFilter extends ItemFilter<PaperCard> {
|
||||
@Override
|
||||
protected void doLayout(float width, float height) {
|
||||
float padding = FList.PADDING;
|
||||
float controlWidth = (width - padding * 4) / 3;
|
||||
float controlHeight = (height - padding * 3) / 3;
|
||||
float buttonWidth = (width - padding * 4) / 3;
|
||||
float buttonHeight = (height - padding * 3) / 3;
|
||||
|
||||
float x = padding;
|
||||
float y = padding;
|
||||
for (FDisplayObject obj : getChildren()) {
|
||||
obj.setBounds(x, y, controlWidth, controlHeight);
|
||||
x += controlWidth + padding;
|
||||
if (x > width - controlWidth) {
|
||||
float dx = buttonWidth + padding;
|
||||
float dy = buttonHeight + padding;
|
||||
|
||||
btnNotBeforeParen.setBounds(x, y, buttonWidth, buttonHeight);
|
||||
x += dx;
|
||||
btnOpenParen.setBounds(x, y, buttonWidth, buttonHeight);
|
||||
x += dx;
|
||||
btnNotAfterParen.setBounds(x, y, buttonWidth, buttonHeight);
|
||||
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