Git Product home page Git Product logo

elementa's People

Contributors

blackbeltpanda avatar callumbugajski avatar camnwalter avatar caoimhebyrne avatar chachydev avatar dediamondpro avatar djtheredstoner avatar falsehonesty avatar johni0702 avatar karkkikuppi avatar kerbybit avatar llamalad7 avatar mattco98 avatar mew avatar moulberry avatar nichrosia avatar redepicness avatar shedaniel avatar sk1er avatar sychic avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

elementa's Issues

Customisable Scroll Animation

Is your feature request related to a problem? Please describe.
Scrolling with the Elementa UI library feels pretty smooth, but I would like to choose the specific animation algorithm - the scrolling in other programs such as my web browser uses a different animation.

Describe the solution you'd like
In the constructor, add a parameter to change the AnimationStategy.

Describe alternatives you've considered
I tried subclassing ScrollComponent, but it appears to be final.

[Craftify (based on Elementa)] Elementa crashes after a while of leaving the game open, killing the Craftify GUI.

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Run minecraft with Craftify (a music control mod)
  2. Join a world and set up Craftify using /craftify (Documentation here)
  3. Leave the game open and idle for who knows how long
  4. You'll get a message in chat and a ton of spam in the logs, and the "now playing" area will stop rendering.

Expected behavior
Leaving the game open doesn't cause any errors

Additional context

System: Arch Linux (6.4.4-zen1-1-zen)
Java version: 17
Minecraft: 1.20.1
Elementa version: integrated as a child mod, unknown

Log:

[13:14:36] [Render thread/INFO]: Game entered main loop!   <-- Game officially started

...    over 4 hours later of various logs from other mods and the main game...

[17:35:23] [Render thread/INFO]: [STDOUT]: Elementa: Cyclic constraint structure detected!
[17:35:23] [Render thread/INFO]: [STDOUT]: If you are a developer, set the environment variable "elementa.dev=true" to assist in debugging the issue.
[17:35:23] [Render thread/INFO]: [STDOUT]: Gui name: class_433
[17:35:23] [Render thread/INFO]: [STDERR]: java.lang.StackOverflowError
[17:35:23] [Render thread/INFO]: [STDERR]: 	at gg.essential.elementa.constraints.RelativeConstraint.getWidthImpl(RelativeConstraint.kt:38)
[17:35:23] [Render thread/INFO]: [STDERR]: 	at gg.essential.elementa.constraints.WidthConstraint.getWidth(Constraint.kt:138)
[17:35:23] [Render thread/INFO]: [STDERR]: 	at gg.essential.elementa.constraints.animation.WidthAnimationComponent.getWidthImpl(AnimationComponent.kt:163)
[17:35:23] [Render thread/INFO]: [STDERR]: 	at gg.essential.elementa.constraints.WidthConstraint.getWidth(Constraint.kt:138)
[17:35:23] [Render thread/INFO]: [STDERR]: 	at gg.essential.elementa.constraints.animation.WidthAnimationComponent.getWidthImpl(AnimationComponent.kt:163)

...    Continues for thousands of lines

[17:35:23] [Render thread/INFO]: [STDERR]: 	at gg.essential.elementa.constraints.animation.WidthAnimationComponent.getWidthImpl(AnimationComponent.kt:163)
[17:35:23] [Render thread/INFO]: [STDERR]: 	at gg.essential.elementa.constraints.WidthConstraint.getWidth(Constraint.kt:138)
[17:35:23] [Render thread/INFO]: [STDERR]: 	at gg.essential.elementa.constraints.animation.WidthAnimationComponent.getWidthImpl(AnimationComponent.kt:163)
[17:35:23] [Render thread/INFO]: [STDERR]: 	at gg.essential.elementa.constraints.WidthConstraint.getWidth(Constraint.kt:138)
[17:35:23] [Render thread/INFO]: [CHAT] §cElementa encountered an error while drawing a GUI. Check your logs for more information.
[17:35:23] [DefaultDispatcher-worker-6/ERROR]: Uncaught exception in thread "DefaultDispatcher-worker-6"
java.lang.StackOverflowError: null
	at gg.essential.elementa.constraints.WidthConstraint.getWidth(Constraint.kt:138) ~[elementa-590-c4250c8341948a4b.jar:?]
	at gg.essential.elementa.constraints.animation.WidthAnimationComponent.getWidthImpl(AnimationComponent.kt:163) ~[elementa-590-c4250c8341948a4b.jar:?]
	at gg.essential.elementa.constraints.WidthConstraint.getWidth(Constraint.kt:138) ~[elementa-590-c4250c8341948a4b.jar:?]
	at gg.essential.elementa.constraints.animation.WidthAnimationComponent.getWidthImpl(AnimationComponent.kt:163) ~[elementa-590-c4250c8341948a4b.jar:?]

