Exploring Ruby DSLs for UI building... and Tk!
Disclaimer: I'm definitely not advocating to use Tk instead of libYUI or Qt. I'm perfectly aware that Tk is not exactly "the future" (unless you are somehow reading this from 1996). Having said that... Not so long ago, we were discussing about the future of libYUI, about how we use it currently in YaST (with those intermediate YCP bindings that provide some kind of DSL with the cost of loosing direct access to the original OOP API of libYUI) and about how we would like to write the UI code from Ruby in the future. At some other recent point in time, we were also toying with the idea of having the possibility to define grid-based layouts for libYUI interfaces, although that project never took off. Fast-forward to yesterday's morning. I wanted to use part of my research time to take a look to other ruby-based UI DSLs out there and I did it by developing this: https://github.com/ancorgs/glimmer-tk-calculator Let me explain what it is and what can we learn from it (if anything). 1) What is Glimmer? Not being technically precise, we could say Glimmer is a GUI development library for Ruby (JRuby and Opal). You specify your UI in a pretty nice DSL and you get a SWT interface if you are using JRuby. https://github.com/AndyObtiva/glimmer-dsl-swt That same code can be executed in a web browser using OPAL and that UI will be rendered in HTML+Javascript. https://github.com/AndyObtiva/glimmer-dsl-opal One of the cool features of Glimmer is that it offers a data-binding library that works very well out of the box to connect elements on the interface with elements on the underlying model. In my experience, bidirectional data-binding is a tool that must be used with care but that is really useful in many situations. 2) What is Glimmer-DSL-Tk So far just an experiment form the original Glimmer developer to bring the functionality of Glimmer to MRI Ruby. The DSL is not fully compatible with the one used by Glimmer to define interfaces in SWT and Opal. Instead, it's closer to the Tk API... which I found quite nice because it gave the opportunity to learn the Tk basis from a very convenient environment. As you can see here, you can write the UI in a thin object-oriented wrapper on top of Tk or using the nice Glimmer declarative syntax. https://github.com/AndyObtiva/glimmer-dsl-tk#glimmer-gui-dsl-concepts 3) My experiment I just stole a calculator model from one of the Glimmer SWT/Opal demos and wrote an UI for it using glimmer-dsl-tk. As you can see, the UI code is really declarative and free of manual steps like populating values or taking care of the event loop. There is also no boilerplate code like the one we have in YaST to connect our object-oriented CWM widgets to the underlying model (you know, defining #init, #store, etc.). https://github.com/ancorgs/glimmer-tk-calculator/blob/master/lib/views/glimm... Data-binding works like a charm. This simple call you can find in the code does all the connection magic, providing interactivity for free: bind(presenter, :result) It was also an opportunity to me to learn about Tk's grid layout system. It's pretty neat. It's based in just a few simple concepts and it's quite easy to understand, but it still gives the developer quite some power. It's true that, used directly, it pollutes a bit the UI code (as you can see in my code). But it should be easy to find a way to not need to pass all those row/column values to every single widget. I though the whole Tk approach would work quite well for a TUI as well... and I was not the first one. There are two implementations of Tk for ncurses. The development of both was stopped a looong time ago and I would be surprised if any of them is still useful in modern times, but at least it looks like there is people who still try to keep them compiling with relatively recent versions of Tk. https://github.com/credil/ck https://github.com/rkeene/CTk As final words, I'm not saying we should adopt Tk and/or Glimmer, but I think we can take inspiration from both to whatever we do in the future regarding the UI. There are quite some neat ideas in both. Writing an interactive UI turned to be a quite pleasant experience with such tools (as opposed to our not-so-nice experience in YaST). Cheers. -- Ancor González Sosa YaST Team at SUSE Software Solutions
On Thu, 11 Mar 2021 14:27:07 +0100
Ancor Gonzalez Sosa
Disclaimer: I'm definitely not advocating to use Tk instead of libYUI or Qt. I'm perfectly aware that Tk is not exactly "the future" (unless you are somehow reading this from 1996).
<snip>
3) My experiment
I just stole a calculator model from one of the Glimmer SWT/Opal demos and wrote an UI for it using glimmer-dsl-tk. As you can see, the UI code is really declarative and free of manual steps like populating values or taking care of the event loop. There is also no boilerplate code like the one we have in YaST to connect our object-oriented CWM widgets to the underlying model (you know, defining #init, #store, etc.).
https://github.com/ancorgs/glimmer-tk-calculator/blob/master/lib/views/glimm...
Data-binding works like a charm. This simple call you can find in the code does all the connection magic, providing interactivity for free: bind(presenter, :result)
Hi, at first thanks for sharing it. Really interesting reading. I check your experiment and to be honest I still see similar issue we have with yast. UI is focused on programmers. You write code that produce some UI. And to be honest I do not like it. I prefer GUI designer that produce some description of UI like qt designer or java swing designer that allows to play with UI elements its organization. Testing how it will look when you resizing size, etc. And then connect UI elements to code like e.g. that bind call. This way it is much easier for designer to play with it. Now we get just screenshot with red circles what we should change and we need to do it ourself and wait again for designer to look at it and say his oppinion.
It was also an opportunity to me to learn about Tk's grid layout system. It's pretty neat. It's based in just a few simple concepts and it's quite easy to understand, but it still gives the developer quite some power. It's true that, used directly, it pollutes a bit the UI code (as you can see in my code). But it should be easy to find a way to not need to pass all those row/column values to every single widget.
I am not sure, but how it will look like when you resize dialog? All those hard-coded padding a bit scary me. For me still the best layout is relative one which defines constrints like Spring Layout which for me works well and looks good.
I though the whole Tk approach would work quite well for a TUI as well... and I was not the first one. There are two implementations of Tk for ncurses. The development of both was stopped a looong time ago and I would be surprised if any of them is still useful in modern times, but at least it looks like there is people who still try to keep them compiling with relatively recent versions of Tk. https://github.com/credil/ck https://github.com/rkeene/CTk
As final words, I'm not saying we should adopt Tk and/or Glimmer, but I think we can take inspiration from both to whatever we do in the future regarding the UI. There are quite some neat ideas in both. Writing an interactive UI turned to be a quite pleasant experience with such tools (as opposed to our not-so-nice experience in YaST).
I like that binding approach to present raw data in UI. But still I think we should focus more on using some kind of GUI designer. My old idea was to use qt designer to produce UI file and then try to create ncurses UI from it, but I never move it forward. The approach that goes a bit further in this direction was experiment with shoes like definition in https://github.com/libyui/ruby-ui/blob/master/examples/wizard1.uit but still too far from GUI designer which anyone from UX/UI team can use. Josef
Cheers.
participants (2)
-
Ancor Gonzalez Sosa
-
josef Reidinger