Skip to content
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

Add "reset" and "redo" color codes #549

Open
wants to merge 3 commits into
base: main
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
5 changes: 5 additions & 0 deletions src/client/java/minicraft/gfx/Color.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public class Color {
public static final String MAGENTA_CODE = Color.toStringCode(Color.MAGENTA);
public static final String CYAN_CODE = Color.toStringCode(Color.CYAN);

// Reset color to the original setting of the string.
public static final String RESET_CODE = COLOR_CHAR + "\u0002\u0000\u0000\u0000";
// Set the color before the last color code; if the last code is: RESET or unset: no operation; REDO: RESET.
public static final String REDO_CODE = COLOR_CHAR + "\u0003\u0000\u0000\u0000";

/**
* This returns a minicraftrgb.
* a should be between 0-1, r,g,and b should be 0-255
Expand Down
75 changes: 54 additions & 21 deletions src/client/java/minicraft/gfx/Font.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package minicraft.gfx;

import minicraft.core.Action;
import minicraft.core.Renderer;
import minicraft.gfx.SpriteLinker.SpriteType;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

public class Font {
// These are all the characters that will be translated to the screen. (The spaces are important)
Expand Down Expand Up @@ -39,32 +43,61 @@ public static void draw(String msg, Screen screen, int x, int y) {
}
}

public static void drawColor(String message, Screen screen, int x, int y) {
// Set default color message if it doesn't have initially
if (message.charAt(0) != Color.COLOR_CHAR) {
message = Color.WHITE_CODE + message;
}
public static void drawColor(String message, Screen screen, int x, int y) { drawColor(message, screen, x, y, -1); }
public static void drawColor(String message, Screen screen, int x, int y, int whiteTint) {
AtomicInteger leading = new AtomicInteger();
AtomicReference<StringBuilder> toRender = new AtomicReference<>(new StringBuilder());
SizedStack<Integer> colors = new SizedStack<>(2);
Action textRenderer = () -> {
if (toRender.get().length() > 0) {
String text = toRender.toString();
Font.draw(text, screen, x + leading.get(), y, colors.isEmpty() ? whiteTint : colors.peek());
leading.addAndGet(Font.textWidth(text));
toRender.set(new StringBuilder()); // Clears the appended text.
}
};
for (int i = 0; i < message.length(); i++) {
char c = message.charAt(i);
if (c == Color.COLOR_CHAR) {
if (message.length() - 1 - i >= 4) { // There should be 4 chars for color values.
textRenderer.act(); // Renders with the last color instantly.
String colorCode = message.substring(i, i + 5); // Gets the 5 characters including color char.
if (colorCode.equals(Color.RESET_CODE)) {
colors.clear();
} else if (colorCode.equals(Color.REDO_CODE)) {
if (colors.size() > 0) colors.pop();
} else {
colors.add(Color.get(colorCode));
}

i += 4; // Shifts for 4 characters (color values).
continue;
}
}

int leading = 0;
for (String data : message.split(String.valueOf(Color.COLOR_CHAR))) {
if (data.isEmpty()) {
continue;
toRender.get().append(c);
if (i == message.length() - 1) { // If this is the last character
textRenderer.act(); // Renders the text remaining.
}
}
}

String text;
String color;
// Reference: https://stackoverflow.com/a/16206356
private static class SizedStack<T> extends Stack<T> {
private final int maxSize;

try {
text = data.substring(4);
color = data.substring(0, 4); // ARGB value
} catch (IndexOutOfBoundsException ignored) {
// Bad formatted colored string
text = data;
color = Color.WHITE_CODE;
}
public SizedStack(int size) {
super();
this.maxSize = size;
}

Font.draw(text, screen, x + leading, y, Color.get(color));
leading += Font.textWidth(text);
@Override
public T push(T object) {
//If the stack is too big, remove elements until it's the right size.
while (this.size() >= maxSize) {
this.remove(0);
}
return super.push(object);
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/client/java/minicraft/screen/entry/KeyInputEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@ private void setMapping(String mapping, Set<String> duplicated) {
for (int spaces = 0; spaces < Screen.w / Font.textWidth(" ") - action.length() - mapping.length(); spaces++)
buffer.append(" ");

String newMapping = "";
StringBuilder newMapping = new StringBuilder();
for (String k : mapping.split("\\|")) {
if (duplicated.contains(k)) k = Color.RED_CODE + k;
k = Color.GRAY_CODE + k + Color.WHITE_CODE;
newMapping += k + "|";
if (duplicated.contains(k)) k = Color.RED_CODE + k + Color.RESET_CODE;
newMapping.append(k).append("|");
}

this.mapping = newMapping.substring(0, newMapping.length() - 1);
Expand Down
6 changes: 3 additions & 3 deletions src/client/java/minicraft/screen/entry/ListEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void render(Screen screen, int x, int y, boolean isSelected, String conta

String string = toString();

Font.drawColor(string.replace(contain, Color.toStringCode(containColor) + contain + Color.WHITE_CODE), screen, x, y);
Font.drawColor(string.replace(contain, Color.toStringCode(containColor) + contain + Color.REDO_CODE), screen, x, y);
}

/**
Expand All @@ -43,9 +43,9 @@ public void render(Screen screen, int x, int y, boolean isSelected, String conta
*/
public void render(Screen screen, int x, int y, boolean isSelected) {
if (visible) {
String text = toString().replace(Color.WHITE_CODE + Color.GRAY_CODE, Color.toStringCode(getColor(isSelected)));
String text = toString();
if (text.contains(String.valueOf(Color.COLOR_CHAR)))
Font.drawColor(Color.toStringCode(getColor(isSelected)) + text, screen, x, y);
Font.drawColor(text, screen, x, y, getColor(isSelected));
else
Font.draw(text, screen, x, y, getColor(isSelected));
}
Expand Down
Loading