AUI (Advanced Universal Interface) Framework
repository·master·Indexed 20 days ago
https://github.com/aui-framework/auiA cross-platform, high-performance, module-based framework for developing hardware-accelerated graphical desktop applications using modern C++20. AUI provides a retained-mode UI experience for building, styling, and dependency management without custom languages or external compilers. It supports cross-platform deployment on Windows, macOS, Linux, Android, and iOS, and allows for custom OpenGL shaders and GPU-friendly rendering via ITexture and AImage.
What's inside AUI
- AUI (Advanced Universal Interface) is a cross-platform, high-performance, module-based framework designed for developing and deploying hardware-accelerated graphical desktop applications using modern C++20. It is inspired by Qt and focuses on providing a pure C++ experience for dependency management, packaging, UI building, styling, and debugging without requiring custom programming languages or external compilers.
Core UI building blocks in AUI
masterBuilding a user interface in AUI involves composing several key abstractions:
- Views: The fundamental building blocks (e.g.,
AButton,ALabel,ATextInput). - Layout: Managers used to arrange Views in logical structures, ranging from linear layouts to complex adaptive grids.
- Styles (ASS): A CSS-like styling system used to define themes and customize the visual appearance of components.
- Data Binding: A mechanism built on the
signal-slotsystem that connects UI components directly to application data objects, ensuring the UI stays in sync with the underlying state.
- Views: The fundamental building blocks (e.g.,
Android support in AUI Framework
masterAndroid support in the AUI Framework is currently an Early Access Feature. It is in an early stage of development and lacks many features available on other platforms. While Android shares a kernel with Linux, AUI treats Android as a distinct platform rather than a Linux distribution.Visualize grids using CellsView
masterThe
CellsViewclass is used to visualize a grid by updating a texture whenever cell states change.Key behaviors:
- Rendering Optimization: It uses a
drawGridlambda to compose grid lines, which are then passed to the renderer to perform a single draw call for the entire grid. - Interaction: Pressing the pointer on the view toggles the state of the cell located under the cursor.
- Rendering Optimization: It uses a
Embed external files using AUI Assets
masterAUI Assets is a feature provided by
aui.toolboxthat embeds external files (images, sounds, text, etc.) directly into your application or library's binary. This makes your application self-contained and avoids the need to manage platform-specific file paths or packaging.To reference an embedded asset in your code, prefix the file path with a colon (
:) character (e.g.,":background.png").Implement data models with AListModel and AProperty
masterThe Notes App example demonstrates how to manage application data using
AListModelfor collections andAPropertyfor individual state tracking.- Use
AListModelto hold a list of data objects (e.g., a list ofNotestructs). - Use
APropertyto manage reactive state, such as the currently selected item (mCurrentNote) or application state flags likemDirty(indicating unsaved changes). - Properties can be used to drive the enabled/disabled state of UI components (e.g., enabling a 'Save' button only when
mDirtyis true).
- Use
Build declarative UIs with AWindow and UIBuildingHelpers
masterAUI uses a declarative syntax for building user interfaces. You can define a window by inheriting from
AWindowand overriding its contents usingsetContentswith layout containers and widgets.Key Concepts:
- Layouts: Use containers like
Vertical,Horizontal, orCenteredto structure elements. - Widgets: Use functions like
Label { "text" }or_new<AButton>("label")to create UI elements. - Event Connection: Use
.connect(&AView::clicked, this, [] { ... })to attach logic to widget events. - Platform Actions: Use
APlatform::openUrl("url")to perform platform-level actions like opening a web browser.
Example:
#include <AUI/Platform/AWindow.h> #include <AUI/View/ALabel.h> #include <AUI/View/AButton.h> #include <AUI/Platform/APlatform.h> using namespace declarative; class MainWindow: public AWindow { public: MainWindow() : AWindow("App Title", 300_dp, 200_dp) { setContents( Vertical{ Label { "Hello!" }, _new<AButton>("Click Me").connect(&AView::clicked, this, [] { APlatform::openUrl("https://example.com"); }) } ); } };MainWindow::MainWindow(): AWindow("Project template app", 300_dp, 200_dp) { setContents( Centered{ Vertical{ Centered { Label { "Hello world from AUI!" } }, _new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] { APlatform::openUrl("https://github.com/aui-framework/aui"); }), } } ); }- Layouts: Use containers like
Design considerations for Android AUI applications
masterWhen developing AUI applications for Android, keep the following platform-specific behaviors in mind:
- Navigation: Android workflows rely heavily on the "back button" for closing views or navigating to previous pages. Note that modern devices may use software buttons or gestures instead of physical hardware buttons.
- Display Density: Android smartphones typically feature high-density displays. To ensure consistent UI scaling across different devices, you must use density-independent dimension units, specifically
_dp. - Customization Limits: Unlike Linux, Android apps have limited end-user customization options, generally restricted to fonts, launcher icons, and virtual keyboards.
- Manufacturer Variance: While core services vary by manufacturer, AUI applications are generally immune to these specifics unless you explicitly invoke native Java or Kotlin APIs.
How AUI Assets compilation works
masterThe
aui_compile_assetscommand creates a build-time dependency onaui.toolbox. For every file found in theassets/directory, the toolbox generates a corresponding*.cppfile. These generated files contain a byte array of the asset data, which is automatically registered to AUI'sABuiltinFilesfilesystem during compilation.Before being embedded,
aui.toolboxperforms two transformations:- Compression: Data is compressed to reduce binary size and make reverse engineering more difficult (especially for textual files like
.svg). - HEX Conversion: The compressed data is converted into a HEX string within the generated C++ source.
- Compression: Data is compressed to reduce binary size and make reverse engineering more difficult (especially for textual files like
Understanding Retained vs. Immediate vs. Declarative UI in AUI
masterAUI supports three distinct UI paradigms, though it is primarily designed as a hybrid/declarative framework to provide the best developer experience and performance.
- Retained Mode UI: Traditional approach where UI elements (like
AButton) are created as persistent objects in memory. You must manually manage their state (e.g., callingsetText()when data changes) and maintain a link between business logic and the UI state. - Immediate Mode UI: The UI is rebuilt from scratch every frame (e.g., Dear ImGui). It is highly expressive and stateless but can be resource-intensive as it redraws everything constantly.
- Declarative UI (AUI's Hybrid Approach): AUI uses a hybrid model. You describe what the UI should look like based on current state using a declarative contract. AUI then manages the underlying retained-mode objects and updates them efficiently using state management and diffing. This provides the simplicity of immediate mode with the performance of retained mode.
Recommendation: AUI strongly suggests using declarative mode for most use cases due to its dynamism and responsiveness.
- Retained Mode UI: Traditional approach where UI elements (like
AUI vs Jetpack Compose: Retained vs Immediate Mode
masterAUI and Jetpack Compose represent different UI paradigms:
Feature AUI (Retained Mode) Jetpack Compose (Immediate Mode) State Stored inside a class member Local variable using rememberVertical Layout VerticalColumnHorizontal Layout HorizontalRowDisplay Label { AUI_REACT("{}"_format(mCounter)) }Text(text = "Counter $counter")Increment Button { .content = Label { "Count" }, .onClick = [this] { mCounter += 1; } }Button(onClick = { counter++ })Key Distinction: AUI is a retained mode UI, meaning the framework maintains a model of the UI hierarchy, whereas Jetpack Compose is an immediate mode UI.
Debug and design UIs with AUI Devtools
masterAUI provides a dedicated set of Devtools designed to streamline the development workflow. These tools include visual debugging capabilities to help you design, test, and inspect your UI components in real-time.