Home

Awesome

How To Build Desktop Applications in Ruby

RubyConf 2023 Workshop Code Exercises by Andy Maleh

Please star ("⭐️") this project and Glimmer DSL for LibUI to save for later reference with regards to Ruby Desktop Development. Glimmer DSL for LibUI was used in this workshop because it is the simplest and quickest to setup in standard Ruby (aka MRI / CRuby), but the lessons learned are applicable to other Glimmer GUI DSLs (with some syntax variations), including more mature ones like Glimmer DSL for SWT, which might be better for more serious usage after finishing the workshop. If you discover any issues or get stuck while going through the material of this repo, please report them in GitHub issues or discuss in the Glimmer Gitter Chat.

Table of Contents

Setup Glimmer DSL for LibUI

(aka Exercise 0)

1- Follow Presentation Slides at:

Short Link:

https://bit.ly/rubyconf2023desktop

Long Link:

https://docs.google.com/presentation/d/e/2PACX-1vTzKJ_covbLCfT2Ozse-FGhK8SRRdJ9xrOHQMpzlerhlyj09BlunreTKBWUfoKz3hpE2C5ZEn2LnUpD/pub?start=false&loop=false&delayms=60000&slide=id.g140fe579a5a_0_0

2- Open Terminal (on Mac or Linux) or Command-Prompt/Git-Bash (on Windows) [do not use WSL or PowerShell]

3- Install glimmer-dsl-libui gem

Run:

gem install glimmer-dsl-libui -v0.11.4

4- Load Glimmer Meta-Example to test gem

Run:

glimmer examples

You should see the Glimmer Meta-Example (the example of examples).

MacWindowsLinux
glimmer-dsl-libui-mac-meta-example.pngglimmer-dsl-libui-windows-meta-example.pngglimmer-dsl-libui-linux-meta-example.png

5- Launch 3 basic examples:

Basic Window

MacWindowsLinux
glimmer-dsl-libui-mac-basic-window.pngglimmer-dsl-libui-windows-basic-window.pngglimmer-dsl-libui-linux-basic-window.png

Basic Button

MacWindowsLinux
glimmer-dsl-libui-mac-basic-button.png glimmer-dsl-libui-mac-basic-button-msg-box.pngglimmer-dsl-libui-windows-basic-button.png glimmer-dsl-libui-windows-basic-button-msg-box.pngglimmer-dsl-libui-linux-basic-button.png glimmer-dsl-libui-linux-basic-button-msg-box.png

Basic Scrolling Area

MacWindowsLinux
glimmer-dsl-libui-mac-dynamic-area.png glimmer-dsl-libui-mac-dynamic-area-updated.pngglimmer-dsl-libui-windows-dynamic-area.png glimmer-dsl-libui-windows-dynamic-area-updated.pngglimmer-dsl-libui-linux-dynamic-area.png glimmer-dsl-libui-linux-dynamic-area-updated.png

6- Launch 3 advanced examples:

Control Gallery

MacWindowsLinux
glimmer-dsl-libui-mac-control-gallery.pngglimmer-dsl-libui-windows-control-gallery.pngglimmer-dsl-libui-linux-control-gallery.png

Form Table

MacWindowsLinux
glimmer-dsl-libui-mac-form-table.png glimmer-dsl-libui-mac-form-table-contact-entered.png glimmer-dsl-libui-mac-form-table-filtered.pngglimmer-dsl-libui-windows-form-table.png glimmer-dsl-libui-windows-form-table-contact-entered.png glimmer-dsl-libui-windows-form-table-filtered.pngglimmer-dsl-libui-linux-form-table.png glimmer-dsl-libui-linux-form-table-contact-entered.png glimmer-dsl-libui-linux-form-table-filtered.png

Snake

MacWindowsLinux
glimmer-dsl-libui-mac-snake.png glimmer-dsl-libui-mac-snake-game-over.pngglimmer-dsl-libui-windows-snake.png glimmer-dsl-libui-windows-snake-game-over.pngglimmer-dsl-libui-linux-snake.png glimmer-dsl-libui-linux-snake-game-over.png

Setup Workshop GitHub Repository

git clone https://github.com/AndyObtiva/how-to-build-desktop-applications-in-ruby.git
cd how-to-build-desktop-applications-in-ruby
bundle

Resources

Exercises

Exercises are numbered and organized under sections.

You can run an exercise by simply passing the exercise main Ruby file name as an argument to the glimmer command.

