Searchables is a library mod that adds helper methods that allow for searching and filtering elements based on components (shape:square color:red
), as well as offering built in auto-complete functionality.
Assuming you have the following code structure, which defines a Shape
object and a list of Shapes:
public record Shape(String name, String type, String colour) {}
public static final List<Shape> SHAPES = List.of(
new Shape("one", "square", "red"),
new Shape("two", "square", "dark blue"),
new Shape("three", "circle", "red"),
new Shape("four", "triangle", "yellow")
);
You may want to be able to filter that list of Shapes to find specific shapes or shapes that meet certain criteria.
To do this, you can define a SearchableType<Shape>
object like so:
public static final SearchableType<Shape> SHAPE = new SearchableType.Builder<Shape>() // Starts a builder
.defaultComponent(SearchableComponent.create("name", shape -> Optional.of(shape.name()))) // Sets the name of the shape as the default component
.component(SearchableComponent.create("type", shape -> Optional.of(shape.type()))) // Adds a new component for the type of the shape
.component(SearchableComponent.create("color", shape -> Optional.of(shape.colour()))) // Adds a new component for the color of the shape
.build();
Once you have a SearchableType
, you are able to perform searches like so:
SHAPE.filterEntries(SHAPES, "one"); // Returns a list with a single entry of Shape("one", "square", "red") - When searching for a default component, you don't need to specify the key
SHAPE.filterEntries(SHAPES, "color:red"); // Returns a list with the entries, Shape("one", "square", "red") and Shape("three", "circle", "red")
SHAPE.filterEntries(SHAPES, "one color:red"); // Returns a list with a single entry of Shape("one", "square", "red")
SHAPE.filterEntries(SHAPES, "color:red one"); // Returns a list with a single entry of Shape("one", "square", "red") - The search itself can be in any order
SHAPE.filterEntries(SHAPES, "color:'dark blue'"); // Returns a list with a single entry of Shape("two", "square", "dark blue") - terms with spaces, or quote characters need to be quoted - valid quote characters are '"`
Auto complete is done using a custom EditBox
class, AutoCompletingEditBox
, like so:
public class MyScreen extends Screen {
private AutoCompletingEditBox<TestConstants.Shape> search;
protected MyScreen(Component title) {
super(title);
}
@Override
protected void init() {
super.init();
this.search = addRenderableWidget(new AutoCompletingEditBox<>(
font, // The Font used for rendering text
width / 2 - 75, // x
22, // y
Button.DEFAULT_WIDTH, // width
Button.DEFAULT_HEIGHT, // height
search, // This box - Used when init is re-run to carry over the old value
SearchablesConstants.COMPONENT_SEARCH, // Message to display when the search is empty and unfocused
TestConstants.SHAPE, // The SearchableType that will be searched
() -> TestConstants.SHAPES)); // Supplier for the elements - used for auto complete
this.search.addResponder(this::filter); // Adds a responder to the search to filter the elements on every change in the EditBox
}
@Override
public void render(GuiGraphics guiGraphics, int mxPos, int myPos, float partialTicks) {
super.render(guiGraphics, mxPos, myPos, partialTicks);
this.search.autoComplete().render(guiGraphics, mxPos, myPos, partialTicks); // Render the autocomplete above other elements
}
@Override
public boolean mouseScrolled(double xpos, double ypos, double xDelta, double yDelta) {
// This is required to be able to scroll on the autocomplete widget to scroll
if(search.autoComplete().mouseScrolled(xpos, ypos, yDelta)) {
return true;
}
return super.mouseScrolled(xpos, ypos, yDelta);
}
}
If you're looking for help with the mod, or just want to come hang out, we have a Discord server.
If you're running into a bug or have a feature request, please don't be afraid to make an issue on the tracker.
Distributed under the MIT License. See the LICENSE file for more information.
To set up the Searchables development environment you must clone the repo.
git clone https://github.com/jaredlll08/searchables.git
After the project has been cloned and initialized you can directly import it into your IDE of choice.
Building the project is as easy as running a Gradle command! Simply run:
gradlew build
and the outputted .jar
files will be put in build/libs/
folder of each subproject (common/build/libs/
, fabric/build/libs/
and forge/build/libs/
).
Every push to this repository is built and published to the BlameJared maven, to use these builds in your project, first add the BlameJared maven to your repositories
block in your build.gradle file like so:
repositories {
maven {
url = 'https://maven.blamejared.com'
name = 'BlameJared Maven'
}
}
Then, depending on what modloader you are using, you can use the following snippets, just replace [VERSION]
with the latest version for each artifact.
dependencies {
modImplementation("com.blamejared.searchables:Searchables-fabric-1.20.5:[VERSION]")
// Example:
// modImplementation("com.blamejared.searchables:Searchables-fabric-1.20.5:1.0.0")
}
dependencies {
compileOnly(fg.deobf("com.blamejared.searchables:Searchables-forge-1.20.5:[VERSION]"))
// Example:
// implementation(fg.deobf("com.blamejared.searchables:Searchables-forge-1.20.5:1.0.0"))
}
If you are in a multi-modloader environment (Such as MultiLoader), you can bring the Common artifact (code that does not depend on any specific mod loader but rather just the vanilla game) into your Common project like so:
dependencies {
compileOnly("com.blamejared.searchables:Searchables-common-1.20.5:[VERSION]")
// Example:
// compileOnly("com.blamejared.searchables:Searchables-common-1.20.5:1.0.0")
}