Glimmer Gets Its First Official Custom Shape Gems
Tags: ruby, gui, graphics, desktop
Published: 2021-03-13 22:47:16

[Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt), which made it to the [Top 8 Ruby Framework Projects on LibHunt for Feb 2021](https://andymaleh.blogspot.com/2021/03/glimmer-is-in-top-8-ruby-frameworks-on.html), recently [added support for Custom Shapes](https://andymaleh.blogspot.com/2021/03/glimmer-dsl-for-swt-custom-shapes.html), which are reusable graphical constructs akin of Custom Widgets (reusable widget constructs). [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) just got its first official [custom shape gems](https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#custom-shapes): [glimmer-cp-bevel](https://rubygems.org/gems/glimmer-cp-bevel), providing the `bevel` keyword, and [glimmer-cp-stickfigure](https://rubygems.org/gems/glimmer-cp-stickfigure), providing the `stick_figure` keyword. They are covered below.

**[Bevel](https://github.com/AndyObtiva/glimmer-cp-bevel)**
This represents a bevel square custom shape that can have various colors and sizes, and you only need to set its base color for it to figure out the rest. It is customizable via its [API](https://github.com/AndyObtiva/glimmer-cp-bevel#api).

![Bevel Screenshot](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-swt/master/images/glimmer-example-image-shape-dsl.png)

Currently used in [Glimmer Tetris](https://dev.to/andyobtiva/glimmer-tetris-in-one-day-3k4o).

![Glimmer Tetris](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-swt/master/images/glimmer-tetris.png)

Glimmer GUI DSL Code Example:

```ruby
# From: https://github.com/AndyObtiva/glimmer-cp-bevel#example

require 'glimmer-cp-bevel'

include Glimmer

shell {
  text 'Glimmer Tetris Icon'
  label {
    text 'Check out the application icon!'
    font height: 20
  }
  icon_block_size = 64
  icon_bevel_size = icon_block_size.to_f / 25.to_f
  icon_bevel_pixel_size = 0.16*icon_block_size.to_f
  icon_size = 8
  icon_pixel_size = icon_block_size * icon_size
  image(icon_pixel_size, icon_pixel_size) {
    icon_size.times { |row|
      icon_size.times { |column|
        colored = row >= 1 && column.between?(1, 6)
        color = colored ? color(([:white] + [:cyan, :blue, :dark_yellow, :yellow, :green, :magenta, :red]).sample) : color(:white)
        x = column * icon_block_size
        y = row * icon_block_size
        bevel(x: x, y: y, base_color: color, size: icon_block_size)
      }
    }
  }
}.open
```

Tetris icon image produced:

![Tetris icon image](https://raw.githubusercontent.com/AndyObtiva/glimmer-dsl-swt/master/images/glimmer-tetris-icon.png)


**[Stick Figure](https://github.com/AndyObtiva/glimmer-cp-stickfigure)**
This represents a stick figure custom shape that can have colors and sizes, and you only need to set its base size for it to figure out the rest for the stick figure head, torso, arms, and legs. It is customizable via its [API](https://github.com/AndyObtiva/glimmer-cp-stickfigure#api).

![Stick Figure Screenshot](https://github.com/AndyObtiva/glimmer-cp-stickfigure/raw/master/images/glimmer-cp-stickfigure-hello-stick-figure.png)

Currently used in the upcoming [DCR](https://github.com/AndyObtiva/dcr) project

![DCR](https://raw.githubusercontent.com/AndyObtiva/dcr/master/images/dcr-screenshot.png)

Glimmer GUI DSL code for [Hello, Stick Figure! Sample](https://github.com/AndyObtiva/glimmer-cp-stickfigure#hello-stick-figure):

```ruby
# From: https://github.com/AndyObtiva/glimmer-cp-stickfigure/blob/master/samples/stick_figure/hello_stick_figure.rb

require_relative '../../lib/glimmer-cp-stickfigure' # Use `require 'glimmer-cp-stickfigure'` if gem is installed

class HelloStickFigure
  include Glimmer::UI::CustomShell
  
  WIDTH = 220
  HEIGHT = 235
  
  body {
    shell {
      text 'Hello, Stick Figure!'
      minimum_size WIDTH, HEIGHT
    
      @canvas = canvas {
        background :white
        
        15.times { |n|
          x_location = (rand*WIDTH/2).to_i%WIDTH + (rand*15).to_i
          y_location = (rand*HEIGHT/2).to_i%HEIGHT + (rand*15).to_i
          foreground_color = rgb(rand*255, rand*255, rand*255)
          
          stick_figure(location_x: x_location, location_y: y_location, size: 35+n*2) {
            foreground foreground_color
          }
        }
        
        on_mouse_down { |mouse_event|
          @drag_detected = false
          @canvas.cursor = :hand
          # select shape at location
          @selected_shape = @canvas.shape_at_location(mouse_event.x, mouse_event.y)
          # select shape parent if it is a nested shape like an arm or leg
          @selected_shape = @selected_shape.parent_shapes.last if @selected_shape.parent_shapes.any?
        }
        
        on_drag_detected { |drag_detect_event|
          @drag_detected = true
          @drag_current_x = drag_detect_event.x
          @drag_current_y = drag_detect_event.y
        }
        
        on_mouse_move { |mouse_event|
          if @drag_detected
            @selected_shape&.move_by(mouse_event.x - @drag_current_x, mouse_event.y - @drag_current_y)
            @drag_current_x = mouse_event.x
            @drag_current_y = mouse_event.y
          end
        }
        
        on_mouse_up { |mouse_event|
          @canvas.cursor = :arrow
          @drag_detected = false
          @selected_shape = nil
        }
      }
    }
  }
end

HelloStickFigure.launch
```

Hello, Stick Figure!

![Hello, Stick Figure Screenshot](https://github.com/AndyObtiva/glimmer-cp-stickfigure/raw/master/images/glimmer-cp-stickfigure-hello-stick-figure.png)


Happy [Glimmering](https://github.com/AndyObtiva/glimmer-dsl-swt)!