[HN Gopher] Show HN: Brisk - Cross-Platform C++ GUI Framework: D...
___________________________________________________________________
Show HN: Brisk - Cross-Platform C++ GUI Framework: Declarative,
Reactive, Fast
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.
Author : danlcaza
Score : 71 points
Date : 2024-12-18 15:01 UTC (7 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| hilti wrote:
| "However, for those who wish to use Brisk in proprietary or
| closed-source applications, a commercial license is also
| available."
|
| Unfortunately there is no public information on the pricing.
| danlcaza wrote:
| The pricing information will be made public at the time of the
| next Beta release. Currently, the framework is refining Linux
| support, with plans to include mobile platforms as well.
| gpderetta wrote:
| All those naked 'new's in the example make me nervous. I see that
| the library uses exceptions, if one of the widget constructor
| throws while composing the overall widget hierarchy, it would
| leak memory.
|
| 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 wrote:
| Thank you for the feedback. The framework was originally built
| with exceptions always disabled, and it is currently being
| reworked to support both modes: exceptions enabled and
| disabled. Some approaches definitely need to be reconsidered.
|
| 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/
| khold_stare wrote:
| Why is heap allocation and shared_ptr required? Can't you
| have the user store the widgets in whatever manner they want,
| as values?
| CyberDildonics wrote:
| You absolutely can. Heap allocation for every component is
| already unneccesary, but loose pointers on top of that is a
| huge red flag.
|
| This seems like someone who isn't up to date with the most
| elegant and fastest ways to write C++. Charging money on
| top of that is egregious, not to mention that there are
| lots of great GUI libraries already. FLTK, Juce, Qt to name
| a few.
| danlcaza wrote:
| Heap allocation is necessary in real-world scenarios
| because it allows a tree of potentially derived widget
| types to be manipulated easily. This is precisely how any
| robust GUI library is implemented.
| int_19h wrote:
| Why not std::make_shared, given that you require C++20
| anyway?
| vinkelhake wrote:
| Just a quick note that the basic form of std::make_shared
| (which is the one that is relevant here) has been in the
| language since C++11.
| NoZZz wrote:
| I don't want to be a party pooper here, but, I am so that's how
| it comes out. In code declaration of user interfaces was old hat
| in Qt, and wxWidgets Why no interpreter? Recompiling to fritz
| with UI is just a bore.
| danlcaza wrote:
| Specifying things declaratively within the language itself goes
| far beyond simply constructing widgets by calling library
| functions.
|
| 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.
| fsloth wrote:
| Wouldn't pure data based definition scheme enable all of the
| above in any case?
|
| If the underlying model is tree, then any graph based
| configuration data could be used to build it.
|
| I mean underneath it could be implemented using the api as
| is, but as a C++ dev I don't see any compelling reason to be
| interested in this.
|
| You can do the most astounding things nowadays in 100fps. I'm
| not sure if manually handcrafting object initialization trees
| to a ui framework is something I want to do as a developer in
| 2024.
|
| This is not intended as a put-down! This must have been
| enormous amount of work.
|
| I would love to hear the rationale for why exposing the user
| API as a class structure like this - I'm sure there are good
| reasons and would love to hear them.
| mdaniel wrote:
| Since it's cited as cross-platform, including non-Windows
| screenshots would be helpful
| https://github.com/brisklib/brisk#screenshots
|
| 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 wrote:
| Good point about the non-Windows screenshots, but the Brisk
| library apps look _exactly_ the same (except for window
| decorations and DPI scaling) on any supported OS due to its
| custom pixel-perfect graphics engine and its own font engine
| (based on FreeType and HarfBuzz, of course). Key bindings are
| not supported at the moment. The calc example shows a possible
| workaround for this.
| joeld42 wrote:
| This looks really good. It's nice to see some options like this
| (and slint) appearing for cross-platform desktop GUI. I'm pretty
| skeptical of "modern" c++ but this looks like a good example of
| using it where it makes sense.
|
| 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.
| Night_Thastus wrote:
| As someone who lives and breathes QT at the moment - what would
| you says the main differences are? What does Brisk offer that QT
| doesn't and vice-versa?
|
| Though unfortunately since it's not lGPL or MIT, it doesn't look
| like I could use it anyways.
| jenadine wrote:
| > Though unfortunately since it's not lGPL or MIT, it doesn't
| look like I could use it anyways.
|
| Why not. They also intend to have a commercial license. Don't
| event want to consider paying?
| Night_Thastus wrote:
| It's difficult to convince others and leadership when a free,
| well-understood and time tested alternative exists. At least,
| not without a big reason.
| feverzsj wrote:
| To make it really declarative and exception safe, you need to
| wrap widget creation in function and return smart pointer.
| mllev wrote:
| Great job, looks like a huge amount of work.
| baudaux wrote:
| I see that WebGPU is used so it is a good candidate for being
| tried in https://exaequos.com, the OS I am creating and that
| fully runs in the web browser
| samiv wrote:
| The one thing I have to wonder is: How many
| people really want to spend time programming their UIs?
|
| I use Qt myself and one of the best things about the framework
| and toolkit is the UI tooling that allows me to drag and drop and
| visually create my UIs in the UI Designer app.
|
| 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 wrote:
| > I use Qt myself and one of the best things about the
| framework and toolkit is the UI tooling that allows me to drag
| and drop and visually create my UIs in the UI Designer app.
|
| 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/
| samiv wrote:
| Huh, can you elaborate what you mean by this
|
| "But then it's not trivial to write responsive/adaptive
| applications."
|
| Personally I prefer the widgets over QML mostly because QML
| is just too poorly typed and checked + you normally need to
| do a bunch of integration work between the QML and the C++
| code. I do see the appeal though.
| rubymamis wrote:
| I mean that it's much easier to write apps that change
| their layout based on window size. Especially if you want
| to target both a desktop app and a mobile app using the
| same codebase. QML is great for that.
|
| QML is definitely getting better in regard to type
| checking. For example, you can annotate a list with a type:
|
| property list<int> myNumbers: [1, 2, 3]
|
| You can annotate a signal with the expected types:
|
| signal onThisChange(x: int, str : string)
|
| Etc.
|
| You can also ENABLE_TYPE_COMPILER[1][2] to convert QML
| files to C++ which require you to type your code in order
| to work, but I don't really have experience with that.
|
| I'm sure there are even more examples I'm missing. There
| was a discussion regarding TypeScript support in QML[3] but
| I guess they decided to do it their own way[4].
|
| [1] https://doc.qt.io/qt-6/qtqml-qml-type-compiler.html
|
| [2] https://www.qt.io/blog/compiling-qml-to-c-qtquick-
| controls-a...
|
| [3] https://bugreports.qt.io/browse/QTBUG-63600
|
| [4] https://bugreports.qt.io/browse/QTBUG-68791
| criddell wrote:
| How well integrated with the underlying platform is it? For
| example, on Windows do you take advantage of accessibility APIs
| for things like screen readers?
| apitman wrote:
| I don't think open source GUI toolkit developers should be
| expected to handle accessibility until OS vendors spend some of
| their billions of dollars to develop a reasonable cross-
| platform API.
| duped wrote:
| Why should OS vendors spend money devaluing their product?
| It's up to the cross platform software developers to make
| abstractions that work _across_ platforms, not on platform
| developers to make things that work on _other_ platforms.
|
| Just seems absurd.
| apitman wrote:
| See response to sibling. Why is this the responsibility of
| GUI toolkit developers and not app developers?
|
| EDIT: Also, how is this different from any other cross-
| platform API like POSIX, sockets, TCP, etc?
| deergomoo wrote:
| If you are creating tooling for people to create GUIs, it
| should always be possible to make those GUIs accessible. I'm
| not saying this one doesn't--I don't know if it does--but in
| the general case it absolutely should. Not everyone is going
| to bother, but not even giving people the ability would be
| deeply irresponsible.
| apitman wrote:
| Why is this the responsibility of GUI toolkit developers
| and not app developers? There's nothing stopping app
| developers from making a separate version for their app
| designed specifically for accessibility. This results in a
| better UX for the users and the toolkit developers.
| pjmlp wrote:
| Those developers have the option to make use of said OS APIs.
| apitman wrote:
| So do app developers. The reason everyone assume this is
| the responsibility of GUI toolkit devs is because it's a
| meme. See response to sibling.
| pjmlp wrote:
| Apps need an OS to run on.
| apitman wrote:
| I agree. Apps need OSes almost as much as OSes need apps.
| criddell wrote:
| Are you speaking for the Brisk project?
| apitman wrote:
| Do you have some reason to think I am?
| taraharris wrote:
| I spent a very long time giving SolveSpace a native Haiku UI. I'm
| going to keep doing this kind of thing because there's nothing I
| personally dislike more than apps that don't use the platform's
| native UI.
|
| 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 wrote:
| " nothing I personally dislike more than apps that don't use
| the platform's native UI"
|
| 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.
| DrBenCarson wrote:
| They said "apps," not games nor websites
|
| App usability and performance typically benefit greatly from
| using the native platform they're running on. Plus all the
| egress savings of not shipping chromium with every download
| fsloth wrote:
| "App usability and performance typically benefit greatly
| from using the native platform they're running on"
|
| I know this has always been the design dogma but is there
| any research to back this up? It's a _plausible_ dogma of
| course!
|
| To be honest I don't see the distinction between apps and
| games. I am usually irritated if the software I'm using has
| different UI on different platforms. I realize it's
| possible most users don't use three or four operating
| systems daily.
|
| "Plus all the egress savings of not shipping chromium with
| every download"
|
| I'm not sure what this refers to. Creating a custom UI does
| not require embedding a browser runtime - it's the most
| silly thing to do IMO.
| clarge1120 wrote:
| Nice to see someone taking a swing at a C++ GUI framework.
| Implementing a real on is not for the weak. If it's really works,
| it'll be expensive to license.
| DrBenCarson wrote:
| Incredible to see people working on this so kudos
|
| Why would someone use C++ and not Rust in 2024? Familiarity and
| experience?
| hgs3 wrote:
| Nice project! Do you think you'd ever support a "live preview" or
| "hot reloading" of the UI or is that beyond the scope of the
| project?
| ks2048 wrote:
| I've only dabbled a bit in 3D graphics (OpenGL, THREE.js, swift
| SceneKit). When these 2D GUIs say "GPU-accelerated", does that
| mean they are doing the same thing you would do for 3D - build
| triangular meshes, materials, etc - and then just essentially
| point an orthographic camera at this "scene"? Or what kind of
| low-level GPU APIs (eg WebGPU) are used?
| gosub100 wrote:
| I think it just means the texture image for the widgets are
| loaded into gpu memory space instead of a traditional
| framebuffer that gets copied to the gpu.
|
| I dabbled in 3D for a while too and was astonished how much 2D
| stuff there is for it.
| delta_p_delta_x wrote:
| > When these 2D GUIs say "GPU-accelerated", does that mean they
| are doing the same thing you would do for 3D
|
| 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.
| samiv wrote:
| Sorry just have to pop in and say that the DPI scaling makes
| the concept of "resolution of the window" much more
| complicated since you have some logical resolution and then
| the actual rendering resolution and two may not necessarily
| map 1:1 if DPI scaling is in effect.
| joeld42 wrote:
| Most of the drawing work of a GUI is drawing text, shape paths,
| and images. A GPU-accelerated UI layer draws these using GPU
| commands. It's not exactly the same as making an ortho 2D
| scene, but conceptually that's pretty much it. Often it means
| using crude geometry (such as a quad per glyph in a text
| renderer, or a "ribbon" of quads to cover a curve) and using a
| shader to draw the glyph or curve itself.
|
| 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.
| rubymamis wrote:
| While I welcome new cross-platform GUI Frameworks, I wonder why
| not use a declarative UI similar to QML? Even Slint[1] (which is
| built in Rust) uses such syntax for its UI.
|
| [1] https://slint.dev
| igortg wrote:
| I second that. I used Dash for a while. Although it's nice to
| have everything wired up for free, the code quickly becomes a
| mess as soon as you try some more complex things (or you put
| everything in one function and got a big super nested
| structure, or you build a lot of small components and quickly
| get lost in a sea of small functions).
|
| I'd rather build the HTML myself.
|
| [1]: https://dash.plotly.com/
| CyberDildonics wrote:
| It isn't really that important to have a declarative UI, making
| the UI is rarely the time consuming or difficult part of making
| a program. An extra markup language for a UI adds bloat and
| ambiguity. Now you're learning a different ad hoc language and
| trying to get around its quirks just to be able to feed in data
| that could have been done directly with functions.
| wczekalski wrote:
| My friend and I used to build a cross platform UI library in
| OCaml called... brisk. We didn't make it production ready so i am
| sure the naming is a coincidence
| https://github.com/briskml/brisk.
___________________________________________________________________
(page generated 2024-12-18 23:01 UTC)