...    more log spam

	at gg.essential.elementa.constraints.animation.WidthAnimationComponent.getWidthImpl(AnimationComponent.kt:163) ~[elementa-590-c4250c8341948a4b.jar:?]
	at gg.essential.elementa.constraints.WidthConstraint.getWidth(Constraint.kt:138) ~[elementa-590-c4250c8341948a4b.jar:?]
	at gg.essential.elementa.constraints.animation.WidthAnimationComponent.getWidthImpl(AnimationComponent.kt:163) ~[elementa-590-c4250c8341948a4b.jar:?]
	at gg.essential.elementa.constraints.WidthConstraint.getWidth(Constraint.kt:138) ~[elementa-590-c4250c8341948a4b.jar:?]
	at gg.essential.elementa.constraints.animation.WidthAnimationComponent.getWidthImpl(AnimationComponent.kt:163) ~[elementa-590-c4250c8341948a4b.jar:?]
[17:37:48] [Render thread/INFO]: [CHAT] [Rank]Multiplayerplayer1: Ill give someone a stack of emeralds for feather falling 4
[17:37:59] [Render thread/INFO]: [CHAT] [Rank]Multiplayerplayer2: ive got one
[17:38:21] [Render thread/INFO]: [CHAT] [Rank]Multiplayerplayer1: Bet

MSDF FontRenderer misaligned text height

Describe the bug
Text rendered with the MSDF FontRenderer is higher than it should be, outside the bounding box of the constraints.

To Reproduce
Steps to reproduce the behavior:

  1. Render any UIText with fontProvider set to one that uses MSDF FontRenderer.
  2. Having an OutlineEffect makes the misalignment easier to see.

Expected behavior
Text should be rendered inside the bounding box of the constraints.

Screenshots
image
Sample text rendered using DefaultFonts.ELEMENTA_MINECRAFT_FONT_RENDERER with CenterConstraint() and an OutlineEffect().

image
Same text and code, but using DefaultFonts.VANILLA_FONT_RENDERER instead.

Additional context
Only affects fonts created with FontRenderer. VanillaFontRenderer and BasicFontRenderer are rendered correctly

Message Preview Selection

Describe the bug
While in the texting box in Essential, if you have a message at least 3 lines long in the preview, and you try to select the lines below, it crashes the GUI.
image

To Reproduce

  1. Go to a PM/DM of any user
  2. Type a message at least 3 lines long
  3. Go to the top and try selecting the lines below by holding down your cursor on the text you wrote and moving your cursor down
  4. It crashes, with an error

Expected behavior
The text below that you are trying to select should be selected, instead you are meant with the GUI closing

Screenshots/Videos
Video Example

ExampleGui.kt not working correctly

Describe the bug
So, when the GUI opens there are two problems with the StickyNote() classwhen you click on "Create Notes!":

  1. You aren't able to write any text
  2. The "textHolder" is 2 pixels to high

To Reproduce
Steps to reproduce the behavior:
First Bug

  1. Open the GUI in any way you set it up (I did it with a command)
  2. Click on 'Create Notes!'
  3. See error: You can't write any text

