Skip to content
HunlongyuPublic

About

A framework-independent C++20 layout library for native UI, with Block, Flexbox, Grid, and incremental layout caching.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Axisly

English · 简体中文

A C++20 layout library for native UI
Block · Flexbox · Grid

Version 0.2.0 C++20 CMake 3.25 or newer Core uses only the C++ standard library View CI workflow

Quick start · Layout guide · Examples · Benchmarks · Changelog


Axisly turns layout trees, styles, and content measurements into widget positions and sizes. Your host provides windows, widgets, text measurement, and rendering. Axisly computes the geometry for an existing UI framework or a custom interface.

Core features

  • Framework independent: the core uses only the C++ standard library and ships as a static library. A normal build downloads no third-party dependencies.
  • Composable layouts: nest Block, Flexbox, and Grid in one tree with shared sizing, measurement, and alignment rules.
  • Incremental updates: retain the tree and reuse unchanged results through dirty tracking and measurement and layout caches.
  • Flexible integration: let Axisly manage the tree or adapt an existing host tree, with per-node queries, reusable memory, and batch computation of independent trees.

Layout capabilities

Layout Capabilities
Block / FlowRoot Block flow, floats and clear, independent formatting contexts
Flexbox Rows and columns, grow and shrink, wrapping, reverse directions, baseline alignment, and balanced wrapping
Grid Explicit and implicit tracks, auto-placement, spans, named lines, template areas, minmax, and automatic repetition

All three layouts share fixed and percentage sizes, min/max-content sizing, typed calc values, box-model and aspect-ratio constraints, relative and absolute positioning, bidirectional alignment, scroll extents, reserved scrollbar space, and optional device-pixel rounding. See the layout guide and compatibility matrix for individual fields and behavior limits.

Quick start

Requires a C++20 compiler and CMake 3.25+.

Download the source ZIP or tar.gz from GitHub Releases. Each release includes SHA-256 checksums. Build the library with the compiler and configuration used by your application.

1. Add Axisly to your CMake project

Place the source in your project, for example at third_party/axisly, and link the exported target:

add_subdirectory(third_party/axisly)
target_link_libraries(your_app PRIVATE axisly::axisly)

Tests and examples are disabled by default when Axisly is included as a subproject.

Use an installed CMake package

Add the installation prefix to CMAKE_PREFIX_PATH and link the same target:

find_package(axisly CONFIG REQUIRED)
target_link_libraries(your_app PRIVATE axisly::axisly)

See the build guide for installation steps.

2. Describe and compute a layout

Style::display defaults to Flex with a horizontal main axis. Set Display::Block explicitly for block layout.

This example creates two flexible items in a row, in a container of width 320 with a gap of 8:

#include <axisly/css_tree.hpp>
#include <cstdio>

int main() {
    namespace css = axisly::css;
    css::LayoutTree tree;

    css::Style row;
    row.display = css::Display::Flex;
    row.box.size = {css::Length::length(320), css::Length::length(48)};
    row.gap.width = css::Length::length(8);
    const auto root = tree.create_node(row);

    css::Style item;
    item.box.size = {css::Length::length(80), css::Length::length(24)};
    item.flex_grow = 1;
    tree.append_child(root, tree.create_node(item));
    tree.append_child(root, tree.create_node(item));

    const auto& result = tree.compute(root, {
        css::AvailableSpace::definite(320),
        css::AvailableSpace::definite(48)});
    if (!result.succeeded()) return 1;

    for (const auto& node : result.nodes) {
        if (node.node == root) continue;
        const auto& r = node.border_box;
        std::printf("%.0f %.0f %.0f %.0f\n", r.x, r.y, r.width, r.height);
    }
}

Each output line contains x y width height:

0 0 156 24
164 0 156 24

3. Apply the result to your UI

  • Apply each returned rectangle to its widget. Coordinates in the example are relative to the layout root.
  • Supply a measurement callback through create_node(style, measure) for text, images, and other content.
  • Call mark_dirty(node) after content changes. set_style(node, style) automatically invalidates affected cached results.

The tree owns the result, and subsequent computations update it. Copy results that need to survive across frames.

See the CSS layout guide for measurement contracts, error handling, and host integration.

Choose an integration

Approach When to use it API
Axisly owns the layout tree Let the library manage nodes, styles, caches, and incremental invalidation LayoutTree
Adapt an existing host tree Connect an existing widget tree and style system to the layout engine LayoutSource / LayoutSession

Both approaches share the same CSS Block, Flexbox, and Grid semantics. Grid uses Style::grid, TrackSizing, and GridLine; nested grids are ordinary child nodes in the same tree. Layout-tree and style APIs live in axisly::css. Include individual headers as needed, or use the umbrella header <axisly/axisly.hpp>.

Examples

Example What it demonstrates Entry point
Console example Tracks, measurement, spans, alignment, nesting, caching, and rounding Source
SDL3 Playground Resize the canvas and inspect grid lines, item borders, and final rectangles Run guide
GeeyoouUI Showcase Windows host integration across 19 pages, including forms, tables, and themes Run guide

Graphical examples are optional development targets; their UI and rendering dependencies stay outside the core library. Follow the host integration steps to connect measurement, invalidation, and rectangle application in another framework.

Scope and compatibility

CSS layout uses Taffy 0.14.0 as its versioned compatibility reference, with differential checks against fixed cases, property combinations, and the upstream corpus. Known differences between Taffy and browser specifications are documented in the compatibility guide.

The library accepts typed C++ styles. CSS string parsing, selectors, the cascade, DOM, text shaping, and rendering are outside its scope, as are browser features such as inline formatting, table layout, vertical writing, and pagination. Scroll extents are layout output; the host implements scrolling and clipping.

The current release is 0.2.0. Source and binary compatibility across versions is not guaranteed. Rebuild all consumers when upgrading and review the changelog and migration notes.

Documentation

Detailed guides and the changelog are currently available in Simplified Chinese.

Guide Contents
Build guide Compilation, installation, and CMake options
CSS layout guide Styles, measurement, updates, and result lifetime
Execution resources Memory reuse, batch execution, rounding, and PGO
Compatibility matrix Layout field mapping and scope
Specification differences Independent specification cases, browser replays, and known differences
Examples Console, SDL3, and GeeyoouUI examples
Testing Contract tests, upstream replay, and sanitizers
Benchmarks Comparing Axisly, Taffy, and Yoga with identical input

Core implementation lives in src and public interfaces in include/axisly. Reference implementations, benchmark tools, and graphical examples are optional development dependencies.

About

A framework-independent C++20 layout library for native UI, with Block, Flexbox, Grid, and incremental layout caching.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages