Skip to content

Add TextFieldWidget::setFormatAsInteger #145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/main/java/com/cleanroommc/modularui/test/TestTile.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class TestTile extends TileEntity implements IGuiHolder<PosGuiData>, ITic
private long time = 0;
private int val, val2 = 0;
private String value = "";
private int intValue = 1234567;
private double doubleValue = 1;
private final int duration = 80;
private int progress = 0;
Expand Down Expand Up @@ -221,8 +222,17 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager,
.child(new FluidSlot()
.margin(2)
.width(30)
.syncHandler(SyncHandlers.fluidSlot(this.fluidTankPhantom).phantom(true)))
)))
.syncHandler(SyncHandlers.fluidSlot(this.fluidTankPhantom).phantom(true))))
.child(new Column()
.debugName("button and slots test 3")
.coverChildren()
.alignY(Alignment.START)
.child(new TextFieldWidget()
.size(60, 20)
.value(SyncHandlers.intNumber(() -> this.intValue, val -> this.intValue = val))
.setNumbers(0, 9999999)
.setFormatAsInteger(true)
.hintText("integer")))))
.addPage(new Column()
.debugName("Slots test page")
.coverChildren()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,30 @@
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

import java.awt.*;
import java.awt.geom.Point2D;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class TextFieldRenderer extends TextRenderer {
private static final DecimalFormat INTEGER_FIELD_FORMAT = new DecimalFormat("#");
private static final char groupingSeparator = INTEGER_FIELD_FORMAT.getDecimalFormatSymbols().getGroupingSeparator();

static {
INTEGER_FIELD_FORMAT.setGroupingUsed(true);
INTEGER_FIELD_FORMAT.setGroupingSize(3);
}

protected final TextFieldHandler handler;
protected int markedColor = 0x2F72A8;
protected int cursorColor = 0xFFFFFFFF;
protected boolean renderCursor = false;
private boolean formatAsInteger = false;

public TextFieldRenderer(TextFieldHandler handler) {
this.handler = handler;
Expand All @@ -42,6 +55,30 @@ public void setCursorColor(int cursorColor) {
this.cursorColor = cursorColor;
}

@ApiStatus.Experimental
public void setFormatAsInteger(boolean formatAsInteger) {
this.formatAsInteger = formatAsInteger;
}

@Override
public void draw(List<String> lines) {
if (formatAsInteger) lines = decorateLines(lines);
super.draw(lines);
}

private static @NotNull List<String> decorateLines(List<String> lines) {
return lines.stream().map(TextFieldRenderer::tryFormatString)
.collect(Collectors.toList());
}

private static @NotNull String tryFormatString(String str) {
try {
return INTEGER_FIELD_FORMAT.format(Long.parseLong(str));
} catch (NumberFormatException e) {
return str;
}
}

@Override
protected void drawMeasuredLines(List<Line> measuredLines) {
drawMarked(measuredLines);
Expand Down Expand Up @@ -96,39 +133,79 @@ public Point getCursorPos(List<String> lines, int x, int y) {
if (lines.isEmpty()) {
return new Point();
}
if (formatAsInteger) lines = decorateLines(lines);
List<Line> measuredLines = measureLines(lines);
y -= getStartY(measuredLines.size());
int index = (int) (y / (getFontHeight()));
if (index < 0) return new Point();
if (index >= measuredLines.size())
return new Point(measuredLines.get(measuredLines.size() - 1).getText().length(), measuredLines.size() - 1);
if (index >= measuredLines.size()) {
return new Point(getRealLength(measuredLines.get(measuredLines.size() - 1).getText()), measuredLines.size() - 1);
}
Line line = measuredLines.get(index);
x -= getStartX(line.getWidth());
if (line.getWidth() <= 0) return new Point(0, index);
if (line.getWidth() < x) return new Point(line.getText().length(), index);
if (line.getWidth() < x) {
return new Point(getRealLength(line.getText()), index);
}
float currentX = 0;
int ignoredChars = 0;
for (int i = 0; i < line.getText().length(); i++) {
char c = line.getText().charAt(i);
float charWidth = getFontRenderer().getCharWidth(c) * this.scale;
currentX += charWidth;
if (isIgnoredChar(c)) ignoredChars++;
if (currentX >= x) {
// dist with current letter < dist without current letter -> next letter pos
if (Math.abs(currentX - x) < Math.abs(currentX - charWidth - x)) i++;
return new Point(i, index);
return new Point(i - ignoredChars, index);
}
}
return new Point();
}

/**
* Whether the given character should be ignored for cursor positioning purposes
*/
@ApiStatus.Experimental
protected boolean isIgnoredChar(int c) {
return formatAsInteger && c == groupingSeparator;
}

private int getRealLength(String text) {
int length = text.length();
if (formatAsInteger) length -= (int) text.chars().filter(this::isIgnoredChar).count();
return length;
}

public Point2D.Float getPosOf(List<Line> measuredLines, Point cursorPos) {
if (measuredLines.isEmpty()) {
return new Point2D.Float(getStartX(0), getStartYOfLines(1));
}
Line line = measuredLines.get(cursorPos.y);
String sub = line.getText().substring(0, Math.min(line.getText().length(), cursorPos.x));
String sub = getStringBeforeCursor(line, cursorPos);
return new Point2D.Float(getStartX(line.getWidth()) + getFontRenderer().getStringWidth(sub) * this.scale, getStartYOfLines(measuredLines.size()) + cursorPos.y * getFontHeight());
}

private @NotNull String getStringBeforeCursor(Line line, Point cursorPos) {
String text = line.getText();
String sub = text.substring(0, Math.min(text.length(), cursorPos.x));
if (formatAsInteger) {
int i = 0;
int ignoredChars = 0;
while (i < sub.length() && i + ignoredChars < text.length()) {
if (isIgnoredChar(text.charAt(i + ignoredChars))) {
ignoredChars++;
} else {
i++;
}
}
if (ignoredChars > 0) {
sub = sub + text.substring(sub.length(), Math.min(text.length(), cursorPos.x + ignoredChars));
}
}
return sub;
}

@SideOnly(Side.CLIENT)
public void drawMarked(float y0, float x0, float x1) {
y0 -= 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.cleanroommc.modularui.value.sync.SyncHandler;
import com.cleanroommc.modularui.value.sync.ValueSyncHandler;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

import java.awt.*;
Expand Down Expand Up @@ -232,6 +233,12 @@ public TextFieldWidget setDefaultNumber(double defaultNumber) {
return this;
}

@ApiStatus.Experimental
public TextFieldWidget setFormatAsInteger(boolean formatAsInteger) {
this.renderer.setFormatAsInteger(formatAsInteger);
return getThis();
}

public TextFieldWidget value(IStringValue<?> stringValue) {
this.stringValue = stringValue;
setValue(stringValue);
Expand Down