Second Bug

  1. Open the GUI in any way you set it up (I did it with a command)
  2. Click on 'Create Notes!'
  3. The Gray Area is too long, goes till outside the "StickyNote" on the bottom side

Screenshots
Second Bug
image

Elementa throws NoSuchElementException when using empty lists in Markdown Component

Describe the bug
When trying to create a Markdown Component with a character that's also a markdown prefix, such as a single hyphen ("-") which normally denotes a list, Elementa will throw a NoSuchElementException and not render the screen.

To Reproduce
Steps to reproduce the behavior:

  1. Create a Markdown Component
  2. Set the components text content to "-"
  3. See error

Expected behavior
A list prefix with no other content should probably just render the prefix itself.

Additional context
It's possible that the same would occur for other elements that expect a markdown prefix to be followed by some content, but I haven't tested that to make sure.

Clicks are not detected outside of parents

Describe the bug
If you create an object that has a negative coordinate, or a coordinate outside the parent, the onMouseClick event will not trigger. onMouseEnter and onMouseLeave still trigger however.

To Reproduce
Steps to reproduce the behavior:

  1. Create a parent object
  2. Create a child of the parent object, with a location outside the parent object
  3. Give the parent object an onMouseClick event

Expected behavior
The click event should trigger (as does the onMouseEnter and onMouseLeave)

1.19+

Hello, is it possible to update the mod to 1.19.2 ?
It crash because TranslatableText can't be casted to Text

Server Plugin GUI

Hi there, I was browsing in the Internet for some GUI server plugin and I ran into Elementa. So the question is: can this be used for plugin's GUI?

Timer API

Is your feature request related to a problem? Please describe.
Sometimes, a gui will require running certain code at repeating intervals, such as performing an action while a button is being held. Currently, the Animation API supports running an animation for a specified amount of time, so I'd like there to be a general way to run any code over a certain period.

Describe the solution you'd like
An API such as the following could be nice:

component.startTimer(interval: Float, delay: Float) {

}

component.stopTimer()

Though this API is only feasible for a single timer. To support multiple timers, the start timer function could return a timer ID which could then be passed to stop timer, mimicking the browser's setInterval and clearInterval functions.

Hide API

Is your feature request related to a problem? Please describe.
When certain elements need to be dynamically hidden, the current best option is to simply remove it from its parent, and then re-add it at a later time. The issue with this is the fact that its a little bulky and unintuitive.

Describe the solution you'd like
An API similar to

component.hide()
component.unhide()

component.animateBeforeHide {
	color = ...
}

component.animateAfterUnhide {
	width = ...
}

This would provide a simply, intuitive way to hide and unhide components, while also providing the flexibility of being able to animate in/out those components.

Features: Suggestions

Here's just a few suggestions that would make the GUI's we can create far more feature rich and appealing.

Ideas

  • Add scrollable areas
  • Rounding shader
  • Outline constraint
  • Add text wrapping
  • Shadows

Stenciling performance

Describe the bug
When you have a category with a bunch of options, performance is hit heavily wasting time trying to render but also being told to not render.

To Reproduce
Create a bunch of options using Vigilance, open the gui, watch everything come to a halt

Screenshots
A gui with ~30 options
image

A gui with ~200 options
image

StencilEffect doesn't work on 1.18

Describe the bug
Elementa's StencilEffect doesn't work in 1.18 as the enableStencil function doesn't have any implementation for versions less than 1.15.

To Reproduce
Steps to reproduce the behavior:

  1. Call StencilEffect.enableStencil() in your mod's initializer
  2. Add the StencilEffect to your component

Expected behavior
The component should be scissored around the parent component

Additional context
To enable stencils in 1.18, I found this gist, but I wasn't able to get it working properly.

README.md install instructions do not seem to be up to date and a little bit vague

This project tells people to install the latest snapshot versions by adding implementation "club.sk1er:Elementa:129-$mcVersion-SNAPSHOT" in their dependencies section. However, Vigilance specifies "gg.essential:Elementa:339-$mcVersion-SNAPSHOT" instead.