Example:

glimmer section-01-gui-basics/exercise-09/hello_operations.rb

Section 1 GUI Basics

Exercise 1 Empty Window

section-01-gui-basics/exercise-01/empty_window.rb

Run this command from cloned repo directory:

glimmer section-01-gui-basics/exercise-01/empty_window.rb

Screenshot(s):

empty window

Exercise 2 Hello, World! Window with Args

section-01-gui-basics/exercise-02/hello_world_window_with_args.rb

Run this command from cloned repo directory:

glimmer section-01-gui-basics/exercise-02/hello_world_window_with_args.rb

Screenshot(s):

hello world window with args

Exercise 3 Hello, World! Window with Props

section-01-gui-basics/exercise-03/hello_world_window_with_props.rb

Run this command from cloned repo directory:

glimmer section-01-gui-basics/exercise-03/hello_world_window_with_props.rb

Screenshot(s):

hello world window with props

Exercise 4 Hello, World! Window + Label with Args

section-01-gui-basics/exercise-04/hello_world_window_label_with_args.rb

Run this command from cloned repo directory:

glimmer section-01-gui-basics/exercise-04/hello_world_window_label_with_args.rb

Screenshot(s):

hello world window label with args

Exercise 5 Hello, World! Window + Label with Props

section-01-gui-basics/exercise-05/hello_world_window_label_with_props.rb

Run this command from cloned repo directory:

glimmer section-01-gui-basics/exercise-05/hello_world_window_label_with_props.rb

Screenshot(s):

hello world window label with args

Exercise 6 Hello, Button!

section-01-gui-basics/exercise-06/hello_button.rb

Run this command from cloned repo directory:

glimmer section-01-gui-basics/exercise-06/hello_button.rb

Screenshot(s):

hello button

hello button clicked

Exercise 7 Hello, Layout! with Horizontal Box

section-01-gui-basics/exercise-07/hello_layout_with_horizontal_box.rb

Run this command from cloned repo directory:

glimmer section-01-gui-basics/exercise-07/hello_layout_with_horizontal_box.rb

Screenshot(s):

hello layout with horizontal box

Exercise 8 Hello, Layout! with Horizontal & Vertical Boxes

section-01-gui-basics/exercise-08/hello_layout_with_horizontal_and_vertical_boxes.rb

Run this command from cloned repo directory:

glimmer section-01-gui-basics/exercise-08/hello_layout_with_horizontal_and_vertical_boxes.rb

Screenshot(s):

hello layout with horizontal and vertical boxes

Exercise 9 Option Selector

section-01-gui-basics/exercise-09/option_selector.rb

Run this command from cloned repo directory:

glimmer section-01-gui-basics/exercise-09/option_selector.rb

Screenshot(s):

option selector screenshot 1

option selector screenshot 2

See another version of the Option Selector in Section 2 Exercise 10.

Section 2 MVC Software Architecture

Exercise 10 Option Selector MVC Explicit Controller

section-02-mvc-software-architecture/exercise-10/option_selector_mvc_explicit_controller.rb

Run this command from cloned repo directory:

glimmer section-02-mvc-software-architecture/exercise-10/option_selector_mvc_explicit_controller.rb

Screenshot(s):

option selector screenshot 1

option selector screenshot 2

See another version of the Option Selector in Section 2 Exercise 11.

Exercise 11 Option Selector MVC Implicit Controller

section-02-mvc-software-architecture/exercise-11/option_selector_mvc_implicit_controller.rb

Run this command from cloned repo directory:

glimmer section-02-mvc-software-architecture/exercise-11/option_selector_mvc_implicit_controller.rb

Screenshot(s):

option selector screenshot 1

option selector screenshot 2

See another version of the Option Selector in Section 3 Exercise 12.

Section 3 MVP & Data-Binding

Exercise 12 Option Selector MVP and Data-Binding

section-03-mvp-data-binding/exercise-12/option_selector_mvp_and_data_binding.rb

Run this command from cloned repo directory:

glimmer section-03-mvp-data-binding/exercise-12/option_selector_mvp_and_data_binding.rb

Screenshot(s):

option selector screenshot 1

option selector screenshot 2

See another version of the Option Selector in Section 3 Exercise 13.

Exercise 13 Option Selector with Reset

section-03-mvp-data-binding/exercise-13/option_selector_mvp_and_data_binding_with_reset.rb

