40
Glimmer DSL for GTK
Yes, I've done it! I built an entire Glimmer DSL in one day! I built Glimmer DSL for GTK after receiving an issue request for it on the Glimmer project page on GitHub!
Enjoy reading the README below!
Happy Glimmering!
Hello, World!
window {
title 'Hello, World!'
label('Hello, World!')
}.show
Mac Screenshot:

NOTE: Glimmer DSL for GTK is currently in early alpha mode (incomplete proof-of-concept). Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still an early alpha, so the more feedback and issues you report the better.
Other Glimmer DSL gems you might be interested in:
Run this command to install directly:
gem install glimmer-dsl-gtk
Add the following to
Gemfile
:gem 'glimmer-dsl-gtk', '~> 0.0.1'
And, then run:
bundle
Require the library and mixin the
Glimmer
module to utilize the Glimmer GUI DSL for GTK:require 'glimmer-dsl-gtk'
include Glimmer
window {
title 'Demo'
on(:destroy) do
puts 'Bye Bye'
::Gtk.main_quit
end
}.show
For actual application development outside of simple demos, mixin the
Glimmer
module into an application class instead:require 'glimmer-dsl-gtk'
class SomeGlimmerApplication
include Glimmer
def launch
application('org.glimmer.hello-application', :flags_none) {
on(:activate) do |app|
application_window(app) {
title 'Actual Application'
}.present
end
}.run
end
end
SomeGlimmerApplication.new.launch
application_window(app)
for Gtk::ApplicationWindow.new(app)
). Keywords can be nested under other keywords to represent the true hierarchy of nested widgets on the screen (e.g. window { label('Hello') }
is a label
nested under a window
). Note that widget objects returned are proxies of the GTK widget counterparts. This shields consumers of GTK from its lower-level details via composition (Proxy Design Pattern). To access lower-level GTK widget, simply call #gtk
method on widget proxy object (e.g. @w = window {...}; @w.gtk # Gtk::Window widget object
).window {|w| ... }
):
- Properties: All GTK widget properties can be set via lowercase underscored names (without the 'set_' prefix) nested under widget keywords (e.g.
window {title 'Hello, World'}
setstitle
property ofwindow
) - Signals: All GTK signals can be wired with
on(signal) { ... }
syntax (e.g.on(:activate) { do_something }
)
You can run the
girb
command (bin/girb
if you cloned the project locally):girb

This gives you
irb
with the glimmer-dsl-gtk
gem loaded and the Glimmer
module mixed into the main object for easy experimentation with GUI.Gotcha: On the Mac, when you close a window opened in
girb
, it remains open until you enter exit or open another GUI window.Mac Screenshot:

Run (via installed gem):
ruby -r glimmer-dsl-gtk -e "require 'samples/hello/hello_world'"
Run (via locally cloned project):
ruby -r ./lib/glimmer-dsl-gtk.rb samples/hello/hello_world.rb
Code:
window {
title 'Hello, World!'
label('Hello, World!')
}.show
Mac Screenshot:

Run (via installed gem):
ruby -r glimmer-dsl-gtk -e "require 'samples/hello/hello_application'"
Run (via locally cloned project):
ruby -r ./lib/glimmer-dsl-gtk.rb samples/hello/hello_application.rb
Code:
require 'glimmer-dsl-gtk'
include Glimmer
application('org.glimmer.hello-application', :flags_none) {
on(:activate) do |app|
application_window(app) {
title 'Hello, Application!'
}.present
end
}.run
Mac Screenshot:


Run (via installed gem):
ruby -r glimmer-dsl-gtk -e "require 'samples/hello/hello_button'"
Run (via locally cloned project):
ruby -r ./lib/glimmer-dsl-gtk.rb samples/hello/hello_button.rb
Code:
require 'glimmer-dsl-gtk'
include Glimmer
window { |w|
title 'Hello, Button!'
button('Button') {
on(:clicked) do
message_dialog(w) { |md|
title 'Information'
text 'You clicked the button'
on(:response) do
md.destroy
end
}.show
end
}
}.show
Mac Screenshot:


Run (via installed gem):
ruby -r glimmer-dsl-gtk -e "require 'samples/hello/hello_entry'"
Run (via locally cloned project):
ruby -r ./lib/glimmer-dsl-gtk.rb samples/hello/hello_entry.rb
Code:
require 'glimmer-dsl-gtk'
include Glimmer
window { |w|
title 'Hello, Entry!'
default_size 300, 50
box(:vertical) {
e = entry {
on(:changed) do
puts e.text
$stdout.flush # For Windows
end
}
button('Button') {
on(:clicked) do
message_dialog(w) { |md|
title 'You entered'
text e.text
on(:response) do
md.destroy
end
}.show
end
}
}
}.show
40