Also, $mcVersion does not seem to be a well explained variable. Generally, variables like that are expected to be replaced version numbers such as "1.16.5". But, looking through the repository's maven-metadata.xml, it seems that the format is different, e.g. $mcVersion = 11602 is used for all 1.16 versions.

Focus API

Is your feature request related to a problem? Please describe.
In order to support elements such as modals, a component needs to be able to grab focus away from other components, to avoid clicking "through" a component.

Describe the solution you'd like
I'd like for a UIComponent to be able to "focus" a single of its children. This would mean that any focused component would be the only child to receive mouse and keyboard events.

Fix Elementa ScrollComponent

Is your feature request related to a problem? Please describe.
Horizontal scrolling only works when the shift is pressed, regardless of whether vertical scrolling is enabled or not. Code Link Code Link

Describe the solution you'd like
If vertical scrolling is disabled, then horizontal scrolling does not require pressing Shift.

Describe alternatives you've considered
The use of ASM transformers (Mixin) in this case is not advisable, and a private fork with a bug fix is ​​redundant.

Additional context
Discord Message

Support for displaying a UScreen as an Elementa component

Is your feature request related to a problem? Please describe.
No

Describe the solution you'd like
Currently in Elementa there is no component to provide a Minecraft GUI (UScreen) as an element. This means that people who would like to incoporate Minecraft GUIs into their own mod have to open the GUI normally making it look tacky.

