Skip to content

Commit f9a0e5c

Browse files
committed
theme builder & drawable to json
1 parent 048394a commit f9a0e5c

22 files changed

+468
-73
lines changed

TODO.md

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,33 @@
11
# ModularUI TODO's
22

3-
:boom: = Potential breaking changes
4-
53
## Widgets
64

7-
* [ ] Trackpad
8-
* [X] improve List (column but scrollable) :boom:
9-
* [X] improve Sortable List (for bogosorter) :boom:
10-
* [X] improve Slot Group (Builder, sorting) :boom:
11-
* [X] improve Dialog :boom:
12-
* [X] improve Popup menu :boom:
5+
* [ ] Context Menu
136
* [ ] Dropdown menu
7+
* [ ] Trackpad
148
* [ ] Pie menu
159

10+
## High Priority
11+
- [ ] merge animations with NEA
12+
- [ ] check JEI click interactions
13+
1614
## Medium Priority
1715

18-
- [ ] texture json registry improvements :boom:
1916
- [ ] Entity drawable
20-
- [ ] Fake world drawable
21-
- [ ] Text editor :boom:
17+
- [ ] Text editor
2218
- [ ] Json Guis
23-
- [ ] Inject to any mc gui :boom:
19+
- [ ] Inject to any mc gui
2420
- [ ] Error handling with on-screen reports
2521

2622
## Low Priority
2723

2824
- [ ] Config lib
2925
- [ ] Keybind api
3026
- [ ] create JEI UIs (?)
31-
- [ ] properly add modularui elements to any gui screen
27+
- [x] properly add modularui elements to any gui screen (possible with overlays currently)
3228
- [ ] a gui to create guis
3329
- [ ] sounds ?
3430

35-
## HoloUI :boom:
31+
## HoloUI
3632
- [ ] Fix/Remove current rotations
3733
- [ ] Implement interactions

