Skip to content

Releases: Samerion/Fluid

v0.7.0-alpha.2: 0.7.0-alpha.2 — `TextInput` improvements

29 Apr 13:01
Compare
Choose a tag to compare

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 of string 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 to GridFrame. (Thanks @LiamM32)
  • frameButton has been renamed to vframeButton.

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 supports Vector2 (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

26 Feb 19:51
3aeb037
Compare
Choose a tag to compare
Pre-release

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 requires drawCircle.
  • Container is no longer respected by scrollIntoView, use FluidScrollable instead.

New features:

  • Styles can tint nodes as a whole, including changing their opacity by altering the a channel.
    The opacity 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 from FluidPopup.
  • MapFrame was introduced to replace MapSpace. 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

25 Jan 10:59
ba1c37d
Compare
Choose a tag to compare
Pre-release

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 now InputNode
  • All subclasses of InputNode must mixin 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 or node.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 or immutable anymore. mixin defineStyles will now define mutable style fields.
  • Side arrays used in styles for padding, margin and border are now float[4] and not int[4] to support changes to how Fluid handles HiDPI.

Previously deprecated

  • dropdown and GluiDropdown were renamed to popup and Popup respectively.
  • mousePass was renamed to ignoreMouse.
  • hidden, hovered and disabled were renamed to isHidden, isHovered and isDisabled respectively.
  • preventOverlap was renamed to preventOverflow.
  • 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 boolean isBranchDisabled. Also, a more generic LayoutTree.depth was added, which doesn't track disabled nodes.
  • All font related fields in Style, except for font 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 to fileInput
  • [vh]scrollBar have been renamed to [vh]scrollInput
  • popup has been renamed (again) to popupFrame
  • BasicNodeParams is deprecated. Node constructors should now take NodeParams as the first argument instead. The burden of collecting theme and layout has been moved to simpleConstructor.

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...
Read more

0.5.0 — Finishing essentials

21 Apr 14:22
Compare
Choose a tag to compare
Pre-release

0.5.0-alpha — Preview of the 0.5.0 release

21 Feb 08:58
2b3fc37
Compare
Choose a tag to compare

0.4.4 — Add HiDPI support

13 Nov 17:55
63f82b2
Compare
Choose a tag to compare
Pre-release

0.4.3 — Hotfix for hidden expand nodes

15 Oct 12:12
Compare
Choose a tag to compare
  • A false-positive in layout validity checks caused hidden expand nodes to crash debug programs.

0.4.2

15 Oct 09:16
e1ca44c
Compare
Choose a tag to compare
0.4.2 Pre-release
Pre-release

What's Changed

Full Changelog: Samerion/Glui@v0.4.1...v0.4.2

0.4.1

30 Aug 16:44
Compare
Choose a tag to compare
0.4.1 Pre-release
Pre-release

Only bugfixes.

  • Add .length setter to Children
  • Bugfix hidden expand nodes taking space
  • Make GluiOnionFrame respect GluiNode.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

16 Aug 15:24
374f349
Compare
Choose a tag to compare
0.4.0 Pre-release
Pre-release
  • 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.
  • Split GluiFrame to itself and GluiSpace to allow making transparent frames which don't take events, useful for overlays etc.
  • Margins and padding