Skip to content

Commit 47cf883

Browse files
authored
Detach Mui from GuiScreenWrapper (#64)
* detach GuiScreenWrapper * fix mouse input * slightly scuffed gui overlays * fix text widget for unusual scales * lots of small stuff * setup tests & own matrix and vector impl * dont use deprecated field * move overlay test to own class * test button overlapping * allow creating custom gui wrappers from UIFactory * helpers & javadoc for ui factories
1 parent 3e1e9cc commit 47cf883

65 files changed

Lines changed: 2941 additions & 557 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ enableSpotless = false
162162

163163
# Enable JUnit testing platform used for testing your code.
164164
# Uses JUnit 5. See guide and documentation here: https://junit.org/junit5/docs/current/user-guide/
165-
enableJUnit = false
165+
enableJUnit = true
166166

167167
# Deployment debug setting
168168
# Uncomment this to test deployments to CurseForge and Modrinth

src/main/java/com/cleanroommc/modularui/ClientEventHandler.java

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package com.cleanroommc.modularui;
22

33
import com.cleanroommc.modularui.drawable.Stencil;
4-
import com.cleanroommc.modularui.screen.GuiScreenWrapper;
5-
import com.cleanroommc.modularui.screen.ModularScreen;
4+
import com.cleanroommc.modularui.screen.GuiContainerWrapper;
65

76
import net.minecraftforge.client.event.GuiScreenEvent;
87
import net.minecraftforge.fml.common.eventhandler.EventPriority;
@@ -11,7 +10,6 @@
1110
import net.minecraftforge.fml.relauncher.Side;
1211
import net.minecraftforge.fml.relauncher.SideOnly;
1312

14-
import org.lwjgl.input.Mouse;
1513
import org.lwjgl.opengl.GL11;
1614

1715
import java.io.IOException;
@@ -32,17 +30,6 @@ public static void onClientTick(TickEvent.ClientTickEvent event) {
3230
}
3331
}
3432

