The Crystal Programming Language Forum

State & Plans of GUI development with Crystal

I did a quick search for “GUI development in Crystal” and got back some dated references to “Shards” and “Amber” web application framework. While I am well aware that enterprise development for desktop is not the current fad, I keep hoping some upcoming language will view that as a good sign of a real opportunity. Far more than just another library to combine with Qt and a lot of prayer (time sunk mastering Qt intricacies) I have a particular hunger for a Delphi, Lazarus, or C# language where the integration is first class.

I DON’T regard perfect “native” look and feel as nearly so important as batteries-included, RAD, IDE drag-n-drop for quickly building full user interface. A language with enough DSL/Meta powers to artfully subsume the GUI design would be a major, major goal. Does Crystal have what it takes here?)

Linux support would be MY most important preference but, as I said, I don’t care if that is Qt, GTK, or something else - just so long as it is near seamless (compare to Lazarus if you don’t know what I am talking about). An alternative would be to try to get ahead of the curve (jump the shark?) with web-assembly+GUI (see https://insights.dice.com/2019/02/28/webassembly-web-gui-future/) and just focus on making the GUI blazing fast and lean (instead of the usual bloat). My hope would be that the outcome would be fully competitive, and ideally a whole lot more straightforward and lean, than, say, fiddling with a whole different language paradigm and the normal bloat-ware approach to putting together things with bailing wire and bubblegum.

I am NOT proposing this as a new bottleneck for Crystal 1.0. I am mostly asking if (a) this is even a reasonably good fit for Crystal capabilities now or coming. And (b) if any of this is already under serious consideration.

KInd of ending with the same point I started from: the current “turning away from” Delphi-style drag and drop GUI development is, imo, a FAD…and, again IMO, driven more by marketing and lack of real decision making by fully informed programmers and managers than good long-term sense. The web has done many things both good and bad: elevating bloat and cobbling things together to meet deadlines with low-grade resources on hand has been one of the really bad developments (which will take decades and lives to correct; here’s looking at you, Boeing).

With every new language on my radar which purports to be future oriented, and with some of the old (e.g., Pharo, Red, and Lazarus), I ask about GUI development, so forgive me if the topic seems off topic for Crystal.

3 Likes

Maybe just binding a nice GUI library would be sufficient. Crystal is quite young in the client-side department compared to its monolithically beautiful server-side capabilities.

Sadly, a lot of newer devs are growing up on garbage Electron apps and the “native UI feel” is slowly degrading over time (and becoming normalized). It’s sad, but it’s just the reality we are in.

1 Like

Yes. I got too caught up in talking about other languages and down the road possibilities. How solid is current GUI support in Crystal? Is anyone actively working on that as a good starting point?

I read that Crystal is “object oriented” – but not dynamic like Ruby. I gather this means introspection is limited and I imagine that might make it harder to pull off something like two way interaction between code to widgets and widgets to code, in a drag and drop IDE environment. On the other hand, Delphi and Lazarus are based on compiled Pascal from 20+ years ago. If something so amazing can be done in compiled, almost-prehistoric Pascal, shouldn’t it be much easier to implement in compiled Crystal? Or am I thinking wrongly about this? I’ve heard that the Pascal compiler is single pass – which might lend itself better to resolving two way complications? Can anyone active on the Crystal compiler speak to this?

Hi there! I’ve been thinking the same thing lately and have done some research on the topic. In my opinion, I think Crystal is a really great fit. When it comes to GUIs it matters less about Crystal, and more so what toolkit you want to depend on. Since that translates to which bindings you want to contribute to.

Here is a short list of Desktop app toolkits:

gtk shard I have used this and confirmed it works for basic apps
qt shard haven’t used but looked promising
lilth os not a toolkit, but I thought the author did some creative stuff worth checking out

I personally have decided to go with gtk, mostly because of my love for XFCE, GPL licensing, and I’m already somewhat familiar with it. I also don’t care about targeting anything but Linux. So my thoughts are mostly related to that, but I think it applies to Qt as well.

If you look at the space for language bindings for gtk you see C, Python, Vala, and Rust mostly. C isn’t a terrible choice, but can be not fun quickly. Python is okay, and a popular choice. But it can be slow, and doesn’t compile to an executable without packaging the entire Python runtime. So I think Crystal can compete really well with Python here. Vala is described as a dead language, so not much of a comparison. And Rust…

I spent a while messing with gtk-rs, especially since GNOME has sort of signaled institutional adoption of Rust. It can compete with Crystal in a lot of ways of course. BUT I find the gtk-rs quite hard to use because the Rust compiler and the Gtk C library are so antithetical. In order to make it work the devs have done some gnarly stuff, just to get a button to click requires a lesson in strong and weak references.

My point being that I think Crystal hits the mark for hobbyist desktop developers in a similar way to Python, but still gives you performance and deployability like Rust or C. Which is what I love about Crystal, you don’t have to choose between tradeoffs.

Sidenote: Crystal would probably be a good fit for small games as well, but I don’t see it competing in the professional gaming space like Rust might be able to.

I hope that Crystal gets some kind of “Crystal-native” GUI support, ideally Linux + Windows.

I don’t think an IDE/drag’n’drop is important — if the GUI library is there, people can use it to write an IDE or GUI designer.

Nim nim-lang.org (a compiled Python-like language) has a Nim-native GUI Linux (Gtk) + Windows (win32): NiGui (search github.com for NiGui) which shows it can be done (< 3000 LOC). However, it is very bare bones and incomplete. A similar attempt was made for Python with PyGUI but that seems to be making no progress. And, of course, there’s IUP www.tecgraf.puc-rio.br/iup/.

Another route is to create a platform-independent GUI library, either based on SDL2 or GLFW an OpenGL/Vulcan library for desktop GUIs. Or with one of the new minimalist libraries like libui (search github for libui) or nuklear (search github for nuklear).

Personally, so long as the same API applies to Linux and Windows, and it was Crystal’s official GUI library, I’d be glad to use any of these or with Qt or wxWidgets bindings).

