stride3d / stride3d/stride

New UI Layout System

Open
#2,641 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
C#
Stars
7.8k
Forks
1.2k
Avg merge
2d 17h
Merged PRs (30d)
49

Description

Overview

The current UI layout system is has limited layout abilities, inconsistent behaviors, and un-needed properties. These make it clunky and slow to create complex UIs with. This proposes a new layout system using a single type that can be a fixed size, flex or percent of parent.

Current Issues

  1. Alignment
    • Context: UIElement has vertical and horizontal alignment properties that influence size and position.
    • These only take affect with certain parent configurations, making them feel unpredictable and useless much of the time.
    • Mixes size and position responsibility between parents and children.
  2. Default size
    • Context: UIElement has a default size property for each axis.
    • These are only used when an axis size and MeasureOverirde() both are NaN.
    • They add add bloat when creating UI and are rarely used.
  3. Margins
    • Context: UIElement has margins property for each side of the element.
    • They generally make elements difficult to re-use.
    • Margins don't really belong to any given element since it is the space between them.
    • If margins are used to separate elements in a collection, special handling is needed for the last/first one.

Proposed System

Introduce a new Length value type with three modes:

  • Fixed – Absolute pixel value.
  • Flex – Fills available space.
  • Percent – Relative to the parent’s size.

Use Length for all spacing and sizing properties (Width, Height, Padding, etc.).

Refactored/Replace StackPanel
  • Orientation – Defines the layout axis.
  • SpaceBefore / SpaceAfter – Controls space before/after the first/last element along the main axis.
  • SpaceBetween – Defines space between elements along the main axis.
  • DefaultCrossAxisSpaceBefore / After – Default space between children between a child and the edges of the panel along the cross axis.
  • CrossAxisSpaceBefore / After (attached property) – The cross axis spacing defined per-child.

Other elements (Canvas, ContentControl, Grid, etc.) would see similar changes.

New System Rules
  • Parents control child positioning and external spacing.
  • An element can never be smaller than the size of its content or defined size (whichever is larger).
  • The fallback size of an element is always to its smallest size.
  • Flex values in infinite space default to the smallest fixed value (e.g. content size for flex elements, or 0 for padding, etc.).
  • Conflicting positioning defaults to centering, unless the parent specifies otherwise.
Removals
  • Margins – Parent elements control spacing.
  • Vertical/Horizontal Alignment – Positioning is managed by parents; stretching is handled by Flex.
  • Default Width/Height – Replaced with sensible default behavior when encountering a NaN size.

Conclusion

This system would allow much more versatile layouts than are currently possible, and keeps to a set of simple, predictable rules that are reused through the system.

Here is a prototype of the changes to the StackPanel showing the Length based properties.

https://github.com/user-attachments/assets/c732fe1b-48d5-47b0-9e3d-cfc192118b20

This would either have to be a very breaking change, or introduce a lot of redundant properties and elements. For example, changing public float Width {get; set;} to public Length Width {get; set; } would be desired, but breaking. Could introduce a new property, but then you have 2 sets of widths (and lots of others) which would add to the bloat.

Please let me know if you have any thoughts, like or dislike it, questions etc!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the existing UIElement, StackPanel, Canvas, ContentControl, and Grid APIs, then compare them with the proposed Length-based StackPanel prototype. A complete contribution would require an agreed design for the breaking or compatibility approach, followed by implementation and validation across the affected UI elements.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
game-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.