35-
@SubscribeEvent
36-
public static void onScroll(GuiScreenEvent.MouseInputEvent.Pre event) {
37-
ModularScreen screen = ModularScreen.getCurrent();
38-
if (screen != null) {
39-
int w = Mouse.getEventDWheel();
40-
if (w != 0 && screen.onMouseScroll(w > 0 ? ModularScreen.UpOrDown.UP : ModularScreen.UpOrDown.DOWN, Math.abs(w))) {
41-
event.setCanceled(true);
42-
}
43-
}
44-
}
45-
4633
@SubscribeEvent
4734
public static void preDraw(TickEvent.RenderTickEvent event) {
4835
if (event.phase == TickEvent.Phase.START) {
@@ -78,6 +65,6 @@ public static void onGuiInput(GuiScreenEvent.KeyboardInputEvent.Pre event) {
7865
}
7966

8067
private static boolean hasDraggable(GuiScreenEvent event) {
81-
return event.getGui() instanceof GuiScreenWrapper screenWrapper && screenWrapper.getScreen().getContext().hasDraggable();
68+
return event.getGui() instanceof GuiContainerWrapper screenWrapper && screenWrapper.getScreen().getContext().hasDraggable();
8269
}
8370
}

src/main/java/com/cleanroommc/modularui/ClientProxy.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.cleanroommc.modularui;
22

33
import com.cleanroommc.modularui.drawable.DrawableSerialization;
4-
import com.cleanroommc.modularui.factory.GuiManager;
54
import com.cleanroommc.modularui.holoui.HoloScreenEntity;
65
import com.cleanroommc.modularui.holoui.ScreenEntityRender;
76
import com.cleanroommc.modularui.keybind.KeyBindHandler;
7+
import com.cleanroommc.modularui.overlay.OverlayManager;
8+
import com.cleanroommc.modularui.screen.ClientScreenHandler;
89
import com.cleanroommc.modularui.test.EventHandler;
10+
import com.cleanroommc.modularui.test.OverlayTest;
911
import com.cleanroommc.modularui.theme.ThemeManager;
1012
import com.cleanroommc.modularui.theme.ThemeReloadCommand;
1113

@@ -31,10 +33,13 @@ void preInit(FMLPreInitializationEvent event) {
3133
super.preInit(event);
3234

3335
MinecraftForge.EVENT_BUS.register(ClientEventHandler.class);
36+
MinecraftForge.EVENT_BUS.register(ClientScreenHandler.class);
37+
MinecraftForge.EVENT_BUS.register(OverlayManager.class);
3438
MinecraftForge.EVENT_BUS.register(KeyBindHandler.class);
3539

3640
if (ModularUIConfig.enabledTestGuis) {
3741
MinecraftForge.EVENT_BUS.register(EventHandler.class);
42+
OverlayTest.init();
3843
}
3944

4045
DrawableSerialization.init();

src/main/java/com/cleanroommc/modularui/CommonProxy.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package com.cleanroommc.modularui;
22

3-
import com.cleanroommc.modularui.factory.GuiManager;
4-
import com.cleanroommc.modularui.factory.ItemGuiFactory;
5-
import com.cleanroommc.modularui.factory.SidedTileEntityGuiFactory;
6-
import com.cleanroommc.modularui.factory.TileEntityGuiFactory;
3+
import com.cleanroommc.modularui.factory.*;
74
import com.cleanroommc.modularui.holoui.HoloScreenEntity;
85
import com.cleanroommc.modularui.network.NetworkHandler;
96
import com.cleanroommc.modularui.screen.ModularContainer;
@@ -42,9 +39,7 @@ void preInit(FMLPreInitializationEvent event) {
4239

4340
NetworkHandler.init();
4441

45-
GuiManager.registerFactory(TileEntityGuiFactory.INSTANCE);
46-
GuiManager.registerFactory(SidedTileEntityGuiFactory.INSTANCE);
47-
GuiManager.registerFactory(ItemGuiFactory.INSTANCE);
42+
GuiFactories.init();
4843
}
4944

5045
void postInit(FMLPostInitializationEvent event) {

src/main/java/com/cleanroommc/modularui/ModularUI.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ public void postInit(FMLPostInitializationEvent event) {
4949
proxy.postInit(event);
5050
}
5151

52-
@Mod.EventHandler
53-
public void onLoadComplete(FMLLoadCompleteEvent event) {
54-
}
55-
5652
@Mod.EventHandler
5753
public void onServerLoad(FMLServerStartingEvent event) {
5854
proxy.onServerLoad(event);
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.cleanroommc.modularui.api;
2+
3+
import com.cleanroommc.modularui.core.mixin.GuiContainerAccessor;
4+
import com.cleanroommc.modularui.screen.ClientScreenHandler;
5+
import com.cleanroommc.modularui.screen.ModularScreen;
6+
7+
import net.minecraft.client.gui.GuiScreen;
8+
import net.minecraft.client.gui.inventory.GuiContainer;
9+
import net.minecraft.inventory.Slot;
10+
11+
import net.minecraftforge.fml.relauncher.Side;
12+
import net.minecraftforge.fml.relauncher.SideOnly;
13+
14+
import org.jetbrains.annotations.ApiStatus;
15+
import org.jetbrains.annotations.NotNull;
16+
17+
import java.awt.*;
18+
import java.util.function.IntConsumer;
19+
20+
/**
21+
* Implement this interface on a {@link GuiScreen} to be able to use it as a custom wrapper.
22+
* The GuiScreen should have final {@link ModularScreen} field, which is set from the constructor.
23+
* Additionally, the GuiScreen MUST call {@link ModularScreen#construct(IMuiScreen)} in its constructor.
24+
* See {@link com.cleanroommc.modularui.screen.GuiScreenWrapper GuiScreenWrapper} and {@link com.cleanroommc.modularui.screen.GuiContainerWrapper GuiContainerWrapper}
25+
* for default implementations.
26+
*/
27+
@SideOnly(Side.CLIENT)
28+
public interface IMuiScreen {
29+
30+
/**
31+
* Returns the {@link ModularScreen} that is being wrapped. This should return a final instance field.
32+
*
33+
* @return the wrapped modular screen
34+
*/
35+
@NotNull
36+
ModularScreen getScreen();
37+
38+
/**
39+
* {@link GuiScreen GuiScreens} need to be focused when a text field is focused, to prevent key input from
40+
* behaving unexpectedly.
41+
*
42+
* @param focused if the screen should be focused
43+
*/
44+
default void setFocused(boolean focused) {
45+
getGuiScreen().setFocused(focused);
46+
}
47+
48+
/**
49+
* This method decides how the gui background is drawn.
50+
* The intended usage is to override {@link GuiScreen#drawWorldBackground(int)} and call this method
51+
* with the super method reference as the second parameter.
52+
*
53+
* @param tint background color tint
54+
* @param drawFunction a method reference to draw the world background normally with the tint as the parameter
55+
*/
56+
@ApiStatus.NonExtendable
57+
default void handleDrawBackground(int tint, IntConsumer drawFunction) {
58+
if (ClientScreenHandler.shouldDrawWorldBackground()) {
59+
drawFunction.accept(tint);
60+
}
61+
ClientScreenHandler.drawDarkBackground(getGuiScreen(), tint);
62+
}
63+
64+
/**
65+
* This method is called every time the {@link ModularScreen} resizes.
66+
* This usually only affects {@link GuiContainer GuiContainers}.
67+
*
68+
* @param area area of the main panel
69+
*/
70+
default void updateGuiArea(Rectangle area) {
71+
if (getGuiScreen() instanceof GuiContainer container) {
72+
ClientScreenHandler.updateGuiArea(container, area);
73+
}
74+
}
75+
76+
/**
77+
* @return if this wrapper is a {@link GuiContainer}
78+
*/
79+
@ApiStatus.NonExtendable
80+
default boolean isGuiContainer() {
81+
return getGuiScreen() instanceof GuiContainer;
82+
}
83+
84+
/**
85+
* Hovering widget is handled by {@link com.cleanroommc.modularui.screen.viewport.GuiContext}.
86+
* If it detects a slot, this method is called. Only affects {@link GuiContainer GuiContainers}.
87+
*
88+
* @param slot hovered slot
89+
*/
90+
@ApiStatus.NonExtendable
91+
default void setHoveredSlot(Slot slot) {
92+
if (getGuiScreen() instanceof GuiContainerAccessor acc) {
93+
acc.setHoveredSlot(slot);
94+
}
95+
}
96+
97+
/**
98+
* Returns the {@link GuiScreen} that wraps the {@link ModularScreen}.
99+
* In most cases this does not need to be overridden as this interfaces should be implemented on {@link GuiScreen GuiScreens}.
100+
*
101+
* @return the wrapping gui screen
102+
*/
103+
default GuiScreen getGuiScreen() {
104+
return (GuiScreen) this;
105+
}
106+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.cleanroommc.modularui.api;
2+
3+
import net.minecraft.client.Minecraft;
4+
import net.minecraft.client.entity.EntityPlayerSP;
5+
import net.minecraft.client.gui.GuiScreen;
6+
7+
public class MCHelper {
8+
9+
public static boolean hasMc() {
10+
return getMc() != null;
11+
}
12+
13+
public static Minecraft getMc() {
14+
return Minecraft.getMinecraft();
15+
}
16+
17+
public static EntityPlayerSP getPlayer() {
18+
if (hasMc()) {
19+
return getMc().player;
20+
}
21+
return null;
22+
}
23+
24+
public static boolean closeScreen() {
25+
if (!hasMc()) return false;
26+
EntityPlayerSP player = Minecraft.getMinecraft().player;
27+
if (player != null) {
28+
player.closeScreen();
29+
return true;
30+
}
31+
Minecraft.getMinecraft().displayGuiScreen(null);
32+
return false;
33+
}
34+
35+
public static boolean displayScreen(GuiScreen screen) {
36+
Minecraft mc = getMc();
37+
if (mc != null) {
38+
mc.displayGuiScreen(screen);
39+
return true;
40+
}
41+
return false;
42+
}
43+
44+
public static GuiScreen getCurrentScreen() {
45+
Minecraft mc = getMc();
46+
return mc != null ? mc.currentScreen : null;
47+
}
48+
}

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.cleanroommc.modularui.api;
22

33
import com.cleanroommc.modularui.factory.GuiData;
4+
import com.cleanroommc.modularui.screen.GuiContainerWrapper;
5+
import com.cleanroommc.modularui.screen.ModularContainer;
46
import com.cleanroommc.modularui.screen.ModularPanel;
57
import com.cleanroommc.modularui.screen.ModularScreen;
6-
78
import com.cleanroommc.modularui.value.sync.PanelSyncManager;
89

910
import net.minecraft.entity.player.EntityPlayer;
@@ -51,6 +52,22 @@ public interface UIFactory<D extends GuiData> {
5152
@ApiStatus.OverrideOnly
5253
ModularScreen createScreen(D guiData, ModularPanel mainPanel);
5354

55+
/**
56+
* Creates the screen wrapper for the GUI. Is only called on client side.
57+
*
58+
* @param container container for the gui
59+
* @param screen the screen which was created in {@link #createScreen(GuiData, ModularPanel)}
60+
* @return new screen wrapper
61+
* @throws IllegalStateException if the wrapping screen is not a {@link net.minecraft.client.gui.inventory.GuiContainer GuiContainer} or if the
62+
* container inside is not the same as the one passed to this method. This method is not the thrower, but the
63+
* caller of this method.
64+
*/
65+
@SideOnly(Side.CLIENT)
66+
@ApiStatus.OverrideOnly
67+
default IMuiScreen createScreenWrapper(ModularContainer container, ModularScreen screen) {
68+
return new GuiContainerWrapper(container, screen);
69+
}
70+
5471
/**
5572
* Writes the gui data to a buffer.
5673
*

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.cleanroommc.modularui.api.drawable;
22

3+
import com.cleanroommc.modularui.drawable.DrawableArray;
34
import com.cleanroommc.modularui.drawable.Icon;
45
import com.cleanroommc.modularui.screen.viewport.GuiContext;
56
import com.cleanroommc.modularui.theme.WidgetTheme;
@@ -10,6 +11,7 @@
1011
import net.minecraftforge.fml.relauncher.SideOnly;
1112

1213
import com.google.gson.JsonObject;
14+
import org.jetbrains.annotations.Nullable;
1315

1416
/**
1517
* An object which can be drawn. This is mainly used for backgrounds and overlays in
@@ -138,6 +140,14 @@ default void loadFromJson(JsonObject json) {}
138140
*/
139141
IDrawable NONE = (context, x, y, width, height, widgetTheme) -> {};
140142

143+
static boolean isVisible(@Nullable IDrawable drawable) {
144+
if (drawable == null || drawable == EMPTY || drawable == NONE) return false;
145+
if (drawable instanceof DrawableArray array) {
146+
return array.getDrawables().length > 0;
147+
}
148+
return true;
149+
}
150+
141151
/**
142152
* A widget wrapping a drawable. The drawable is drawn between the background and the overlay.
143153
*/

src/main/java/com/cleanroommc/modularui/api/layout/IViewportStack.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.cleanroommc.modularui.api.layout;
22

33
import com.cleanroommc.modularui.screen.viewport.TransformationMatrix;
4+
import com.cleanroommc.modularui.utils.Vector3f;
45
import com.cleanroommc.modularui.widget.sizer.Area;
56

67
import org.jetbrains.annotations.Nullable;
7-
import org.lwjgl.util.vector.Vector3f;
88

99
/**
1010
* This handles all viewports in a GUI. Also keeps track of a matrix stack used for rendering and

0 commit comments

Comments
 (0)