glimmer-dsl-opal 0.27.0 → 0.28.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|