Glimmer DSL for SWT just had a new feature release (4.18.7.0) introducing the concept of custom shapes, which is similar to custom widgets, except it is applied to shapes from the Canvas Shape DSL.
In fact, it supports both a method-based approach and a class-based more modular approach for defining new custom shape keywords.
This enables higher order visual concepts, such as defining a car from polygons, defining a beach_scene from tree, sand, and sunset, etc... The possibilities are endless!
This realizes Lisp's ultimate vision of code as data and data as code by being able to abstract and hide an entire concept like `boat` that is consisting of hundreds of `polygon` shapes behind a single keyword representing `boat` data, which in turn embodies the entire `boat` shape visual code. Just imagine the possibilities of having something like this with Ruby's ultra-fluid pliable syntax! It is time Ruby upended all other languages in desktop development, no!?! You can now productively enlarge your GUI DSL vocabulary endlessly and compose ever higher visual concepts as well as decorations for existing widgets.
I will let the newly added code samples explain more about custom shapes.
Hello, Shape!
This sample enables leveraging the generic `shape` keyword as a sort of a shape composite (similar to widget `composite`) that contains other nested shapes and defines common shared attributes for all of them. It uses that keyword in fact to build a method-based custom shape.
# From: https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_SAMPLES.md#hello-shape | |
require 'glimmer-dsl-swt' | |
class HelloShape | |
include Glimmer::UI::CustomShell | |
body { | |
shell { | |
text 'Hello, Shape!' | |
minimum_size 200, 225 | |
@canvas = canvas { | |
background :white | |
15.times { |n| | |
x_location = (rand*125).to_i%200 + (rand*25).to_i | |
y_location = (rand*125).to_i%200 + (rand*25).to_i | |
foreground_color = rgb(rand*255, rand*255, rand*255) | |
stick_figure(x_location, y_location, 50, 50) { | |
foreground foreground_color | |
} | |
} | |
} | |
} | |
} | |
# method-based custom shape using `shape` keyword as a composite shape containing nested shapes | |
def stick_figure(x, y, width, height, &block) | |
head_width = width*0.2 | |
head_height = height*0.2 | |
trunk_height = height*0.4 | |
extremity_length = height*0.4 | |
shape(x + head_width/2.0 + extremity_length, y) { | |
# common attributes go here before nested shapes | |
block.call # invoking content block (e.g. used from the outside to set foreground) | |
# nested shapes go here | |
oval(0, 0, head_width, head_height) | |
line(head_width/2.0, head_height, head_width/2.0, head_height + trunk_height) | |
line(head_width/2.0, head_height + trunk_height, head_width/2.0 + extremity_length, head_height + trunk_height + extremity_length) | |
line(head_width/2.0, head_height + trunk_height, head_width/2.0 - extremity_length, head_height + trunk_height + extremity_length) | |
line(head_width/2.0, head_height*2, head_width/2.0 + extremity_length, head_height + trunk_height - extremity_length) | |
line(head_width/2.0, head_height*2, head_width/2.0 - extremity_length, head_height + trunk_height - extremity_length) | |
} | |
end | |
end | |
HelloShape.launch | |
Hello, Custom Shape!
# From: https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_SAMPLES.md#hello-custom-shape | |
require 'glimmer-dsl-swt' | |
# Creates a class-based custom shape representing the `stick_figure` keyword by convention | |
class StickFigure | |
include Glimmer::UI::CustomShape | |
options :x, :y, :width, :height | |
before_body { | |
@head_width = width*0.2 | |
@head_height = height*0.2 | |
@trunk_height = height*0.4 | |
@extremity_length = height*0.4 | |
} | |
body { | |
shape(x + @head_width/2.0 + @extremity_length, y) { | |
oval(0, 0, @head_width, @head_height) | |
line(@head_width/2.0, @head_height, @head_width/2.0, @head_height + @trunk_height) | |
line(@head_width/2.0, @head_height + @trunk_height, @head_width/2.0 + @extremity_length, @head_height + @trunk_height + @extremity_length) | |
line(@head_width/2.0, @head_height + @trunk_height, @head_width/2.0 - @extremity_length, @head_height + @trunk_height + @extremity_length) | |
line(@head_width/2.0, @head_height*2, @head_width/2.0 + @extremity_length, @head_height + @trunk_height - @extremity_length) | |
line(@head_width/2.0, @head_height*2, @head_width/2.0 - @extremity_length, @head_height + @trunk_height - @extremity_length) | |
} | |
} | |
end | |
class HelloCustomShape | |
include Glimmer::UI::CustomShell | |
WIDTH = 220 | |
HEIGHT = 235 | |
body { | |
shell { | |
text 'Hello, Custom Shape!' | |
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) | |
a_stick_figure = stick_figure(x: x_location, y: y_location, width: 35+n*2, height: 35+n*2) { | |
foreground foreground_color | |
drag_and_move true | |
# on mouse click, change color | |
on_mouse_up do | |
a_stick_figure.foreground = rgb(rand*255, rand*255, rand*255) | |
end | |
} | |
} | |
} | |
} | |
} | |
end | |
HelloCustomShape.launch | |
No comments:
Post a Comment