Model-View-Controller (MVC)

Building Native GUI Apps in Ruby

Building Native GUI Apps in Ruby

by Andy Maleh

In this presentation at RubyConf 2022, speaker Andy Maleh discusses the development of native GUI (Graphical User Interface) applications using Ruby, emphasizing the unique capabilities that this approach provides compared to traditional web development.

Key Points Discussed:

  • Understanding Native GUI Apps: Native GUI apps utilize operating system-specific libraries and allow for applications that run independently of web browsers, promoting ease of user interaction and providing a faster experience.
  • Benefits of Native GUI Apps: These apps can be built to enhance productivity and can function offline. They also enable tailored applications for specific user needs, secure data interaction, and offer performance advantages over non-native solutions.
  • Introduction to Glimmer: The talk focuses on Glimmer DSL for LibUI, a Ruby gem that simplifies GUI development with a straightforward, declarative syntax. It emphasizes creating components with minimal code, enhancing rapid development.
  • Real-World Applications: Maleh shares examples like:
    • Math Bowling 2: A children’s math game.
    • Are We There Yet?: A project management tool designed in just 11 days.
    • Ruby Radio: An internet radio application.
    • Gladiator: A code editor tailored for specific programming needs.
  • Glimmer DSL Frameworks: Maleh outlines various Glimmer DSLs, including those for LibUI, TK, GTK, and more, noting that the LibUI library won an award in 2022.
  • Learning and Usage: No prerequisites are needed to start using Glimmer; simply install the gem and run sample apps to see how they work. Essential topics include controls (widgets), control arguments, and data binding, which are critical for efficient app development.
  • Architecture Patterns: Explains the Model-View-Controller (MVC) and Model-View-Presenter (MVP) patterns, along with the advantages of utilizing bi-directional data binding for dynamic UI behavior.
  • Advanced Features: Maleh discusses area graphics and drag-and-drop capabilities, enabling the creation of unique interactive elements within native apps.
  • Contribution and Community: By concluding, Maleh encourages the audience to contribute to the Glimmer project, indicating opportunities for developing new tools, enhancing graphics, or creating custom controls.

Conclusion:

The talk emphasizes Ruby’s potential for building native GUI applications via the Glimmer DSL, urging developers to explore this tool for creating efficient and visually appealing apps. With rich capabilities, Glimmer offers a streamlined path for developers to transition into GUI app creation efficiently.

This presentation highlights not just the technical aspects of building applications but also the thriving community around enhancing Glimmer's functionalities, encouraging collaborative growth in the Ruby ecosystem.