Run this command from cloned repo directory:

glimmer section-03-mvp-data-binding/exercise-13/option_selector_mvp_and_data_binding_with_reset.rb

Screenshot(s):

option selector screenshot 1

option selector screenshot 2

option selector with reset

See another version of the Option Selector in Section 4 Exercise 17.

Exercise 14 Address Form

section-03-mvp-data-binding/exercise-14/address_form.rb

Run this command from cloned repo directory:

glimmer section-03-mvp-data-binding/exercise-14/address_form.rb

Screenshot(s):

address form

Exercise 14b Form Table

section-03-mvp-data-binding/exercise-14b/form_table.rb

Run this command from cloned repo directory:

glimmer section-03-mvp-data-binding/exercise-14b/form_table.rb

Screenshot(s):

MacWindowsLinux
glimmer-dsl-libui-mac-form-table.png glimmer-dsl-libui-mac-form-table-contact-entered.png glimmer-dsl-libui-mac-form-table-filtered.pngglimmer-dsl-libui-windows-form-table.png glimmer-dsl-libui-windows-form-table-contact-entered.png glimmer-dsl-libui-windows-form-table-filtered.pngglimmer-dsl-libui-linux-form-table.png glimmer-dsl-libui-linux-form-table-contact-entered.png glimmer-dsl-libui-linux-form-table-filtered.png

Exercise 15 Dynamic Form

section-03-mvp-data-binding/exercise-15/dynamic_form.rb

Run this command from cloned repo directory:

glimmer section-03-mvp-data-binding/exercise-15/dynamic_form.rb

Screenshot(s):

dynamic form 1

dynamic form 2

Exercise 16 Dynamic Address Forms

section-03-mvp-data-binding/exercise-16/dynamic_address_forms.rb

Run this command from cloned repo directory:

glimmer section-03-mvp-data-binding/exercise-16/dynamic_address_forms.rb

Screenshot(s):

dynamic address forms 1

dynamic address forms 2

dynamic address forms 3

Section 4 Advanced Data-Binding

Exercise 17 Option Selector with Data-Binding Converters and Hooks

section-04-advanced-data-binding/exercise-17/option_selector_data_binding_converters_and_hooks.rb

Run this command from cloned repo directory:

glimmer section-04-advanced-data-binding/exercise-17/option_selector_data_binding_converters_and_hooks.rb

Screenshot(s):

option selector screenshot 1

option selector screenshot 2

option selector with reset

See another version of the Option Selector in Section 4 Exercise 18.

Exercise 18 Option Selector with Computed Data-Binding

section-04-advanced-data-binding/exercise-18/option_selector_with_computed_data_binding.rb

Run this command from cloned repo directory:

glimmer section-04-advanced-data-binding/exercise-18/option_selector_with_computed_data_binding.rb

Screenshot(s):

option selector screenshot 1

option selector screenshot 2

option selector with reset

Exercise 19 Address Form with Nested Indexed Data-Binding

section-04-advanced-data-binding/exercise-19/address_form_with_nested_indexed_data_binding.rb

Run this command from cloned repo directory:

glimmer section-04-advanced-data-binding/exercise-19/address_form_with_nested_indexed_data_binding.rb

Screenshot(s):

address form nested indexed data-binding

In addition to Nested Indexed Data-Binding, this exercise demonstrated how to reuse the Address Form as a Method-Based Custom Control component.

See another version of this Address Form reused as a Class-Based Custom Control component in Section 7 Exercise 24.

Section 5 Area (Canvas) Graphics

Exercise 20 Area Shapes (Individual)

1- Line

section-05-area-canvas-graphics/exercise-20/line.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/line.rb

Screenshot(s):

area shapes line

2- Rectangle

section-05-area-canvas-graphics/exercise-20/rectangle.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/rectangle.rb

Screenshot(s):

area shapes rectangle

3- Square

section-05-area-canvas-graphics/exercise-20/square.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/square.rb

Screenshot(s):

area shapes square

4- Arc

section-05-area-canvas-graphics/exercise-20/arc.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/arc.rb

Screenshot(s):

area shapes arc

5- Circle

section-05-area-canvas-graphics/exercise-20/circle.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/circle.rb

Screenshot(s):

area shapes circle

6- Bezier

section-05-area-canvas-graphics/exercise-20/bezier.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/bezier.rb

Screenshot(s):

area shapes bezier

7- Figure

