Giter VIP home page Giter VIP logo

modularui's Introduction

ModularUI

What is ModularUI?

ModularUI is a library for Minecraft aiming to make GUI's much easier.

Why ModularUI?

Minecrafts (and Forges) gui code is not very good and the code gets really messy really fast. With ModularUI you can build GUIs fast by adding Widgets to panels with layout widgets, so you don't have to calculate positions and sizes yourself. ModularUI is very dynamic and allows for very complicated client only or even client-server synced GUIs. A good example is fluid slots in GUIs. Minecraft and Forge don't offer anything to add fluid slots or tanks to a GUI. With ModularUI you simply call .child(new FluidSlot().syncHandler(new FluidTank(16000))) (along with some setters).

Key features

  • panel system similar to windows
  • widgets are placed in a tree like structure
  • widget rendering and interactions are automatically handled
  • easy and dynamic widget sizing and positioning
  • syncing widget values
  • good for client only GUIs and client-server synced GUIs
  • GUI themes are loaded via JSON and can be added and modified by resourcepacks
  • JEI compat for things like exclusion zones

History

  • First appearance of ModularUI in GTCE by Archengius
  • on 30th December 2021 GTCEu released with some improvements to its GUI library
  • on 16th January 2022 Rongmario created the ModularUI repository in the CleanroomMC organization with the intention to rewrite it
  • on 19th February I (brachy) started working on ModularUI
  • on 21st May 2022 ModularUI version 1.0.0 was released on Curseforge
  • miozune decided to port ModularUI to 1.7.10 for GTNH
  • after 3 month of updates I decided to rewrite some parts of the library
  • the rewrite turned very large and thus ModularUI 2 was born
  • on 21st March 2023 I uploaded version 2.0.0 to Curseforge
  • since then ModularUI is constantly receiving updates

modularui's People

Contributors

brachy84 avatar bruberu avatar ghzdude avatar miozune avatar rongmario avatar serenibyss avatar testure avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

modularui's Issues

`modularui 2.3.0` Crash on game load

Loading game with updated modularui 2.3.0 causing crash:

NullPointerException: Unexpected error
    at net.minecraft.client.Minecraft.handler$zgc000$timer(Minecraft.java:5337)
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1094)

crash-2023-11-07_11.03.40-client.txt

Downgrading to previous version fixes the issue.

What means `[main/ERROR] [mixin]: Classloader restrictions [PACKAGE_TRANSFORMER_EXCLUSION]`?

Loading E2E-E with ModularUI print this errors in debug.log file:

[main/ERROR] [mixin]: Classloader restrictions [PACKAGE_TRANSFORMER_EXCLUSION] encountered loading mixin.modularui.json:SlotMixin from mod unknown-owner, name: com.cleanroommc.modularui.core.mixin.SlotMixin
[main/ERROR] [mixin]: Classloader restrictions [PACKAGE_TRANSFORMER_EXCLUSION] encountered loading mixin.modularui.json:GuiContainerAccessor from mod unknown-owner, name: com.cleanroommc.modularui.core.mixin.GuiContainerAccessor
[main/ERROR] [mixin]: Classloader restrictions [PACKAGE_TRANSFORMER_EXCLUSION] encountered loading mixin.modularui.json:GuiContainerMixin from mod unknown-owner, name: com.cleanroommc.modularui.core.mixin.GuiContainerMixin
[main/ERROR] [mixin]: Classloader restrictions [PACKAGE_TRANSFORMER_EXCLUSION] encountered loading mixin.modularui.json:KeyBindAccess from mod unknown-owner, name: com.cleanroommc.modularui.core.mixin.KeyBindAccess
[main/ERROR] [mixin]: Classloader restrictions [PACKAGE_TRANSFORMER_EXCLUSION] encountered loading mixin.modularui.json:MinecraftMixin from mod unknown-owner, name: com.cleanroommc.modularui.core.mixin.MinecraftMixin
[main/ERROR] [mixin]: Classloader restrictions [PACKAGE_TRANSFORMER_EXCLUSION] encountered loading mixin.modularui.json:SlotAccessorClient from mod unknown-owner, name: com.cleanroommc.modularui.core.mixin.SlotAccessorClient

What does them means? Is that means some of GUIs or functionality of BogoSorter wouldnt work?

Opening configs with fading causing fade blink

Im opening configs of Bogo Sorting mod from inside of container.

  • Inside containers, background already faded.
  • As i clicking [...] button, fade becomes 100% transparent and than fade in again into black

This causing unpleasant "blink".

javaw_p2BYRQxSt8.mp4

Proper way to sync ItemStack created from NBT data

When you scrolling, ItemSlotSH#phantomScroll(MouseData) will be called, and it will try increase the stack by call ItemSlotSH#incrementStackCount(I) method.
However, this method will not working since it only increase the ItemStack object, but not treat ItemStackItemHandler as special case.


In ItemStackItemHandler#getStackInSlot(I), the ItemStack is created using NBTData, result in a new ItemStack object. This cause some issues when you try to use it as a phantom slot(s).