PS reason for lack of links it that it only allows new users to put 2 links in a post!

  1. I don’t think Crystal need or will have “official” GUI, that is a de-facto part of official distribution, like in e.g. Lazarus\FreePascal. This would be a separate shard, maybe popular like Rails for Ruby, but still separate. Core team has enough headaches without gui library so it’s up to enthusiasts to create it.

  2. I’ve looked for gui libraries recently: https://github.com/crystal-community/crystal-libraries-needed/issues/63#issuecomment-557476762
    2.1. qT (https://github.com/Papierkorb/qt5.cr) currently doesn’t work (with crystal 0.31). And there is slightly too much magic - no chances to fix it without author.
    2.2. GTK (https://github.com/jhass/crystal-gobject/) works. I’m going to use it as a basis for my gui library in future. There is plenty of magic too though (it generates bindings at compile-time using gobject introspection), but as author is core team member chances are that it will work with future versions.
    2.3. libui (https://github.com/Fusion/libui.cr) works. But libui is… strange. No way to fine tune position of controls (custom margins, fixed layouts), only flow. No trees and it is unlikely they will be added soon.
    2.4. there is also an IUP(https://www.tecgraf.puc-rio.br/iup/), that is C library so should be pretty easy to bind, but by screenshots it looks too “old-school”. Maybe that’s just my impression though, it is using native controls after all.

  3. As for vulkan\opengl library - I don’t like this way. This isn’t going to work on low-end pc or something like raspberry, going to eat battery and will require much efforts to look “native” due to different render of fonts. But this is just my opinion and of cource this is still much better than chromium\webassembly.

  4. As for my own library (https://gitlab.com/kipar/no-no-gui) - at first I wrapped Lazarus LCL with (slightly) shoes-like wrapper, this mostly works but not ideal (you have to install Lazarus as a development dependency, it uses GTK2 or qT and adds unnecessary level of wrappers).
    Then i replaced LCL with pascal GTK3 bindings. https://gitlab.com/kipar/no-no-gui/tree/gtk3 - this partially works, but there are some problems with controls size calculations. The planned step is after fixing problems drop pascal stage completely and use GTK3 bindings from (2.2) to make pure crystal gui library. I didn’t have a time to work on it recently though but hopefully this would change.

4 Likes

This would be great. I would love a good simple crystal gui option.

konovod

1m

I’m impressed with the community consideration of my question, in general.

konovod: The detailed pros and cons and personal experience you bring is especially gratifying. I’m perhaps reading a little too much between the lines, but your personal hacking on Lazarus gives you special credibility so I am going to ask: Were you considering / are you considering using the Lazarus framework (which is independent of the “free pascal” compiler) and re-purposing it as a drag-n-drop IDE for Crystal itself? Is that even possible, or are the languages just too alienated for that to be worth a try?

At first my plan was to convert lfm (and maybe also dfm, fmx) files to crystal cofe using automated tool. This way you would be able to edit form in Lazarus as usual, then tool produce .cr file similar to pascal unit where you can edit event handlers.
But then i discovered reactive ui concept. In short: most usual thing in guis i made is a list of frames, each corresponding to some model object. Like a listview, but more customized, because items can have own lists, and don’t have to be positioned vertically. For example: list of columns for each category, each consists of border, caption and list of cards for issues in this category, each card consists of some text and a checklist for items in this issue. For the sake of example let checkboxes in it be somewhat customized too - say they include progressbar and some icon. In a lazarus/delphi i have to create a frame for each thing (column, card, checkbox), write a procedure that syncronize thing with model item (category/issue/subissue), maintain a lists of categories/issues/subitems and then my syncronization procedure will add/delete/modify things once something changed. It works, vut require some boilerplate, so each time we need to add another list it is tedious.
With reactive ui like a Vue, i describe one column/card/checkbox and then add “v-for: issue in category.issues” to make a list of them. You don’t even need to make them separate files - if element is simple it is easier to describe it inplace, all above example will fit in one small file.
This is so beautiful, I’m now thinking that DSL with such feature IS a way to do complex GUI.
I haven’t tried this approach at work though, only at pet project, so am not sure how this will work with buttons drawn in Photoshop and other things where drag-n-drop editor usually shine. Maybe some parts still have to be designed visually.

1 Like