[config-ui-tiny] massive editor screen improvement and better positioning
This commit is contained in:
parent
2607253458
commit
0d800e2a9d
|
@ -9,5 +9,7 @@
|
|||
"libjf-config-reflect-v1-testmod.jfconfig.enumTest.tooltip": "Enum Test Tooltip",
|
||||
"libjf-config-reflect-v1-testmod.jfconfig.enum.Test.Test": "Test",
|
||||
"libjf-config-reflect-v1-testmod.jfconfig.enum.Test.ER": "ER",
|
||||
"libjf-config-reflect-v1-testmod.jfconfig.moskau": "Moskau"
|
||||
"libjf-config-reflect-v1-testmod.jfconfig.moskau": "Moskau",
|
||||
"libjf-config-reflect-v1-testmod.jfconfig.stringList": "String list",
|
||||
"libjf-config-reflect-v1-testmod.jfconfig.stringList.tooltip": "Tooltip of the String list"
|
||||
}
|
|
@ -10,16 +10,16 @@ import net.minecraft.client.font.TextHandler;
|
|||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ingame.BookScreen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.util.NarratorManager;
|
||||
import net.minecraft.client.util.SelectionManager;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.util.math.Rect2i;
|
||||
import net.minecraft.screen.ScreenTexts;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.*;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
|
@ -29,12 +29,10 @@ import java.util.*;
|
|||
import java.util.function.Consumer;
|
||||
|
||||
public class EditorScreen extends Screen {
|
||||
//TODO simple box background
|
||||
//TODO scrollable
|
||||
private static final int MAX_TEXT_WIDTH = 114;
|
||||
private static final int MAX_TEXT_HEIGHT = 128;
|
||||
private static final int WIDTH = 192;
|
||||
private static final int HEIGHT = 192;
|
||||
private static final int SCROLLBAR_SIZE = 7;
|
||||
private static final int HEADER_SIZE = 32;
|
||||
private static final int FOOTER_SIZE = 36;
|
||||
private static final int PADDING = 14;
|
||||
|
||||
private int tickCounter;
|
||||
private final String initialText;
|
||||
|
@ -44,20 +42,50 @@ public class EditorScreen extends Screen {
|
|||
this::setText,
|
||||
this::getClipboard,
|
||||
this::setClipboard,
|
||||
string -> string.length() < 1024 && this.textRenderer.getWrappedLinesHeight(string, MAX_TEXT_WIDTH) <= MAX_TEXT_HEIGHT
|
||||
string -> true
|
||||
);
|
||||
|
||||
private long lastClickTime;
|
||||
private int lastClickIndex = -1;
|
||||
|
||||
private double scrollAmount;
|
||||
private boolean scrolling;
|
||||
|
||||
private int getViewportHeight() {
|
||||
return height - HEADER_SIZE - FOOTER_SIZE - PADDING * 2;
|
||||
}
|
||||
|
||||
private int getViewportWidth() {
|
||||
return width - SCROLLBAR_SIZE - PADDING * 2;
|
||||
}
|
||||
|
||||
private int getMaxScroll() {
|
||||
return Math.max(0, getMaxPosition() - getViewportHeight());
|
||||
}
|
||||
|
||||
private int getMaxPosition() {
|
||||
return getPageContent().lines.length * textRenderer.fontHeight;
|
||||
}
|
||||
|
||||
private int getScrollbarPositionX() {
|
||||
return width - 7;
|
||||
}
|
||||
|
||||
private void setScrollAmount(double amount) {
|
||||
this.scrollAmount = MathHelper.clamp(amount, 0, getMaxScroll());
|
||||
invalidatePageContent();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PageContent pageContent = PageContent.EMPTY;
|
||||
private final Screen parent;
|
||||
private final Consumer<String> onSave;
|
||||
@Nullable private final Text subtitle;
|
||||
|
||||
public EditorScreen(@Nullable Text title, @Nullable Screen parent, @Nullable String text, @Nullable Consumer<String> onSave) {
|
||||
public EditorScreen(@Nullable Text title, @Nullable Text subtitle, @Nullable Screen parent, @Nullable String text, @Nullable Consumer<String> onSave) {
|
||||
super(title == null ? NarratorManager.EMPTY : title);
|
||||
this.parent = parent;
|
||||
this.subtitle = subtitle == null ? null : subtitle.copy().formatted(Formatting.GRAY);
|
||||
this.initialText = text;
|
||||
if (text != null) this.text = text;
|
||||
this.onSave = onSave == null ? R::nop : onSave;
|
||||
|
@ -89,17 +117,15 @@ public class EditorScreen extends Screen {
|
|||
|
||||
@Override
|
||||
protected void init() {
|
||||
ButtonWidget cancelButton;
|
||||
ButtonWidget doneButton;
|
||||
this.invalidatePageContent();
|
||||
doneButton = this.addDrawableChild(
|
||||
this.addDrawableChild(
|
||||
ButtonWidget.builder(ScreenTexts.DONE, button -> quit(true))
|
||||
.dimensions(this.width / 2 + 2, HEIGHT + 4, 98, 20)
|
||||
.dimensions(this.width / 2 + 4, height - FOOTER_SIZE + 8, 150, 20)
|
||||
.build()
|
||||
);
|
||||
cancelButton = this.addDrawableChild(
|
||||
this.addDrawableChild(
|
||||
ButtonWidget.builder(ScreenTexts.CANCEL, button -> quit(false))
|
||||
.dimensions(this.width / 2 - 102, HEIGHT + 4, 98, 20)
|
||||
.dimensions(this.width / 2 - 154, height - FOOTER_SIZE + 8, 150, 20)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
@ -255,17 +281,44 @@ public class EditorScreen extends Screen {
|
|||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
this.renderBackground(matrices);
|
||||
renderBackground(matrices);
|
||||
if (subtitle == null) {
|
||||
drawCenteredTextWithShadow(matrices, textRenderer, title, width / 2, (HEADER_SIZE - textRenderer.fontHeight) / 2, 0xFFFFFF);
|
||||
} else {
|
||||
drawCenteredTextWithShadow(matrices, textRenderer, title, width / 2, HEADER_SIZE / 2 - textRenderer.fontHeight, 0xFFFFFF);
|
||||
drawCenteredTextWithShadow(matrices, textRenderer, subtitle, width / 2, HEADER_SIZE / 2, 0xFFFFFF);
|
||||
}
|
||||
this.setFocused(null);
|
||||
RenderSystem.setShaderTexture(0, BookScreen.BOOK_TEXTURE);
|
||||
int i = (this.width - WIDTH) / 2;
|
||||
drawTexture(matrices, i, 2, 0, 0, WIDTH, HEIGHT);
|
||||
|
||||
if (client.world == null) {
|
||||
RenderSystem.setShaderTexture(0, DrawableHelper.OPTIONS_BACKGROUND_TEXTURE);
|
||||
RenderSystem.setShaderColor(0.125f, 0.125f, 0.125f, 1.0f);
|
||||
drawTexture(matrices, 0, HEADER_SIZE, width - SCROLLBAR_SIZE, height - FOOTER_SIZE + (int)scrollAmount, width - SCROLLBAR_SIZE, height - HEADER_SIZE - FOOTER_SIZE, 32, 32);
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
enableScissor(0, HEADER_SIZE, width - SCROLLBAR_SIZE, height - FOOTER_SIZE);
|
||||
PageContent pageContent = this.getPageContent();
|
||||
for (Line line : pageContent.lines) {
|
||||
this.textRenderer.draw(matrices, line.text, line.x, line.y, -16777216);
|
||||
this.textRenderer.draw(matrices, line.text, line.x, line.y, 0xFFFFFFFF);
|
||||
}
|
||||
this.drawSelection(matrices, pageContent.selectionRectangles);
|
||||
this.drawCursor(matrices, pageContent.position, pageContent.atEnd);
|
||||
disableScissor();
|
||||
|
||||
int i = this.getScrollbarPositionX();
|
||||
int j = i + 6;
|
||||
int m;
|
||||
if ((m = this.getMaxScroll()) > 0) {
|
||||
int n = (getViewportHeight() * getViewportHeight()) / getMaxPosition();
|
||||
n = MathHelper.clamp(n, 32, getViewportHeight() - 8);
|
||||
int o = (int)scrollAmount * (getViewportHeight() - n) / m + HEADER_SIZE;
|
||||
if (o < HEADER_SIZE) o = HEADER_SIZE;
|
||||
fill(matrices, i, HEADER_SIZE, j, height - FOOTER_SIZE, 0xFF000000);
|
||||
fill(matrices, i, o, j, o + n, 0xFF808080);
|
||||
fill(matrices, i, o, j - 1, o + n - 1, 0xFFC0C0C0);
|
||||
}
|
||||
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
|
@ -273,7 +326,7 @@ public class EditorScreen extends Screen {
|
|||
if (this.tickCounter / 6 % 2 == 0) {
|
||||
position = this.absolutePositionToScreenPosition(position);
|
||||
if (!atEnd) {
|
||||
DrawableHelper.fill(matrices, position.x, position.y - 1, position.x + 1, position.y + this.textRenderer.fontHeight, -16777216);
|
||||
DrawableHelper.fill(matrices, position.x, position.y - 1, position.x + 1, position.y + this.textRenderer.fontHeight, 0xFFFFFFFF);
|
||||
} else {
|
||||
this.textRenderer.draw(matrices, "_", position.x, position.y, 0);
|
||||
}
|
||||
|
@ -288,17 +341,17 @@ public class EditorScreen extends Screen {
|
|||
int j = rect2i.getY();
|
||||
int k = i + rect2i.getWidth();
|
||||
int l = j + rect2i.getHeight();
|
||||
fill(matrices, i, j, k, l, -16776961);
|
||||
fill(matrices, i, j, k, l, 0xFF0000FF);
|
||||
}
|
||||
RenderSystem.disableColorLogicOp();
|
||||
}
|
||||
|
||||
private Position screenPositionToAbsolutePosition(Position position) {
|
||||
return new Position(position.x - (this.width - WIDTH) / 2 - 36, position.y - 32);
|
||||
return new Position(position.x - PADDING, position.y - HEADER_SIZE - PADDING + (int)scrollAmount);
|
||||
}
|
||||
|
||||
private Position absolutePositionToScreenPosition(Position position) {
|
||||
return new Position(position.x + (this.width - WIDTH) / 2 + 36, position.y + 32);
|
||||
return new Position(position.x + PADDING, position.y + HEADER_SIZE + PADDING - (int)scrollAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -306,9 +359,10 @@ public class EditorScreen extends Screen {
|
|||
if (super.mouseClicked(mouseX, mouseY, button)) {
|
||||
return true;
|
||||
}
|
||||
if (button == 0) {
|
||||
scrolling = button == 0 && mouseX >= getScrollbarPositionX();
|
||||
if (button == 0 && !scrolling) {
|
||||
long l = Util.getMeasuringTimeMs();
|
||||
int i = this.getPageContent().getCursorPosition(this.textRenderer, this.screenPositionToAbsolutePosition(new Position((int)mouseX, (int)mouseY)));
|
||||
int i = this.getPageContent().getCursorPosition(this.textRenderer, this.screenPositionToAbsolutePosition(new Position((int) mouseX, (int) mouseY)));
|
||||
if (i >= 0) {
|
||||
if (i == this.lastClickIndex && l - this.lastClickTime < 250L) {
|
||||
if (!this.currentPageSelectionManager.isSelecting()) {
|
||||
|
@ -338,13 +392,31 @@ public class EditorScreen extends Screen {
|
|||
return true;
|
||||
}
|
||||
if (button == 0) {
|
||||
int i = this.getPageContent().getCursorPosition(this.textRenderer, this.screenPositionToAbsolutePosition(new Position((int)mouseX, (int)mouseY)));
|
||||
this.currentPageSelectionManager.moveCursorTo(i, true);
|
||||
this.invalidatePageContent();
|
||||
if (scrolling) {
|
||||
if (mouseY < HEADER_SIZE) setScrollAmount(0);
|
||||
else if (mouseY > height - FOOTER_SIZE) setScrollAmount(getMaxScroll());
|
||||
else {
|
||||
double d = Math.max(1, getMaxScroll());
|
||||
int i = getViewportHeight();
|
||||
int j = MathHelper.clamp((int)((float)(i * i) / (float)this.getMaxPosition()), 32, i - 8);
|
||||
double e = Math.max(1d, d / (i - j));
|
||||
setScrollAmount(scrollAmount + deltaY * e);
|
||||
}
|
||||
} else {
|
||||
int i = this.getPageContent().getCursorPosition(this.textRenderer, this.screenPositionToAbsolutePosition(new Position((int)mouseX, (int)mouseY)));
|
||||
this.currentPageSelectionManager.moveCursorTo(i, true);
|
||||
this.invalidatePageContent();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
|
||||
setScrollAmount(scrollAmount - amount * textRenderer.fontHeight * 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
private PageContent getPageContent() {
|
||||
if (this.pageContent == null) {
|
||||
this.pageContent = this.createPageContent();
|
||||
|
@ -368,7 +440,7 @@ public class EditorScreen extends Screen {
|
|||
MutableInt lineIndexM = new MutableInt();
|
||||
MutableBoolean mutableBoolean = new MutableBoolean();
|
||||
TextHandler textHandler = this.textRenderer.getTextHandler();
|
||||
textHandler.wrapLines(content, MAX_TEXT_WIDTH, Style.EMPTY, true, (style, start, end) -> {
|
||||
textHandler.wrapLines(content, getViewportWidth(), Style.EMPTY, true, (style, start, end) -> {
|
||||
int lineIndex = lineIndexM.getAndIncrement();
|
||||
String string = content.substring(start, end);
|
||||
mutableBoolean.setValue(string.endsWith("\n"));
|
||||
|
|
|
@ -6,6 +6,7 @@ import io.gitlab.jfronny.libjf.config.api.v1.ConfigCategory;
|
|||
import io.gitlab.jfronny.libjf.config.api.v1.dsl.CategoryBuilder;
|
||||
import io.gitlab.jfronny.libjf.config.impl.entrypoint.JfConfigSafe;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry.EntryListWidget;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry.WidgetState;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ui.tiny.presets.PresetsScreen;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
@ -127,7 +128,7 @@ public class TinyConfigScreen extends Screen {
|
|||
this.renderBackground(matrices);
|
||||
this.placeholder.render(matrices, mouseX, mouseY, delta);
|
||||
|
||||
drawCenteredTextWithShadow(matrices, textRenderer, title, width / 2, 15, 0xFFFFFF);
|
||||
drawCenteredTextWithShadow(matrices, textRenderer, title, width / 2, 16 - textRenderer.fontHeight, 0xFFFFFF);
|
||||
|
||||
Optional<Text> hovered = placeholder.getChild().getHoveredEntryTitle(mouseY);
|
||||
if (hovered.isPresent()) {
|
||||
|
|
|
@ -3,8 +3,7 @@ package io.gitlab.jfronny.libjf.config.impl.ui.tiny;
|
|||
import io.gitlab.jfronny.libjf.config.api.v1.ConfigCategory;
|
||||
import io.gitlab.jfronny.libjf.config.api.v1.ConfigInstance;
|
||||
import io.gitlab.jfronny.libjf.config.api.v1.ui.tiny.WidgetFactory;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry.EntryInfoWidgetBuilder;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry.EntryListWidget;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry.*;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ui.tiny.presets.PresetsScreen;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.ScreenRect;
|
||||
|
@ -31,8 +30,7 @@ public class TinyConfigTab implements Tab {
|
|||
widget.updateCache();
|
||||
}
|
||||
|
||||
this.list = new EntryListWidget(screen.getClient(), textRenderer, screen.width, screen.height, 32, screen.height - 32, 25);
|
||||
if (screen.hasClient() && screen.getClient().world != null) this.list.setRenderBackground(false);
|
||||
this.list = new EntryListWidget(screen.getClient(), textRenderer, screen.width, screen.height, 32, screen.height - 36, 25);
|
||||
|
||||
if (isRoot) {
|
||||
for (Map.Entry<String, ConfigCategory> entry : config.getCategories().entrySet()) {
|
||||
|
|
|
@ -3,24 +3,22 @@ package io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry;
|
|||
import io.gitlab.jfronny.commons.ref.R;
|
||||
import io.gitlab.jfronny.commons.serialize.gson.api.v1.GsonHolders;
|
||||
import io.gitlab.jfronny.commons.throwable.Try;
|
||||
import io.gitlab.jfronny.gson.JsonElement;
|
||||
import io.gitlab.jfronny.gson.stream.JsonWriter;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.api.v1.ConfigCategory;
|
||||
import io.gitlab.jfronny.libjf.config.api.v1.EntryInfo;
|
||||
import io.gitlab.jfronny.libjf.config.api.v1.type.Type;
|
||||
import io.gitlab.jfronny.libjf.config.api.v1.ui.tiny.WidgetFactory;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ui.tiny.EditorScreen;
|
||||
import io.gitlab.jfronny.libjf.config.impl.ui.tiny.WidgetState;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.toast.SystemToast;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Language;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
@ -177,8 +175,10 @@ public class EntryInfoWidgetBuilder {
|
|||
} else {
|
||||
jsonified = state.tempValue;
|
||||
}
|
||||
String key = config.getTranslationPrefix() + info.getName();
|
||||
screen.getClient().setScreen(new EditorScreen(
|
||||
Text.translatable(config.getTranslationPrefix() + info.getName()),
|
||||
Text.translatable(key),
|
||||
I18n.hasTranslation(key + ".tooltip") ? Text.translatable(key + ".tooltip") : null,
|
||||
screen,
|
||||
jsonified,
|
||||
json -> {
|
||||
|
|
|
@ -21,10 +21,11 @@ import java.util.function.Supplier;
|
|||
public class EntryListWidget extends ElementListWidget<EntryListWidget.ConfigEntry> {
|
||||
TextRenderer textRenderer;
|
||||
|
||||
public EntryListWidget(MinecraftClient minecraftClient, TextRenderer tr, int i, int j, int k, int l, int m) {
|
||||
super(minecraftClient, i, j, k, l, m);
|
||||
public EntryListWidget(MinecraftClient client, TextRenderer tr, int i, int j, int k, int l, int m) {
|
||||
super(client, i, j, k, l, m);
|
||||
this.centerListVertically = false;
|
||||
textRenderer = tr;
|
||||
setRenderBackground(client.world == null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl.ui.tiny;
|
||||
package io.gitlab.jfronny.libjf.config.impl.ui.tiny.entry;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.api.v1.EntryInfo;
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
|||
public class PresetListWidget extends ElementListWidget<PresetListWidget.PresetEntry> {
|
||||
public PresetListWidget(MinecraftClient client, int i, int j, int k, int l, int m) {
|
||||
super(client, i, j, k, l, m);
|
||||
setRenderBackground(client.world == null);
|
||||
}
|
||||
|
||||
public void addButton(ClickableWidget button) {
|
||||
|
|
|
@ -53,7 +53,7 @@ public class PresetsScreen extends Screen {
|
|||
this.renderBackground(matrices);
|
||||
this.list.render(matrices, mouseX, mouseY, delta);
|
||||
|
||||
drawCenteredTextWithShadow(matrices, textRenderer, title, width / 2, 15, 0xFFFFFF);
|
||||
drawCenteredTextWithShadow(matrices, textRenderer, title, width / 2, 16 - textRenderer.fontHeight / 2, 0xFFFFFF);
|
||||
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue