DEV Community

Tomasz Wegrzanowski
Tomasz Wegrzanowski

Posted on

Electron Adventures: Episode 82: Glimmer DSL

I went through all the promising Electron alternatives, but there's still bottom of the barrel to scrape. So for this episode - Glimmer DSL.

Glimmer DSL is a Ruby DSL for creating UIs. As a warning sign, it doesn't try to be good DSL for one UI library, it tries to do 6. Now three of them are just Opal HTML, CSS, and XML, and we can do that stuff in Electron already, so let's look at the other three.

glimmer-dsl-tk

As far as I can tell, it's not possible to install Tk on Mac in any sensible way. I have tcl-tk installed in brew, but gem install glimmer-dsl-tk doesn't see it.

Here's the Gemfile that crashes:

source "https://rubygems.org"

gem "glimmer-dsl-tk", "~> 0.0.32"
Enter fullscreen mode Exit fullscreen mode

If you're on Linux, you could probably give it a try.

glimmer-dsl-libui

LibUI is a "portable GUI library for C". It comes with so many disclaimers that it's an incomplete alpha version.

So we prepare the following Gemfile and then run bundle install:

source "https://rubygems.org"

gem "glimmer-dsl-libui", "~> 0.2.16"
Enter fullscreen mode Exit fullscreen mode

Hello World isn't too bad:

#!/usr/bin/env ruby

require "glimmer-dsl-libui"

include Glimmer

window("Hello, world!", 800, 600).show
Enter fullscreen mode Exit fullscreen mode

Episode 82 Screenshot A

Except it refuses to activate that window on OSX, so it's in the background.

I proceeded to try to write a simple counter app with +1 and -1 buttons and showing a total, but libui segfaulted if I looked at it funny. Between no documentation, no feedback in REPL, constant segfaults, and library itself being open about being really incomplete, I just dropped it at this point.

glimmer-dsl-swt

Well, there's one more thing to try. The final supported library is Java SWT, for which we'll need to use JRuby. This is already problematic, as JRuby has very slow startup, and supports a lot fewer libraries than the regular Ruby, but it could be good enough.

We can start by this .rubyversion (if you use rbenv to manage multiple Ruby versions:)

jruby-9.3.1.0
Enter fullscreen mode Exit fullscreen mode

And this Gemfile:

source "https://rubygems.org"

gem "glimmer-dsl-swt", "~> 4.21"
Enter fullscreen mode Exit fullscreen mode

Installation took a while, and didn't tell me that I need to pass special options to jruby or I'd get a crash. With special option -J-XstartOnFirstThread, here's the Hello World:

#!/usr/bin/env ruby -J-XstartOnFirstThread

require "glimmer-dsl-swt"

include Glimmer

shell {
  text "Glimmer"
  label {
    text "Hello, World!"
  }
}.open
Enter fullscreen mode Exit fullscreen mode

As you might have noticed, it has nothing in common with Glimmer LibUI version. It's really unclear to me why Glimmer tries to be one project with multiple UI libraries that have so little in common, but I guess the DSL concept might be somewhat similar.

Episode 82 Screenshot B

Counter app in glimmer-dsl-swt

After digging through the examples in documentation, I managed to do this:

#!/usr/bin/env ruby -J-XstartOnFirstThread

require 'glimmer-dsl-swt'

class CounterApp
  include Glimmer::UI::CustomShell

  attr_accessor :count

  before_body do
    @count = 0
  end

  body {
    shell {
      text "Hello, Button!"
      row_layout :vertical

      label {
        text <= [self, :count, on_read: lambda{|v| "Count: #{v}" }]
      }

      group {
        row_layout :horizontal

        button {
          text "+1"
          on_widget_selected { self.count += 1 }
        }

        button {
          text "-1"
          on_widget_selected { self.count -= 1 }
        }
      }
    }
  }
end

CounterApp.launch
Enter fullscreen mode Exit fullscreen mode

All reactivity needs to be explicit. We do [self, :count, on_read: lambda{|v| "Count: #{v}" }] to tell it to observe changes in self.count, and may them with a lambda given.

And we need to to update self.count rather than @count, so observer code is notified.

It starts OK, unfortunately then things go bad when count exceeds one digit:

Episode 82 Screenshot C

Did you notice that cut "18"? The label size is only determined when we create the label. Updates change label contents, but they don't change label size. It's possible to work around it by including extra spaces at the end, but honestly, is this what we left HTML+CSS world for? I don't think so.

Results

In case it's not obvious yet, do not use any of this. It's a strong contender for the world one yet.

In the next episode we'll try JavaFX for JRuby, and see if that's better than Glimmer and SWT.

As usual, all the code for the episode is here.

Top comments (0)