glimmer-dsl-opal 0.27.0 → 0.28.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +71 -3
- data/VERSION +1 -1
- data/lib/glimmer/dsl/opal/dsl.rb +3 -0
- data/lib/glimmer/dsl/opal/image_expression.rb +64 -0
- data/lib/glimmer/dsl/opal/property_expression.rb +1 -2
- data/lib/glimmer/dsl/opal/shape_expression.rb +35 -6
- data/lib/glimmer/swt/canvas_proxy.rb +27 -0
- data/lib/glimmer/swt/composite_proxy.rb +0 -2
- data/lib/glimmer/swt/custom/shape/arc.rb +75 -0
- data/lib/glimmer/swt/custom/shape/image.rb +98 -0
- data/lib/glimmer/swt/custom/shape/line.rb +53 -0
- data/lib/glimmer/swt/custom/shape/oval.rb +58 -0
- data/lib/glimmer/swt/custom/shape/point.rb +53 -0
- data/lib/glimmer/swt/custom/shape/polygon.rb +53 -0
- data/lib/glimmer/swt/custom/shape/polyline.rb +53 -0
- data/lib/glimmer/swt/custom/shape/rectangle.rb +101 -0
- data/lib/glimmer/swt/custom/shape/text.rb +114 -0
- data/lib/glimmer/swt/custom/shape.rb +205 -0
- data/lib/glimmer/swt/image_proxy.rb +29 -0
- data/lib/glimmer/swt/menu_proxy.rb +1 -1
- data/lib/glimmer/swt/point.rb +2 -0
- data/lib/glimmer/swt/rectangle.rb +7 -0
- data/lib/glimmer/swt/widget_proxy.rb +15 -4
- data/lib/glimmer-dsl-opal/samples/elaborate/tetris/view/block.rb +44 -0
- data/lib/glimmer-dsl-opal/samples/elaborate/tetris.rb +4 -8
- data/lib/glimmer-dsl-opal/samples/elaborate/weather.rb +4 -3
- data/lib/glimmer-dsl-opal/samples/hello/hello_canvas.rb +106 -0
- data/lib/glimmer-dsl-opal/samples/hello/hello_text.rb +1 -1
- data/lib/glimmer-dsl-opal/samples/hello/images/scaffold_app.png +0 -0
- data/lib/glimmer-dsl-opal/vendor/two.min.js +24 -0
- data/lib/glimmer-dsl-opal.rb +1 -0
- metadata +19 -2
@@ -0,0 +1,114 @@
|
|
1
|
+
# Copyright (c) 2020-2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'glimmer/swt/custom/shape'
|
23
|
+
require 'glimmer/swt/swt_proxy'
|
24
|
+
require 'glimmer/swt/display_proxy'
|
25
|
+
require 'glimmer/swt/color_proxy'
|
26
|
+
# require 'glimmer/swt/transform_proxy'
|
27
|
+
|
28
|
+
module Glimmer
|
29
|
+
module SWT
|
30
|
+
module Custom
|
31
|
+
class Shape
|
32
|
+
class Text < Shape
|
33
|
+
def parameter_names
|
34
|
+
if text_parameter_names.size == @args.size
|
35
|
+
@parameter_names = text_parameter_names
|
36
|
+
elsif text_transparent_parameter_names.size == @args.size
|
37
|
+
@parameter_names = text_transparent_parameter_names
|
38
|
+
elsif text_flags_parameter_names.size == @args.size
|
39
|
+
@parameter_names = text_flags_parameter_names
|
40
|
+
end
|
41
|
+
@parameter_names || text_parameter_names
|
42
|
+
end
|
43
|
+
|
44
|
+
def possible_parameter_names
|
45
|
+
# TODO refactor and improve this method through meta-programming (and share across other shapes)
|
46
|
+
(text_parameter_names + text_transparent_parameter_names + text_flags_parameter_names).uniq
|
47
|
+
end
|
48
|
+
|
49
|
+
def text_parameter_names
|
50
|
+
[:string, :x, :y]
|
51
|
+
end
|
52
|
+
|
53
|
+
def text_transparent_parameter_names
|
54
|
+
[:string, :x, :y, :is_transparent]
|
55
|
+
end
|
56
|
+
|
57
|
+
def text_flags_parameter_names
|
58
|
+
[:string, :x, :y, :flags]
|
59
|
+
end
|
60
|
+
|
61
|
+
def set_parameter_attribute(attribute_name, *args)
|
62
|
+
if @parameter_names.to_a.map(&:to_s).include?(attribute_name.to_s)
|
63
|
+
super(attribute_name, *args)
|
64
|
+
build_dom
|
65
|
+
reattach(dom_element)
|
66
|
+
return
|
67
|
+
end
|
68
|
+
if text_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
69
|
+
@parameter_names = text_parameter_names
|
70
|
+
elsif text_transparent_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
71
|
+
@parameter_names = text_transparent_parameter_names
|
72
|
+
elsif text_flags_parameter_names.map(&:to_s).include?(attribute_name.to_s)
|
73
|
+
@parameter_names = text_flags_parameter_names
|
74
|
+
end
|
75
|
+
super(attribute_name, *args)
|
76
|
+
end
|
77
|
+
|
78
|
+
def reattach(old_element)
|
79
|
+
old_element.attr('x', Element[@dom].attr('x'))
|
80
|
+
old_element.attr('y', Element[@dom].attr('y'))
|
81
|
+
old_element.text(Element[@dom].html)
|
82
|
+
end
|
83
|
+
|
84
|
+
def background=(value)
|
85
|
+
# TODO override background= to fill a rectangle containing text, matching its size
|
86
|
+
# For now, disable background when foreground is not set
|
87
|
+
super(value) unless foreground.nil?
|
88
|
+
end
|
89
|
+
|
90
|
+
def foreground=(value)
|
91
|
+
super(value)
|
92
|
+
self.background = value
|
93
|
+
end
|
94
|
+
|
95
|
+
def element
|
96
|
+
'text'
|
97
|
+
end
|
98
|
+
|
99
|
+
def dom
|
100
|
+
shape_id = id
|
101
|
+
shape_class = name
|
102
|
+
@dom ||= xml {
|
103
|
+
tag(:_name => 'text', id: shape_id, class: shape_class, x: @args[1], y: @args[2]) {
|
104
|
+
@args[0]
|
105
|
+
}
|
106
|
+
}.to_s
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
String = Text
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
# Copyright (c) 2007-2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'glimmer/swt/property_owner'
|
23
|
+
require 'glimmer/swt/swt_proxy'
|
24
|
+
require 'glimmer/swt/display_proxy'
|
25
|
+
require 'glimmer/swt/color_proxy'
|
26
|
+
require 'glimmer/swt/font_proxy'
|
27
|
+
# require 'glimmer/swt/transform_proxy'
|
28
|
+
require 'glimmer/swt/point'
|
29
|
+
require 'glimmer/swt/rectangle'
|
30
|
+
|
31
|
+
module Glimmer
|
32
|
+
module SWT
|
33
|
+
module Custom
|
34
|
+
# Represents a shape (graphics) to be drawn on a control/widget/canvas/display
|
35
|
+
# That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
|
36
|
+
class Shape < WidgetProxy
|
37
|
+
include PropertyOwner
|
38
|
+
|
39
|
+
class << self
|
40
|
+
def create(parent, keyword, args, &property_block)
|
41
|
+
potential_shape_class_name = keyword.to_s.camelcase(:upper).to_sym
|
42
|
+
if constants.include?(potential_shape_class_name)
|
43
|
+
const_get(potential_shape_class_name).new(parent, args, &property_block)
|
44
|
+
else
|
45
|
+
new(parent, args, &property_block)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid?(parent, keyword, args, &block)
|
50
|
+
return true if keyword.to_s == 'shape'
|
51
|
+
keywords.include?(keyword.to_s)
|
52
|
+
end
|
53
|
+
|
54
|
+
def keywords
|
55
|
+
constants.select do |constant|
|
56
|
+
constant_value = const_get(constant)
|
57
|
+
constant_value.respond_to?(:ancestors) && constant_value.ancestors.include?(Glimmer::SWT::Custom::Shape)
|
58
|
+
end.map {|constant| constant.to_s.underscore}
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def background=(value)
|
64
|
+
value = ColorProxy.new(value) if value.is_a?(String) || value.is_a?(Symbol)
|
65
|
+
@background = value
|
66
|
+
dom_element.css('fill', background.to_css) unless background.nil?
|
67
|
+
end
|
68
|
+
|
69
|
+
def foreground=(value)
|
70
|
+
value = ColorProxy.new(value) if value.is_a?(String) || value.is_a?(Symbol)
|
71
|
+
@foreground = value
|
72
|
+
dom_element.css('stroke', foreground.to_css) unless foreground.nil?
|
73
|
+
dom_element.css('fill', 'transparent') if background.nil?
|
74
|
+
end
|
75
|
+
|
76
|
+
def post_add_content
|
77
|
+
# TODO avoid rendering unless args changed from initialize args (due to setting of piecemeal attributes)
|
78
|
+
render
|
79
|
+
end
|
80
|
+
|
81
|
+
def render(custom_parent_dom_element: nil, brand_new: false)
|
82
|
+
super(custom_parent_dom_element: nil, brand_new: false)
|
83
|
+
self.background = background
|
84
|
+
self.foreground = foreground
|
85
|
+
self.font = font
|
86
|
+
end
|
87
|
+
|
88
|
+
# parameter names for arguments to pass to SWT GC.xyz method for rendering shape (e.g. draw_image(image, x, y) yields :image, :x, :y parameter names)
|
89
|
+
def parameter_names
|
90
|
+
[:x, :y, :width, :height]
|
91
|
+
end
|
92
|
+
|
93
|
+
# subclasses may override to specify location parameter names if different from x and y (e.g. all polygon points are location parameters)
|
94
|
+
# used in calculating movement changes
|
95
|
+
def location_parameter_names
|
96
|
+
[:x, :y]
|
97
|
+
end
|
98
|
+
|
99
|
+
def possible_parameter_names
|
100
|
+
parameter_names
|
101
|
+
end
|
102
|
+
|
103
|
+
def parameter_name?(attribute_name)
|
104
|
+
possible_parameter_names.map(&:to_s).include?(attribute_getter(attribute_name))
|
105
|
+
end
|
106
|
+
|
107
|
+
def current_parameter_name?(attribute_name)
|
108
|
+
parameter_names.include?(attribute_name.to_s.to_sym)
|
109
|
+
end
|
110
|
+
|
111
|
+
def parameter_index(attribute_name)
|
112
|
+
parameter_names.index(attribute_name.to_s.to_sym)
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_parameter_attribute(attribute_name)
|
116
|
+
@args[parameter_index(attribute_getter(attribute_name))]
|
117
|
+
end
|
118
|
+
|
119
|
+
def set_parameter_attribute(attribute_name, *args)
|
120
|
+
@args[parameter_index(attribute_getter(attribute_name))] = args.size == 1 ? args.first : args
|
121
|
+
end
|
122
|
+
|
123
|
+
def has_attribute?(attribute_name, *args)
|
124
|
+
parameter_name?(attribute_name) or
|
125
|
+
(respond_to?(attribute_name, super: true) and respond_to?(attribute_setter(attribute_name), super: true))
|
126
|
+
end
|
127
|
+
|
128
|
+
def set_attribute(attribute_name, *args)
|
129
|
+
attribute_getter_name = attribute_getter(attribute_name)
|
130
|
+
attribute_setter_name = attribute_setter(attribute_name)
|
131
|
+
if parameter_name?(attribute_name)
|
132
|
+
return if attribute_getter_name == (args.size == 1 ? args.first : args)
|
133
|
+
set_parameter_attribute(attribute_getter_name, *args)
|
134
|
+
elsif (respond_to?(attribute_name, super: true) and respond_to?(attribute_setter_name, super: true))
|
135
|
+
return if self.send(attribute_getter_name) == (args.size == 1 ? args.first : args)
|
136
|
+
self.send(attribute_setter_name, *args)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def get_attribute(attribute_name)
|
141
|
+
if parameter_name?(attribute_name)
|
142
|
+
arg_index = parameter_index(attribute_name)
|
143
|
+
@args[arg_index] if arg_index
|
144
|
+
elsif (respond_to?(attribute_name, super: true) and respond_to?(attribute_setter(attribute_name), super: true))
|
145
|
+
self.send(attribute_name)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# TODO look why image is not working with the method_missing and respond_to? on shape
|
150
|
+
def method_missing(method_name, *args, &block)
|
151
|
+
if method_name.to_s.end_with?('=')
|
152
|
+
set_attribute(method_name, *args)
|
153
|
+
elsif has_attribute?(method_name) && args.empty?
|
154
|
+
get_attribute(method_name)
|
155
|
+
else # TODO support proxying calls to handle_observation_request for listeners just like WidgetProxy
|
156
|
+
super(method_name, *args, &block)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def respond_to?(method_name, *args, &block)
|
161
|
+
options = args.last if args.last.is_a?(Hash)
|
162
|
+
super_invocation = options && options[:super]
|
163
|
+
if !super_invocation && has_attribute?(method_name)
|
164
|
+
true
|
165
|
+
else
|
166
|
+
super(method_name, *args, &block)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def attach(the_parent_dom_element)
|
171
|
+
the_parent_dom_element.html("#{the_parent_dom_element.html()}\n#{@dom}")
|
172
|
+
end
|
173
|
+
|
174
|
+
def element
|
175
|
+
'g'
|
176
|
+
end
|
177
|
+
|
178
|
+
def dom
|
179
|
+
shape_id = id
|
180
|
+
shape_class = name
|
181
|
+
@dom ||= xml {
|
182
|
+
g(id: shape_id, class: shape_class) {
|
183
|
+
}
|
184
|
+
}.to_s
|
185
|
+
end
|
186
|
+
|
187
|
+
# TODO implement shape_at_location potentially with document.elementFromPoint(x, y);
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
require 'glimmer/swt/custom/shape/arc'
|
198
|
+
require 'glimmer/swt/custom/shape/image'
|
199
|
+
require 'glimmer/swt/custom/shape/line'
|
200
|
+
require 'glimmer/swt/custom/shape/oval'
|
201
|
+
require 'glimmer/swt/custom/shape/point'
|
202
|
+
require 'glimmer/swt/custom/shape/polygon'
|
203
|
+
require 'glimmer/swt/custom/shape/polyline'
|
204
|
+
require 'glimmer/swt/custom/shape/rectangle'
|
205
|
+
require 'glimmer/swt/custom/shape/text'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module SWT
|
3
|
+
# emulating org.eclipse.swt.graphics.Image
|
4
|
+
class ImageProxy
|
5
|
+
class << self
|
6
|
+
def create(*args, &content)
|
7
|
+
if args.size == 1 && args.first.is_a?(ImageProxy)
|
8
|
+
args.first
|
9
|
+
else
|
10
|
+
new(*args, &content)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :file_path, :width, :height
|
16
|
+
|
17
|
+
def initialize(*args)
|
18
|
+
options = args.last.is_a?(Hash) ? args.last : {}
|
19
|
+
# TODO support a parent as a first argument before the file path
|
20
|
+
@file_path = args.first
|
21
|
+
@width = options[:width]
|
22
|
+
@height = options[:height]
|
23
|
+
end
|
24
|
+
|
25
|
+
# TODO implement scale_to
|
26
|
+
end
|
27
|
+
# TODO alias as org.eclipse.swt.graphics.Image
|
28
|
+
end
|
29
|
+
end
|
@@ -198,6 +198,7 @@ module Glimmer
|
|
198
198
|
# delay this till all children rendered (perhaps post_add_content block)
|
199
199
|
parent_dom_element.css('position', 'relative')
|
200
200
|
parent_dom_element.css('margin-top', '30px')
|
201
|
+
parent_dom_element.css('height', '114%')
|
201
202
|
redraw
|
202
203
|
`$(#{path}).menu({
|
203
204
|
position: { my: "top", at: "bottom" },
|
@@ -222,7 +223,6 @@ module Glimmer
|
|
222
223
|
@visible = value
|
223
224
|
if @visible
|
224
225
|
parent.menu_requested = true
|
225
|
-
parent.dom_element.css('position', 'relative')
|
226
226
|
render
|
227
227
|
dom_element.css('position', 'absolute')
|
228
228
|
dom_element.css('left', parent.menu_x - parent.dom_element.offset.left)
|
data/lib/glimmer/swt/point.rb
CHANGED
@@ -30,7 +30,7 @@ module Glimmer
|
|
30
30
|
class WidgetProxy
|
31
31
|
include Glimmer
|
32
32
|
include PropertyOwner
|
33
|
-
|
33
|
+
|
34
34
|
Event = Struct.new(:widget, keyword_init: true)
|
35
35
|
|
36
36
|
JS_KEY_CODE_TO_SWT_KEY_CODE_MAP = {
|
@@ -295,6 +295,7 @@ module Glimmer
|
|
295
295
|
end
|
296
296
|
|
297
297
|
def font=(value)
|
298
|
+
return if value.nil?
|
298
299
|
@font = value.is_a?(FontProxy) ? value : FontProxy.new(self, value)
|
299
300
|
dom_element.css('font-family', @font.name) unless @font.nil?
|
300
301
|
dom_element.css('font-style', 'italic') if @font&.style == :italic || [@font&.style].flatten.compact.include?(:italic)
|
@@ -331,9 +332,10 @@ module Glimmer
|
|
331
332
|
brand_new = @dom.nil? || old_element.empty? || brand_new
|
332
333
|
build_dom(layout: !custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
|
333
334
|
if brand_new
|
334
|
-
|
335
|
+
# TODO make a method attach to allow subclasses to override if needed
|
336
|
+
attach(the_parent_dom_element)
|
335
337
|
else
|
336
|
-
old_element
|
338
|
+
reattach(old_element)
|
337
339
|
end
|
338
340
|
observation_requests&.each do |keyword, event_listener_set|
|
339
341
|
event_listener_set.each do |event_listener|
|
@@ -347,6 +349,14 @@ module Glimmer
|
|
347
349
|
content_on_render_blocks.each { |content_block| content(&content_block) } unless skip_content_on_render_blocks?
|
348
350
|
end
|
349
351
|
alias redraw render
|
352
|
+
|
353
|
+
def attach(the_parent_dom_element)
|
354
|
+
the_parent_dom_element.append(@dom)
|
355
|
+
end
|
356
|
+
|
357
|
+
def reattach(old_element)
|
358
|
+
old_element.replace_with(@dom)
|
359
|
+
end
|
350
360
|
|
351
361
|
def content_on_render_blocks
|
352
362
|
@content_on_render_blocks ||= []
|
@@ -367,7 +377,7 @@ module Glimmer
|
|
367
377
|
def build_dom(layout: true)
|
368
378
|
# TODO consider passing parent element instead and having table item include a table cell widget only for opal
|
369
379
|
@dom = nil
|
370
|
-
@dom = dom
|
380
|
+
@dom = dom # TODO unify how to build dom for most widgets based on element, id, and name (class)
|
371
381
|
@dom = @parent.get_layout.dom(@dom) if @parent.respond_to?(:layout) && @parent.get_layout
|
372
382
|
@dom
|
373
383
|
end
|
@@ -1143,6 +1153,7 @@ require 'glimmer/swt/combo_proxy'
|
|
1143
1153
|
require 'glimmer/swt/c_combo_proxy'
|
1144
1154
|
require 'glimmer/swt/checkbox_proxy'
|
1145
1155
|
require 'glimmer/swt/composite_proxy'
|
1156
|
+
require 'glimmer/swt/canvas_proxy'
|
1146
1157
|
require 'glimmer/swt/date_time_proxy'
|
1147
1158
|
require 'glimmer/swt/group_proxy'
|
1148
1159
|
require 'glimmer/swt/label_proxy'
|
@@ -25,10 +25,54 @@ class Tetris
|
|
25
25
|
include Glimmer::UI::CustomWidget
|
26
26
|
|
27
27
|
options :game_playfield, :block_size, :row, :column
|
28
|
+
|
29
|
+
attr_accessor :bevel_pixel_size
|
30
|
+
|
31
|
+
before_body do
|
32
|
+
self.bevel_pixel_size = 0.16*block_size.to_f
|
33
|
+
end
|
28
34
|
|
29
35
|
body {
|
30
36
|
canvas { |canvas_proxy|
|
31
37
|
background <= [game_playfield[row][column], :color]
|
38
|
+
polygon(0, 0, block_size, 0, block_size - bevel_pixel_size, bevel_pixel_size, bevel_pixel_size, bevel_pixel_size) {
|
39
|
+
background <= [game_playfield[row][column], :color, on_read: ->(color_value) {
|
40
|
+
unless color_value.nil?
|
41
|
+
color = color(color_value)
|
42
|
+
rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
43
|
+
end
|
44
|
+
}]
|
45
|
+
}
|
46
|
+
polygon(block_size, 0, block_size - bevel_pixel_size, bevel_pixel_size, block_size - bevel_pixel_size, block_size - bevel_pixel_size, block_size, block_size) {
|
47
|
+
background <= [game_playfield[row][column], :color, on_read: ->(color_value) {
|
48
|
+
unless color_value.nil?
|
49
|
+
color = color(color_value)
|
50
|
+
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
51
|
+
end
|
52
|
+
}]
|
53
|
+
}
|
54
|
+
polygon(block_size, block_size, 0, block_size, bevel_pixel_size, block_size - bevel_pixel_size, block_size - bevel_pixel_size, block_size - bevel_pixel_size) {
|
55
|
+
background <= [game_playfield[row][column], :color, on_read: ->(color_value) {
|
56
|
+
unless color_value.nil?
|
57
|
+
color = color(color_value)
|
58
|
+
rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
59
|
+
end
|
60
|
+
}]
|
61
|
+
}
|
62
|
+
polygon(0, 0, 0, block_size, bevel_pixel_size, block_size - bevel_pixel_size, bevel_pixel_size, bevel_pixel_size) {
|
63
|
+
background <= [game_playfield[row][column], :color, on_read: ->(color_value) {
|
64
|
+
unless color_value.nil?
|
65
|
+
color = color(color_value)
|
66
|
+
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
67
|
+
end
|
68
|
+
}]
|
69
|
+
}
|
70
|
+
rectangle(0, 0, block_size, block_size) {
|
71
|
+
foreground <= [game_playfield[row][column], :color, on_read: ->(color_value) {
|
72
|
+
color_value == Model::Block::COLOR_CLEAR ? :gray : color_value
|
73
|
+
}]
|
74
|
+
}
|
75
|
+
|
32
76
|
}
|
33
77
|
}
|
34
78
|
end
|