00:00:00.000 Ready for takeoff.
00:00:16.920 So we're going to get started. My name is Andy Maleh, and I'm a senior software developer at Lexop.
00:00:21.060 Lexop is a digital-only debt collection agency. Today's talk is going to be about building native GUI apps in Ruby.
00:00:27.119 But before we get started, I have a few questions for the audience. The first one is: who here knows what a native GUI app is?
00:00:35.340 Okay, we have a good number—it's about forty percent. By the way, I'm giving away some Lexop swag. As you can see, we have caps and t-shirts.
00:00:44.280 I have a few extra things as well, like Christmas socks. So participation is encouraged! Who here would be willing to tell us what a native GUI app is?
00:01:18.900 Yes, part of the answer is correct. We use libraries that are native for the operating systems, and they're pre-compiled.
00:01:22.140 However, the application that's written on top of them does not have to be completely compiled. So part of the answer is correct.
00:01:28.320 But we'll get into more details about native apps in a second. Now, why would you build a native GUI app?
00:01:34.619 Somebody answered the question. Yes, we want to build an app that runs without using a browser.
00:01:38.939 Next, how many people here have experience with native GUI apps or desktop development in general? Okay, it's about thirty. Perhaps it's a good number. But hopefully, we'll get that number higher! Why do we want native GUI apps?
00:02:00.740 We want to productively build apps that support visual user interaction. So once you graduate from building command line apps, the next type of app you want to build is a GUI app. We want to build tools to increase productivity, like IDEs or code editors.
00:02:12.900 We also want to quickly build offline applications that do not need the internet and create online applications for specific users without needing a browser. This way, we can tailor apps exactly for a certain class of users and make it simpler for them to launch the app without using a browser.
00:02:36.000 We want to be able to report and summarize data from databases locally and securely. Moreover, we need to provide user-friendly, platform-conforming native user interfaces, like on macOS Ventura.
00:02:53.760 For example, Glimmer DSL for LibUI will run and look fully native, just like if you've written the app in Swift, and also on Windows and Linux.
00:03:38.760 We want to avoid writing many layers of complex web code when we don't need it. Additionally, we aim to avoid wasting time fine-tuning graphical user interfaces because desktop apps have operating system style guidelines.
00:03:43.320 This means you won't waste too much time like you do on the web with CSS. Desktop apps provide fast performance for graphical control input/output. If you use a native GUI toolkit as opposed to a non-native one, like Java Swing, you'll experience faster performance.
00:04:05.640 However, you can still quickly invent brand new visual concepts for user interaction. A big misconception is that native apps are limited to native widgets, but that's not true.
00:04:09.180 You can also create your own non-native widgets and even build local games. Let's discuss Glimmer.
00:04:19.059 If you just say 'window open', it opens a window that is completely empty—it's the simplest syntax possible to open a window. It doesn't get simpler than that.
00:04:39.660 You add text to provide a title to the window, and if you want to add a label, you can just say the word 'label' declaratively and add a property within it. This will give you a label that says 'Hello World'.
00:04:45.240 Finally, you can fine-tune the label by adding a font with a specified font height. It's very simple and productive. This is the most straightforward GUI DSL available for transitioning from zero to GUI.
00:05:07.740 Now let's discuss real world applications built with Glimmer. One example is 'Math Bowling 2', which is a kids' math game that adopts bowling rules.
00:05:38.640 If you get the answer correctly, it's like hitting a strike, and if you're off by a few numbers, it's like missing a few pins when you bowl. I use this game to teach my nieces, who were seven years old at the time.
00:05:51.060 This game was built with Glimmer DSL for SWT and demonstrates that you are not limited in any way when building GUIs on the desktop.
00:06:03.060 Another example is 'Are We There Yet?', which is a small project management app designed for an interior designer to utilize in their workflow. It includes a Gantt chart and was built in about 11 days for the MVP version.
00:06:46.680 You might imagine that such an app would take longer to build on the web, but it only took 11 days using Glimmer. Then we have 'Ruby Radio', an internet radio app created by a developer who works in bioinformatics but also helps me with my Glimmer projects.
00:07:18.000 I actually use it as my main app for internet radio. He built another app that summarizes his own data from a local database in, as far as I know, less than an hour using Glimmer.
00:07:45.360 Next is 'Gladiator', a code editor that I've been using full-time for the last two years. The DCR programming language, which stands for Draw Color Repeat, is a kids' programming language based on Logo, focused on Turtle graphics.
00:08:10.920 This is a variation that uses a stick figure instead of a turtle.
00:08:37.320 Another example is an IDE I built for the B-Flunch programming language after discovering it was implemented in a Ruby gem. I also built a metronome that I trust more than my phone's version—it took about ten minutes to develop.
00:09:02.580 So, what are all the Glimmer GUI DSLs? We have Glimmer DSL for LibUI, which runs on CRuby (MRI Ruby) and won the Fukuoka Ruby 2022 special award earlier this year in February.
00:09:38.160 This library is the main focus of my talk today. Other available libraries include Glimmer DSL for TK, GTK, FX Ruby, SWT on JRuby, Swing, and JavaFX.
00:10:11.160 The SWT is the only one that is final; the rest are all in alpha, but they still work.
00:10:57.799 The idea of Glimmer proved itself enough to cover all the available toolkits in Ruby that are actively maintained with a Glimmer DSL.
00:11:03.160 So today, we're primarily discussing LibUI.
00:11:25.180 There are no prerequisites to get started. If you have Ruby, you're ready to go. All you have to do is install the gem, and then you can run samples to see examples.
00:11:50.900 This app, called the Meta example, shows many basic and advanced examples, such as Tetris, Snake, Tic-Tac-Toe, and others.
00:12:21.440 For simple apps, we can look at a 'Hello World' example, which is cross-platform, demonstrating the app's functionality across all platforms.
00:12:49.059 A more sophisticated app can store contacts in a sort of database and display them in a table. Most business apps will have a table widget and a form.
00:13:21.180 As we delve into the Glimmer GUI DSL basics, the first thing to learn about are controls, also known as widgets or components, depending on the GUI toolkit you're using.
00:13:40.380 In LibUI, they call them controls, which serve as the basic building blocks for displaying visual components on the screen and allowing user input.
00:14:07.800 They are generally declared in underscore case, meaning lowercase, following the Ruby naming conventions. Essentially, if you say 'window', it gives you a window; if you say 'button', you get a button.
00:14:34.920 Given that we only have 30 minutes in this talk, I recommend you do some homework to discover the rest of the widgets or controls.
00:14:54.780 Here's a list with various options like check boxes and combo boxes. Additionally, please do check out the exhaustive list at the Glimmer DSL for LibUI project page.
00:15:18.540 The next topic is control arguments. Controls can optionally receive arguments in the DSL that match the LibUI API so for a window, you can pass it a title such as 'Hello World'.
00:15:51.780 You can also pass extra arguments such as width and height when it starts. After you declare a keyword like 'window', you can open a block in Ruby.
00:16:11.340 It's important to use curly braces in this context. You want to declare properties, listeners, or nested controls within this block.
00:16:36.780 For instance, properties can include the window's title or content size. As part of your homework, check out the exhaustive list of properties at the Glimmer DSL for LibUI webpage.
00:17:02.460 Listeners always start with the prefix 'on_' and follow the Observer pattern. They are usually followed by an imperative code block.
00:17:24.360 Listeners are the only imperative part of the code. Thus, when you specify an 'on closing' event for a window, you insert the actions you want to take when that event occurs.
00:17:44.640 The final part of the content block is nested controls, which allow you to declare a hierarchy of widgets. For example, a window can contain a button, and this follows the composite design pattern.
00:18:12.960 There are several layout controls, such as vertical boxes and horizontal boxes for arranging controls. This leads to more advanced windows containing tables and labels as examples.
00:18:43.560 The last important aspect of the Glimmer GUI DSL is control operations, which are invoked through Ruby methods on objects returned by the DSL keyword.
00:19:13.260 They mimic the LibUI API that is wrapped by the Glimmer DSL for LibUI library, and keep in mind that this ensures seamless operation.
00:19:38.279 Let's talk about software architecture. The main architectural pattern in desktop GUI applications is the MVC, or Model-View-Controller.
00:20:07.320 MVC originates from the earliest incarnations of desktop development, specifically Smalltalk, where the view observes the model and updates itself accordingly.
00:20:31.020 It's important to note that this is the clean implementation of MVC, unlike the corrupted version often seen in web applications.
00:21:04.920 Change triggers in the view will consequently update the model accordingly. In addition to MVC, MVP, or Model-View-Presenter, is a newer pattern that utilizes bi-directional data binding.
00:21:36.720 This approach enhances the controller into a presenter that observes both the model and view, allowing changes to be automatically reflected on either side.
00:22:17.580 Let's discuss data binding. Data binding allows you to minimalistically connect views to models.
00:22:52.500 For example, you could bind a text field to display the first name of a user, using a simple syntax that leverages Ruby's meta programming.
00:23:19.920 If the user's first name changes programmatically, the view updates automatically, and inputs change will automatically affect the model.
00:23:56.960 This approach is simpler than many JavaScript frameworks, and the same binding can be applied to read-only properties with options for conversions on read and write.
00:24:38.460 In more complex cases, you can bind buttons and labels to change text based on model updates. For instance, the button showing a count that increments each time it's clicked.
00:25:07.740 As homework, explore advanced data binding features such as converters, hooks for read and write operations, and indexed data binding.
00:25:43.680 Next, we delve into area graphics. An area control can draw arbitrary graphics, allowing for the building of non-native visual concepts.
00:26:09.420 For instance, creating complex visualizations for UML designs or traffic signaling systems is possible using area controls that function like a canvas.
00:26:42.720 Additionally, Glimmer provides support for drag and drop operations, which can enhance user interaction through simple mouse actions.
00:27:14.400 Custom components further allow for unique visual elements that may not exist as native widgets or are variations of existing ones.
00:27:41.520 With the Glimmer LibUI custom control module, you can specialize controls with specific colors or functionalities, include them multiple times, and create custom shapes by combining simpler shapes.
00:28:17.760 As homework, check out all the examples that come with Glimmer DSL for LibUI, including AI-powered notetaking and games.
00:28:44.100 I also want to highlight Glimmer DSL for SWT, which is the feature-complete version running on JRuby, featuring scaffolding and native executable packaging support.
00:29:09.060 To set it up, install JDK like version 19, and JRuby version 9.38, followed by installing the Glimmer DSL SWT gem.
00:29:38.220 You can then generate native applications across platforms with container packaging ensuring a seamless user experience.
00:30:12.720 To conclude, I encourage you to contribute to Glimmer in various ways, be it custom controls, code editors, or developing new tools.
00:30:47.880 We seek help in enhancing graphical capabilities or creating gaming frameworks that leverage retained mode graphics using bi-directional data binding.
00:31:18.040 Please check my blog for competition details and other resources, and feel free to reach out with any further questions after this talk.
00:31:54.000 Thank you!