Describe alternatives you've considered
An alternative would be simply opening the Minecraft GUI via the way provided by the version (Minecraft#displayGuiScreen in 1.8.9).

Additional context

MarkdownComponent: NotImplementedError in certain edge cases with blank markdown

Describe the bug
In certain cases, the a MarkdownComponent can have 0 drawables, which causes a NotImplementedError here.

To Reproduce
Steps to reproduce the behavior:

  1. Apply this patch to ComponentsGui
@@ -267,7 +268,7 @@
         } childOf window
 
         ComponentType("Markdown") {
-            MarkdownComponent(
+            val c = MarkdownComponent(
                 """
                     # Markdown!
                     
@@ -283,6 +284,11 @@
                 width = 200.pixels()
                 height = 100.pixels()
             } childOf this
+
+            c.onMouseClick {
+                c.bindText(BasicState(""))
+            }
+
         } childOf window
 
         ComponentType("SVG") {
  1. Open the components gui
  2. Click on the current text of the markdown component, hold and drag to another location on the screen
  3. The gui crashes and a NotImplementedError is logged (example)

Expected behavior
The the markdown component becomes blank without crashing the gui.

Additional context
There are possibly other ways to trigger this issue, but this is the way I found. The root cause appears to be commonmark's parser not having any children nodes for a blank document, causing MarkdownRenderer to produce an empty drawable list

Bug with at least 1.15+ Elementa

Describe the bug
When loading the game, the game crashes, presumably because of the slick2d dependency (as I was told on the discord)

To Reproduce
Steps to reproduce the behavior:

  1. Load the game
  2. Crash

Expected behavior
I expected the game to not crash on startup

  • OS: Windows 10 2004

Crash Error:
https://pastebin.com/NpNSd7ud

Cannot set cursorColor for UITextInput

Describe the bug
UITextInput constructor accepts cursorColor field, but always constructs superclass with Color.WHITE

To Reproduce
Steps to reproduce the behavior:

  1. Create UITextInput component with custom cursorColor.
  2. See it always WHITE in game.

Expected behavior
UITextInput with cursor colored by color from cursorColor field.

Additional context
Just one line fix here.

Unify units of time throughout the project

Elementa uses multiple units of time in various APIs, when it should really only ever use one. We need to choose between using floats for number of seconds, or Longs for number of milliseconds. This has to be resolved before release of 2.0, as it would be a breaking change.

Add support for rounded images through shaders

Is your feature request related to a problem? Please describe.
At the moment, images can only be rounded through stencil which can look very pixelated and ugly

Describe the solution you'd like
fsh:

#version 110
uniform float u_Radius;
uniform vec4 u_InnerRect;

uniform sampler2D u_Texture;

varying vec2 f_Position;
varying vec2 f_TexCoord;

void main() {
    vec2 tl = u_InnerRect.xy - f_Position;
    vec2 br = f_Position - u_InnerRect.zw;
    vec2 dis = max(br, tl);
    float v = length(max(vec2(0.0), dis)) - u_Radius;
    float a = 1.0 - smoothstep(0.0, 1.0, v);
    gl_FragColor = vec4(texture2D(u_Texture, f_TexCoord).rgb, a);
}

vsh:

#version 110

varying vec2 f_Position;
varying out vec2 f_TexCoord;

void main() {
    f_Position = gl_Vertex.xy;
    f_TexCoord = gl_MultiTexCoord0.xy;

    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    gl_FrontColor = gl_Color;
}

effect:

class ShaderEffect(private val radius: Float) : Effect() {
    private var shader: Shader = Shader("rounded_image", "rounded_image")
    private var shaderRadiusUniform: FloatUniform = FloatUniform(shader.getUniformLocation("u_Radius"))
    private var shaderInnerRectUniform = Vec4Uniform(shader.getUniformLocation("u_InnerRect"))

    override fun beforeDraw() {
        shader.bindIfUsable()
        shaderRadiusUniform.setValue(radius)
        shaderInnerRectUniform.setValue(
            Vector4f(
                boundComponent.getLeft() + radius,
                boundComponent.getTop() + radius,
                boundComponent.getRight() - radius,
                boundComponent.getBottom() - radius
            )
        )
    }

    override fun afterDraw() {
        shader.unbindIfUsable()
    }
}

Describe alternatives you've considered
Stencil

Additional context
with the shader:
image

Improve Docs

  • #92
  • Add constraints docs page
  • Maybe add something about states

Encourage use of `by` instead of `=`

Using val example by UIExampleComponent() instead of val example = UIExampleComponent() has the huge advantage that the inspector can show the name of the component.
We should explain this in the docs somewhere, and consistently make use of it in all example code.

Debug Visual Mode

Is your feature request related to a problem? Please describe.
When debugging a GUI, it is sometimes hard to tell the bounds of a component, leading to the user attempting to add extraneous debug components, etc.

Describe the solution you'd like
Instead, there should be a "Debug Visual Mode" that the user can enable with a system property. This mode will outline all UIComponents with a little, brightly colored outline to make it obvious what the bounds of a component are. The outline can be done simply through 4 draw rect calls, and performance isn't really an issue.

FillConstraint ignores paddings by SiblingConstrains

Describe the bug
When you make a stacked component and for example use Y, and every time you use SiblingConstraint() with paddings, the space in the parent component reduces, but FillComponent ignores that and uses full size and exceeds the space given by the parent component.

To Reproduce
Steps to reproduce the behavior:

val block = UIBlock().constrain {
                y = CramSiblingConstraint(3f)
                x = CramSiblingConstraint(3f)
                width = 100.pixels
                height = 110.pixels
                color = ConstantColorConstraint(VigilancePalette.getDividerDark())
            } effect ScissorEffect() childOf scroller
            UIImage.ofResource(module.logo).constrain {
                x = CenterConstraint()
                y = SiblingConstraint(3f) + 5f.pixels
                width = 64.pixels
                height = 64.pixels
            } childOf block
            UIText(module.spacedName).constrain {
                x = CenterConstraint()
                y = SiblingConstraint(10f)
            } childOf block
            val statusBlock = UIBlock(ConstantColorConstraint(BooleanDefinedColorState(module::state))).constrain {
                y = SiblingConstraint()
                x = CenterConstraint()
                width = 100.percent
                height = FillConstraint()
            } childOf block

            UIText("Enabled").constrain {
                x = CenterConstraint()
                y = CenterConstraint()
            } childOf statusBlock

Expected behavior
Used hard coded values

Снимок экрана 2023-10-11 в 20 26 17

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
No paddings:
No paddings
With paddings:
Paddings

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.