Introduction
Welcome to SableUI - a modern, high-performance C++ UI/application framework that takes the good from web-based applications without the negative performance impact and removes the bridge between the frontend and the backend for low-level applications.
Who Is This For?
SableUI is designed for C++ developers who want want to write applications without the limitations of the web, featuring:
- Declarative, reactive components
- Cross-platform support
- Full control and open access over rendering and memory management
Philosophy
Traditional C++ UI frameworks are often verbose and fatiguing with large limitations. Web frameworks are often the solution to this, but come with a performance cost and a large abstraction between UI and application. SableUI attempts to bridge this gap by bringing the developer experience of React to C++ while maintaining the speed and control you would get with a native C++ framework.
// An example of a counter component
class Counter : public SableUI::BaseComponent {
public:
void Layout() override {
Div(bg(245, 245, 245) p(30) centerXY w_fit h_fit rounded(10))
{
Text(SableString::Format("Count: %d", count),
fontSize(28) mb(20) textColour(20, 20, 20) justify_center);
Div(left_right p(4) centerX rounded(9))
{
Div(bg(90, 160, 255) p(8) mr(5) rounded(5)
onClick([=]() { setCount(count + 1); }))
{
Text("Increment",
mb(2) textColour(255, 255, 255) fontSize(16) justify_center);
}
Div(bg(255, 120, 120) p(8) rounded(5)
onClick([=]() { setCount(count - 1); }))
{
Text("Decrement",
mb(2) textColour(255, 255, 255) fontSize(16) justify_center);
}
}
}
}
private:
useState(count, setCount, int, 0);
};
Current Status
SableUI is incomplete but actively being developed and approaching v1.0. The core features are stable and production-ready, but won't get most too far, with ongoing work on:
- Vulkan/Metal support
- ID-based components for improved flexibility
- Expansion of component library (scrollable views, input fields, tab stacks, ...)
- Documentation and examples
- Panel docking (maybe not v1.0.)
Want to build something? Quick Start or Installation
What is SableUI?
SableUI is a high-performance C++ UI/application framework that reimagines native UI development by borrowing the best ideas from modern web frameworks.
React-Inspired Components
Components in SableUI work just like React components:
class MyComponent : public SableUI::BaseComponent {
public:
void Layout() override {
// Element tree starts here
Div(bg(32, 32, 32) p(10)) {
Text("Hello, World!");
}
}
};
Every component has a Layout() method that can be overriden that describes what should be rendered. When state changes through useState() or otherwise, SableUI manages to only what's necessary through virtual DOM reconciliation.
Declarative, Composable UI
Instead of the traditional approach which can get messy with complex layouts:
ElementInfo divInfo{};
divInfo.backgroundColuor = Colour(32, 32, 32);
divInfo.padding = 10;
StartDiv(info);
AddText("Hello world");
EndDiv();
SableUI utilises macros and RAII to abstract the complexities that come with low-level ui libraries remaing safe and impossible to forget matching a End() to a Start() in the process:
Div(bg(32, 32, 32) p(10)) {
Text("Hello, World!");
}
Both methods however are supported in SableUI, but for more complex layouts, macros are provided to make layouts more readable, easy, and safe. You can understand how to layout elements here. <- TO ADD and the legacy method here. <- TO ADD
Tailwind-Inspired Styling
Styling is fast and intuitive with chainable modifiers: <- adding link to styling page
Div(
w(200) h(100) // Fixed Width and height
bg(45, 45, 45) // Background color
p(10) // Padding (all around)
m(5) // Margin (all around)
rounded(8) // Border radius (all corners)
centerXY // Center content in both axis
)
Flexible Panel-Based Layouts
SableUI includes a powerful splitter panel system for complex layouts:
int main() {
SableUI::Window* window = SableUI::Initialise("My App", 1200, 800);
HSplitter() { // Horizontal splitter
VSplitter() { // Vertical splitter on the left
Panel("FileTree");
Panel("Editor");
}
Panel("Console"); // Console on the right
}
while (SableUI::PollEvents())
{
SableUI::Render();
}
SableUI::Shutdown();
return 0;
}
Panels can be resized at runtime (and in the future save their state across multiple sessions), and you can set minimum/maximum bounds for scale-sensitive panels.
Couple of noteable features
Component State
Use useState to create reactive state:
class Counter : public SableUI::BaseComponent {
void Layout() override {
Text(SableString::Format("Count: %d", count));
Div(onClick([this]() { setCount(count + 1); })) {
Text("Increment");
}
}
private:
useState(count, setCount, int, 0);
/* Same as following for react, but implemented *
* as a macro due to limitations within c++ *
* const [count, setCount] = useState<int>(0); */
};
Virtual DOM
SableUI utilises a virtual DOM for comparing new/old trees, and only updating and rendering the changes between them. Reconciliation only occurs on components whose state has been changed or has been manually flagged for reconciliation. This ensures good performance for reactive states, and maintain flexibility for users.
Text Rendering
Text rendering is advanced, as if something is even subtly wrong or unsupported it can make an applciation awkward to use, and users would unconsiously prefer web-based apps to ensure good text rendering. Below are features SableUI supports:
- Full Unicode support (including emoji (greyscale only), CJK characters, any range supplied by the bundled font packs)
- Multiple font styles (bold, italic, light)
- Word wrapping and truncation
- LCD subpixel rendering for legibility on older displays
- Cached glyph atlases for performance
Graphics Backend Support
Currently supported:
- OpenGL 3.3+ (Fully implemented)
Planned:
- Vulkan (In progress)
- Metal (Will come with VK via MoltenVK)
You can select the preferred backend at initialisation:
SableUI::SetBackend(SableUI::Backend::OpenGL);
// or via command line: --opengl, --vulkan
The backend selection ships with the program. I.e. a device compiling the library without the VulkanSDK will not be able to use ship vulkan compatability with their application, for that there will be precompiled binaries (not as of current though).
Platform Support
- Windows (MSVC, WSL) MinGW untested
- Linux (WSL) GCC & Clang untested
- macOS Untested
What's Next?
If SableUI sounds right for you, you can now get started with building your first application!
Or explore:
- Core Concepts
- Examples
- API Reference