Glimmer DSL for SWT Ruby Desktop Development GUI Framework

Summarized using AI

Glimmer DSL for SWT Ruby Desktop Development GUI Framework

Andy Maleh • October 05, 2022 • Montréal, Canada • Talk

The video titled "Glimmer DSL for SWT Ruby Desktop Development GUI Framework" features Andy Maleh presenting at the Montreal.rb Meetup in October 2022. The focus of the presentation is on the Glimmer DSL for SWT, a powerful framework that simplifies GUI development using Ruby. Throughout the video, Maleh demonstrates various features of the framework, showcasing its ease of use and efficiency in creating desktop applications.

Key points discussed include:
- Installation and Start-Up: The video begins with a quick overview of how to install the Glimmer gem and launch the sample applications. Maleh runs a demo app that lists sample codes on the left and displays the corresponding code on the right, showcasing the ease of accessing different examples.
- Simple Examples: Maleh presents a basic "Hello World" application, highlighting how simple it is to create a GUI with very little code. He illustrates how Glimmer's syntax is intuitive, allowing developers to rapidly prototype and build applications.
- Data Binding: He explains data binding capabilities in Glimmer, which facilitate the dynamic updating of UI components in response to data model changes. Maleh provides an example with a contact manager app that uses tables and filtering, displaying real-life application scenarios.
- Game Development: The presentation showcases the potential for game development using Glimmer, including demos of simple games like Tetris, highlighting its versatility beyond basic GUI applications.
- Real-World Applications: Maleh shares anecdotes about real-world applications he has built with Glimmer, such as educational games for children, including a math bowling game to improve math skills, and an IDE for a programming language called DCR.
- Software Architecture: He touches upon common software architectures such as MVC (Model-View-Controller) and MVP (Model-View-Presenter), explaining their significance in structuring applications developed using Glimmer.
- Advanced Features: The talk also delves into advanced topics, including custom components, drag-and-drop functionality, and canvas graphics for non-native widget creation.
- App Packaging: Maleh concludes with a demonstration on how to package a Glimmer app into native executable formats. This includes packaging for Mac as a DMG file, ensuring that Ruby apps can be distributed seamlessly.

The key takeaways from the video emphasize Glimmer's capability to streamline desktop application development through its declarative syntax, robust data binding features, and ease of packaging applications as native executables, ultimately showcasing its potential for both simple and complex application development.

