Releases: Samerion/Fluid
v0.7.0-alpha.2: 0.7.0-alpha.2 — `TextInput` improvements
TextInput
has gotten a massive boost, and is now a proper text editor. On top of that, its subclass, CodeInput
is now available with optional syntax highlighting (a separate package is available on DUB: fluid-tree-sitter
). Both are full in terms of completeness and behave a lot like native or well-known editors. This is a significant step forward and it highlights Fluid's possibilities and maturity as a general library.
0.7.0 is currently exactly equal to 0.6.0 in terms of commits, scoring 171 commits since 0.6.3, for a total of 342 commits since 0.5.2. Fluid has reached a milestone of 500 commits!
Further improvements may still be performed, for example selection may be moved to Text
.
New features:
- ModuleView: New experimental and optional node for displaying Ddoc documentation with Fluid. Includes support for live, editable examples. Incomplete.
- ProgressBar: A new node for indicating progress.
- CodeInput: A new code editor node has been added, which supports syntax highlighting and automatic indents.
- Rope: Fluid now uses
Rope
instead ofstring
in all context where text rendering is involved. This is a significant change as it greatly influences all workflow surrounding text rendering. However, it is in great compatibility with original strings, so in many scenarios the change is not noticeable. - FluidScrollable: A new interface is available in
fluid.scroll
that makes it possible to define a scrollable node in a uniform manner. - Text: Massive optimizations in terms of performance involving large amounts of text. Text will only be rasterized once it reaches the screen. Low level API is exposed through
CompositeTexture
. - TextInput: Multiline TextInput is now available with the
.multiline
node property. A separate constructor may be added in the future. - TextInput: The caret now can be moved using arrow keys or the mouse.
- TextInput: Text can now be selected, copied, pasted.
- TextInput: Support for undo and redo was added.
- Image & Texture: Images now support two new formats, and Textures support two corresponding rendering modes in order to support texture masks and palettes.
- TagList: New method
remove
can be used to remove tags. - FrameButton:
hframeButton
is now available.
Removed features:
- SimpledisplayBackend has been removed. arsd.simpledisplay no longer supports the D language and has moved on to OpenD.
Deprecations:
Grid
has been renamed toGridFrame
. (Thanks @LiamM32)frameButton
has been renamed tovframeButton
.
Improvements:
- The tour now has a separate DUB recipe.
- MapFrame:
addChild
will now fail contracts on null nodes. toFluid
has been added to use Raylib textures in fluid.Texture contexts (Thanks @LiamM32).- ImageView: Images can now be used directly with ImageView (Thanks @LiamM32).
- Raylib: Trilinear filtering is now used by default when rendering textures.
- MapFrame:
addChild
now has one more overload that supportsVector2
(Thanks @LiamM32) - The showcase now defaults to Raylib, which is also now included in Fluid.
- FreetypeTypeface:
advance
result is now cached. - Typeface.measure: New overload has been added to operate directly on
TextRuler
. - Tree now uses a separate set of key bindings on macOS.
- Better Unicode test coverage for
TextInput
. - PasswordInput: Shredding is now explicit.
- The showcase has been renamed to Tour and its directory has been renamed accordingly.
Bugfixes:
- SwitchSlot: Make sure the correct size is used if there are multiple references to a child. #138
- DragSlot: Ignore
Style.gap
for hidden handles. - Space: Include
Style.gap
in minSize - TextInput: Unicode related bugfixes
- Text: Bugfix multiline text not updating when changed.
- Possible use-after-free if TextureGC is used inside as a dynamic array element.
0.6.3 — Additional features
This is the final release from the 0.6.x series, unless an important bugfix or patch is needed. Next up on the road is 0.7.0.
Breaking:
FluidBackend
now requiresdrawCircle
.Container
is no longer respected byscrollIntoView
, useFluidScrollable
instead.
New features:
- Styles can tint nodes as a whole, including changing their opacity by altering the
a
channel.
Theopacity
field exists as a shortcut. - New nodes:
FieldSlot
,Checkbox
,Radiobox
,NumberInput
,Slider
,SwitchSlot
. - Scrolling is now implemented separately from mouse input, using
FluidScrollable
. - New showcase article on writing forms.
Bugfixes & improvements:
- Fix #58: Spaces now accurately calculate and distribute space.
FileInput
now inherits fromFluidPopup
.MapFrame
was introduced to replaceMapSpace
. The latter is now deprecated.beforeResize
now fires before any node that is resized, instead of before the entire tree is resized.- Resizing is now far faster, as text is only rendered when necessary, during drawing.
- The showcase now has an outline!
0.6.0 — Debugging & misc stuff
With 134 commits in since last release, 0.6.0 is probably the biggest update to Fluid yet, and the first one to use the new name. It offers a lot of new improvements, making it easier to manage input thanks to Input Actions, automatic keyboard support through tabbing and arrow keys, improving and optimizing text rendering and providing out-of-the-box Unicode support. Furthermore, Tree Actions enable lazily walking through the tree while drawing and there are significant changes to the library's core, making it possible to use Fluid without depending on Raylib.
Breaking changes
- The entire package has been renamed. Glui is now Fluid.
- Node class prefixes have been removed with few exceptions. Goodbye
GluiFrame
,GluiLabel
,GluiButton
, now we can be more concise.GluiInput
is nowInputNode
- All subclasses of
InputNode
mustmixin enableInputActions
. Presence of the mixin is checked at runtime. - Fluid may now perform some actions by default when pressing Tab, Shift+Tab, Arrow keys, or chosen gamepad buttons (LB, RB, A, B, D-pad). You may override those with
node.tree.bindInputReplace
ornode.tree.clearBoundInput
- Fluid now uses its own
Typeface
class to implement font rendering on top of Freetype2 or Raylib. RichLabel
was removed, because it was rooted in old codebase and impossible to maintain. There is no replacement yet.- Supoprt for Raylib versions 3 and 4 has been dropped. Please use Raylib 5.
- Nodes cannot use Styles and Themes that are
const
orimmutable
anymore.mixin defineStyles
will now define mutable style fields. - Side arrays used in styles for padding, margin and border are now
float[4]
and notint[4]
to support changes to how Fluid handles HiDPI.
Previously deprecated
dropdown
andGluiDropdown
were renamed topopup
andPopup
respectively.mousePass
was renamed toignoreMouse
.hidden
,hovered
anddisabled
were renamed toisHidden
,isHovered
andisDisabled
respectively.preventOverlap
was renamed topreventOverflow
.childRef
has been removed.
Now deprecated
TextInput.multiline
was never implemented. It would probably be better off as a subclass or a separate node.LayoutTree.disabledDepth
has been replaced with a simple booleanisBranchDisabled
. Also, a more genericLayoutTree.depth
was added, which doesn't track disabled nodes.- All font related fields in
Style
, except forfont
itself, have been deprecated. Please use fields and methods present in the Typeface interface, e.g.Style.typeface.lineHeight
. Many options are currently vendor-specific. label
defaulting to being empty is now deprecated — initial text is now required.filePicker
has been renamed tofileInput
[vh]scrollBar
have been renamed to[vh]scrollInput
popup
has been renamed (again) topopupFrame
BasicNodeParams
is deprecated. Node constructors should now takeNodeParams
as the first argument instead. The burden of collecting theme and layout has been moved tosimpleConstructor
.
Input actions
Fluid 0.6.0 introduces the all-new input actions. Those let you easily bind inputs to methods for focused or hovered nodes. Those inputs can later be rebound, so you can make them configurable for the user.
By default, every node has actions bound to switch between nodes via tab, shift+tab and arrow keys. Neighboring nodes are picked based on distance and semantic information, making the feature intuitive for the user with minimal to no effort needed from the programmer.
class MyNode : InputNode!Label {
mixin enableInputActions;
/// Triggers when you press the node with left mouse button or press Enter when focused.
@(FluidInputAction.press)
void _press() {
writeln("Node pressed!");
}
}
// Actions can be rebound
auto ui = vframe(
label("Hello, World!")
);
ui.draw();
ui.tree.bindInput(FluidInputAction.press, InputStroke(KeyboardKey.z));
// Warning: ui.tree access requires at least one draw!
// Gamepads are also supported!
ui.tree.bindInput(FluidInputAction.press, InputStroke(GamepadButton.rightTrigger));
// Actions can be checked at any time with isDown and isActive
ui.tree.isDown!(FluidInputAction.press);
ui.tree.isActive!(FluidInputAction.press);
// You can define your own actions by creating an enum and marking it @InputAction
enum MyAction {
attack,
jump,
dash,
}
class InputHandler : InputNode!Node {
mixin enableInputActions;
@(MyAction.attack)
void _attack() {
}
// You can handle multiple actions in a single function:
@(MyAction.jump, MyAction.dash)
void _move(MyAction action) {
}
}
focusImpl
and mouseImpl
can be used for advanced usage input actions cannot handle.
On a related change, FluidHoverable
is now available as a subset of FluidFocusable
, for nodes that interact with the mouse, but not the keyboard.
textInput now correctly processes repeated backspace thanks to changes in Raylib 5 and backend split.
PR #70, issue #8
Popup improvements
Popups have seen significant improvements thanks to a related change, the introduction of tree actions. Popups can now be displayed without making mapSpace
the root of your node tree, they can be nested and have full keyboard support.
A new node, popupButton
has been introduced, which will open a popup when clicked. It's perfect for creating dropdown menus, and can be nested.
popupButton("Options",
button("Edit", delegate { }),
button("Copy", delegate { }),
popupButton("Share",
button("SMS", delegate { }),
button("Via e-mail", delegate { }),
button("Send to device", delegate { }),
),
);
Freetype2 integration
Fluid now comes with Freetype2 support, which means:
- Improved Unicode support — A compatible font should work straight out of the box!
- Reduced memory footprint — Text should only drain memory when updated.
- Better font quality — All the precious hinting shouldn't get lost.
Moreover, Freetype2 is now the default font backend. The default font is also now Ruda, instead of Raylib's raster typeface.
If you used Style.loadFont
(now aliased to Style.loadTypeface), your app should automatically start using Freetype2. You might however encounter issues if you relied on
Font, since the function now returns a
Typeface`.
Please note that it's still possible to draw text with the Raylib backend, which should see improved performance as well, but is from now on discouraged. This must be done explicitly by using new RaylibTypeface
.
Improved HiDPI support
Fluid now consistently uses "pixel" as 1/96th of an inch. It's possible to specify the DPI of a texture to make it scale better under HiDPI environments. This makes text display a lot better on displays with increased DPI.
Raylib's FLAG_WINDOW_HIGHDPI
flag is now discouraged.
Switching backends
While Raylib remains supported and the best option to use with Fluid, Fluid does not exclusively rely on Raylib anymore. For example, arsd.simpledisplay can now be used with Fluid using the built-in SimpledisplayBackend
. It's possible Hipreme Engine will also get support soon.
This is also a significant shift in development focus of Fluid, since the library could now be integrated into different rendering APIs like Metal or Vulkan, or even CPU rendering. With further modifications, core components could be modified to bind to existing GUI frameworks like Qt, Windows Forms or Cocoa.
The HeadlessBackend is now also available, if you'd like to Fluid flowing in your code, even when not rendering anything. It's particularly useful for running tests — and is now powering Fluid's unit tests.
New showcase
The old examples have been notoriously bad for what examples should have been. They had their share as a testing suite, but Fluid has now moved to regular unit tests.
Instead, they have been replaced with a unified showcase. A single app that goes through different topics covering Fluid usage, with live code examples. It's similar to D's tour page, except specifically to talk about Fluid.
The showcase is still a work in progress and isn't complete, but hopefully should already offer a good start to anyone looking to start using Fluid!
On another note, the readme.md
file has been updated to offer a friendlier introduction to Fluid.
Tree actions
Advanced stuff: Tree actions let you lazily iterate the tree while it's being drawn. It can be really useful for managing focus or performing more complex node tree operations.
A few actions come built-in:
focusRecurse
will set focus on the first available node within a given branch of the tree. Its variant,focusRecurseChildren
will ignore the root of the branch.scrollIntoView
will update any parent scrolling container so that the chosen node appears in the view.
class MyAction : TreeAction {
override void beforeDraw(Node node, Rectangle space) {
// stuff!
// Call `stop()` to immediately end the action. Note afterDraw and afterTree won't be called.
}
// Tree actions are only performed once by default. Override `afterTree` to stop this behavior.
override void afterTree() {
// or if you want to keep it, call `stop()` or `super.afterTree()`
}
}
// Queue an action for the next draw
tree.queueAction(new MyAction);
// Or, queue it for a specific tree branch
node.queueAction(new MyAction);
PR #70, issue #71
Miscellaneous improvements
- Various allocation optimizations; Fluid shouldn't allocate du...
0.5.0 — Finishing essentials
See release notes on the upstream: https://git.samerion.com/Samerion/Glui/releases/tag/v0.5.0
0.5.0-alpha — Preview of the 0.5.0 release
See changelog on the upstream: https://git.samerion.com/Samerion/Glui/releases/tag/v0.5.0-alpha
0.4.4 — Add HiDPI support
- Add HiDPI support, fix #19 by @Soaku in https://github.com/Samerion/Glui/pull/29
0.4.3 — Hotfix for hidden expand nodes
- A false-positive in layout validity checks caused hidden expand nodes to crash debug programs.
0.4.2
What's Changed
- Add a couple of sizing checks by @Soaku in https://github.com/Samerion/Glui/pull/27
- Update Glui for Raylib 3.7.0 compatibility by @Soaku in https://github.com/Samerion/Glui/pull/28
Full Changelog: Samerion/Glui@v0.4.1...v0.4.2
0.4.1
Only bugfixes.
- Add
.length
setter toChildren
- Bugfix hidden
expand
nodes taking space - Make
GluiOnionFrame
respectGluiNode.toRemove
- Correct file picker value and
offsetSuggestion(-1)
- Bugfix mouse focus for invisible items
- Add public targetArea read-only access
- Remove an invalid assert from hoverButton
0.4.0
- Scrolling containers
- Proper text wrapping
- Make Glui
@safe
- Added helpers for declaring new themes
- + related theming bugfixes
GluiFilePicker
behavior correction- Rework input handling
Node.remove
lazy tree removal- Add debug runtime checks for changing
.children
while drawing as it can't work with said lazy functionality.
- Add debug runtime checks for changing
- Split
GluiFrame
to itself andGluiSpace
to allow making transparent frames which don't take events, useful for overlays etc. - Margins and padding