Skip to content

Commit

Permalink
Start writing javadocs - autcomplete done
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredlll08 committed May 6, 2023
1 parent ceb92c9 commit b7b66bb
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 31 deletions.
@@ -1,11 +1,14 @@
package com.blamejared.searchables.api;

import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;

public class SearchablesConstants {

public static final String MOD_ID = "searchables";

public static final Component COMPONENT_SEARCH = Component.translatable("options.search");

public static ResourceLocation rl(final String path) {

return new ResourceLocation(MOD_ID, path);
Expand Down
Expand Up @@ -13,6 +13,11 @@
import java.util.*;
import java.util.function.*;

/**
* A small widget that displays current suggestions for an {@link AutoCompletingEditBox<T>}.
*
* @param <T> The type of element that is being searched for.
*/
public class AutoComplete<T> extends AbstractWidget implements Consumer<String> {

private final SearchableType<T> type;
Expand All @@ -28,11 +33,34 @@ public class AutoComplete<T> extends AbstractWidget implements Consumer<String>
private final Vector2d lastMousePosition;
private int lastCursorPosition;

/**
* Create a new AutoComplete with the given values and a {@code maxSuggestion} size of 7
*
* @param type The {@link SearchableType<T>} that this {@link AutoComplete<T>} completes for.
* @param editBox The attached {@link AutoCompletingEditBox<T>} that this {@link AutoComplete<T>} is attached to.
* @param entries The entries that should be used for completion.
* @param x The x position of this widget on the screen.
* @param y The y position of this widget on the screen.
* @param width The width of this widget on the screen.
* @param suggestionHeight The height of each individual suggestion. Recommended to be {@code Font#lineHeight + 2}
*/
public AutoComplete(SearchableType<T> type, AutoCompletingEditBox<T> editBox, Supplier<List<T>> entries, int x, int y, int width, int suggestionHeight) {

this(type, editBox, entries, x, y, width, suggestionHeight, 7);
}

/**
* Create a new AutoComplete with the given values.
*
* @param type The {@link SearchableType<T>} that this {@link AutoComplete<T>} completes for.
* @param editBox The attached {@link AutoCompletingEditBox<T>} that this {@link AutoComplete<T>} is attached to.
* @param entries The entries that should be used for completion.
* @param x The x position of this widget on the screen.
* @param y The y position of this widget on the screen.
* @param width The width of this widget on the screen.
* @param suggestionHeight The height of each individual suggestion.
* @param maxSuggestions How many suggestions to show.
*/
public AutoComplete(SearchableType<T> type, AutoCompletingEditBox<T> editBox, Supplier<List<T>> entries, int x, int y, int width, int suggestionHeight, int maxSuggestions) {

super(x, y, width, suggestionHeight * maxSuggestions, Component.empty());
Expand All @@ -48,6 +76,11 @@ public AutoComplete(SearchableType<T> type, AutoCompletingEditBox<T> editBox, Su
this.lastCursorPosition = -1;
}

/**
* Compiles suggestions for the given value.
*
* @param value the input argument
*/
@Override
public void accept(String value) {

Expand Down Expand Up @@ -99,11 +132,17 @@ public boolean mouseClicked(double mx, double my, int mb) {
return false;
}

/**
* Inserts the currently selected suggestion into attached {@link AutoCompletingEditBox<T>}.
*/
public void insertSuggestion() {

CompletionSuggestion suggestion = this.suggestions.get(displayOffset + selectedIndex);
this.editBox.deleteChars(suggestion.replacementRange());
this.editBox.insertText(suggestion.toInsert());
int index = displayOffset + selectedIndex;
if(index >= 0 && index < this.suggestions.size()) {
CompletionSuggestion suggestion = this.suggestions.get(index);
this.editBox.deleteChars(suggestion.replacementRange());
this.editBox.insertText(suggestion.toInsert());
}
}

@Override
Expand All @@ -126,7 +165,7 @@ public void renderWidget(PoseStack pose, int mx, int my, float partial) {
this.lastMousePosition.set(mx, my);
}

public void updateHoveringState(double xpos, double ypos) {
private void updateHoveringState(double xpos, double ypos) {

if(!lastMousePosition.equals(xpos, ypos)) {
selectedIndex = -1;
Expand All @@ -143,27 +182,43 @@ public void updateHoveringState(double xpos, double ypos) {
}
}

/**
* Scrolls the current suggestions up by 1.
*/
public void scrollUp() {

this.scrollUp(1);
}

/**
* Scrolls the current suggestions up by the given amount.
*
* @param amount The amount to scroll by.
*/
public void scrollUp(int amount) {

this.offsetDisplay(this.selectedIndex - amount);
}

/**
* Scrolls the current suggestions down by 1.
*/
public void scrollDown() {

this.scrollDown(1);
}

/**
* Scrolls the current suggestions down by the given amount.
*
* @param amount The amount to scroll by.
*/
public void scrollDown(int amount) {

this.offsetDisplay(this.selectedIndex + amount);
}

public void offsetDisplay(int offset) {
private void offsetDisplay(int offset) {

offset = Mth.clamp(offset, 0, shownSuggestions() - 1);
final int halfSuggestions = Math.floorDiv(maxSuggestions, 2);
Expand All @@ -176,7 +231,7 @@ public void offsetDisplay(int offset) {
this.selectedIndex = currentItem - this.displayOffset;
}

public int shownSuggestions() {
private int shownSuggestions() {

return Math.min(maxSuggestions, suggestions.size());
}
Expand All @@ -193,7 +248,7 @@ public AutoCompletingEditBox<T> editBox() {

@Override
protected void updateWidgetNarration(NarrationElementOutput output) {

//TODO I am not sure what this should actually do.
}

}
@@ -1,7 +1,6 @@
package com.blamejared.searchables.api.autcomplete;

import com.blamejared.searchables.api.SearchableType;
import com.blamejared.searchables.api.TokenRange;
import com.blamejared.searchables.api.*;
import com.blamejared.searchables.api.formatter.FormattingVisitor;
import com.blamejared.searchables.mixin.AccessEditBox;
import net.minecraft.client.gui.Font;
Expand All @@ -10,11 +9,8 @@
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.*;
import java.util.function.*;

public class AutoCompletingEditBox<T> extends EditBox {

Expand All @@ -33,10 +29,10 @@ public AutoCompletingEditBox(Font font, int x, int y, int width, int height, @Nu
super(font, x, y, width, height, thisBox, message);
this.formattingVisitor = new FormattingVisitor(type);
this.completionVisitor = new CompletionVisitor();
this.autoComplete = new AutoComplete<>(type, this, entries, x, y + 2 + height, width, (font.lineHeight + 2));
setHint(Component.translatable("options.search"));
this.setFormatter(formattingVisitor);
this.setResponder(responders);
this.autoComplete = new AutoComplete<>(type, this, entries, x, y + 2 + height, width, font.lineHeight + 2);
setHint(SearchablesConstants.COMPONENT_SEARCH);
this.setFormatter(this.formattingVisitor);
this.setResponder(this.responders);
addResponder(this.formattingVisitor);
addResponder(this.completionVisitor);
addResponder(this.autoComplete);
Expand Down Expand Up @@ -83,6 +79,11 @@ public boolean keyPressed(int key, int scancode, int mods) {
return super.keyPressed(key, scancode, mods);
}

/**
* Deletes the characters as the given {@link TokenRange}.
*
* @param range The range to delete characters from
*/
public void deleteChars(TokenRange range) {

if(!this.getValue().isEmpty()) {
Expand All @@ -107,7 +108,12 @@ public Consumer<String> getResponder() {
return ((AccessEditBox) this).searchables$getResponder();
}

/**
* Should not be used, use {@link AutoCompletingEditBox#addResponder(Consumer)} instead
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Override
@Deprecated
public void setResponder(Consumer<String> responder) {

if(this.getResponder() == null) {
Expand Down
Expand Up @@ -3,13 +3,33 @@
import com.blamejared.searchables.api.TokenRange;
import net.minecraft.network.chat.Component;

/**
* Represents a suggestion to be shown in {@link AutoComplete}
*
* @param suggestion The suggestion to insert.
* @param display The component to display to the user.
* @param suffix The text to insert of the {@code suggestion}. Generally either {@literal ":"} or {@literal " "}
* @param replacementRange The range of the current String to replace with this suggestion. Given the string {@code "sha"} and suggestion of {@code "shape"}, the range will be {@code TokenRange(0, 5)}
*/
public record CompletionSuggestion(String suggestion, Component display, String suffix, TokenRange replacementRange) {

/**
* Inserts the suggestion into the given string.
*
* @param into The string to insert into.
*
* @return The given string with this suggestion inserted into it.
*/
public String replaceIn(final String into) {

return replacementRange.replace(into, toInsert());
}

/**
* Gets the string to insert, combining the suggestion and the suffix.
*
* @return The string to insert.
*/
public String toInsert() {

return suggestion + suffix;
Expand Down
Expand Up @@ -8,26 +8,34 @@
import java.util.*;
import java.util.function.Consumer;

/**
* Generates a list of TokenRanges that can be used to split a given string into parts.
* Mainly used to split strings for completion purposes.
*/
public class CompletionVisitor implements Visitor<TokenRange>, Consumer<String> {

private final List<TokenRange> tokens = new ArrayList<>();
private TokenRange lastRange = TokenRange.EMPTY;

/**
* Resets this visitor to a state that allows it to run again.
*/
public void reset() {

tokens.clear();
lastRange = TokenRange.EMPTY;
}

public List<TokenRange> tokens() {

return tokens;
}

public void reduceTokens() {

//TODO look into if this is even needed or if it can be done while visiting

/**
* Reduces the tokens into their outermost parts.
* For example the string {@code "shape:square color:red"} will be split into:
* {@code [
* TokenRange(0, 12, [TokenRange(0, 5), TokenRange(5, 6), TokenRange(6, 12)]),
* TokenRange(13, 22, [TokenRange(13, 18), TokenRange(18, 19), TokenRange(19, 22)])
* ]}
*/
protected void reduceTokens() {
// Can this be done while visiting?
ListIterator<TokenRange> iterator = tokens.listIterator(tokens.size());
TokenRange lastRange = null;
while(iterator.hasPrevious()) {
Expand All @@ -45,13 +53,37 @@ public void reduceTokens() {
}
}

/**
* Gets the tokens in this visitor.
*
* @return The tokens in this visitor.
*/
public List<TokenRange> tokens() {

return tokens;
}

/**
* Gets the {@link Optional<TokenRange>} at the given position.
*
* @param position The current cursor position.
*
* @return An {@link Optional<TokenRange>} at the given range, or an empty optional if out of bounds.
*/
public Optional<TokenRange> tokenAt(final int position) {

return tokens.stream()
.filter(range -> range.contains(position))
.findFirst();
}

/**
* Gets the {@link TokenRange} at the given position, or {@link TokenRange#EMPTY} if out of bounds.
*
* @param position The current cursor position.
*
* @return An {@link TokenRange} at the given range, or {@link TokenRange#EMPTY} if out of bounds.
*/
public TokenRange rangeAt(final int position) {

return tokenAt(position).orElse(TokenRange.EMPTY);
Expand Down Expand Up @@ -107,6 +139,11 @@ private TokenRange getAndPushRange(final int end) {
return TokenRange.between(oldRange.end(), oldRange.end() + end);
}

/**
* Resets this visitor and compiles a list of {@link TokenRange} from the given String
*
* @param search The string to search
*/
@Override
public void accept(final String search) {

Expand All @@ -115,7 +152,7 @@ public void accept(final String search) {
}

@Override
public TokenRange postVisit(TokenRange obj) {
public TokenRange postVisit(final TokenRange obj) {

this.reduceTokens();
return Visitor.super.postVisit(obj);
Expand Down
Expand Up @@ -4,10 +4,8 @@
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;

import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.*;

@Mixin(EditBox.class)
public interface AccessEditBox {
Expand Down

0 comments on commit b7b66bb

Please sign in to comment.