00:00:00.840 okay so once you've installed the gem and then launched the glimmer meta sample through the glimmer samples
00:00:06.839 command then you should see something like this
00:00:13.200 can you guys all see this Yeah so basically this is an app that lists all the samples on the left side
00:00:20.699 uh and it shows you the code of every Sample When you select it on the right side so I just selected hello text so
00:00:27.660 it's showing me the code of hello text I bumped up the font just for this presentation by default so you guys
00:00:34.380 should this this text should be readable right guys awesome so
00:00:39.660 um so yeah let's get let me show you a few samples just to demonstrate what glimmer is I mean so I just showed you
00:00:46.379 let me delete this uh license code doesn't matter but um I just showed you
00:00:52.620 a video that was demonstrating how to do hello world so I mean this is hello world I'm going to zoom in to show you
00:00:58.920 what what you get you end up getting a window that has the title glimmer uh with the label within it that says hello
00:01:04.799 world uh the nice thing about being able to get something like that with so little code is that this encourages the
00:01:11.820 people to learn programming uh very in a very friendly way a lot of people are
00:01:17.700 discouraged by programming because if you want to show any kind of graphical user interface with web libraries you
00:01:22.979 have to build something very complicated using the simplest web framework out
00:01:28.200 there rails rails is one of the best Frameworks out there and yet it's still a lot more complicated than this here I
00:01:34.320 can just uh if I delete all of this code and type window by the way windows and Alias for shell and swt they use the
00:01:42.180 word shell to describe windows but I provide an alias for it which is window
00:01:47.280 and glimmer DSL for swt in a fight type just window open it opens a window which
00:01:53.280 is awesome that's the quickest way to you know get from code to graphical user interface I believe in the world I don't
00:01:59.640 think there's a better way than this because of Ruby thanks to Ruby and then if you want to do you know customize it
00:02:05.759 a little bit you just open a Ruby block but given that we're operating within a DSL this DSL Works kind of like an H
00:02:12.480 like HTML but within the Ruby language so basically uh now we're within the
00:02:18.599 window so we can add properties so I can add a property of text for example glimmer
00:02:25.980 uh launch it and now we see here glimmer uh but then I can for example I can add
00:02:33.120 the minimum size of 640 by 480.
00:02:38.280 now we have a window of you know 640 by 480 so this is more of a proper window now
00:02:45.599 um and then I can add a label and uh I can say here uh text hello
00:02:52.260 world and let's let's add a font well I mean let's launch it first
00:02:58.739 so it does say hello world here but it's very tiny so let's make it bigger so I
00:03:04.080 can just add a font and give it a high to whatever let's just say 60.
00:03:10.560 and boom or maybe make it even bigger 120. there you go so uh glimmer DSL for swt
00:03:19.860 helps you build apps very quickly and this is just a the simplest example but what if we were to build a more serious
00:03:26.159 app that involves more complex widgets not just a label let's just say we want a table
00:03:31.860 so a table is basically one of the most important widgets in business applications almost all business
00:03:37.319 applications will use tables to summarize data and list them and list them and allow you to filter by queries
00:03:45.299 as well as sort the data so if you want that I'm going to launch the contact manager app and I won't get into the
00:03:52.319 code yet because I have not explain to you uh the glimmer DSL rules yet we'll
00:03:59.220 get into that in a second but this is a more sophisticated app that uses data binding uh glimmer DSL for swt supports
00:04:06.420 declarative data binding which enables you to write the you know the simplest code possible to populate widgets with
00:04:12.840 data so this table is populated with data using data binding it supports uh you know sorting out of the box
00:04:19.739 I can do filtering so if I want to search for last name Smith and hit find
00:04:25.259 now it finds me all the Smiths I can if I want uh let's do list all again and
00:04:32.280 then add a new user like John Doe whoops
00:04:39.180 and create John Dawn there we go John Doe got created and added to the table so I get all of that functionality uh by
00:04:48.060 using the glimmer DSL Forest WT so this is a more sophisticated real app that demonstrates how uh real business apps
00:04:54.660 could be built with this uh let's go into something even more complex so suppose I want to use non-native widgets
00:05:00.300 now I already mentioned you guys could do non-native things as well I'm going to launch uh I'm going to launch a game
00:05:06.780 so I have a number of games I have uh snake I have quarto I have Tetris I have
00:05:13.320 tic-tac-toe but I just launched Tetris um so I mean this is just demonstrating that using the same principles of uh
00:05:21.180 using a DSL as well as using data binding declarative data binding you can even build games if you want
00:05:27.840 um and building games this way will result in some of the like most minimal code possible for building
00:05:34.560 the game and I'll show you that in a second so let me close this for now and
00:05:40.440 get back into the presentation so we went through hello world we went
00:05:47.400 through the contact manager and went through Tetris so let's talk about some uh real world
00:05:52.740 apps uh that I've built with glimmer DSL for swt so there's this math bowling
00:05:57.900 game that I built for my nieces for it to help them learn math it's a game that
00:06:03.060 lets you uh test your math skills like what is 14x10 uh you know for kids this might be tougher than you you think for
00:06:10.440 us it's easy but anyways it has levels the difficulties but basically they'll pretend that if they answer the question
00:06:17.160 it's as if they made the bowling throw like as if they bowled basically in a bowling alley and then they'll get a
00:06:23.880 they get the results and depending on how far the answer is from the real answer that's how many uh pins they
00:06:31.020 knocked basically so it's a sort of a educational game but it's built with glimmer DSL for swt because you know
00:06:36.960 it's a perfect fit it's a it's a local game um and also glimmer DSL for swt enables
00:06:42.539 you to package Ruby code as real native apps like on the Mac it would be a DMG
00:06:47.880 file that people can download and install so I I built this game and I'm my sister installed it and I had my
00:06:55.020 nieces learn math through that through it and uh yeah they liked it quite a bit uh this is a another real app that that
00:07:02.699 has a Gantt chart so this is demonstrating some some non-native Concepts like if I want to do
00:07:09.000 a Gantt chart that's definitely not a native widget but thankfully I can reuse any available Java swt widget on in the
00:07:16.680 Java market so I was able to find the Gantt charts widget for swt custom widget and use it in Ruby uh very
00:07:23.699 effortlessly and then I use the table with data binding and then a form with data binding and that app basically got
00:07:30.599 used by my sister and an interior design in her interior design work she's an
00:07:35.819 interior designer uh this is Gladiator which is a code editor that I built in Ruby it's um I
00:07:42.960 demonstrated it during the last Montreal RB Meetup a few months ago but basically
00:07:48.360 it's a it's a code editor that supports syntax highlighting for about 200 programming no out of the box 50
00:07:55.139 programming languages but I can I can offer 200 if needed but uh yeah it also supports file lookup and a whole bunch
00:08:01.979 of other features that I won't get into right now but I've been using it as my main editor for the last two years just
00:08:07.800 as a way of educating myself actually on how to build code editors I found that a very interesting exercise and every once
00:08:15.120 in a while you know somebody mentions to me something that's a missing feature like Mark Andre mentioned to me I don't
00:08:20.520 have dark mode so the other day I added dark mode to it so it's pretty cool that
00:08:25.919 I could uh you know augment it and uh and build it very quickly with glimmer DSL for swt this is the programming
00:08:33.360 language for kids it's called DCR draw color repeat it's based on on Logo as
00:08:38.940 anybody here heard of logo before okay yeah I heard of it too because when I was a kid actually it was one of the
00:08:44.820 first programming languages I've used so I I built a ruby IDE for it using
00:08:49.920 glimmer DSL for swt so you stay here forward 80 pixels uh turn right by 45
00:08:55.440 degrees repeat six times and then color it yellow and there you go we got a we got this uh hexacon whatever octagon
00:09:02.760 shape so this is another programming language ID is for the b-funge programming language so I found that
00:09:09.839 Ruby engine that in the ruby gem that lets you basically interpret the b-funge
00:09:16.440 programming language I simply built an IDE on top of it using glimmer this is a Klondike Solitaire it's like you know
00:09:23.459 the good old Solitaire from Windows but in my opinion this is nicer much nicer
00:09:28.760 because I built it this is the world if you guys you guys know where though
00:09:34.380 yeah this is the desktop version of it that lets you play infinitely unlike the web game that you know has only one
00:09:39.959 puzzle a day so I love I I played this a lot when I first built it I I learned a
00:09:45.959 lot building uh playing it this is a metronome that I use I'm a I'm a drummer by the way as a hobbyist i play John
00:09:52.380 Cena and two rock bands this I use this for my training
00:09:57.899 um yeah and it's solid enough gives me all the options I need and it's actually more reliable than my phone metronome I
00:10:04.500 mean part of the reason why I built it is my phone metronome got an update one time and then it ended up with bugs it
00:10:11.160 wasn't reliable anymore so I ended up deleting it and then I built this app in like 10 minutes for the first version it
00:10:16.800 took me an hour for more improvements but 10 minutes for the initial version it was awesome
00:10:22.140 so what are the GUI DSL Basics how do we get started with glimmer so uh glimmer
00:10:28.260 aims to be uh it has a few goals uh behind it one of the main goals is to be
00:10:33.779 declarative and to require the minimum amount of code possible that you could think of so when you think of something
00:10:40.640 if I think button I should be able to just say button and then I end up with a button you guys saw that already I said
00:10:47.579 window and we ended up with a window so that's the minimum amount of code possible like there's no crazy like an
00:10:53.940 HTML usually you have to add crazy you know uh whatever brackets around the
00:10:59.100 HTML tags and also a closing tag like so much redundancy you have to add a closing tag Etc or if you're using
00:11:06.000 something like react you have to do render and you have to add a lot of JavaScript code and weird Hooks and
00:11:11.640 stuff before you get what you want here no we just declare it we're using Ruby Ruby is like one of the most Superior
00:11:16.980 languages in the world for declarative programming and we get it so we can say button label text radio
00:11:24.320 shell meaning window and there's a whole bunch of widgets that are supported in
00:11:29.459 swt out of the box basically every native widget out there and operating systems is supported so I'll get into
00:11:35.100 that later but that's just an example the next thing you want to learn the second thing is widget arguments so
00:11:40.500 widgets can optually receive arguments so if I want a button that has the text aligned left I passed it a symbol that
00:11:46.680 says left and swt all widgets have a uniform API that receives something
00:11:54.360 called swt Styles in glimmer instead of passing swt Styles the swt way which
00:12:01.560 they require you to pass a bit or its integers which is something like very crazy low level you don't have to worry
00:12:08.700 about that just use symbols in Ruby and then if you want to pass multiple of them you don't have to do bittering you
00:12:13.980 just separate them by comma and the library will take care of the rest for you so here I'm saying I want a button
00:12:19.860 that has the flat style with that left align text the third thing we want to know is
00:12:25.800 widget content block so any widget can be followed by a Content block and since we're operating in a declarative way in
00:12:32.399 a DSL you don't want to do a do end like you do in Ruby with multi-line blocks
00:12:37.560 usually because do end is imperative you're saying do till it ends here we're
00:12:43.500 being declarative think of this more like HTML except you don't need the closing tags what tag what you do is you
00:12:49.680 open this curly brace and then you close it and this is the body of the button so and that's the equivalent of a button in
00:12:55.260 HTML So within the body you can put properties and you can put listeners
00:13:00.779 so let's go next and and obviously you can take arguments
00:13:06.600 uh so let's start with properties so properties uh if you check out the swt API for every widget there's a big list
00:13:13.980 of properties that you can set and here what you do to set them you don't set them imperatively so imperatively the
00:13:21.660 way to do it is you would say button dot set text and you pass it the text here
00:13:27.720 in glimmer ds.m first WT we don't want to waste time on that kind of low level code like what you do is just say button
00:13:33.899 then you declare the property text and you you pass it the value and that's it you're done
00:13:39.060 uh you can pass multiple properties so we have a text here we have a font here and not only that since we're in Ruby
00:13:45.839 syntax you can if you need to mix an if else statement for some piece of logic
00:13:51.120 that you need to have you can actually mix it with a DSL natively so unlike with HTML where you cannot do that in
00:13:57.959 HTML you have to add a Erb tag in rails in order to mix logic with it and also
00:14:03.899 and react you cannot do that in order to mix jsx with JavaScript you have to open
00:14:09.180 curly braces here in Ruby we are in the same language you don't have to do anything just add an info statement and
00:14:14.399 it'll work and I'll show you examples uh in a minute how to do that next widget
00:14:21.480 content block listeners so they're basically the Observer pattern and they let you run imperative code so in the
00:14:29.279 end eventually you you will need some imperative code to do logic but usually the GUI structure is declarative you
00:14:35.459 want to declare what the GUI hierarchy is you know you have a window that has the label that has buttons Etc but when
00:14:42.060 you're executing logic when people click a button then you have to do imperative code and so this is the point where you
00:14:48.660 actually declare a listener with on on underscore the name of the the event so
00:14:53.880 it's very similar to say JavaScript with HTML but then you say do and this is the place to do a do end and that cleanly
00:15:00.420 separates imperative code logic from declarative code and then here you do what the button should do when you press
00:15:06.120 the button um by the way the reason I have this here
00:15:11.519 is it's demonstrating you know we have a button and we have a window I'm just trying to give you a visual as well as
00:15:16.680 we're going along but eventually I'm going to show you the code of that sample um so yeah listeners could be different
00:15:22.620 types of listeners you can listen to when the text is modified on a text field you can listen to when a keyboard
00:15:28.920 button is pressed on a text field and there's a whole list of listeners that's available in the swt API Docs
00:15:36.180 uh last the last thing you need to know is widget operations so when you actually build that widget like a shell
00:15:42.720 or or text a text widget or a button you end up receiving back a ruby object and
00:15:49.260 that Ruby object can have does have methods so you can just invoke operations on it uh it basically follows
00:15:57.060 exactly the API the swt widgets and the swt docs it actually wraps the swt
00:16:04.079 widgets with Ruby objects so there are swt widgets that are created in Java they get wrapped with Ruby objects but
00:16:10.019 to you it doesn't matter you can invoke the same methods on them uh jruby prevents sorry jruby will give you Ruby
00:16:16.800 friendly versions of all the API methods so I'll show you what that means in a
00:16:21.959 second but also behavior is sometimes augmented with smart defaults so what does that mean meaning when you
00:16:28.620 open a shell usually in any GUI Library out there they tell you not only should
00:16:34.260 you open a window but you also have to start something called the the GUI event loop at least in swt that's required
00:16:40.620 maybe gtk requires it too but anyways you have to start something called the GUI event Loop here we don't have to do
00:16:46.800 it it happens automatically for us so there are smart defaults but here's an example of operation so I
00:16:54.180 mean I already showed one which is opening a window so that's why here we say dot open but
00:16:59.940 also if you have a checkbox for example and I built it the Ruby object returned
00:17:05.880 is the terms checkbox and then I can say here dot selection equal true and this is the clean Ruby way of doing it and
00:17:13.199 jruby gives you that automatically so in Java the API is actually set selection so let me show you you could do it this
00:17:19.559 way too set underscore selection or you can even write the Java way which is set selection camo case that's how the API
00:17:27.000 was designed at swt but jruby will automatically support the other options for you so so that you can just operate
00:17:33.179 the Ruby way and not worry about it so I mean that's pretty much uh it as far as the basics of the GUI
00:17:40.320 DSL this gives you uh you know all the basics except data binding which I'm
00:17:46.740 going to get into in a bit uh but before we get there uh let's talk about software architecture so the most common
00:17:53.340 software architecture and desktop applications is MVC uh because that's
00:17:58.919 the oldest architecture it came from Small Talk MVC which is one of the oldest GUI libraries out there I believe
00:18:05.460 it is the first GUI Library out there so um in small talk MVC or MVC in general
00:18:12.000 the pure version this is the purest version you have a view meaning
00:18:18.840 things that you see on the screen that give you data a view of information or
00:18:24.600 data so that could be a text field that is showing you the name of a user could be a label that's showing you a summary
00:18:31.140 of the total of an order or it could be a table displaying a whole bunch of rows of information so this is what a view
00:18:38.400 does controller is uh basically the object that will receive events or interactions
00:18:45.840 from the user in order to mutate the data so if the user wants to edit the
00:18:51.600 name they have to submit a new name for the text text which in the text widget so in
00:18:58.980 order to do that they have to do that through the controller finally the model will basically embody business rules
00:19:05.820 about the data so if we have for example an order and it has to calculate the
00:19:11.039 total automatically the model will contain the tax for example amount like the tax percentage like it has to add 15
00:19:17.580 percent to 5 15 to any uh amount for the order so the model will embody the
00:19:24.120 business rules and that's pretty much what NBC is but a few things to note about NBC the pure version which you
00:19:30.960 don't see in rails for example because rails is a bit different because it's a web interface that's happening through multiple servers sorry like a web
00:19:39.059 architecture that's happening through multiple servers here when we're we're all local and it's in on the same
00:19:44.700 machine um you simply have a view that represents a
00:19:49.799 widget however the view typically in small talk MVC if you're following it correctly
00:19:56.820 will observe the model for changes and as soon as the model changes it'll update itself so that that way uh the
00:20:04.679 model doesn't have to know about the view but the view knows about the model so what that means is you can pass the
00:20:10.200 view a person object and then the view will pick the first name and last name and display them in the text Fields the
00:20:15.720 controller on the other hand will observe the view so it observes it but then it receives events about uh view
00:20:23.340 changes what that means is when a user clicks the button that's a view change so that the controller will get alerted
00:20:29.820 that the button got clicked and then it'll do work uh the thing about NBC that makes it so
00:20:35.220 clean is that um you should never have the model update the view directly The View should
00:20:41.400 be observing the model and updating it itself but also you should never have the controller manipulate the view directly it should manipulate the models
00:20:48.380 and then the view will update itself as the models change so that will result in
00:20:53.820 the cleanest code possible uh usually and I'll show you examples of that in a minute
00:21:00.840 so yeah I mean examples of model attributes or yeah I mean as far as
00:21:06.240 model update Advanced model updates uh sorry attribute changes
00:21:11.400 uh yeah so I mean that's pretty much it and then here is observing a mouse up
00:21:16.500 event a key up event on the keyboard a selection of a list and a list for
00:21:22.080 example or table Etc uh however uh a more advanced uh
00:21:28.380 graphical user interface pattern that emerged eventually was something called MVP MVP is just an evolution of MVC it
00:21:35.340 doesn't really violate it necessarily uh basically the controller gets replaced with a presenter and the presenter what
00:21:42.419 it'll do is it'll do something it'll do bi-directional data binding what that means is it'll observe the view for any
00:21:48.720 changes and when it receives the change the events it'll update the model and then it will observe the model for any
00:21:55.020 changes and when it receives events it'll update the view so that way the view and the model are fully decoupled
00:22:01.740 from from each other you don't want to always do that but sometimes that is very useful for example if I have models
00:22:09.780 that don't care about how to present the models like if I'm presenting the data on a table I might have I might want
00:22:16.080 some rows to be colored Reds and other rose colored green uh that that information is not model related
00:22:22.620 information the business logic doesn't care about that the business logic might be more about okay these rows are
00:22:27.900 delinquent customers and these rows are uh you know good standing customers Etc
00:22:33.780 uh so you would introduce the presenter that abstracts those details out and handle all those details so that's what
00:22:40.200 the MVP is uh so let's start looking into some code examples
00:22:45.240 because I'm sure that's a lot more interesting than just diagrams um so okay here's an MVC example with an
00:22:51.960 explicit controller so uh in glimmer DSL first WT you have the observed keywords
00:22:57.299 that you can use in the view to observe any attribute on a model for changes transparently meaning uh if I were to
00:23:04.260 use uh Java or anything else like C plus plus whatever usually you have to go to
00:23:10.320 the model and include a sub a superclass or or super something that makes it an
00:23:16.559 observable and then you can observe its attributes uh glimmer DSL for swt aims
00:23:21.900 at making that completely transparent so that you as the programmer build the models without worrying about
00:23:27.299 observability so as as long as you have account equal method in account reader
00:23:33.480 meaning an attribute reader and a writer I can have the view observe the model for any changes to that attribute using
00:23:40.620 Ruby meta programming so that way the model code remains as simple as possible it doesn't even know about the fact that
00:23:46.860 it's being observed by a view so here we observe a counter for the count and as
00:23:52.080 soon as we receive the change count we actually update the view button text so
00:23:57.539 this is the MVC pure MVC the view is updating itself as soon as the model changes so that's the first observation
00:24:04.140 I mentioned and then the second object division is the controller observing The View so we have an on widget selected
00:24:10.860 listener as soon as it fires there's a controller here that will increment count
00:24:16.620 so this is how to do it using the MVC way now you can do something called implicit controller implicit controller
00:24:23.940 is basically the observation here it stays the same but here we're not dealing with the controller directly anymore what we do is we have the view
00:24:31.100 fire and increment method on the model directly and then as soon as the model
00:24:37.320 changes this code will fire automatically and the view will update itself and this block is the controller
00:24:43.980 this do end block is an implicit controller in Ruby so that's one of the nice idea of using Ruby is you can have
00:24:50.940 implicit controllers when I use Java in the past you always have to have an explicit controller you can do this this
00:24:57.299 okay here it gets even nicer here we're using data binding you don't even have to observe the model anymore now we're
00:25:03.419 doing MVP now you just declare the button so by the way here I assign the
00:25:08.820 button to a variable in order to use it here here you don't even have to assign the button to a variable all you do is
00:25:14.460 you take this text property and say I want want one-way data binding so there's an arrow going to the left side
00:25:19.799 that's saying whenever the count on the counter presenter changes it'll update
00:25:25.260 the text of the button and on read of the data it'll execute a converter so
00:25:31.260 here it'll convert the value into click to increment value so here in the GUI you end up seeing click to increment 12
00:25:37.679 and then 13 and then 14 and then 15. and on which is selected all it does is it
00:25:43.260 triggers the increment count method on the presenter which is playing the role of a controller
00:25:48.299 now there's an even nicer option which is the implicit presenter so you can even do away with a presenter altogether
00:25:54.179 and just bind them the view to the model directly and the presenter becomes transparent it's actually as part of the
00:26:00.000 glimmer uh framework itself you don't have to deal with it directly so here we have a text that's data bound to the
00:26:07.200 model you need directional data binding same thing I showed you before but then here when you click all I have to do is
00:26:13.799 augment the like increment the count on the counter model and automatically The View will get updated so that's that's
00:26:21.299 the most advanced option however that said all options are useful in different apps that I built I often use will use
00:26:28.500 different options depending on the situation so it's good to know about all of them uh okay finally there's
00:26:33.900 bi-directional data binding so in our case before we did not need bi-directional data by name because the
00:26:39.000 button can only be pressed um um and and then the text can only
00:26:45.179 receive changes uh however if you had a text field a text field actually enabled
00:26:51.419 bi-directional uh interaction because you can enter text and you can see text that comes back as as an update so what
00:26:58.860 that means is I can data bind the text of a counter uh to the count on a
00:27:04.500 counter model and on read I will convert it to a string on right I'll convert it
00:27:10.440 back to an integer so you can use converters that's a feature that you have when using glimmer data binding and
00:27:16.860 then the button will just work the same way so let me demonstrate this it's time to do a real demo
00:27:22.760 so uh let's see actually I have Gladiator open over here
00:27:27.900 and I believe I have that code that I just showed you open over here there it is so I can just launch it directly from
00:27:34.380 Gladiator so boom let me zoom in okay so the way the button works is if
00:27:40.559 you click it it increments but because we have uh dotted binding on both sides the button and the text field you end up
00:27:47.039 seeing changes in both however if I go here now and update this to 30 it ends up updating it back into the
00:27:53.460 button because the bi-directional data binding and all of that is declarative so bi-direction the head of binding is
00:27:58.620 as simple as making this arrow that was unidirectional into a bi-directional arrow that's it boom you have
00:28:04.200 bi-direction data binding now but it has to happen on a property that supports read writes so this property is a read
00:28:10.620 write property whereas the text property on a button is a read only does not have a right because you cannot change it
00:28:16.559 from clicking the button um so I just gave you a very good Thai
00:28:22.679 overview of how to use the library overall in general that's pretty much it but the nice thing
00:28:28.740 about it is that let's talk about data binding now bi-directional syntax you just use the double arrow for read write
00:28:35.520 properties so read write properties like the text on text field like the selection on a combo box
00:28:41.340 Etc or you could do unidirectional binding on read-only properties so it's
00:28:46.679 like the enablement of a button is something that will only change from based on changes in the model but not
00:28:53.340 vice versa also the text of a labels that way and thanks to Ruby meta programming I'm
00:28:59.100 able to do operator overloading on those arrows and use them for data binding to to do declarative programming uh I mean
00:29:06.120 the nice thing about this declarative programming is this the simplest most minimal code possible to describe what
00:29:11.340 you want there's no you cannot go any less than that that's pretty much the minimum you can go is I'm saying okay I
00:29:18.059 want to bind the enablement of the button to whether the presenter of the user is logged in or not where their
00:29:23.880 user is logged in or not basically anyway so we already saw converters you can have an on read or on-rite converter
00:29:30.480 you can either either pass it a Ruby block like that or you can pass it uh you can use the symbol syntax that's
00:29:36.120 familiar in Ruby uh there's hooks like before read after read before right after right uh the most useful one I
00:29:43.740 would say is after right so after I write something to the model I might want to filter and paginate the table
00:29:48.960 because this is a query term so as uh so after I update the query attribute I
00:29:55.020 want to filter and passionate the table that's an example uh there's nested data binding so I can
00:30:01.559 data bind to the street on the address object on the company that's called nested data binding so it's extremely
00:30:09.000 Advanced like all the advanced features you would want and data binding are available nested indexed data binding so
00:30:16.440 here I'm saying I want the index 0 on the array of addresses and then the street on it
00:30:21.899 to be data bound to the text property of the text widget that we're seeing there
00:30:26.940 is key data binding meaning it's a hash so if I have a hash addresses I want the main address so I pass it a ruby symbol
00:30:33.779 so it can accept key data binding can accept either symbols or strings for the
00:30:39.120 for the key of the hash and then I could do nested and keyed at the same time that's what we're doing here
00:30:45.360 finally the last thing is computer data binding so if I have a logged out property that gets computed when the
00:30:52.080 status changes you could do computer dynamics that way if I change status on the model it'll automatically notify
00:30:58.500 listeners of log out logged out that it got changed and that will update the
00:31:04.200 enablement of the button so to show you a quick example of that uh
00:31:13.799 oh yeah yeah here um okay so if we were to go login
00:31:19.020 the login sample uh if I were to type something like Andy and a password when I log in the up the
00:31:26.760 enablement got updated automatically here here and here that's because of data binding so if we were to look at
00:31:32.700 the code there you go like you can see there's unidirectional data binding to logged
00:31:37.740 out which is computed by whoops computed by status so um that's what caused that so that's
00:31:45.779 computed data binding okay so uh now that we have a pretty
00:31:52.260 good idea on how to write glimmer applications let's take a survey through
00:31:57.659 all the widgets that are available in glimmer DSL for swt so I'm going to go go through those samples
00:32:04.260 so first sample is hello world we already went through that one okay let's go through hello label just to talk
00:32:09.600 about what labels are so by the way here on the top I have the
00:32:15.840 basic widget uh samples and if I close this at the bottom I have the advanced samples
00:32:21.480 just wanted to note that when you're playing if you play around with it after the presentation so I highly recommend
00:32:26.940 but let's go into uh label hello label so that's the code of hello label as far
00:32:33.960 as label it's really it's a very simple widget all it is it has a text field and it
00:32:40.320 ends up with a text value and you can populate it any way you want you could do a ruby looping construct like each
00:32:46.380 Loop or any kind of loop iterator like any kind of iterator or you could populate it a different way and here it
00:32:51.720 receives Styles because it's an swt widget so it could be left aligned Center aligned right aligned
00:32:59.580 you can have an image on a label you can have a background image on a label so I
00:33:05.399 mean let's start looking at it let's start looking at how it looks like so I mean these are labels that are left aligned Center aligned right aligned
00:33:12.179 images only there's no text background images with text on top of it
00:33:18.559 horizontal labels sorry horizontal separators so this separator is a form of a label and then there's a vertical
00:33:25.140 separator which is this one so I mean that's pretty much it so right now I'm just giving you a quick overview of all
00:33:30.419 the available widgets so let's go next text
00:33:36.659 uh text is is what you would think a text is it's just it lets you type um
00:33:42.779 if there's no style it ends up with no border but you can add a border you can align it you can make it a password text
00:33:48.899 that's very useful it could be read only so I cannot type here uh it could be with event handlers
00:33:55.740 that verify the data so if I type let's see if I type any keys that are not numbers
00:34:01.919 nothing happens but if I type numbers something happens um
00:34:06.960 and this one is a multi-line text widget so that's pretty much it
00:34:14.099 so again the goal here is to give you an overview and not necessarily to have you memorize the syntax uh I'll leave that
00:34:20.280 to you as homework later hello button let me we already saw one but let me
00:34:28.560 y'all know we already saw a button I can show it one more time but it's basically this incrementer
00:34:33.839 there's not much to it um okay next spinner okay spinner is a
00:34:39.060 nice one spinner is like a text except it's specialized in handling numbers so if I want to display numbers it's
00:34:46.200 usually better to use a spinner it's more user friendly because it enables the user to do this and you can select basically how much it
00:34:53.760 increments when the user clicks those buttons so you can provide a minimum value maximum the increment the page
00:34:59.880 increment meaning if they hold page page up page down it increments even faster and then here you can just data bind the
00:35:06.960 selection which is the value of the spinner bi-directionally to the donation attribute on the person model that's it
00:35:13.320 and the rest happens for you automatically it's not spinner there's check box
00:35:20.339 okay let's look at checkbox there are different flavors of check box like there's checkbox group and checkbox
00:35:26.700 they're both very useful but uh I mean checkbox is what you would imagine it's a checkbox and it has
00:35:32.579 selection and selections data binds to a Boolean so if I were to look at it the Boolean
00:35:38.339 when it's false it's unselected when it's true is selected that's pretty much it and if I for example if I since they're
00:35:45.300 data bound when I do reset activities it's going to trigger a controller action that will or an implicit
00:35:52.020 controller action that will tell the model reset everything and it'll reset it back to the original value it's
00:35:57.660 assuming that snowboarding is what people like the most whatever that's because I I'm a snowboarder uh okay so
00:36:05.040 hello radio is radio button another very useful widget and again these are all Native widgets
00:36:12.420 meaning any code you write using glimmer DSL for swt will produce GUI that is similar to code written in Swift so if
00:36:20.339 you're using Swift on the Mac that's exactly the GUI you would get on Windows it's the same thing it's equivalent of
00:36:26.520 win32 API which is the windows uh most native way of building uh GUI and on
00:36:32.040 Linux is equivalent to gtk which is what Linux usually uses so um so again the
00:36:37.859 nice thing about that is that the user interface is very friendly to the user and it's very predictable and again data
00:36:45.540 binding syntax could be used just like everywhere else um
00:36:51.119 hello shell so shell is the window and there are many different kinds of shells let me demonstrate so I have an
00:36:58.859 outer shell right now meaning it's a main shell that represents the app but then there's a nested shell the nested
00:37:04.740 shell is nested on top of the other shell the benefit of it is if you make
00:37:10.320 it nested you have to pass it the parent as part of the arguments when you do that then you can hit the escape button
00:37:16.500 and get back to the original shell this is an independent shell so if I hit Escape nothing happens that's just
00:37:23.220 demonstrating a different option this is a shell with a close button only without minimize
00:37:28.859 uh this is a shell with minimize button only uh this is the show with maximize only
00:37:35.579 this is the buttonless show I mean sometimes useful if you want to show a dialogue this is a no trim shell
00:37:42.060 this is useful for games if you want to build a game with no like no window around it even could do this uh this is
00:37:48.359 an always on top shelf so no matter what I do it's going to be on top but yeah you can hit escape on all of
00:37:54.960 them by the way get out of them that way and the code is just everything is a shell I mean there's no the only
00:38:00.660 difference is that am I passing it the parent shell if you do that it becomes a nested shell uh here I'm not passing the
00:38:06.839 parent shell so it's an independent shell this one is a shell with a close button only by default you get all of
00:38:13.440 close maximize and minimize but if you don't if you pass an option then you can pass minimize only maximize only Etc
00:38:20.880 I'll leave that as an exercise to you guys figuring out the rest okay combo is like
00:38:26.760 this is a combo box uh one special thing about combo data
00:38:32.400 binding is that it leverages something called convention over configuration which is borrowed from rails it's an
00:38:38.280 idea that comes from rails originally so when I say here down to buying the combo uh selection to the country attribute on
00:38:46.500 person I mean let's first demonstrate it so I have a country I can change it U.S
00:38:52.200 Mexico I can reset selection it goes back to Canada but the key of it is it's
00:38:57.420 data bound and when I reset it I only did reset on the model and it
00:39:02.940 automatically propagated the change to the view because of data binding but the key thing is that how does it know that
00:39:09.420 I mean if I'm data binding to Country on person how does it know that I have the options with Canada us and Mexico
00:39:15.680 it is going to know that there is a value of Canada on that person for country but it doesn't know that these
00:39:20.760 are all my options well that works by convention so by convention if you have a country attribute you need to provide
00:39:26.460 a our country options attribute as well and the country options attribute will
00:39:31.680 hold the options that are available so in this case it's just uh Mt or Canada U.S or Mexico so by convention you can
00:39:38.640 provide the options of this data binding so there are a few uh properties that are data bindable with conventions uh
00:39:45.780 table is another one of those and which will basically it's minimizing
00:39:50.940 the code we're writing we're writing a lot less code as a result uh so let's look at list
00:39:56.339 list as so you can have a single selection list or multi-selection list this is a single selection list which is
00:40:02.760 very similar to combo except they're all laid out in front of you the options this is a multi-selection list so let me
00:40:09.359 select multiple options if I want I'll reset them
00:40:15.180 okay I lost my place okay table okay so table
00:40:21.359 is one of the most sophisticated widgets out there um
00:40:27.359 this is a table um you could do a lot of things with tables you can add images next to each
00:40:34.200 cell you can have if I book this game it becomes colored green
00:40:39.960 and then I can switch I'm doing something called here uh uh not nested
00:40:45.480 data binding this is called Master details data binding meaning I have a data binding on the combo and this data
00:40:51.180 binding will affect the data binding that's secondary on the table so show me different data when I change the options
00:40:56.760 on the combo so they call that the master details pattern it's a very common pattern in desktop applications
00:41:03.359 um so that's one way of doing it another way of doing it is instead of using combo you could use a tree which I'll
00:41:08.579 I'll demonstrate soon so tree is next oh no not next okay
00:41:13.740 refine table refined table is a new custom widget that I added to glimmer DSL for swt because a lot of people ask
00:41:20.820 for filtering and pagination when working with table data so this gives me a table that is automatically supporting
00:41:27.660 filtering so I can support by all Red Sox baseball games for example this is a game schedule or I can do pagination or
00:41:36.060 I can type in here the page name like 50 enter Etc so it gives me all of that for free
00:41:41.400 out of the box including sorting even I get sorting for free as well so you get all of that for free just by using
00:41:46.980 refine table as far as the code whether it's a table or a refined table the data binding
00:41:52.920 happens to this statement which basically um
00:41:58.440 Actually I don't even need the last part like if I delete that part this should be enough so by convention on data
00:42:03.900 binding to all the games that are on the baseball season object uh and it'll figure out all the attributes from the
00:42:10.680 game object that map to the table column names so if I have date ballpark home team away team it assumes you have those
00:42:17.460 attributes on the model so by convention it'll pick up all of those attributes from the model and that fill the data
00:42:23.820 for you just by typing that tiny Short Line of code unlike say when I did this
00:42:28.980 in Java in the past I had to type pages of code before I could populate the table with data I had to use something
00:42:35.280 called the viewer which here is not even needed um okay hello tree let's look at trees
00:42:41.820 so tree is the second I would say most important widget for business apps so here we have a a company hierarchy we
00:42:49.200 have a CEO CTO CFO under the CTO there's the VP engineering there's a director
00:42:54.420 engineering manager engineering it's a very large company and finally a senior engineer like me uh June mid-level
00:43:02.940 engineer and a junior engineer and then this is a master details view as well so if I click on this it changes the data
00:43:08.760 here it changes all the data binding on that on this form so now I'm data bound
00:43:13.800 to the values of Stephanie Davis and I can for example increase the salary and
00:43:19.680 it remembers that if I go here and come back it remembers this so that's tree for tree the data binding is very
00:43:26.880 similar to table except uh actually you need one more piece of information for tree you need to figure
00:43:33.420 out how to iterate over every child of the tree to pick out the children of it and to do that uh let me see where's
00:43:40.440 tree okay there's the tree so um the three
00:43:46.800 items are that about you need unidirectionally in this case uh to the CEO at the top so you need to just give
00:43:53.460 it the root at the top of the tree and then here in three properties you need to give it what is the method that
00:43:59.520 you use to pick the subordinates it's just subordinates in this case and then what is the method you need to use in
00:44:04.680 order to convert the every child into a piece of text that you can display in
00:44:10.260 the tree and here is just the Ruby to us nothing special so that's pretty much it for tree
00:44:17.940 hello style text style text text is the widget we're looking at right now over here this is a text that that is tiled
00:44:24.960 meaning different parts of the text have different colors and different styling so uh let me show you another example
00:44:31.319 it's basically how you build word processors this is like how to build Microsoft Word basically you use this
00:44:37.079 widget to start text you can do underlining you can do highlighting you can do balding try strikethroughing Etc
00:44:43.980 so that's just style text and it works almost exactly like text except it gives
00:44:49.619 you a new listener called on online get style that will let you populate the style for every line which you can check
00:44:56.579 on your own time but there's a special specialization of this wedge widget called hello code text hello code text
00:45:03.900 actually does the same thing except it automatically Styles code so you just
00:45:09.480 give it the name of the language you're using so in this case for example uh let's see
00:45:14.520 I have a code text widget that takes a language of Ruby and then I populate its text
00:45:21.359 with data binding the same way you do it and anywhere else and then when I launch it it gives me Ruby syntax highlighted
00:45:28.680 code automatically and this is what I used in order to build Gladiator the Ruby code editor that I showed you
00:45:35.040 earlier so in supports JavaScript supports HTML Etc you can build your own
00:45:40.560 themes now there's support for building your own themes if you want it comes with a few themes out of the box but you
00:45:45.900 could also build your own themes I have a blog post about how to do that uh that's pretty much it you guys just
00:45:51.900 got a quick overview of all the widgets so um okay the next set of widgets is
00:45:56.940 organizational composite is a widget that lets you fit multiple widgets underneath and then lay them out either
00:46:02.339 horizontally or vertically or in a grid that's what composite is uh scrolled composite just adds the scroll bar
00:46:09.300 uh sash form let me show you slash form we already have a sash form here here sash form lets you separate two areas
00:46:16.020 and then resize between them that's pretty much it they call this a sash
00:46:22.200 um there is hello group group is what you're seeing here on the screen we have a gender group and an age group
00:46:28.140 uh hello tab is basically tabs let me show you that one because it's very useful
00:46:33.900 so I have Hello World done in two languages English and French so these are two tabs
00:46:43.920 uh hello toolbar toolbar is what you see in Microsoft Office applications often
00:46:49.440 so like cut copy paste like you have a toolbar with icons the icon resolution I
00:46:55.680 have here is a bit low that's why they look ugly you can make them look nicer if you have nicer icons but that's pretty much a toolbar kind of like the
00:47:02.040 toolbar you would see in the Microsoft Office app or there's something more advanced which is called the cool bar
00:47:07.380 which is the next uh the next complexity so a cool bar is
00:47:12.900 formed of multiple toolbars so here we have two toolbars we have this one on the left uh and then we have this one on
00:47:18.540 the right this one is cut copy paste this one is font size uh the key thing about toolbars laid within a cool bar is
00:47:24.599 it gives you the three Sizer that lets you resize them or move them around like that
00:47:29.700 kind of like when office applications as well
00:47:34.920 um okay what else do we have tray item try item is interesting so try items
00:47:40.319 basically uh showing an item here in the tray at the top right corner and on Windows usually it's at the top at the
00:47:46.440 bottom right corner but let's launch the trail item app so I just launched it and it added this extra icon over here and
00:47:53.819 now if I want I can close it but it stays open so if you want to keep an app in the background you can do that using
00:47:59.579 a tray item app and then I can click show application and it shows it again so that's just that's where I the map
00:48:05.520 which could be useful if you want to keep something in the background whoops I actually exited the glimmer
00:48:11.640 samples no big deal okay hello menu bar so menu bar is what you see here
00:48:16.800 um it's what you see here in the menu in the menu bar so I'm gonna be launching
00:48:22.260 an app that will demonstrate that clearly uh
00:48:29.760 I don't know why why it zoomed in
00:48:36.119 doesn't matter so let's do a Hello menu bar
00:48:43.079 okay I just launched a menu bar app and if I were to drag it here it gave me all of those menus so all of
00:48:50.460 those menus came with it so I have a file menu that has standard file menu stuff I have an edit menu options I can
00:48:56.579 enable the options and then select either one so this is kind of like a radio this is multiple so it's kind of
00:49:02.819 like check boxes I can do uh image menu items to change
00:49:08.520 the language I can change the country with an image and a word I can change uh like the background
00:49:14.520 color yellow and uh foreground
00:49:19.920 Etc and then I could do a view here and then finally help so this is a way of
00:49:25.920 doing menus and apps which is a very common thing the second kind of menus is pop-up menus
00:49:33.240 which is if I right click on a widget it gives me a menu and then you can uh whoops then you can add a whole bunch of
00:49:39.900 things to it and perform actions when when the user clicks one of those menu items
00:49:46.740 um that's pretty much it for organizational stuff uh finally it's dialogues so
00:49:53.579 message box you guys already saw an example color dialogue for selecting color font dialogue file dialog
00:49:59.400 directory print uh and a general dialog General dialogue you can put anything in
00:50:04.619 it um anyways let's move on next okay so next thing is another Advanced topic
00:50:10.140 which is canvas Graphics how do we build non-native widgets if I had a Brand New Concept that does not have a widget
00:50:16.079 already how do I build it let's just say I want to build a uml diagram designer how do I do that well I can use canvas
00:50:22.319 graphics and you can use in it the following shapes out of the box like point line
00:50:28.560 rectangle oval you can see them here on the right side Arc
00:50:33.800 polygon polyline image or text
00:50:39.060 um if you want a shape that is not any of those shapes what you could do is do
00:50:45.119 something called custom shapes you can build your own Advanced custom shapes out of those shapes so you can compose
00:50:51.240 more complex shapes from simpler shapes as well so canvas Graphics lets you do things
00:50:56.940 like that so obviously it helps you with building things like uml diagram
00:51:02.640 designer or you can build games with it as well this is how you build games uh so there are a whole bunch of samples
00:51:09.000 for it uh maybe I'll just demonstrate one of them let's do
00:51:14.280 let's see
00:51:19.920 hello cam this drag and drop is interesting so this is just painting a bunch of circles and a rectangle here I
00:51:25.800 can just drag them and when I drag them it copies the value that's within it and adds it to the value that's here so now
00:51:32.520 it's 10 now it's 14. now it's 21 Etc so I mean that's showing you a custom app
00:51:38.700 with non-native Graphics or basically custom graphics or they're also called canvas graphics
00:51:44.880 there are a whole bunch of samples I'll let you check them out check them out on your own but okay next topic is custom
00:51:51.059 components so custom components is you building your own custom widgets kind of like how I built code text as a custom
00:51:57.059 widget kind of uh so you can build your own custom widgets as well so a custom
00:52:02.640 widget is usually uh will mix in glimmer UI custom widget module it accepts
00:52:08.640 options and it's useful for three one of three things either a specializing widget so if I want to provide a label
00:52:15.119 that's always read Because I want to use a red label on certain things you can create a widget called red label and
00:52:20.460 just use it and it's pre-specialized for your needs you can do aggregate aggregation of widgets that's if I build
00:52:27.300 a name and address form and I reuse that multiple times in an app that's an aggregation and the third concept is uh
00:52:34.640 for example the code text widget which syntax sorry yeah it does syntax
00:52:39.900 highlighting for programming languages that's the specialization of Style Style text so that one's the first case the
00:52:46.920 other one refine table which I already demonstrated that gives you pagination and filtering that's an aggregation it
00:52:53.819 aggregated a whole bunch of pagination buttons in a filter text field in addition to a table so that's an
00:52:59.940 aggregation custom component the third case is building brand new Concepts like an oscilloscope like this one or like
00:53:07.260 the Gantt chart or like a watch like a clock so this is how to build non-native
00:53:12.780 widgets the second type of components that's custom components is custom shells meaning custom windows basically
00:53:19.740 all apps are custom windows when you build an app it's a window that has its own things that are that are unique for
00:53:25.980 that app so when you build an app usually you want to mix in a glimmer UI application which is a as an alias for
00:53:33.420 custom window or custom shell and not only that if I build an app like Gladiator
00:53:39.859 automatically for free when you build it as a custom shell or custom window it becomes a reusable uh widget as well
00:53:46.380 meaning I can fire up a different app that is uh called whatever my bit my
00:53:51.839 lexstop business app let's just say I launch it every day it shows me my contacts at Alexa I can add a button to
00:53:58.680 it uh that would automatically open Gladiator as well as just a custom window and as a custom component so you
00:54:05.339 can reuse apps within apps basically automatically by building Uh custom uh shells or custom or apps
00:54:12.480 another example is building a window that shows you the email content of an email
00:54:18.720 um and I mean to do a quick demo of that
00:54:25.680 custom wait custom is here is here custom shell okay this is like an email client we have a window here
00:54:31.859 then I can click one of those and it reuses this window so every time you want to display an email it's always the
00:54:37.260 same type of window that shows you the metadata on top and then the body on the bottom so that's that's the custom shell
00:54:42.839 or custom window uh the third thing is uh the third type of custom component is
00:54:48.300 custom shapes custom shapes is what I mentioned earlier about composing simpler shapes into more advanced shapes
00:54:54.180 that way you can build games for example I can build a stick figure that I can reuse it in different sizes and colors I
00:55:00.720 can build uh playing cards and just reuse them in Klondike Solitaire like these are these are all playing cards uh
00:55:07.740 or I can this game quarto let's see I have quarto here quarter is
00:55:13.559 that one of the newer games that I added but yeah it has all of those custom shapes uh by the way anybody played this game
00:55:19.500 before it's a real board game uh it's kind of like the more advanced version of tic-tac-toe like a much much more
00:55:25.079 interesting tic-tac-toe like you have to hand a piece to your opponent and then he has to place it somewhere and then he
00:55:31.440 hands you at peace and then you need to place it somewhere etc etc and you need to form a line based on either color
00:55:37.260 height or shape so this is built with the canvas Graphics this is a very good example of
00:55:43.200 that and it's it uses custom shapes and the nice thing is not only did I build those custom shapes like cylinder and
00:55:49.619 the cube I also extracted them into their own gems so now anybody can add a
00:55:54.720 cylinder or cube to their app by adding those ruby gems um
00:56:00.119 okay so that's pretty much it for custom shapes
00:56:05.940 they support relative positioning by the way so they work so much like SVG and SVG usually you have a component that
00:56:12.420 includes multiple smaller sorry other shape you have a big shape that includes smaller shapes within it and it's an
00:56:18.480 aggregation this works very much like SVG so if you've ever used SVG and web
00:56:23.579 development this is very similar but in Ruby and pure Ruby uh drag and drop
00:56:29.940 okay I'm just going to give a very quick highlight of drag and drop so the key thing you need to know about drag and drop is usually you have a drag source
00:56:36.000 so you need to activate the drag Source property to true and then you need to designate something
00:56:41.940 else as the drop Target so for example here every label is a drag source and a drop Target at the same time here we
00:56:48.300 have a text widget that's draggable and a text widget that's droppable or a drop Target
00:56:53.700 so and when you drag it it'll automatically copy the data for you and glimmer and that's it that's all you have to do for the basic drag and drop
00:57:00.119 support if you need more advanced support like I'm moving a file here or I'm doing something crazy uh you can
00:57:06.480 listen you can listen to listeners like on drug detected on drag started on drag
00:57:12.180 set data when it starts on drop what to do on drop and within those listeners
00:57:18.000 you could do some work that would occur when you drop something so I mean
00:57:23.819 to give you an example uh if I were to play clondag Solitaire
00:57:29.300 when I for example let's see if I drag this and drop it here in the on drop action I basically
00:57:36.200 interact with the model layer and I tell them move this card from this pile into
00:57:41.700 the other pile and once the model does it since I'm following NBC The View will automatically refresh itself from the
00:57:47.520 models and update itself because I'm following NBC correctly so this all happens because of using the on drop
00:57:54.000 action so that's pretty much it for drag and drop but obviously there are more nuances which you learn if you look into
00:58:00.180 the once you study all the samples and do the homework uh I mean Hello drag and drop I don't
00:58:06.119 have to demo it because you guys are seeing it on the right side here that's pretty much hello drag and drop
00:58:13.619 um okay oh hello canvas drag and drop we already took a look at it
00:58:19.559 this is it uh it's a little uh it's a little different with canvas because with basic
00:58:25.440 drag and drop you're dragging data that that is usually a text a piece of text uh like when I had a list
00:58:34.260 um yeah see I'm dragging a word from this list to this list uh whereas with canvas there isn't
00:58:40.859 necessarily a text it's just a concept and then you can give it any meaning you want and you have to do extra work in
00:58:46.740 the on drop listener to do that or in the models actually if you're doing clean MVC directing the models
00:58:52.920 there's also something called drag and move which you can make anything movable if you want automatically by using drag
00:58:59.819 and move property but not necessarily a movable for dropping it's just movable
00:59:05.460 so that that's something you get for free anyways let's get into the final parts of the presentation so
00:59:12.900 um how do you build an app from scratch so the best way to do so is to use
00:59:17.940 scaffolding which is very similar to how rails works again this is an idea borrowed from rails it's good to reuse
00:59:24.000 good ideas so I like the idea of scaffolding a lot in rails because it helps you get started very quickly and
00:59:29.760 glimmer is the same way you can scaffold an application with this command glimmer scaffold app name that's it
00:59:37.260 um in fact while I'm talking about the other options of scaffolding let's scaffold an app I already have an app.
00:59:44.280 scaffolded but let's scaffold another one just just in case uh let me make sure that I have the
00:59:49.500 glimmer command here yeah I have it okay good so glimmer
00:59:57.720 scaffold and uh greeting I'm gonna call it greeting
01:00:04.079 and I'm gonna run it okay while it's capitaling let's talk about the rest so you can scaffold the custom shape like I
01:00:10.079 mentioned so that'll build the class for how to build a custom shape automatically for you with all the skeleton and then you just fill the rest
01:00:15.960 later I mean at your convenience you can scaffold custom windows or custom
01:00:21.420 shelves custom widgets uh you can you can desktop it file get into it later
01:00:27.059 you can scaffold custom shape gems so if
01:00:32.760 you want to extract if you want to build a gem and then share it with other people that has a custom shape or custom
01:00:38.579 shell or custom widget you can scaffold the the entire structure of the gem and it'll give you a very simple command
01:00:44.760 that you can run at the end once you implement it and it'll package it as a gem and it'll help you publish it as
01:00:50.819 well by the way the app that I just scuffled it uh finished there it is it's just
01:00:56.099 hello world that's what you get for free by default and I can even open the preferences and it gives you an example
01:01:02.099 of how to implement preferences and now changed it to howdy partner so
01:01:07.799 um so what do you what do you get uh when you generate an app it generates a full app when you scaffold the models
01:01:14.700 live under app name model the views live under view app so app name is used as a
01:01:21.240 namespace so if my app is called greetings going to be app greeting model an upgrading view it's just a ruby
01:01:27.720 namespace the app can be run either with bins with a bin script
01:01:33.920 that matches the name of the app actually this should have been bin forward slash app name or by running
01:01:40.260 glimmer run so let me show you an example what I'm talking about so I just scaffolded this
01:01:46.500 app greeting it's inside here greeting uh I can type in glimmer run
01:01:52.680 and that will run the app so that's one way of running the app is glimmer run there it is or I can type in bin forward
01:01:59.339 slash and it gives you a script for free that matches the name of the app by convention and uh gives you that for
01:02:05.040 free and it launches the app uh the code let's look at take a quick look at the code so
01:02:13.079 there it is so I have this scaffolded over here so if I were to zoom in here there it is I have app I have greeter
01:02:19.440 and I have a model and view sorry greeter is a different one that I
01:02:24.780 scaffolded before the presentation but it doesn't matter it's the same thing it gives you an app view by default and a
01:02:31.619 few extra launching scripts and namespacing uh files but this is the key file is app view that's the entry point
01:02:37.880 it basically includes the glimmer UI custom shell because it's a custom window
01:02:42.920 there are things that I didn't talk about but you have support for how to specify options for the app if needed
01:02:48.839 usually it's not needed but you can take advantage of it when needed this is a
01:02:53.940 before body is I hope that executes code before building the GUI body and then the GUI body goes into this body block
01:03:00.180 and then within it gives you a shell with a minimum size an icon image is the
01:03:05.280 icon a label and a menu bar so it gives you an example of everything how to build a menu bar how to make preferences
01:03:12.359 so here at the bottom there's a preferences dialog um that yeah this is the preferences
01:03:18.540 dialogue display preferences dialogue it gives you examples of everything so you can get started with it basically and
01:03:24.720 you'll end up with a menu even so uh
01:03:30.119 let me launch it again so here I have a menu you get this menu for free like a file menu it's a very common thing in a
01:03:36.240 help menu so yeah so that I mean that should help you get started very quickly
01:03:42.960 pretty much it um but the next interesting part most
01:03:48.480 interesting part is how do we package the app as a native executable and give it to people so that they can install it on their machine uh for example uh like
01:03:57.480 when I launched Gladiator I have an icon for it here I can just click on this icon that's how I launch it so how do we
01:04:04.140 install that icon how do we provide an app like that so what you do
01:04:09.599 is you run glimmer um package and if you're on the Mac and
01:04:16.140 you want it to be a damage a DMG sorry you say DMG uh because you can also package as PKG which I'm not a
01:04:23.099 personally a big fan of it but some people prefer it anyway so if I run this command it's
01:04:28.319 going to do a bunch of things before it gives me the package but let me show you another package that I prepared before
01:04:33.420 the Meetup uh let's see code
01:04:39.140 uh greeter no not greeter greeting
01:04:46.920 never mind I must have not prepared it so let's just wait for this
01:04:52.619 so on window on Linux and Mac it'll work out of the box on Windows it'll require you to install libraries oh there it is
01:04:59.400 see it packaged it as a as a dng uh installer which is the typical Mac installer so let me show you how it
01:05:06.180 looks like once I open it so it it ends up under packages and I can go here now and then under
01:05:13.799 bundles I go here and there it is so now if I click this thing
01:05:18.960 uh it gives me an installer and here it puts your license so once you add a license to the app it'll show up over
01:05:24.180 here so it's it's totally official then I can click agree
01:05:29.940 and then it gives me this and the icon this is an icon that I give you for free but you can actually add any icon you
01:05:36.240 want so for Tetris it'll show the tetris icon and all you have to do is drag this to Applications
01:05:42.359 and now it's an official Mac app and nobody will know ever that it's written in Ruby or jruby or glimmer or any of
01:05:48.720 that so here now I can just go to Applications here and run greeter or
01:05:53.880 greeting sorry and I just open it and it should show up at the bottom whoops there it is Boom there it is see that's
01:06:00.720 a native app now it's no longer uh just Ruby code so that's so that's pretty much it so
01:06:07.980 you get DMG files PKG on Windows MSI but you need to install the Wix Tools in order to get that before you do it on
01:06:15.900 windows so only on Windows you need the prerequisites on Linux like Ubuntu you
01:06:21.299 get Deb files on red hat you get RPM files out of the box
01:06:27.660 so that's pretty much it so yeah I mean that's pretty awesome
01:06:34.140 because that's what shoes in the past provided so this gives you everything that shoes didn't provide in the past
01:06:40.619 but shoes is a lot less advanced than glimmer shoes doesn't give you data binding shoes doesn't give you table
01:06:45.960 widgets I don't believe they support table or tree unfortunately unless you hack your own custom code so they look
01:06:52.260 kind of ugly and non-native in the shoes so I mean shoes think of it as as a very shoes was just an educational tool
01:06:58.980 whereas glimmer is the real deal it's a real business app development library that performs in my opinion more
01:07:05.520 productively than any of the Java ones out there or Swift or C plus plus
01:07:10.859 um so uh again we we looked through hello world
01:07:16.640 uh I was thinking at the end I could go into the code of each one of those and dig into them uh but I think I'll just
01:07:23.579 leave it as an exercise to you guys to do it in fact I have a lot of blog posts about them uh so I'm gonna share with
01:07:29.640 you links with my blog post in it you can read blog articles about how I built Tetris and about how I built this one
01:07:35.520 contact manager Etc so I don't have to go through it but let's give you a
01:07:40.980 summary of the talk so basically um we talked about why we want a native
01:07:46.799 GUI we introduced a few GUI samples we jumped into real world apps like math
01:07:52.859 bowling and the DCR programming language I I talked about the basics of the glimmer Dewey DSL and then I went
01:08:00.599 through software architectures and data binding um like NBC MVP and like bi-directional
01:08:07.559 unidirectional data binding uh we talked a little bit about uh so I I gave you a
01:08:12.780 survey of all the widgets and then we went through canvas graphics and finally after that how to build custom
01:08:17.819 components how to do drag and drop how does scaffold an app from scratch and last but not least how to package an app
01:08:24.719 as a native executable so uh that's pretty much it this is a jruby library that was the very first
01:08:32.940 glimmer library that was built eventually the idea became so interesting and applicable uh that it
01:08:40.560 became a good idea to apply to see Ruby as well so the most complete SI Ruby flavor of glimmer is called glimmer DSL
01:08:48.060 for libui that's the one that got demo to Matt's the creator of Ruby early this
01:08:53.699 year and won the award so you guys if you like the jruby version and we want to use C Ruby check out the glimmer DSL
01:08:59.759 for the Bui it almost has all of the features of uh gloomer DSL for swt and I
01:09:05.880 continue to update it to make it match it uh feature by feature for feature but right now it has about I would say 80
01:09:13.259 percent of its features including bi-directional and unidirectional data binding which by the way that is the
01:09:19.020 reason why I I want uh Matt's told me that was the most interesting thing in the project this data binding parts
01:09:25.920 uh and there are many other flavors that are based on other toolkits so I mean in
01:09:31.020 my mind I thought why not support all the Ruby available toolkits so I glimmer now supports them all there's Libya
01:09:37.199 there's TK which is based on tickle TK there's gtk you can use gtk from Ruby
01:09:42.239 with glimmer uh there's FX there's swing and there's Java FX the last three are the are the least developed like they
01:09:49.739 were only uh a few days effort of an alpha at an alpha project level right now but still they're a good start if
01:09:56.880 somebody needs help with them or needs further development just hit me up and I can develop them further
01:10:03.000 um and these are the useful links that you want to keep track of and we I mean
01:10:08.880 we should be posting the presentation slides in the end on the meetup.com page but these are the links for the project
01:10:15.600 uh my GitHub account my blogger and my blog uh Twitter account uh YouTube is
01:10:22.199 interesting because in YouTube I have about 36 uh tutorials of how to use glimmer DSL for swt uh it covers pretty
01:10:30.420 much all the features right now except scaffolding it's almost complete the series and once it's completed
01:10:37.199 um hopefully I'll move on to another GUI toolkit from from glimmer uh but yeah
01:10:42.300 other than that we are hiring at lexap so we're looking for Ruby unreal software Engineers so if you're looking
01:10:49.080 for a job please apply and uh I guess we'll move on to the Q a
01:10:54.420 foreign
01:11:02.100 go ahead um what about performance uh
01:11:07.920 because I'm very impressed by the the easy the the ease of writing and to
01:11:13.860 me it sounds kind of like too good to be true so is there a performance drawback or uh
01:11:18.900 um not exactly so once you launch the app there are no performance Dropbox in fact I did list in the initial slides
01:11:26.159 that because the native the GUI is native it has native performance so the GUI itself uh will will run natively uh
01:11:34.440 it will not freeze because it's using swt which is written in Java on top of C
01:11:39.659 plus plus and C which uh basically the GUI is independent of
01:11:45.480 any Ruby related memory management it doesn't it's not affected by it however launching the app is a bit slow it takes
01:11:53.159 two seconds on this Mac two seconds is fast actually two seconds and a half sorry on this Mac because it's an M1
01:11:58.500 Chip it'll probably take even less time on the M2 Chip but on on older computers it's a bit slow because it's jruby which
01:12:06.120 which has the Java startup time as opposed to the Ruby startup time uh that
01:12:11.460 will improve continuously uh but today the biggest Improvement is that on M1
01:12:16.500 and M2 chips it runs in about two seconds which is tolerable uh hopefully it'll get faster even on on all the
01:12:23.699 platforms eventually because the jruby team is always enhancing Jr Ruby but one thing I wanted
01:12:29.460 to say is that the reason why I ended up exploring C Ruby C Ruby gives you all
01:12:34.860 the benefits you guys just saw with an instant startup time so glimmer DSL for libui starts instantly
01:12:41.239 however swt is the most advanced toolkit library of all of those it's in my
01:12:47.340 opinion it's the most Superior gtk might be the second most superior but gtk unfortunately is only good for Linux
01:12:53.640 it's not on the on the Windows it doesn't give you native widgets whereas swt gives you native widgets on all
01:12:59.040 platforms that's why it's the best lib UI is like aiming to become swt using C
01:13:05.580 Ruby libui also gives you native widgets on all platforms but it's a very underdeveloped uh toolkit at this point
01:13:12.840 it's only at Alpha 5 and they're working very hard on it to make a release very
01:13:18.480 soon um in fact I've been communicating with their with the C library toolkit authors
01:13:24.780 quite heavily lately because I want to make a new release so hopefully this will become the future of glimmer cool
01:13:32.219 any other questions yeah uh yeah I what's your thank you first of all right
01:13:37.739 you're welcome you're welcome I I fully understand why you won the price I'm
01:13:42.960 how how's your flow when you want to develop when you want uh when you want to see why the variable is not
01:13:49.199 instantiated or so on like in typical web development we would look at the console we would have an output do you
01:13:56.280 have a console can you jump in and respect is there a debug mode I don't know or how do you do it usually I'm
01:14:03.360 pretty sure you could use a debugger if needed but I personally never ever use a debugger I use my own Library I don't
01:14:09.780 know if you've heard of it puts debugger it's based on a blog post by Aaron
01:14:16.500 Patterson you know the real the rails uh contributor uh he wrote a blog post that was very
01:14:23.100 funny a few years ago called post debugger and then I put I based a library I built a library based on it
01:14:28.679 I'll show you what I'm talking about in a second uh this one I am a puts debugger
01:14:34.800 uh and then I built a library so let me show you the library though
01:14:42.300 uh it's just a library that will let you uh when you say PD in a variable and not only does it print a variable but it
01:14:48.300 gives me the line number and the file name so I can track what's happening where in the program I personally just
01:14:54.960 do all my debugging with this and I'm pretty happy uh but uh also desktop apps
01:15:01.440 generally uh in the C Ruby version versions they start instantly so if you change the code and start the app again
01:15:07.920 that's fast enough usually for most users in jruby what I do is uh because
01:15:12.960 there's a jruby startup time what I do instead is I use Gladiator Gladiator lets you run apps so I showed you guys
01:15:18.480 already how I ran an app from here like uh this one I just ran it see it runs it runs instantly so as long as you're
01:15:24.840 within an app that is written with glimmer DSL for swt you can actually uh
01:15:30.120 re debug and re-render your apps instantly and to me personally I find that good enough I have not explored
01:15:36.360 debuggers just because I'm not personally a very big fan of them uh but
01:15:41.699 um if you are into debuggers and you want to use it with limit DSL for swt then
01:15:49.500 you are encouraged to do so and then blog about it and help others uh learn how to do that too
01:15:55.140 all right I think you're my third rupees that's viable to me I mean basically you can create a text field and put the
01:16:02.760 values of all your variables with data banking if you want to and follow along yeah I mean even this the glimmer meta
01:16:09.600 sample which ships for free with glimmer DSL for swt it already gives you part of gladiator it gives you part of the
01:16:15.480 editor without all the sophisticated features of gladiator but it gives me an editor so here I already guys showed you
01:16:21.719 how I can do uh yeah like window open it starts instantly and then I can
01:16:27.420 adjust it and like do here this and then text glimmer
01:16:32.880 adjust it so that's to be honest that works pretty well for me it works well
01:16:38.280 enough I mean when I build that metronome that I told you guys I built it in 10 minutes seriously that's that's what I was doing and it took me 10
01:16:44.520 minutes so I mean it took me an hour to fine tune it but 10 minutes for the initial version for the MVP of it so
01:16:51.000 yeah it's a different word basically you don't need test Suites you don't need a bunch of things no no no so no no but
01:16:56.940 the nice thing about following MVC and MVP cleanly is the model layers completely decoupled from The View so
01:17:02.520 yes I do write tests for the models so when I built tic-tac-toe here I have a tic-tac-toe game where is it I built a
01:17:08.940 test first so I wrote all the logic for figuring out when the game is over uh by
01:17:14.159 writing purely model tests and then I wired I wired The View layer on top of it and given that I can observe any
01:17:21.239 model attribute without having to change the model I honor the open close principle so that means the models stay
01:17:28.080 the same but if you can augment it with a GUI cool it makes a lot more sense so
01:17:34.080 you do have tests and sometimes I mean I use them judiciously but yes yes I I
01:17:39.300 wherever I feel like they could be really helpful I do add tests yes what we don't have is a a way when the
01:17:46.440 application is running to go in the pain basically on Solitaire say Hey
01:17:52.860 you know that second card on the second what is the value of that card that's
01:17:58.320 what I use puts debugger for yeah of all and you relaunch the application event which is going to enter well it's
01:18:05.760 nice about PD versus ports is ports doesn't tell me where that variable was printed from so if I just do puts
01:18:11.760 debugging that's not good enough because it'll print the variable value but I have I have no idea where that print statement came from but if I do PD it
01:18:18.659 always gives you the file name and the line number so I even use that in web development to be honest in rails and it
01:18:24.120 works pretty well for me any other questions
01:18:31.920 I have a question uh we here has a desktop development experience
01:18:38.159 oh not much what did you build mostly it was mostly for school projects and
01:18:43.739 everything we're using C sharp and Java okay yeah that was one of my earliest experiences too I used Java Swing back
01:18:50.580 in the day when I was in McGill University so so what sort of apps did you build I'm curious one of the like most I guess
01:18:57.840 complete app that we made was kind of um uh Movie Database where you could put a
01:19:06.120 uh you you link an image and it would like detect the uh for for the the
01:19:13.260 they're covered like the DVD cover or whatever you linked it to it and it's gonna it's it's gonna like use image
01:19:19.560 recognition and like give you the uh the movie and uh you can search it and click on it and start watching it nice so did
01:19:27.480 it use that online element too like did it hit the web um yeah for watching oh it's pretty cool
01:19:33.780 awesome so now your assignment is to rebuild all of that in glimmer with like
01:19:39.480 a tenth of the code no seriously because I I write about a fraction of the code I used to write in Java with Java Swing
01:19:45.179 for example so anyways uh pretty much uh like Photoshop or whatever awesome
01:19:56.040 um yeah one thing I want to conclude the talk with is all of the skills that you guys just learned about MVC and MVP are
01:20:02.400 transferable to the web uh so I what I like about uh programming glimmer as
01:20:08.460 much as I could is it helps me become a better web programmer because every once in a while think of an idea and I'll be like why don't we do this on the web
01:20:14.580 then I try to do it on the web and then I end up with less code even in web development so it's always good to
01:20:20.640 sharpen your skills with desktop development in addition to what in order to become a better overall developer but
01:20:26.640 yeah that's pretty much it thank you guys
Explore all talks recorded at Montreal.rb Meetup
+6