ecosystem: add toolkit

This commit is contained in:
Vaxry 2025-10-03 12:14:37 +01:00
parent b43d9352e4
commit f1b900b531
Signed by: vaxry
GPG key ID: 665806380871D640
3 changed files with 164 additions and 0 deletions

View file

@ -28,6 +28,7 @@ These docs always target latest -git branch of respective apps.
### Libraries and other utilities
- **[hyprtoolkit](./hyprtoolkit)**
- **[hyprcursor](./hyprcursor)**
- **[hyprutils](./hyprutils)**
- **[hyprlang](./hyprlang)**

View file

@ -0,0 +1,30 @@
---
weight: 100
title: hyprtoolkit
---
Hyprtoolkit is a GUI toolkit for developing applications that run natively on Wayland.
It's specifically made for Hyprland's needs, but will generally run on any Wayland compositor
that supports modern standards.
For developer docs, see [development](./development)
## Configuration
The general toolkit config is at `~/.config/hypr/hyprtoolkit.conf`. It contains theming and some minor adjustments.
| variable | description | type | default |
| --- | --- | --- | --- |
| background | background color | color | FF181818 |
| base | base color | color | FF202020 |
| text | text color | color | FFDADADA |
| alternate_base | alternative base color | color | FF272727 |
| bright_text | bright text color | color | FFFFDEDE |
| accent | accent color | color | FF00FFCC |
| accent_secondary | secondary accent color | color | FF0099F0 |
| h1_size | font size for H1 | int | 19 |
| h2_size | font size for H2 | int | 15 |
| h3_size | font size for H3 | int | 13 |
| font_size | font size for regular text elements | int | 11 |
| small_font_size | font size for small text elements | int | 10 |
| icon_theme | name of the icon theme to use, empty for "the first found" | string | empty |

View file

@ -0,0 +1,133 @@
---
weight: 50
title: Development
---
Hyprtoolkit is a pure C++ toolkit. It relies on modern C++ in the Hyprland style (with
hyprutils, etc).
It's recommended you are familiar with C++ before developing an app.
## Getting started
_If you prefer living off of examples, see the `tests/` directory in the hyprtoolkit repo._
Start by creating a backend and opening a window:
```cpp
// in this example we are doing this to skip Hyprtoolkit::
using namespace Hyprtoolkit;
auto backend = CBackend::create();
auto window = CWindowBuilder::begin()->appTitle("Hello")->appClass("hyprtoolkit")->commence();
```
this will create (but not yet open) a window handle for you.
Hyprtoolkit is a retained mode toolkit, so you can define your layout with C++ and forget about it.
First thing we need is a background rectangle, by doing this:
```cpp
window->m_rootElement->addChild(CRectangleBuilder::begin()->color([] { return backend->getPalette()->m_colors.background; })->commence());
```
Remember to always use the palette when possible for your app to adhere to the user's theme.
All elements are under `hyprtoolkit/elements/`, you can browse through them. Let's add a simple layout with
some buttons:
```cpp
auto layout = CColumnLayoutBuilder::begin()->size({CDynamicSize::HT_SIZE_PERCENT, CDynamicSize::HT_SIZE_PERCENT, {1.F, 1.F}})->commence();
layout->setMargin(3);
window->m_rootElement->addChild(layout);
layout->addChild(CButtonBuilder::begin()
->label("Do something")
->onMainClick([](SP<CButtonElement> el) { std::println("Did something!"); })
->size({CDynamicSize::HT_SIZE_AUTO, CDynamicSize::HT_SIZE_AUTO, {1, 1}})
->commence()
);
layout->addChild(CButtonBuilder::begin()
->label("Do something else")
->onMainClick([](SP<CButtonElement> el) { std::println("Did something else!"); })
->size({CDynamicSize::HT_SIZE_AUTO, CDynamicSize::HT_SIZE_AUTO, {1, 1}})
->commence()
);
```
This adds a column layout (elements are stacked on top of each other) with two buttons. These buttons have automatic sizing, so will fit their contents.
Once you are done, add a close callback, open the window and enter the main loop:
```cpp
window->m_events.closeRequest.listenStatic([w = WP<IWindow>{window}] {
w->close();
backend->destroy();
});
window->open();
backend->enterLoop();
```
## Layout system
The layout system relies on absolute and layout positioning modes. Let's zoom into both:
### Absolute mode
This happens when the parent of your element is anything but a `ColumnLayout` or a `RowLayout`. Children are positioned within their parent, accoding to their
position mode. You can set it with `setPositionMode` and add offsets with `setAbsolutePosition`.
For example:
- `setPositionMode` with `CENTER` will center the child inside the parent.
- `setPositionMode` with `ABSOLUTE` will make it be in the top left corner.
- Adding `setAbsolutePosition` to the above with `{200, 200}` will move it 200 layout px down and right from the top left corner of the parent.
### Layout mode
This happens when the parent of your element is a layout. These will attempt to position your child elements. They work similarly to CSS's `flex` and qt's `RowLayout` and `ColumnLayout`,
but will not wrap. If elements overflow and cannot shrink, they will disappear.
RowLayout positions elements next to each other side-by-side, while ColumnLayout does it top-bottom.
### Size
All elements carry a `SizeType`. This tells the layout system how to size the element.
- `ABSOLUTE` takes layout px as size and makes the element rigid.
- `PERCENT` takes a percentage in the form of `(0, 0) - (1, 1)` and will be the size of the parent multiplied by the percentage.
- `AUTO` ignores the passed vector (leave it empty) and instead will always attempt to contain the children\*
\*_Some elements will force their own sizing, like e.g. Text. Leave them AUTO to avoid confusion._
## Elements
Most elements are self-explanatory. You can explore their builder fns to see what styling / behavior options they
support.
Each element is created with a `Builder` which is there to maintain ABI stability. After you call `->commence()`, you
will get a `SP` to the newly created object.
You can rebuild the object at any time by calling `->rebuild()` and you'll get a builder again.
**Remember to call `commence()` after you are done to apply the changes!**
You do not need to keep the `SP` after adding the element to the tree with `addChild`.
## Other
Other, miscellaneous stuff
### System icons
Use the `CBackend::systemIcons()` fn to obtain a ref to `ISystemIconFactory` which allows
you to query system icons by name. You can check the obtained result object for seeing if the icon was found.
Then, you can take that object and slap it into an `ImageElement` to add it to your layout.
### Additional FDs
If you have an app that depends on some other loop, e.g. pipewire, dbus, etc. You need to remember
that hyprtoolkit is strictly single-threaded for layout and rendering. You cannot edit the layout from another thread.
For this, use `CBackend::addFd()` to add a FD to the loop alongside a function that will be called once the fd
is readable. This fn will be called from the main thread, so you can do whatever you want in there.