Brisk is an open-source C++ GUI framework with a declarative approach, offering powerful data bindings, GPU-accelerated graphics, and dynamic widget management. It supports macOS, Linux, Windows, and simplifies UI creation with modern paradigms and CSS-like layouts.
Initially developed for a graphics-intensive project with a complex and dynamic GUI, the framework is currently under active development.
gpderetta|1 year ago
You should be able to make it work with a value-based interface and allocating behind the scenes (this would also enable a few optimization opportunities).
danlcaza|1 year ago
An alternative approach is to use the rcnew macro, which wraps a pointer in a shared_ptr under the hood. Details on the implementation of rcnew can be found at: https://www.kfr.dev/blog/three-cpp-tricks/
mdaniel|1 year ago
Also, I wasn't able to readily find any information about keybindings for the widgets, e.g. the way some frameworks use "&Monday" to make alt-m act on that checkbox https://github.com/brisklib/brisk/blob/v0.9.3/examples/showc...
I did see your "unhandled" event handler doing its own keybinding dispatch <https://github.com/brisklib/brisk/blob/v0.9.3/examples/calc/...> but I hope that's not the normal way to do keybinding
danlcaza|1 year ago
rubymamis|1 year ago
[1] https://slint.dev
CyberDildonics|1 year ago
igortg|1 year ago
I'd rather build the HTML myself.
[1]: https://dash.plotly.com/
joeld42|1 year ago
The data binding looks particularly clever. That's usually the Achilles heel of GUI toolkits (for me at least) and that looks like a clever and novel solution if it works.
danlcaza|1 year ago
criddell|1 year ago
apitman|1 year ago
danlcaza|1 year ago
hilti|1 year ago
Unfortunately there is no public information on the pricing.
danlcaza|1 year ago
Night_Thastus|1 year ago
Though unfortunately since it's not lGPL or MIT, it doesn't look like I could use it anyways.
jenadine|1 year ago
Why not. They also intend to have a commercial license. Don't event want to consider paying?
taraharris|1 year ago
I don't care that my approach is harder for the developer, because the thing I care about is consistency and convenience for the user.
I know the thing you built is neat (I've spent quite a few years working on almost the same thing), but I guess this is why I gave up on pushing my own solution
fsloth|1 year ago
I’m not sure if this is universally applicable dogma. Games generally apply their own UI regardless of platform.
Web apps generally do as well.
I do realize there is space for apps with least surprise per platform, but it’s not obvious to me if an app benefits from platform standard UI any quantifiable way.
danlcaza|1 year ago
pkphilip|1 year ago
The powerful approach used by Delphi for this is something I have never seen any other language use - where you could create your own components and these components could persist their properties into this external file used for storing the details about the form. So when the IDE loads the design from the external file, it would call the components to read the properties from the file to repopulate itself. This allowed for very powerful and deep components to be developed in Delphi
NoZZz|1 year ago
danlcaza|1 year ago
This technique is utilized in modern frameworks like Jetpack Compose, Flutter and SwiftUI and unlocks several powerful features, such as flexible data binding and the ability to rebuild the widget tree on demand, features that would be quite difficult to implement in other libraries.
clarge1120|1 year ago
ks2048|1 year ago
delta_p_delta_x|1 year ago
Yes. Nowadays all modern desktop interfaces—Aero/Metro/WinUI2/3 on Windows, Aqua/Cocoa on macOS, KDE, GNOME, XFCE, LXDE, and even some window managers on Linux—are 'GPU-accelerated'.
Every window is a quad of two triangles. There's no real vertex shading since it's all orthographic as you mentioned. The framebuffer for each window is exactly the x:y resolution for that window (macOS does some interesting 1:2 resizing here sometimes). The 'fragment shaders' is where the GUI toolkit comes in, writes to these buffers, and does any decorating where needed.
The final framebuffer is exactly the resolution of the entire monitor (again, macOS may do some weird 1:2 resizing).
The framebuffers of all windows on-screen are composed into this one. This is where things like transparency effects, the window and scroll controls, drop shadows, any 'rounding off' masks (used to great extent in macOS), and funky 'frosted glass'/'reflection' effects come in. This gives the effect of windows behind/in front of other windows. This is also when partially/fully off-screen windows are clipped/culled against the viewport frustum (not really a frustum but more a cuboid since it's not a perspective).
Once all this is done, you have a frame that's ready to be piped down the display cable into the display.
There are some other facets muddying the water like HDCP DRM protection for the entire framebuffer or some window framebuffers, variable-rate refresh, and so on. The former is how PrintScreen on Windows returns a black screen for some windows—that's HDCP in action.
joeld42|1 year ago
For a simple example, think of a rounded rect. Typically this would draw as a quad (a pair of triangles), and a shader would calculate the rounded corners.
There's also a lot of compositing and clipping that happens in a UI (e.g. a large widget inside a scrollbox) which is challenging to do on GPU as these get nested.
danlcaza|1 year ago
For text rendering, Brisk uses FreeType to render glyphs on the CPU and caches these glyphs in a GPU-accessible texture, which is reused for improved performance. This approach is common among GUI toolkits for handling graphics and fonts.
In addition to this, Brisk employs SDF (signed distance field) graphics wherever possible, which are entirely computed in shaders.
gosub100|1 year ago
I dabbled in 3D for a while too and was astonished how much 2D stuff there is for it.
wczekalski|1 year ago
danlcaza|1 year ago
samiv|1 year ago
I find that for any non-trivial application this type of boilerplate is best done with good tooling that just works and lets the UI to be knocked up fast and efficiently.
I also wrote an UI system for my game engine but it's completely drag & drop in the editor. Styling (skinning) is also via UI builder.
Source:
https://github.com/ensisoft/detonator/tree/master/uikit
Live demo:
https://ensisoft.com/demos/ui/game.html
Question, how do you handle arbitrary clipping masks ? In my solution clipping masks require evaluating all the widget parent's clipping rects and writing them to stencil buffer before rendering the current widget. This is unfortunately quite slow...
rubymamis|1 year ago
But then it's not trivial to write responsive/adaptive applications. In contrast, QML makes it extremely easy to build such apps.
I used to build UIs in the designer as well[1] but after studying QML there's no going back. Here's a new project I program solely in QML (and C++ for the logic)[2].
[1] https://github.com/nuttyartist/notes
[2] https://www.get-vox.com/
unknown|1 year ago
[deleted]
SaintSeiya|1 year ago
hgs3|1 year ago
danlcaza|1 year ago
feverzsj|1 year ago
mllev|1 year ago
gitprolinux|1 year ago
DrBenCarson|1 year ago
Why would someone use C++ and not Rust in 2024? Familiarity and experience?
baudaux|1 year ago