There are two newly updated TextInput components now: UITextInput and UIMultilineTextInput. These are very powerful and useful classes. Read more about these components and how to use them here.
The Inspector component is a great tool for debugging what is happening in your Elementa GUIs. It gives you the ability to see the component hierarchy, view the bounding box of components, view what constraints are being used, and much more. Read more about how to use the Inspector here.
Elementa v2.0.0 now has a full-fledged Markdown parser and renderer. This is a very useful component for rendering
rich text. Read more about the features of the MarkdownComponent
and how to use it here.
The PlotComponent allows the user to display an extremely customizable point graph. Nearly every aspect of the way the graph is drawn is configurable. Read more here
Added a new TreeListComponent component. It is used to display tree-like information in a collapsible list-like hierarchy. This is the primary component used by the Inspector, and is highly customizable. Read more here
The TreeGraphComponent displays nodes in a
top-down tree view. It shows the exact same information as the TreeListComponent
but in a different visual style. Read
more here.
There is now a WindowScreen class provided for an easy way to
avoid the boilerplate of calling all of the Window
events manually. Rather than extending GuiScreen
(or Screen
in
new Minecraft versions) in your GUI class, you can simply extend WindowScreen
and not worry about overriding the
keyTyped
, mouseReleased
, etc. methods. Additionally, it automatically declares a Window
instance for you to use,
and sets up the default key event listeners to that Window
instance, allowing your users to press <escape>
to leave
the GUI.
The utility functions insertChildAt
, insertChildBefore
, insertChildAfter
, and replaceChild
, have been added to
easily place components inside a parent's child hierarchy at useful positions.
By default, when calling UIComponent#hide
, it will wait for the next animation frame before actually removing that
child component from the hierarchy. While this is necessary to give the beforeHideAnimation
a chance to run,
sometimes it isn't what you want, so now the hide
function has an instantly
parameter which, when set to true,
will skip any animations and immediately remove the component.
Sometimes, when popping up a modal or a tooltip, that component should receive click events first, no matter where
it might be in the component hierarchy, because you have programmed it in a way where you know it is on top of
everything else. In order to facilitate this, you can call UIComponent#setFloating(true)
. This means that the
component will receive priority on all click events until you set it to be no longer floating.
The SVG component now supports dynamically changing its underlying SVG, as show in the following example:
svgComponent.setSVG(SVGParser.parseFromResource("/image.svg"))
The ScrollComponent now supports hiding the scrollbar when all the scroll pane's children fit inside of itself, i.e.
when there is nothing to actually scroll. To enable this option, pass the hideWhenUseless = true
argument to the
ScrollComponent#setScrollBarComponent
function.
The ScrollComponent also has overridden many parent UIComponent
functions to work properly, such as childrenOfType
,
removeChild
, etc.
Additionally, the ability to sort children has been added via the ScrollComponent#sortChildren
function.
Added ScrollComponent#setEmptyText(String)
to dynamically change the text displayed when the ScrollComponent
has
no children.
ImageProvider has been refactored, allowing for SVGComponents to now be valid image providers. This also means
that when a UIImage
fails to load, an SVG failure icon appears.
Added addVertices
function to add multiple vertices at once.
Added secondary constructor that accepts an initial ColorConstraint
.
Previously, constructing custom constraints was a hassle, as they had a lot of boilerplate code overriding parent variables and such. However, in v2.0.0 there is now an easy to use DSL to construct one-time constraints:
width = basicWidthConstraint { component ->
component.getHeight() + 10f
}
Pixel constraint now allows changing of the pixel value dynamically with PixelConstraint#setValue(Float)
.
Added the MousePositionConstraint which will evaluate to the current mouse X/Y position.
Added the ChildBasedRangeConstraint which evaluates the width/height difference between the component's two furthest children. This constraint is tricky to use as this component and all of its children need to have their X/Y position not reliant on any parental width/height.
The MinConstraint
and MaxConstraint
constraints that existed previously have been renamed to CoerceAtLeastConstraint
and CoerceAtMostConstraint
, to match the Kotlin stdlib naming. In addition, there is now a CoerceInConstraint
, as well
as a .coerceIn
DSL extension function.
With those constraints renamed, we have added new constraints called MinConstraint
and MaxConstraint
. These now do
what you would expect; MaxConstraint
chooses the larger of the two constraints, and MinConstraint
chooses the
smaller. These constraints have top-level helper functions called max(a, b)
and min(a, b)
.
There is now a way to delay an animation from completing for a certain amount of time after it has actually completed
via the AnimationConstraints#setExtraDelay(Float)
function.
Renamed the old function AnimationConstraints#complete
to AnimationConstraints#isComplete
to clarify any confusion.
Added option to draw the outline after all children have drawn via the drawAfterChildren: Boolean
constructor
parameter.
UIComponent
now has a couple functions relating to timers, to allow repetitive actions:
startTimer(interval: Long, delay: Long, callback: (id: Int) -> Unit): Int
- Starts a timer which activates the callback after a period of
interval
milliseconds has elapsed. Waitsdelay
milliseconds before activating. The callback receives the timer ID for cancelling the timer if needed. - Returns the timer ID
- Starts a timer which activates the callback after a period of
stopTimer(id: Int): Boolean
- Accepts a timer ID and cancels the timer. Returns true if the timer exists and was cancelled, false otherwise.
startDelay(delay: Long, callback: () -> Unit): Int
- Runs the callback once after
delay
milliseconds. - This is implemented as a normal timer, so it returns the timer ID.
- Runs the callback once after
stopDelay(id: Int): Boolean
- Just an alias for
stopTimer
, will work with the return values of bothstartTimer
andstartDelay
- Just an alias for
timer(interval: Long, delay: Long, callback: (id: Int) -> Unit): () -> Unit
- Like
startTimer
, but returns a function which, when executed, will cancel the timer
- Like
delay(delay: Long, callback: () -> Unit): () -> Unit
- Like
startDelay
, but returns a function which, when executed, will cancel the timer
- Like