Solution: A simple instanceof check for ItemStackItemHandler. If true, call setStackInSlot instead.

This solution won't help with other mods broke themself. But atleast it should help the outcome for mods that use or implementing ItemStackItemHandler for their item's capability.

P/s: Will review sync rework once the mod update is pushed

[Suggestion] Add an Interface for Custom Behavior in ModularContainer

Currently, everyone using ModularUI is at the whim's of the existing behavior for the methods in ModularContainer/Container with no easy way to modify them without resorting to mixin or similar.

I propose adding an interface that a class extending ModularSlot can implement, and checking instanceof that interface to do custom behavior for certain methods in ModularContainer instead of the default behavior. Some return type would be needed to check in case an implementing class wants to fallback to default behavior for some reason.

People may want custom behavior for these methods:

  • slotClick()
  • canMergeSlot()
  • onContainerClosed()
  • canInteractWith()
  • mergeItemStack()
  • canAddItemToSlot()
  • clearContainer()
  • transferStackInSlot()

Could also add some methods within transferItem() so that a slot could override the default behavior, to allow support for oversized slots (to handle super/quantum chests from CEu)

I could make a pr that does this, but let me know what you think, when able.

NetworkDispatcher exception

Your mod messing up with packets
Version: modularui-1.0.6
Forge: 14.23.5.2860
Full log: https://paste.gg/p/anonymous/f7201729ffd64b60a3b7de43996b70f1

20:31:24] [Client thread/INFO]: [CHAT] [AC]  Please, login with the command: /login <password>
--
  | [20:31:26] [Client thread/INFO]: [CHAT] [AC]  Successful login!
  | [20:31:27] [Netty Client IO #9/ERROR]: NetworkDispatcher exception
  | io.netty.handler.codec.DecoderException: java.lang.IndexOutOfBoundsException: readerIndex(10) + length(1) exceeds writerIndex(10): UnpooledHeapByteBuf(ridx: 10, widx: 10, cap: 10/10)
  | at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:442) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:280) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:396) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:624) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:559) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:476) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) [netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at java.lang.Thread.run(Thread.java:745) [?:1.8.0_51]
  | Caused by: java.lang.IndexOutOfBoundsException: readerIndex(10) + length(1) exceeds writerIndex(10): UnpooledHeapByteBuf(ridx: 10, widx: 10, cap: 10/10)
  | at io.netty.buffer.AbstractByteBuf.checkReadableBytes0(AbstractByteBuf.java:1396) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at io.netty.buffer.AbstractByteBuf.readByte(AbstractByteBuf.java:687) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
  | at net.minecraft.network.PacketBuffer.readByte(PacketBuffer.java:864) ~[gy.class:?]
  | at net.minecraft.network.PacketBuffer.readVarInt(PacketBuffer.java:201) ~[gy.class:?]
  | at net.minecraft.network.play.server.SPacketSetSlot.handler$zbo000$readPacketData(SourceFile:522) ~[iu.class:?]
  | at net.minecraft.network.play.server.SPacketSetSlot.readPacketData(SourceFile:38) ~[iu.class:?]
  | at net.minecraft.network.NettyPacketDecoder.decode(SourceFile:40) ~[gz.class:?]
  | at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
  | ... 31 more

Replace Java bytecode error in MethodVisitor

The exception is thrown:(indev)

Caused by: java.lang.NoSuchMethodError: net.minecraft.network.PacketBuffer.writeVarInt(I)Lio/netty/buffer/ByteBuf;
	at net.minecraft.network.PacketBuffer.writeItemStack(PacketBuffer.java:365)
	at net.minecraftforge.fml.common.network.ByteBufUtils.writeItemStack(ByteBufUtils.java:180)

(Also the exception is thrown in runtime.)

The method descriptor of "writeVarInt" is "(I)Lnet.minecraft.network.PacketBuffer;" , not "(I)Lio/netty/buffer/ByteBuf;".
Should replace the desc in

if ("writeByte".equals(name)) {
name = WRITE_VAR_INT_METHOD;
} else if ("readByte".equals(name)) {
, taking care of the obfuscated class name of "net.minecraft.network.PacketBuffer".

Issues with PanelSyncHandler

Currently, the PanelSyncHandler (PanelSH) has some issues when opening up and closing popup panels.

Namely;

  • Widgets contained in the panel are not disabled when the panel is closed using close() from the PanelSH
  • ItemSlots created in the panel within the PanelSH are duplicated in ModularContainer and not disabled/invalidated
  • The panel created for the PanelSH does not consider itself synced (isSynced() is not overridden and is always false)

I've considered some solutions, such as;

  • Adding a method in ModularContainer to remove tracked slots in the current container
  • Constructing the panel in PanelSH's constructor (this causes issues if the expect panel is supposed to change under certain conditions)
  • Overriding setEnabled() in ParentWidget<> to call setEnabled() on the parent's children
  • Syncing removing slots and disabling child widgets with the PanelSH
  • Adding the PanelSH to the contructed panel.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.