Skip to content

Commit 833189b

Browse files
committed
ColorController, javadoc and further improvements to StringController
1 parent 9c28330 commit 833189b

7 files changed

Lines changed: 280 additions & 50 deletions

File tree

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
package dev.isxander.yacl.gui.controllers;
2+
3+
import com.google.common.collect.ImmutableList;
4+
import dev.isxander.yacl.api.Option;
5+
import dev.isxander.yacl.api.utils.Dimension;
6+
import dev.isxander.yacl.gui.AbstractWidget;
7+
import dev.isxander.yacl.gui.YACLScreen;
8+
import dev.isxander.yacl.gui.controllers.string.IStringController;
9+
import dev.isxander.yacl.gui.controllers.string.StringControllerElement;
10+
import net.minecraft.client.gui.DrawableHelper;
11+
import net.minecraft.client.util.math.MatrixStack;
12+
import net.minecraft.text.MutableText;
13+
import net.minecraft.text.Text;
14+
import net.minecraft.util.Formatting;
15+
16+
import java.awt.*;
17+
import java.util.List;
18+
19+
/**
20+
* A color controller that uses a hex color field as input.
21+
*/
22+
public class ColorController implements IStringController<Color> {
23+
private final Option<Color> option;
24+
private final boolean allowAlpha;
25+
26+
/**
27+
* Constructs a color controller with {@link ColorController#allowAlpha()} defaulting to false
28+
*
29+
* @param option bound option
30+
*/
31+
public ColorController(Option<Color> option) {
32+
this(option, false);
33+
}
34+
35+
/**
36+
* Constructs a color controller
37+
*
38+
* @param option bound option
39+
* @param allowAlpha allows the color input to accept alpha values
40+
*/
41+
public ColorController(Option<Color> option, boolean allowAlpha) {
42+
this.option = option;
43+
this.allowAlpha = allowAlpha;
44+
}
45+
46+
/**
47+
* {@inheritDoc}
48+
*/
49+
@Override
50+
public Option<Color> option() {
51+
return option;
52+
}
53+
54+
public boolean allowAlpha() {
55+
return allowAlpha;
56+
}
57+
58+
@Override
59+
public String getString() {
60+
return formatValue().getString();
61+
}
62+
63+
@Override
64+
public Text formatValue() {
65+
MutableText text = Text.literal("#");
66+
if (allowAlpha()) text.append(toHex(option().pendingValue().getAlpha()));
67+
text.append(Text.literal(toHex(option().pendingValue().getRed())).formatted(Formatting.RED));
68+
text.append(Text.literal(toHex(option().pendingValue().getGreen())).formatted(Formatting.GREEN));
69+
text.append(Text.literal(toHex(option().pendingValue().getBlue())).formatted(Formatting.BLUE));
70+
return text;
71+
}
72+
73+
private String toHex(int value) {
74+
String hex = Integer.toString(value, 16).toUpperCase();
75+
if (hex.length() == 1)
76+
hex = "0" + hex;
77+
return hex;
78+
}
79+
80+
@Override
81+
public void setFromString(String value) {
82+
if (value.startsWith("#"))
83+
value = value.substring(1);
84+
85+
int alpha = Integer.parseInt(value.substring(0, 2), 16);
86+
int red = Integer.parseInt(allowAlpha() ? value.substring(2, 4) : value.substring(0, 2), 16);
87+
int green = Integer.parseInt(allowAlpha() ? value.substring(4, 6) : value.substring(2, 4), 16);
88+
int blue = Integer.parseInt(allowAlpha() ? value.substring(6, 8) : value.substring(4, 6), 16);
89+
90+
option().requestSet(allowAlpha() ? new Color(red, green, blue, alpha) : new Color(red, green, blue));
91+
}
92+
93+
@Override
94+
public AbstractWidget provideWidget(YACLScreen screen, Dimension<Integer> widgetDimension) {
95+
return new ColorControllerElement(this, screen, widgetDimension);
96+
}
97+
98+
public static class ColorControllerElement extends StringControllerElement {
99+
private final ColorController colorController;
100+
101+
protected Dimension<Integer> colorPreviewDim;
102+
103+
private final List<Character> allowedChars;
104+
105+
public ColorControllerElement(ColorController control, YACLScreen screen, Dimension<Integer> dim) {
106+
super(control, screen, dim);
107+
this.colorController = control;
108+
this.allowedChars = ImmutableList.of('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
109+
}
110+
111+
@Override
112+
protected void drawValueText(MatrixStack matrices, int mouseX, int mouseY, float delta) {
113+
if (isHovered()) {
114+
colorPreviewDim.move(-inputFieldBounds.width() - 5, 0);
115+
super.drawValueText(matrices, mouseX, mouseY, delta);
116+
}
117+
118+
DrawableHelper.fill(matrices, colorPreviewDim.x(), colorPreviewDim.y(), colorPreviewDim.xLimit(), colorPreviewDim.yLimit(), colorController.option().pendingValue().getRGB());
119+
drawOutline(matrices, colorPreviewDim.x(), colorPreviewDim.y(), colorPreviewDim.xLimit(), colorPreviewDim.yLimit(), 1, 0xFF000000);
120+
}
121+
122+
@Override
123+
public void write(String string) {
124+
for (char chr : string.toCharArray()) {
125+
if (!allowedChars.contains(Character.toLowerCase(chr))) {
126+
return;
127+
}
128+
}
129+
130+
if (caretPos == 0)
131+
return;
132+
133+
string = string.substring(0, Math.min(inputField.length() - caretPos, string.length()));
134+
135+
inputField.replace(caretPos, caretPos + string.length(), string);
136+
caretPos += string.length();
137+
setSelectionLength();
138+
139+
updateControl();
140+
}
141+
142+
@Override
143+
protected void doBackspace() {
144+
if (caretPos > 1) {
145+
inputField.setCharAt(caretPos - 1, '0');
146+
caretPos--;
147+
updateControl();
148+
}
149+
}
150+
151+
@Override
152+
protected void doDelete() {
153+
154+
}
155+
156+
@Override
157+
protected boolean canUseShortcuts() {
158+
return false;
159+
}
160+
161+
protected void setSelectionLength() {
162+
selectionLength = caretPos < inputField.length() && caretPos > 0 ? 1 : 0;
163+
}
164+
165+
@Override
166+
protected int getDefaultCarotPos() {
167+
return colorController.allowAlpha() ? 3 : 1;
168+
}
169+
170+
@Override
171+
public void setDimension(Dimension<Integer> dim) {
172+
super.setDimension(dim);
173+
174+
int previewSize = (dim.height() - getYPadding() * 2) / 2;
175+
colorPreviewDim = Dimension.ofInt(dim.xLimit() - getXPadding() - previewSize, dim.centerY() - previewSize / 2, previewSize, previewSize);
176+
}
177+
178+
@Override
179+
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
180+
if (super.keyPressed(keyCode, scanCode, modifiers)) {
181+
caretPos = Math.max(1, caretPos);
182+
setSelectionLength();
183+
return true;
184+
}
185+
return false;
186+
}
187+
188+
@Override
189+
public boolean mouseClicked(double mouseX, double mouseY, int button) {
190+
if (super.mouseClicked(mouseX, mouseY, button)) {
191+
caretPos = Math.max(1, caretPos);
192+
setSelectionLength();
193+
return true;
194+
}
195+
return false;
196+
}
197+
}
198+
}

