[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)