src/main/java/com/cleanroommc/modularui/api/IThemeApi.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,31 @@
1717
*/
1818
public interface IThemeApi {
1919

20+
// widget themes
21+
String FALLBACK = "default";
22+
String PANEL = "panel";
23+
String BUTTON = "button";
24+
String ITEM_SLOT = "itemSlot";
25+
String FLUID_SLOT = "fluidSlot";
26+
String TEXT_FIELD = "textField";
27+
String TOGGLE_BUTTON = "toggleButton";
28+
29+
// properties
30+
String PARENT = "parent";
31+
String BACKGROUND = "background";
32+
String HOVER_BACKGROUND = "hoverBackground";
33+
String COLOR = "color";
34+
String TEXT_COLOR = "textColor";
35+
String TEXT_SHADOW = "textShadow";
36+
String SLOT_HOVER_COLOR = "slotHoverColor";
37+
String MARKED_COLOR = "markedColor";
38+
String HINT_COLOR = "hintColor";
39+
String SELECTED_BACKGROUND = "selectedBackground";
40+
String SELECTED_HOVER_BACKGROUND = "selectedHoverBackground";
41+
String SELECTED_COLOR = "selectedColor";
42+
String SELECTED_TEXT_COLOR = "selectedTextColor";
43+
String SELECTED_TEXT_SHADOW = "selectedTextShadow";
44+
2045
/**
2146
* @return the default api implementation
2247
*/

src/main/java/com/cleanroommc/modularui/api/drawable/IDrawable.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ static IDrawable of(IDrawable... drawables) {
3333
/**
3434
* Draws this drawable at the given position with the given size.
3535
*
36-
* @param context current context to draw with
37-
* @param x x position
38-
* @param y y position
39-
* @param width draw width
40-
* @param height draw height
36+
* @param context current context to draw with
37+
* @param x x position
38+
* @param y y position
39+
* @param width draw width
40+
* @param height draw height
4141
* @param widgetTheme current theme
4242
*/
4343
@SideOnly(Side.CLIENT)
@@ -86,8 +86,8 @@ default void draw(GuiContext context, Area area) {
8686
/**
8787
* Draws this drawable in a given area.
8888
*
89-
* @param context current context to draw with
90-
* @param area draw area
89+
* @param context current context to draw with
90+
* @param area draw area
9191
* @param widgetTheme current theme
9292
*/
9393
@SideOnly(Side.CLIENT)
@@ -107,8 +107,8 @@ default void drawAtZero(GuiContext context, Area area) {
107107
/**
108108
* Draws this drawable at the current (0|0) with the given area's size.
109109
*
110-
* @param context gui context
111-
* @param area draw area
110+
* @param context gui context
111+
* @param area draw area
112112
* @param widgetTheme current theme
113113
*/
114114
@SideOnly(Side.CLIENT)
@@ -144,6 +144,16 @@ default Icon asIcon() {
144144
*/
145145
default void loadFromJson(JsonObject json) {}
146146

147+
/**
148+
* Writes all json data necessary so that deserializing it results in the same drawable.
149+
*
150+
* @param json json to write to
151+
* @return if the drawable was serialized
152+
*/
153+
default boolean saveToJson(JsonObject json) {
154+
return false;
155+
}
156+
147157
/**
148158
* An empty drawable. Does nothing.
149159
*/

src/main/java/com/cleanroommc/modularui/drawable/AdaptableUITexture.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import net.minecraft.client.renderer.GlStateManager;
55
import net.minecraft.util.ResourceLocation;
66

7+
import com.google.gson.JsonObject;
8+
79
public class AdaptableUITexture extends UITexture {
810

911
private final int imageWidth, imageHeight, bl, bt, br, bb;
@@ -153,4 +155,18 @@ public void drawTiled(float x, float y, float width, float height) {
153155
GlStateManager.disableBlend();
154156
GlStateManager.enableAlpha();
155157
}
158+
159+
@Override
160+
public boolean saveToJson(JsonObject json) {
161+
super.saveToJson(json);
162+
if (json.entrySet().size() == 1) return true;
163+
json.addProperty("imageWidth", this.imageWidth);
164+
json.addProperty("imageHeight", this.imageHeight);
165+
json.addProperty("bl", this.bl);
166+
json.addProperty("br", this.br);
167+
json.addProperty("bt", this.bt);
168+
json.addProperty("bb", this.bb);
169+
json.addProperty("tiled", this.tiled);
170+
return true;
171+
}
156172
}

src/main/java/com/cleanroommc/modularui/drawable/Circle.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,44 @@ public Circle() {
2222
this.segments = 40;
2323
}
2424

25-
@Contract("_ -> this")
2625
public Circle setColorInner(int colorInner) {
26+
return colorInner(colorInner);
27+
}
28+
29+
public Circle setColorOuter(int colorOuter) {
30+
return colorOuter(colorOuter);
31+
}
32+
33+
public Circle setColor(int inner, int outer) {
34+
return color(inner, outer);
35+
}
36+
37+
public Circle setSegments(int segments) {
38+
return segments(segments);
39+
}
40+
41+
@Contract("_ -> this")
42+
public Circle colorInner(int colorInner) {
2743
this.colorInner = colorInner;
2844
return this;
2945
}
3046

31-
public Circle setColorOuter(int colorOuter) {
47+
public Circle colorOuter(int colorOuter) {
3248
this.colorOuter = colorOuter;
3349
return this;
3450
}
3551

36-
public Circle setColor(int inner, int outer) {
52+
public Circle color(int inner, int outer) {
3753
this.colorInner = inner;
3854
this.colorOuter = outer;
3955
return this;
4056
}
4157

42-
public Circle setSegments(int segments) {
58+
public Circle color(int color) {
59+
return color(color, color);
60+
}
61+
62+
public Circle segments(int segments) {
4363
this.segments = segments;
4464
return this;
4565
}
@@ -56,4 +76,12 @@ public void loadFromJson(JsonObject json) {
5676
this.colorOuter = JsonHelper.getColor(json, Color.WHITE.main, "colorOuter", "color");
5777
this.segments = JsonHelper.getInt(json, 40, "segments");
5878
}
79+
80+
@Override
81+
public boolean saveToJson(JsonObject json) {
82+
json.addProperty("colorInner", this.colorInner);
83+
json.addProperty("colorOuter", this.colorOuter);
84+
json.addProperty("segments", this.segments);
85+
return true;
86+
}
5987
}

src/main/java/com/cleanroommc/modularui/drawable/DrawableArray.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.cleanroommc.modularui.screen.viewport.GuiContext;
55
import com.cleanroommc.modularui.theme.WidgetTheme;
66

7+
import com.google.gson.JsonObject;
8+
79
import net.minecraftforge.fml.relauncher.Side;
810
import net.minecraftforge.fml.relauncher.SideOnly;
911

@@ -38,4 +40,11 @@ public boolean canApplyTheme() {
3840
public IDrawable[] getDrawables() {
3941
return this.drawables;
4042
}
43+
44+
@Override
45+
public boolean saveToJson(JsonObject json) {
46+
// serialized as special case
47+
// this method should never be called
48+
throw new IllegalStateException();
49+
}
4150
}

src/main/java/com/cleanroommc/modularui/drawable/DrawableSerialization.java

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,43 +19,69 @@
1919

2020
public class DrawableSerialization implements JsonSerializer<IDrawable>, JsonDeserializer<IDrawable> {
2121

22-
private static final Map<String, Function<JsonObject, IDrawable>> DRAWABLE_TYPES = new Object2ObjectOpenHashMap<>();
22+
private static final Map<String, Function<JsonObject, ? extends IDrawable>> DRAWABLE_TYPES = new Object2ObjectOpenHashMap<>();
23+
private static final Map<Class<? extends IDrawable>, String> REVERSE_DRAWABLE_TYPES = new Object2ObjectOpenHashMap<>();
2324
private static final Map<String, UITexture> TEXTURES = new Object2ObjectOpenHashMap<>();
25+
private static final Map<UITexture, String> REVERSE_TEXTURES = new Object2ObjectOpenHashMap<>();
2426

2527
public static void registerTexture(String s, UITexture texture) {
2628
TEXTURES.put(s, texture);
29+
REVERSE_TEXTURES.put(texture, s);
2730
}
2831

2932
public static UITexture getTexture(String s) {
3033
return TEXTURES.get(s);
3134
}
3235

33-
public static void registerDrawableType(String id, Function<@NotNull JsonObject, @NotNull IDrawable> creator) {
36+
public static String getTextureId(UITexture texture) {
37+
return REVERSE_TEXTURES.get(texture);
38+
}
39+
40+
public static <T extends IDrawable> void registerDrawableType(String id, Class<T> type, Function<@NotNull JsonObject, @NotNull T> creator) {
3441
if (DRAWABLE_TYPES.containsKey(id)) {
3542
throw new IllegalArgumentException("Drawable type '" + id + "' already exists!");
3643
}
3744
DRAWABLE_TYPES.put(id, creator);
45+
if (type != null) {
46+
REVERSE_DRAWABLE_TYPES.put(type, id);
47+
}
3848
}
3949

4050
@ApiStatus.Internal
4151
public static void init() {
42-
registerDrawableType("empty", json -> IDrawable.EMPTY);
43-
registerDrawableType("null", json -> IDrawable.EMPTY);
44-
registerDrawableType("none", json -> IDrawable.NONE);
45-
registerDrawableType("texture", UITexture::parseFromJson);
46-
registerDrawableType("color", json -> new Rectangle());
47-
registerDrawableType("rectangle", json -> new Rectangle());
48-
registerDrawableType("ellipse", json -> new Circle());
49-
registerDrawableType("text", DrawableSerialization::parseText);
50-
registerDrawableType("item", ItemDrawable::ofJson);
51-
registerDrawableType("icon", Icon::ofJson);
52+
registerDrawableType("empty", IDrawable.class, json -> IDrawable.EMPTY);
53+
registerDrawableType("null", null, json -> IDrawable.EMPTY);
54+
registerDrawableType("none", null, json -> IDrawable.NONE);
55+
registerDrawableType("texture", UITexture.class, UITexture::parseFromJson);
56+
registerDrawableType("color", null, json -> new Rectangle());
57+
registerDrawableType("rectangle", Rectangle.class, json -> new Rectangle());
58+
registerDrawableType("ellipse", Circle.class, json -> new Circle());
59+
registerDrawableType("text", IKey.class, DrawableSerialization::parseText);
60+
registerDrawableType("item", ItemDrawable.class, ItemDrawable::ofJson);
61+
registerDrawableType("icon", Icon.class, Icon::ofJson);
62+
}
63+
64+
public static IDrawable deserialize(JsonElement json) {
65+
return JsonHelper.deserialize(json, IDrawable.class);
66+
}
67+
68+
public static JsonElement serialize(IDrawable drawable) {
69+
return JsonHelper.serialize(drawable);
5270
}
5371

5472
@Override
5573
public IDrawable deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
5674
if (element.isJsonNull()) {
5775
return IDrawable.EMPTY;
5876
}
77+
if (element.isJsonPrimitive()) {
78+
if ("empty".equals(element.getAsString()) || "null".equals(element.getAsString())) {
79+
return IDrawable.EMPTY;
80+
}
81+
if ("none".equals(element.getAsString())) {
82+
return IDrawable.NONE;
83+
}
84+
}
5985
if (element.isJsonArray()) {
6086
List<IDrawable> list = new ArrayList<>();
6187
for (JsonElement element1 : element.getAsJsonArray()) {
@@ -92,7 +118,36 @@ public IDrawable deserialize(JsonElement element, Type typeOfT, JsonDeserializat
92118

93119
@Override
94120
public JsonElement serialize(IDrawable src, Type typeOfSrc, JsonSerializationContext context) {
95-
throw new UnsupportedOperationException();
121+
if (src == IDrawable.EMPTY) return JsonNull.INSTANCE;
122+
if (src == IDrawable.NONE) return new JsonPrimitive("none");
123+
if (src instanceof DrawableArray drawableArray) {
124+
JsonArray jsonArray = new JsonArray();
125+
for (IDrawable drawable : drawableArray.getDrawables()) {
126+
jsonArray.add(JsonHelper.serialize(drawable));
127+
}
128+
return jsonArray;
129+
}
130+
JsonObject json = new JsonObject();
131+
if (src instanceof IKey) {
132+
json.addProperty("type", "text");
133+
} else {
134+
Class<?> type = src.getClass();
135+
String key = REVERSE_DRAWABLE_TYPES.get(type);
136+
while (key == null && type != null && type != Object.class) {
137+
type = type.getSuperclass();
138+
key = REVERSE_DRAWABLE_TYPES.get(type);
139+
}
140+
if (key == null) {
141+
ModularUI.LOGGER.error("Serialization of drawable {} failed, because a key for the type could not be found!", src.getClass().getSimpleName());
142+
return JsonNull.INSTANCE;
143+
}
144+
json.addProperty("type", key);
145+
}
146+
147+
if (!src.saveToJson(json)) {
148+
ModularUI.LOGGER.error("Serialization of drawable {} failed!", src.getClass().getSimpleName());
149+
}
150+
return json;
96151
}
97152

98153
private static IKey parseText(JsonObject json) throws JsonParseException {

src/main/java/com/cleanroommc/modularui/drawable/Icon.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,19 @@ public static Icon ofJson(JsonObject json) {
159159
return JsonHelper.deserialize(json, IDrawable.class, IDrawable.EMPTY, "drawable", "icon").asIcon();
160160
}
161161

162+
@Override
163+
public boolean saveToJson(JsonObject json) {
164+
json.add("drawable", JsonHelper.serialize(this.drawable));
165+
json.addProperty("width", this.width);
166+
json.addProperty("height", this.height);
167+
json.add("alignment", JsonHelper.serialize(this.alignment));
168+
json.addProperty("marginTop", this.margin.top);
169+
json.addProperty("marginBottom", this.margin.bottom);
170+
json.addProperty("marginLeft", this.margin.left);
171+
json.addProperty("marginRight", this.margin.right);
172+
return true;
173+
}
174+
162175
@Override
163176
public String toString() {
164177
return getClass().getSimpleName() + "(" + this.drawable.getClass().getSimpleName() + ")";

0 commit comments

Comments
 (0)