src/main/java/dev/isxander/yacl/gui/controllers/LabelController.java

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,18 @@
99
import net.minecraft.text.Text;
1010
import org.jetbrains.annotations.ApiStatus;
1111

12+
/**
13+
* Simply renders some text as a label.
14+
*/
1215
public class LabelController implements Controller<Text> {
1316
private final Option<Text> option;
14-
private final int color;
15-
1617
/**
1718
* Constructs a label controller
1819
*
1920
* @param option bound option
2021
*/
2122
public LabelController(Option<Text> option) {
22-
this(option, -1);
23-
}
24-
25-
/**
26-
* Constructs a label controller
27-
*
28-
* @param option bound option
29-
* @param color color of the label
30-
*/
31-
public LabelController(Option<Text> option, int color) {
3223
this.option = option;
33-
this.color = color;
3424
}
3525

3626
/**
@@ -41,10 +31,6 @@ public Option<Text> option() {
4131
return option;
4232
}
4333

44-
public int color() {
45-
return color;
46-
}
47-
4834
@Override
4935
public Text formatValue() {
5036
return option().pendingValue();
@@ -64,7 +50,7 @@ public LabelControllerElement(Dimension<Integer> dim) {
6450

6551
@Override
6652
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
67-
textRenderer.drawWithShadow(matrices, formatValue(), dim.x(), dim.centerY() - textRenderer.fontHeight / 2f, color());
53+
textRenderer.drawWithShadow(matrices, formatValue(), dim.x(), dim.centerY() - textRenderer.fontHeight / 2f, -1);
6854
}
6955
}
7056
}

src/main/java/dev/isxander/yacl/gui/controllers/package-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* <li>For numbers: {@link dev.isxander.yacl.gui.controllers.slider}</li>
66
* <li>For booleans: {@link dev.isxander.yacl.gui.controllers.TickBoxController}</li>
77
* <li>For enums: {@link dev.isxander.yacl.gui.controllers.EnumController}</li>
8+
* <li>For strings: {@link dev.isxander.yacl.gui.controllers.string.StringController}</li>
89
* <li>For {@link dev.isxander.yacl.api.ButtonOption}: {@link dev.isxander.yacl.gui.controllers.ActionController}</li>
910
* </ul>
1011
*/

src/main/java/dev/isxander/yacl/gui/controllers/string/IStringController.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,30 @@
11
package dev.isxander.yacl.gui.controllers.string;
22

33
import dev.isxander.yacl.api.Controller;
4+
import dev.isxander.yacl.api.Option;
45
import net.minecraft.text.Text;
56

7+
/**
8+
* A controller that can be any type but can input and output a string.
9+
*/
610
public interface IStringController<T> extends Controller<T> {
11+
/**
12+
* Gets the option's pending value as a string.
13+
*
14+
* @see Option#pendingValue()
15+
*/
716
String getString();
17+
18+
/**
19+
* Sets the option's pending value from a string.
20+
*
21+
* @see Option#requestSet(Object)
22+
*/
823
void setFromString(String value);
924

25+
/**
26+
* {@inheritDoc}
27+
*/
1028
@Override
1129
default Text formatValue() {
1230
return Text.of(getString());

src/main/java/dev/isxander/yacl/gui/controllers/string/BasicStringController.java renamed to src/main/java/dev/isxander/yacl/gui/controllers/string/StringController.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,18 @@
55
import dev.isxander.yacl.gui.AbstractWidget;
66
import dev.isxander.yacl.gui.YACLScreen;
77

8-
public class BasicStringController implements IStringController<String> {
8+
/**
9+
* A custom text field implementation for strings.
10+
*/
11+
public class StringController implements IStringController<String> {
912
private final Option<String> option;
1013

1114
/**
12-
* Constructs a tickbox controller
15+
* Constructs a string controller
1316
*
1417
* @param option bound option
1518
*/
16-
public BasicStringController(Option<String> option) {
19+
public StringController(Option<String> option) {
1720
this.option = option;
1821
}
1922

0 commit comments

Comments
 (0)