RubyConf 2022

Building Native GUI Apps in Ruby

Ruby is an excellent choice for building desktop apps with a native GUI (Graphical User Interface) that looks familiar on Mac, Windows, and Linux. In fact, Ruby pushes the boundaries of developing such apps in brand new ways not seen in web development by supporting very lightweight and declarative GUI syntax including bidirectional data-binding, thanks to Glimmer DSL for LibUI, a gem that won a Fukuoka Ruby 2022 Special Award. In this talk, I will cover concepts like the GUI DSL, data-binding, custom controls, area graphics, drag & drop, MVC/MVP pattern, and scaffolding, with sample demos.

RubyConf 2022

00:00:00.000 ready for takeoff
00:00:16.920 so we're going to get started my name is
00:00:19.199 Andy Malley and I'm a senior software
00:00:21.060 developer at lexop lexop is a digital
00:00:23.760 only debt collection agency and today's
00:00:27.119 talk is going to be about building
00:00:28.800 native GUI apps in Ruby but before we
00:00:31.380 get started I have a few questions to
00:00:33.000 the audience the first one is who here
00:00:35.340 knows when a native GUI app is
00:00:39.360 okay we have a good number it's about 40
00:00:41.700 percent uh by the way I'm giving away
00:00:44.280 some lexop swag as you can see we have
00:00:46.920 caps t-shirts I have a few extra things
00:00:49.379 as well like Christmas socks so
00:00:51.480 participation is encouraged uh who here
00:00:53.460 would uh be willing to tell us what
00:00:55.140 Native GUI app is
00:00:59.160 go ahead
00:01:18.900 yeah so part of the answer is correct we
00:01:22.140 use libraries that are native for the
00:01:24.900 operating systems and they're
00:01:26.100 pre-compiled however the application
00:01:28.320 that's written on top of them does not
00:01:30.600 have to be completely compiled so part
00:01:32.640 of the answer is correct but we'll get
00:01:34.619 into the into more details about Native
00:01:36.420 apps in a second uh why would you build
00:01:38.939 that native GUI app though
00:01:40.619 somebody answered the question
00:01:43.860 yup go ahead Jeremy
00:01:48.860 exactly we want to build an app that
00:01:51.060 runs without using a browser next is how
00:01:54.960 many people here have experience with
00:01:56.460 Native GUI apps or desktop development
00:01:58.320 in general
00:02:01.259 okay it's about 30 perhaps it's a good
00:02:04.439 number
00:02:05.759 um but hopefully we'll get that number
00:02:07.079 higher so why do we want native GUI
00:02:10.380 we want to productively build apps that
00:02:12.900 support visual user interaction so once
00:02:14.819 you graduate from building command line
00:02:16.440 apps the next type of app you want to
00:02:18.900 build is a GUI app
00:02:20.819 uh build tools to increase productivity
00:02:23.220 so kind of like Ides or code editors
00:02:27.540 quickly build offline applications that
00:02:30.120 do not need internet
00:02:32.340 create online applications for specific
00:02:34.920 users without needing a browser so you
00:02:36.780 can tailor apps exactly for a certain
00:02:38.760 class of users and make it simpler for
00:02:40.980 them to launch the app without using a
00:02:42.420 browser
00:02:43.319 report and summarize data from databases
00:02:45.959 locally securely
00:02:48.480 provide user interface sorry user
00:02:50.940 friendly platform conforming native user
00:02:53.760 interfaces like on Mac OS Ventura for
00:02:56.640 example glimmer DSL for libui will run
00:02:58.739 and will look fully native just like as
00:03:01.379 if you've written the app in Swift and
00:03:03.660 also on Windows and Linux
00:03:07.080 avoid writing many layers of complex web
00:03:10.319 code when you don't need it
00:03:12.420 avoid wasting time fine tuning graphical
00:03:14.700 user interfaces because usually desktop
00:03:16.980 apps have uh operating system style
00:03:20.340 guides for how to build them so you
00:03:22.319 don't waste too much time like you do on
00:03:23.940 the web with CSS
00:03:25.739 provide fast performance for graphical
00:03:27.900 control input output so if it's a native
00:03:30.599 GUI toolkit as opposed to a non-native
00:03:33.180 one like Java Swing it'll have a faster
00:03:36.000 performance
00:03:38.220 uh however you can still quickly invent
00:03:40.739 brand new visual concepts for user
00:03:42.599 interaction so a big misconception is
00:03:44.940 that native apps are limited to Native
00:03:46.440 widgets but that's not true you can also
00:03:48.840 make your own non-native widgets as well
00:03:51.239 uh and also build local games
00:03:54.299 so uh here's an introduction to glimmer
00:03:57.060 if you just say window open it opens a
00:03:59.340 window that's completely empty so it's
00:04:01.560 the simplest syntax possible to open a
00:04:03.480 window it doesn't get more simpler than
00:04:05.519 that you add a text and that adds a
00:04:08.040 title to the window and then if you want
00:04:10.319 to add a label you can just say the word
00:04:12.540 label declaratively and then add a
00:04:14.459 property declaratively within it and
00:04:16.680 it'll give you a label that says hello
00:04:18.120 world
00:04:19.019 and finally you can fine tune the label
00:04:21.419 by adding a font with a font height and
00:04:24.300 then you can even change the font height
00:04:25.860 so it's a very very simple and
00:04:28.440 productive uh GUI DSL it's the simplest
00:04:31.199 DSL possible for going from zero to GUI
00:04:35.699 and let's start by talking about real
00:04:38.100 world apps built with glimmer this is
00:04:40.919 math bowling too which is a a kids math
00:04:43.440 game that adopts bowling rules uh
00:04:46.979 basically you know if you get the answer
00:04:48.300 correctly it's like hitting a strike if
00:04:50.100 you're off by a few numbers it's like
00:04:52.620 you missed a few pins when you uh bold
00:04:54.960 so uh yeah this is a fun game that I use
00:04:58.380 to teach my nieces who were seven years
00:05:00.720 old at the time math and it was built
00:05:03.540 with glimmer DSL for swt and it
00:05:06.000 demonstrates that you are not limited
00:05:07.860 whatsoever in the way you build guise on
00:05:09.780 the desktop
00:05:11.460 uh are we there yet is that small
00:05:13.680 project management app that was built
00:05:15.540 for an interior designer to use in their
00:05:17.340 workflow
00:05:18.960 again it's not limited in any way it
00:05:21.240 includes a Gantt chart it was built in
00:05:23.340 about 11 days for the MVP the first
00:05:25.500 version uh that usually you know we you
00:05:29.160 would imagine that would take more on
00:05:30.419 the web but yeah it took 11 days using
00:05:32.880 glimmer Rubio radio is an app created by
00:05:36.479 kojics uh that's the nickname of a
00:05:39.660 Japanese developer who builds a lot of
00:05:42.240 he works in bioinformatics but he also
00:05:45.720 helps me with my glimmer projects and he
00:05:47.580 built his own radio internet radio app
00:05:49.440 and with glimmer and I actually use it
00:05:51.840 as my main app right now for Internet
00:05:53.220 radio this is another app that he built
00:05:56.340 that is basically summarizing his own
00:05:58.320 data from a database locally he built it
00:06:00.780 as far as I know in less than an hour
00:06:02.580 using glimmer
00:06:04.560 uh this is Gladiator which is a code
00:06:06.600 editor that I've been using full time
00:06:08.220 since for the for the last two years
00:06:10.800 uh this is the DCR programming language
00:06:13.020 draw color repeat which is a kids
00:06:14.940 programming language based on Logo which
00:06:17.100 is Turtle graphics and this is a
00:06:19.259 variation on it that uses uses a stick
00:06:21.180 figure instead of a turtle
00:06:23.220 um
00:06:23.880 this is the b-flunch programming
00:06:25.440 language I built an IDE for it when I
00:06:27.600 after I discovered that somebody coded
00:06:29.400 the b-flunch programming language in a
00:06:31.440 ruby gem as an engine so I used that and
00:06:34.440 built a glimmer GUI on top of it
00:06:37.319 uh Solitaire everybody knows that Wordle
00:06:40.259 everybody knows Wordle uh this is a
00:06:42.539 metronome that I built for my own uses I
00:06:44.460 played drums as a hobby and uh I need a
00:06:47.880 metronome so I built my own and I trust
00:06:50.280 it more than my phone's metronome and it
00:06:52.380 was built in in about the first version
00:06:54.360 was in 10 minutes built in 10 minutes by
00:06:56.400 the way
00:06:57.780 so what are all the glimmer gooey dsls
00:07:00.240 uh so we have glimmer DSL for libui
00:07:03.180 which runs on C Ruby meaning MRI Ruby
00:07:05.699 it's in beta mode uh and uh it won the
00:07:09.360 Fukuoka Ruby 2022 special award earlier
00:07:12.960 this year in February after it got
00:07:15.960 judged by mats the creator of Ruby along
00:07:18.120 with other judges
00:07:20.400 um so this is the library that I'll be
00:07:22.259 talking mostly about today the other
00:07:24.240 libraries that are available are glimmer
00:07:26.160 DSL for TK for gtk for FX Ruby for swt
00:07:29.639 on jruby swing and javafx and the swt-1
00:07:34.020 is the only one that is in final that is
00:07:35.940 final the rest are all Alphas but they
00:07:39.060 still work
00:07:42.000 so I mean the idea of glimmer proved
00:07:43.979 itself enough that it was worth covering
00:07:46.199 all the available toolkits in Ruby that
00:07:48.240 are actively maintained with a glimmer
00:07:49.919 DSL so all of them are covered now
00:07:53.520 uh so yeah we're going to talk about
00:07:55.979 libui today so how do we start there are
00:07:58.800 no prerequisites uh if you have Ruby
00:08:01.020 you're ready to go all you have to do is
00:08:02.940 install the gem and then you can run
00:08:05.039 this command to get started with samples
00:08:07.020 like to look at some examples it opens
00:08:09.360 this app that shows you a whole bunch of
00:08:11.039 examples it's called The Meta example
00:08:12.720 because it's a meta you know it's the
00:08:14.580 example of examples uh and it shows you
00:08:17.220 basic examples on the first tab here
00:08:19.400 Advanced examples over here so the
00:08:22.680 advanced ones include things like Tetris
00:08:24.660 snake tic-tock toads Etc
00:08:27.900 uh so what are some simple apps some
00:08:30.060 simplest thing we could look at is hello
00:08:32.159 world we just took a look at it earlier
00:08:34.380 but this is a a platform a
00:08:36.599 cross-platform version of it oh sorry
00:08:38.339 it's always cross-platform with glimmer
00:08:40.620 but this is just showing it to you on
00:08:41.940 all platforms uh this is a more
00:08:44.219 sophisticated app that basically lets
00:08:46.740 you store contacts in a in a sort of a
00:08:49.740 database and it shows them in a table
00:08:52.260 most business apps will have a table
00:08:54.240 widget and we'll have a form so this is
00:08:56.339 more demonstrating a more businessy kind
00:08:58.080 of app and also you can build games
00:09:02.279 so uh
00:09:04.140 as far as glimmer GUI DSL Basics the
00:09:07.260 first thing you want to learn is uh
00:09:09.600 controls controls are also known as
00:09:12.480 Widgets or components depending on the
00:09:14.940 GUI toolkit you're using in libui they
00:09:16.860 call them controls they're basically the
00:09:18.779 basic building block for showing visual
00:09:21.140 concepts on the screen and allowing the
00:09:23.459 user to import their output data
00:09:25.940 so they usually are declared
00:09:29.459 declaratively they're an underscore case
00:09:32.100 meaning lowercase and you know the Ruby
00:09:34.800 wave naming methods and they're actually
00:09:37.680 Ruby methods behind the scenes and I
00:09:39.480 mean window you just say window and it
00:09:41.040 gives you a window you say a button you
00:09:42.899 get a button you say a label you get a
00:09:45.360 label entry
00:09:47.279 and Etc so there are a whole bunch of
00:09:49.560 widgets and given that we only have 30
00:09:52.200 minutes in this talk I'm going to give
00:09:54.000 you some homework to discover the rest
00:09:55.860 of the widgets or controls so I mean
00:09:58.080 there's this list that has a whole bunch
00:09:59.399 of them like check box like combo box
00:10:01.339 form menu tab Etc however uh please do
00:10:07.140 your homework look look at the
00:10:09.420 exhaustive list at the glimmer DSL for
00:10:11.880 libui project page
00:10:14.580 so the next thing you want to learn
00:10:16.740 about is control arguments so controls
00:10:19.560 can optionally receive arguments in the
00:10:21.360 DSL they match the libuic API uh so for
00:10:26.220 a window you can pass it uh title like
00:10:29.580 hello world or you can pass it extra
00:10:31.260 arguments as well like the width and
00:10:33.060 height when it starts
00:10:35.760 um and that's about it uh next is uh the
00:10:39.300 control content block so after you
00:10:41.399 declare a keyword like window you can
00:10:43.440 open a curly brace Block in Ruby and you
00:10:46.260 want to use curly brace because you're
00:10:47.880 being declarative we don't want to use
00:10:49.380 do and do end is imperative leave that
00:10:52.140 for imperative code when you're in a
00:10:53.880 declarative mode use curly braces that's
00:10:56.700 uh part of the style guide of glimmer
00:10:58.740 and you can put within it properties
00:11:00.920 listeners or nested controls so as far
00:11:05.100 as and also you can pass it arguments
00:11:06.959 but still open the block afterwards so
00:11:09.180 as far as properties you can have things
00:11:10.680 like the title of the window or the
00:11:12.300 content size
00:11:13.560 uh and there's a whole list of
00:11:15.899 properties and again as part of homework
00:11:19.140 uh please go check out the exhaustive
00:11:21.480 list of properties at the glimmer DSL
00:11:23.220 for libui webpage I mean properties
00:11:25.740 include things like selected like the
00:11:27.600 color for a color button like padded
00:11:30.120 whether a box is padded Etc
00:11:33.420 um the next thing is listeners so
00:11:35.339 listeners always start with the on
00:11:36.720 underscore prefix they follow the
00:11:38.880 Observer pattern
00:11:40.860 um they uh they're basically followed by
00:11:43.920 an imperative code block so listeners
00:11:46.079 are the only part that is imperative
00:11:47.760 basically what you say is on closing of
00:11:50.640 a window do this this is the time to do
00:11:53.459 imperative code and within the do end
00:11:55.019 block you put whatever code you want to
00:11:56.760 do upon closing a window
00:11:59.660 and same with a button if you have a
00:12:02.579 button with a title click on clicked do
00:12:05.459 this work uh and in MVC listeners
00:12:09.779 basically are in MVC are kind of like
00:12:13.260 the control troller listening to The
00:12:15.180 View and when the view gets changes like
00:12:17.459 a user clicks a button the controller
00:12:19.920 will get triggered and do some work in
00:12:21.720 the model so these will usually this do
00:12:23.459 end block is an implicit controller it's
00:12:26.640 an it's a Lambda but it's an implicit
00:12:28.260 controller and it basically will
00:12:29.940 manipulate the model so you will usually
00:12:31.740 not manipulate the view directly here
00:12:33.899 again as part of homework check out all
00:12:36.420 the listeners like on clicked unchanged
00:12:38.279 on toggled on closing Etc on Mouse up
00:12:41.120 and it's at the glimmer DSL for libui
00:12:43.980 website or web page on GitHub
00:12:47.220 um
00:12:48.180 finally the last part in the content
00:12:51.420 block is the nested controls so you can
00:12:54.720 basically declare a hierarchy of widgets
00:12:57.180 because in the end when you open a
00:12:58.860 window you want to put something in the
00:13:00.240 windows so so you build the hierarchy of
00:13:02.279 controls so a window can contain a
00:13:04.500 button for example and in a way you're
00:13:07.320 following the composite design pattern
00:13:09.060 because every control that can contain
00:13:11.160 other controls is the composite and
00:13:13.920 there are a few special layout controls
00:13:16.260 like vertical boxed which lays controls
00:13:19.500 uh vertically a horizontal box which
00:13:22.980 lays them horizontally and grid which
00:13:25.260 will build them in a grid
00:13:27.899 um and this is a more advanced example
00:13:30.240 where a window has a vertical box within
00:13:32.339 it which has a label which has a table
00:13:34.620 and then the table has table columns
00:13:38.160 uh okay so the last thing you want to
00:13:40.380 learn as far as the basics of the GUI
00:13:41.940 DSL is the control operations so
00:13:45.260 they're invoked through Ruby methods on
00:13:47.880 the object returned by the DSL keyword
00:13:50.880 they match the libuic API that's wrapped
00:13:54.360 by the glimmer DSL for libui Library so
00:13:56.459 libui is a c toolkit and that's the one
00:13:59.279 we're using from Ruby in glimmer DSL for
00:14:01.200 libui
00:14:03.180 um it proxy calls to the wrapped objects
00:14:05.339 automatically so you don't have to worry
00:14:06.779 about it you just work with the Ruby
00:14:08.579 objects behavior is sometimes augmented
00:14:11.160 with smart smart defaults so for example
00:14:13.440 a window you can you can invoke show on
00:14:16.019 the window and that will invoke an
00:14:17.820 operation that will display the window
00:14:19.700 however that will also start the GUI
00:14:22.560 event Loop for you automatically usually
00:14:24.300 with GUI apps you have an event Loop you
00:14:27.360 don't have to manually start it anymore
00:14:28.740 it'll start automatically for you
00:14:30.360 another example is if you have a
00:14:32.040 checkbox you can check through
00:14:33.660 operations if it's checked and then you
00:14:35.940 can programmatically check it if you
00:14:38.040 want then you can check again and it'll
00:14:40.019 be true afterwards
00:14:42.060 uh so let's talk software architecture
00:14:44.420 uh so the main architectural pattern and
00:14:47.459 desktop apps are GUI apps in general is
00:14:49.740 MVC which comes from the earliest
00:14:52.079 incarnation of desktop apps or desktop
00:14:54.420 development which is Small Talk MVC uh
00:14:57.600 so there's a view a controller and a
00:14:59.279 model usually the view will observe the
00:15:03.480 model and then update itself that's the
00:15:05.820 right way of doing MVC so this is not
00:15:07.440 MVC from the web which is a corrupted
00:15:09.480 version this is the clean pure MVC on
00:15:11.820 the desktop you never want the
00:15:14.339 controller to talk to update the view
00:15:16.019 you want the view to observe the model
00:15:17.699 and then update itself the controller
00:15:19.860 will observe the view for things like on
00:15:21.660 Mouse up on key up on click and then
00:15:24.600 it'll manipulate the model and then
00:15:27.120 given that the model will change upon
00:15:28.800 manipulation The View will automatically
00:15:30.540 update itself so that will by following
00:15:32.820 MVC you will have the cleanest most
00:15:34.800 decoupled code possible however a newer
00:15:37.860 pattern that augments MVC is MVP which
00:15:40.440 is a variation that uses bi-directional
00:15:43.320 data binding basically it upgrades the
00:15:45.600 controller to a presenter that will
00:15:47.639 observe both sides of model and View and
00:15:50.820 when changes happen in either of an
00:15:52.620 it'll go and update the other side
00:15:54.540 automatically for you so it's good to
00:15:56.459 use a combination of MVC and MVP usually
00:15:58.860 in apps uh okay so let's talk about data
00:16:01.560 binding what is data binding so data
00:16:03.720 binding enables you to with the simplest
00:16:06.240 Min most minimal syntax possible connect
00:16:09.060 the view into the models so for example
00:16:12.180 I mean and it follows the way you think
00:16:13.860 about things so I mean if I have a text
00:16:15.899 field and I want it to show the first
00:16:17.579 name of the user all you have to do is
00:16:20.339 use double arrow to say I want to
00:16:22.320 bi-directionally data bind it and then
00:16:24.600 and that that just leverages Ruby meta
00:16:26.940 programming and operating over operator
00:16:29.040 overloading and it'll basically connect
00:16:31.260 it to the first name attribute on a user
00:16:33.600 object from that point on if I update
00:16:36.420 the first name on the user
00:16:37.920 programmatically like through a
00:16:39.540 controller The View will update itself
00:16:41.339 automatically from government and if if
00:16:43.440 they use their interest text in here
00:16:45.500 using the user interface it'll
00:16:47.940 automatically update the model so it's
00:16:50.279 it's very simple it's the simplest way
00:16:51.899 to reason about uh codes actually and
00:16:54.779 don't believe they react people they're
00:16:56.459 lying to you data binding bi-direction
00:16:58.680 data binding is simpler than using
00:17:00.480 something that's more like react uh so
00:17:03.060 that that date time picker is another
00:17:05.040 example it's data binding the event time
00:17:07.679 on a reservation to the time on a date
00:17:09.600 time picker however sometimes you need
00:17:11.699 Genie directional data binding for
00:17:13.140 properties that are read only so a
00:17:14.819 buttons text is read only meaning the
00:17:18.120 user when they click the button that
00:17:19.439 doesn't change the text but the text
00:17:21.540 will change if the model if the count if
00:17:24.480 the count attribute on a counter model
00:17:26.280 updates and you can also add extra
00:17:28.679 options like converters like on read of
00:17:30.840 the data I want to convert it to a
00:17:32.640 string so there are more advanced
00:17:34.799 features in data binding and glimmer
00:17:36.720 that you could leverage as well another
00:17:38.220 example is the label it's got a text and
00:17:41.220 you can update it automatically whenever
00:17:43.799 the order presenter total gets updated
00:17:48.380 here's a slightly bigger example so this
00:17:51.660 is combining MVC and MVP with data
00:17:54.059 binding so we have a button counter
00:17:56.240 click to increment and when you click it
00:17:58.799 it'll increment the numbers so 11 will
00:18:00.660 become 12 12 will become 13 Etc however
00:18:04.520 we also have a text field that's data
00:18:07.260 bound to the same data so how do how do
00:18:09.780 we do that we data bind the entry text
00:18:12.059 to the account attribute on the counter
00:18:14.340 model and then we data bind the same
00:18:16.620 exact attribute to the text of the
00:18:19.380 button so now they're synced they're
00:18:21.360 fully synced and then every time I click
00:18:23.460 on the button I invoke a listener that
00:18:27.419 will basically which is an implicit
00:18:28.799 controller that will increment the count
00:18:30.900 and once it increments 11 becomes 12 so
00:18:33.780 then the text field value also becomes
00:18:36.539 12. however if the user manually
00:18:39.419 manipulates the text field and makes the
00:18:42.120 value 50 it'll automatically gets
00:18:44.160 reflected in the button and the button
00:18:47.100 will show 50 as well so this is data
00:18:49.260 binding in action
00:18:51.360 so again as part of homework for you
00:18:53.460 guys check out the Advanced Data binding
00:18:55.860 features like using Converters on read
00:18:57.539 and on right using hooks before read
00:18:59.760 after read before right after right
00:19:01.620 nested data binding index data binding
00:19:04.200 key data binding computed data binding
00:19:06.059 and all the details are the glimmer DSL
00:19:07.919 for libui GitHub project page
00:19:11.460 so okay next topic is area Graphics so
00:19:14.580 an area control can draw arbitrary
00:19:16.799 Graphics so the benefit of that is
00:19:19.860 basically being able to build non-native
00:19:21.960 visual concepts so you can build any
00:19:24.780 concept you want visually using the area
00:19:26.520 control which is kind of like a canvas
00:19:28.320 basically and you can do it with
00:19:30.240 retained mode uh by nesting shapes
00:19:33.240 directly into the canvas or the area or
00:19:35.940 immediate mode by using the ondraw
00:19:37.860 listener uh usually retained modes will
00:19:40.380 give you more maintainable code that's
00:19:42.539 easier to reason about but the immediate
00:19:44.820 mode will give you slightly higher
00:19:46.919 performance in a few cases not always
00:19:49.080 but in a few cases
00:19:51.840 um so you can Nest shapes like
00:19:53.580 rectangles Square Arc Circle Line bezier
00:19:58.140 curve polygon polyline poly bezier
00:20:03.179 and a figure that could contain anything
00:20:05.520 so I mean what you see on the screen
00:20:07.440 here is a completely you know custom
00:20:09.360 visual concept that's obviously
00:20:11.460 non-native like this is not a native
00:20:12.960 widget but you can build it if you want
00:20:14.760 you can build any concepts you want that
00:20:17.039 can come in handy when you're building
00:20:18.179 things like a uml designer like a
00:20:20.820 traffic signaling app
00:20:22.860 Etc
00:20:26.640 okay so
00:20:28.140 um area will also uh give you support
00:20:30.780 for drag and drop out of the box in
00:20:33.299 glimmer which got added recently and you
00:20:36.299 you get events like on Mouse drag
00:20:38.100 started on Mouse dragged on Mouse
00:20:40.679 dropped uh and there's an example called
00:20:43.380 shape shape coloring that lets you
00:20:45.480 basically using the mouse grab any shape
00:20:47.400 and move it and you can see here in the
00:20:48.960 second uh screen everything is moved
00:20:51.419 around
00:20:53.220 okay next topic is custom components so
00:20:56.039 custom components uh let you let you
00:20:58.740 build Concepts again that are not not
00:21:00.840 either non-native or uh there are
00:21:04.140 variations on Native widgets so let's
00:21:06.240 dig it a little bit into that usually
00:21:08.700 you would just include the glimmer lib
00:21:10.260 UI custom control module it can accept
00:21:12.539 options and it's useful for specializing
00:21:15.600 controls so if I want a label to always
00:21:17.580 be red to use it as a red label you can
00:21:20.039 make your own Red Label control and
00:21:22.500 reuse it everywhere in the code
00:21:24.360 or you can aggregate controls so you can
00:21:26.580 make a name and address form and then
00:21:28.380 use the name and address form in
00:21:29.820 multiple places in your app
00:21:31.500 the last usage is basically build brand
00:21:34.380 new non-native controls with area
00:21:36.059 graphics
00:21:38.640 there's also custom windows which is a
00:21:41.159 variation on custom control that gives
00:21:43.500 you uh all the features of a window so I
00:21:46.679 can make a custom window that will open
00:21:48.179 an email for example and then you can
00:21:49.740 reuse that multiple times or in a custom
00:21:52.620 window that's a code editor that you can
00:21:54.780 open it multiple times in an app
00:21:58.440 um and custom windows are also known as
00:22:01.620 custom applications because you can
00:22:03.059 build an entire application as a custom
00:22:05.400 component so you can include this module
00:22:08.760 or this they're both aliases to each
00:22:10.559 other
00:22:11.580 uh and there there are custom controls
00:22:13.740 the last type is custom shapes which is
00:22:16.020 an upcoming feature in glimmer DSL for
00:22:18.120 lib UI that lets you compose any complex
00:22:20.760 shapes out of simpler shapes and then
00:22:23.100 once you build for example a shape
00:22:24.480 called stick figure you can reuse the
00:22:26.400 keyword stick figure anywhere in your
00:22:27.960 DSL and it just gives you the stick
00:22:30.059 figure right away with all all the
00:22:32.159 everything you would expect from a stick
00:22:33.539 figure and you can obviously customize
00:22:36.299 the size of it the color Etc so this is
00:22:39.179 an upcoming feature in glamor DSL for
00:22:40.799 lib UI but it's a current feature in
00:22:43.080 glimmer DSL for swt which is the final
00:22:45.179 version of glimmer
00:22:47.460 so you just include glimmer libui custom
00:22:49.799 shape it accepts options it Aggregates
00:22:52.740 multiple shapes it supports relative
00:22:55.020 positioning which will simplify the code
00:22:57.780 when you're building them
00:23:00.000 so again as part of homework for you
00:23:02.220 guys I want you to check all the
00:23:04.080 examples that come with glimmer DSL for
00:23:06.120 libui this is a you know a good list of
00:23:08.460 basic examples as well as well as more
00:23:10.440 advanced examples like the gp2 the gpt2
00:23:13.980 notepad which is AI powered there's a
00:23:17.039 Midi player there's a paginated table
00:23:19.760 snake Tetris Etc
00:23:23.700 uh okay so we have a bit of extra time
00:23:26.039 we have about five minutes left so uh
00:23:28.620 now that we finished kind of early I
00:23:30.900 could talk a bit about glimmer DSL for
00:23:32.640 swt which is the finished version of
00:23:34.500 glimmer that runs on jruby uh so this
00:23:37.260 one is 100 feature complete and it also
00:23:39.960 includes scaffolding and Native
00:23:41.520 executable packaging support which
00:23:43.740 hopefully should make it into glimmer
00:23:45.179 DSL for Libya in the future
00:23:47.539 but they're already included in glimmer
00:23:49.980 DSL for swt so I mean how do we set this
00:23:53.039 up you have to install a jdk like jdk 19
00:23:55.799 you have to install jruby like 9 9380
00:24:00.360 uh and uh jruby by the way is basically
00:24:03.059 a 100 compatible Ruby that runs on the
00:24:06.240 Java virtual machine that's implemented
00:24:08.159 on top of the Java virtual machine once
00:24:11.220 you you have the prerequisites all you
00:24:12.840 have to do is install the gem glimmer
00:24:14.340 DSL swt and then you can run samples
00:24:16.799 with glimmer samples
00:24:18.480 and it gives you something like this
00:24:19.919 which is a glimmer meta sample which is
00:24:22.200 kind of like the same thing you got with
00:24:23.520 libui
00:24:24.780 but then you have extra things like
00:24:26.820 scaffolding like I can scaffold the
00:24:28.380 whole app from scratch or I can scaffold
00:24:30.720 components like a custom shape or I can
00:24:33.799 convert a web app into a desktop app
00:24:36.120 with one command by giving it the
00:24:37.919 website
00:24:39.380 and it'll basically generate uh the app
00:24:43.020 directory with the model directory a
00:24:45.000 view directory a script to run the app
00:24:48.659 um as well as let's see oh yeah and you
00:24:51.840 can package the app as the gem
00:24:53.100 automatically it'll come with with the
00:24:55.440 scaffolding and also it gives you an
00:24:57.659 entry point to the app so once you have
00:25:00.360 that then you can do Native executable
00:25:02.100 packaging so from inside the app
00:25:03.720 directory you can run glimmer package
00:25:05.520 and it'll package the app as a native
00:25:08.580 Mac app on the Mac an exe file on the
00:25:12.120 windows on Windows sorry and on Linux
00:25:15.179 like a native app on Linux as well
00:25:17.780 however you can customize it if you want
00:25:20.280 a DMG file on the Mac you can pass DMG
00:25:22.679 as an option or PKG if you prefer PKG on
00:25:25.980 Windows you can pass MSI and get an MSI
00:25:28.580 installer official installer
00:25:31.400 on Linux you can pass Dev for a Debian
00:25:34.440 package or RPM for a red hat package
00:25:37.200 and it gives you something uh that's the
00:25:39.840 real deal it's basically
00:25:41.760 um like this is a Mac PKG file of Tetris
00:25:46.980 this is a Windows MSI installer so
00:25:49.980 people don't have to so when you give
00:25:52.080 this to someone they don't need to
00:25:53.820 install Java they don't need to install
00:25:55.200 Ruby or jruby or anything this includes
00:25:57.900 a package Java a package jruby and the
00:26:00.840 packaged app files so everything is
00:26:02.700 self-contained so when you hand it to
00:26:05.340 users they wouldn't be the wiser about
00:26:07.320 the fact that you built it with with
00:26:08.640 Ruby or jruby
00:26:10.919 uh and this is uh yeah RPM and uh Debian
00:26:14.460 packages on Linux
00:26:16.679 so I want to conclude the talk with a
00:26:18.419 call for help uh so here is how you
00:26:21.539 could contribute to glimmer you can
00:26:23.279 contribute custom controls or custom
00:26:24.900 widgets uh you can build development
00:26:27.480 tools and code editors and Ides
00:26:30.720 um which which are customizable in Ruby
00:26:33.000 which is very unique like if I use right
00:26:34.679 now vs code it's not as far as I know by
00:26:36.840 default it's not customizable with Ruby
00:26:39.000 this will enable you to be able to build
00:26:40.620 apps that are easily scriptable with
00:26:42.179 Ruby uh heart reloading support
00:26:45.659 wizardwick visual designer
00:26:48.539 uh I control hierarchy inspector
00:26:53.100 native executable packaging for C Ruby
00:26:55.679 which hasn't been tackled yet
00:26:57.779 graphing and charting gems to replace
00:26:59.820 python in data science visualization I
00:27:04.080 believe Ruby can do much better than
00:27:05.400 Python and you can help with that by
00:27:08.700 building graphing and charting gems
00:27:10.820 graphical enhancement gems like a shadow
00:27:13.440 system like a particle system theming
00:27:16.260 system Etc
00:27:18.000 uh and finally graeming sorry gaming
00:27:20.760 Frameworks that uniquely take advantage
00:27:22.559 of retained mode graphics with
00:27:24.659 bi-directional data binding so most
00:27:26.580 games actually will use immediate mode
00:27:28.320 and it will give you a sort of a
00:27:29.700 listener that will fire or will render
00:27:32.640 60 times a second or something like that
00:27:36.240 um or 60 whatever 60 times yeah a second
00:27:38.640 uh here you can you can go go a level
00:27:42.480 higher than that and just declaratively
00:27:44.760 declare the gaming concept and they
00:27:47.100 would only make only changes will only
00:27:49.140 happen uh when a real change in the game
00:27:52.080 happened so the code will end up a lot
00:27:54.059 simpler by relying on retained modes and
00:27:57.179 bi-directional data binding uh finally
00:27:59.760 blog and video tutorials so if you can
00:28:01.620 blog about glimmer and write video
00:28:03.419 tutorials or general tutorials even that
00:28:05.880 would be great
00:28:07.799 um
00:28:09.299 okay so we have one more minute uh I'm
00:28:12.179 gonna conclude this last but not least
00:28:14.400 with that glimmer DSL for libui
00:28:16.200 competition that's for rubyconf
00:28:18.779 attendees only for Rubicon 2022 so
00:28:21.720 basically build the code editor and
00:28:23.220 glimmer DSL for swt uh the deadline is
00:28:26.520 January 15 so that's about a month and a
00:28:28.559 half hopefully during Christmas and in
00:28:30.419 the New Year you'll have some time to
00:28:31.799 work on it uh submitted projects are
00:28:34.440 ranked by most feature complete highest
00:28:36.720 in quality shortest implementation time
00:28:39.059 three winners will be chosen all will be
00:28:41.580 mentioned honorably on the on the
00:28:43.799 project page two of them will get
00:28:45.480 lexap's swag like this for free and the
00:28:49.740 the top winner will get three hours of
00:28:52.320 free training and Glimmer from me
00:28:53.880 personally whether it's a individual or
00:28:57.179 group if they want to use it for their
00:28:58.620 work group teamwork
00:29:01.080 sorry the work team and we just need
00:29:03.299 syntax highlighting editor tabs open
00:29:05.880 files from file menu show line numbers
00:29:09.059 find and replace indent out Dent cut
00:29:11.880 copy paste undo redo navigation
00:29:14.880 shortcuts split screen and auto save
00:29:18.720 and everything is has been posted on my
00:29:21.059 blog so here are all the links that you
00:29:23.279 should care about you could take a
00:29:24.360 snapshot of this my blog which is
00:29:27.260 andymalley.blogspot.com has all the
00:29:28.980 details of the competition so you could
00:29:30.720 check them later otherwise we're hiring
00:29:33.179 at lexop our motto is work smart instead
00:29:36.720 of work hard and live well and uh if you
00:29:40.440 want to ask me any further questions
00:29:41.520 please do so after the talk
00:29:47.179 thank you