section-05-area-canvas-graphics/exercise-20/figure.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/figure.rb

Screenshot(s):

area shapes figure

8- Polygon

section-05-area-canvas-graphics/exercise-20/polygon.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/polygon.rb

Screenshot(s):

area shapes polygon

9- Polyline

section-05-area-canvas-graphics/exercise-20/polyline.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/polyline.rb

Screenshot(s):

area shapes polyline

10- Polybezier

section-05-area-canvas-graphics/exercise-20/polybezier.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/polybezier.rb

Screenshot(s):

area shapes polybezier

11- Composite Shape

section-05-area-canvas-graphics/exercise-20/composite_shape.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-20/composite_shape.rb

Screenshot(s):

area shapes composite shape

Exercise 21 Area Shapes

section-05-area-canvas-graphics/exercise-21/area_shapes.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-21/area_shapes.rb

Screenshot(s):

area shapes

Exercise 22 Area Shapes with Selection and Movement

section-05-area-canvas-graphics/exercise-22/area_shapes_with_selection_and_movement.rb

Run this command from cloned repo directory:

glimmer section-05-area-canvas-graphics/exercise-22/area_shapes_with_selection_and_movement.rb

Screenshot(s):

area shapes

area shapes with selection and movement

Section 6 Drag & Drop

Exercise 23 Shape Coloring

section-06-drag-and-drop/exercise-23/shape_coloring.rb

Run this command from cloned repo directory:

glimmer section-06-drag-and-drop/exercise-23/shape_coloring.rb

Screenshot(s):

shape coloring 1

shape coloring 2

shape coloring 3

Section 7 Custom Components

Exercise 24 Address Form Custom Control

section-07-custom-components/exercise-24/address_form_custom_control.rb

Run this command from cloned repo directory:

glimmer section-07-custom-components/exercise-24/address_form_custom_control.rb

Screenshot(s):

address form custom control

Compared to Method-Based Custom Controls, Class-Based Custom Controls provide the added benefit of dividing and conquering the complexity of component code into separate Ruby files, which can even be wrapped as Ruby gems for cross-project reuse if needed.

Exercise 25 User Manager

section-07-custom-components/exercise-25/user_manager.rb

Run this command from cloned repo directory:

glimmer section-07-custom-components/exercise-25/user_manager.rb

Screenshot(s):

user manager

user manager add user

user manager user added

user manager select user

user manager edit user

Exercise 26 Basic Custom Shape

section-07-custom-components/exercise-26/basic_custom_shape.rb

Run this command from cloned repo directory:

glimmer section-07-custom-components/exercise-26/basic_custom_shape.rb

Screenshot(s):

basic custom shape

Section 8 Application Scaffolding

Exercise 27 Application Scaffolding

Glimmer DSL for LibUI Application Scaffolding requires a Git configuration for user.name (git config --global user.name "FirstName LastName") and github.user (git config --global github.user githubusername) as needed by the juwelier Ruby gem used for scaffolding.

Scaffold an application by running:

glimmer "scaffold[hello_world]"

section-08-application-scaffolding/exercise-27/hello_world

The following files are generated and reported by the glimmer command:

Created hello_world/.gitignore
Created hello_world/.ruby-version
Created hello_world/.ruby-gemset
Created hello_world/VERSION
Created hello_world/LICENSE.txt
Created hello_world/Gemfile
Created hello_world/Rakefile
Created hello_world/app/hello_world.rb
Created hello_world/app/hello_world/view/hello_world.rb
Created hello_world/app/hello_world/model/greeting.rb
Created hello_world/icons/windows/Hello World.ico
Created hello_world/icons/macosx/Hello World.icns
Created hello_world/icons/linux/Hello World.png
Created hello_world/app/hello_world/launch.rb
Created hello_world/bin/hello_world

They include a basic Hello, World! application with menus and about/preferences dialogs.

Views live under app/app_name/view (e.g. app/hello_world/view)

Models live under app/app_name/model (e.g. app/hello_world/model)

The application runs automatically once scaffolding is done.

You can run scaffolded application with this command from cloned repo directory:

cd section-08-application-scaffolding/exercise-27/hello_world
glimmer run

or

cd section-08-application-scaffolding/exercise-27/hello_world
bin/hello_world

Screenshot(s):

application scaffolding 1

application scaffolding 2

application scaffolding 3

application scaffolding 4

License

MIT

Copyright (c) 2023 Andy Maleh