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