glimmer-dsl-swt 4.18.6.2 → 4.18.7.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 +34 -0
- data/README.md +4 -4
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +64 -6
- data/docs/reference/GLIMMER_SAMPLES.md +71 -0
- data/glimmer-dsl-swt.gemspec +16 -6
- data/lib/glimmer/dsl/swt/animation_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/custom_shape_expression.rb +61 -0
- data/lib/glimmer/dsl/swt/custom_widget_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/dsl.rb +1 -0
- data/lib/glimmer/dsl/swt/expand_item_expression.rb +4 -4
- data/lib/glimmer/dsl/swt/image_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/multiply_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/shape_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/transform_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/widget_expression.rb +2 -1
- data/lib/glimmer/swt/custom/shape.rb +473 -180
- data/lib/glimmer/swt/custom/shape/image.rb +7 -9
- data/lib/glimmer/swt/custom/shape/path.rb +38 -29
- data/lib/glimmer/swt/custom/shape/path_segment.rb +21 -19
- data/lib/glimmer/swt/custom/shape/polygon.rb +24 -8
- data/lib/glimmer/swt/custom/shape/polyline.rb +5 -0
- data/lib/glimmer/swt/custom/shape/rectangle.rb +10 -19
- data/lib/glimmer/swt/display_proxy.rb +1 -1
- data/lib/glimmer/swt/message_box_proxy.rb +1 -1
- data/lib/glimmer/swt/shell_proxy.rb +1 -1
- data/lib/glimmer/swt/tab_folder_proxy.rb +52 -0
- data/lib/glimmer/swt/transform_proxy.rb +1 -1
- data/lib/glimmer/swt/widget_proxy.rb +1 -1
- data/lib/glimmer/ui/custom_shape.rb +281 -0
- data/samples/elaborate/meta_sample.rb +5 -5
- data/samples/elaborate/metronome.rb +177 -0
- data/samples/elaborate/stock_ticker.rb +0 -6
- data/samples/elaborate/tetris.rb +1 -12
- data/samples/elaborate/tetris/model/game.rb +3 -0
- data/samples/elaborate/tetris/view/bevel.rb +78 -0
- data/samples/elaborate/tetris/view/block.rb +6 -29
- data/samples/hello/hello_canvas.rb +3 -0
- data/samples/hello/hello_canvas_animation_data_binding.rb +66 -0
- data/samples/hello/hello_canvas_data_binding.rb +24 -3
- data/samples/hello/hello_canvas_path.rb +1 -1
- data/samples/hello/hello_custom_shape.rb +78 -0
- data/samples/hello/hello_shape.rb +71 -0
- data/samples/hello/hello_spinner.rb +7 -2
- data/sounds/metronome-down.wav +0 -0
- data/sounds/metronome-up.wav +0 -0
- metadata +14 -4
@@ -215,7 +215,7 @@ class MetaSampleApplication
|
|
215
215
|
|
216
216
|
expand_bar {
|
217
217
|
layout_data(:fill, :fill, true, true)
|
218
|
-
font height:
|
218
|
+
font height: 25
|
219
219
|
|
220
220
|
SampleDirectory.sample_directories.each { |sample_directory|
|
221
221
|
expand_item {
|
@@ -227,7 +227,7 @@ class MetaSampleApplication
|
|
227
227
|
fill true
|
228
228
|
}
|
229
229
|
selection bind(sample_directory, :selected_sample_name)
|
230
|
-
font height:
|
230
|
+
font height: 20
|
231
231
|
}
|
232
232
|
}
|
233
233
|
}
|
@@ -236,12 +236,12 @@ class MetaSampleApplication
|
|
236
236
|
composite {
|
237
237
|
fill_layout
|
238
238
|
layout_data(:fill, :center, true, false) {
|
239
|
-
height_hint
|
239
|
+
height_hint 96
|
240
240
|
}
|
241
241
|
|
242
242
|
button {
|
243
243
|
text 'Launch'
|
244
|
-
font height:
|
244
|
+
font height: 25
|
245
245
|
enabled bind(SampleDirectory, 'selected_sample.launchable')
|
246
246
|
|
247
247
|
on_widget_selected {
|
@@ -254,7 +254,7 @@ class MetaSampleApplication
|
|
254
254
|
}
|
255
255
|
button {
|
256
256
|
text 'Reset'
|
257
|
-
font height:
|
257
|
+
font height: 25
|
258
258
|
enabled bind(SampleDirectory, 'selected_sample.editable')
|
259
259
|
|
260
260
|
on_widget_selected {
|
@@ -0,0 +1,177 @@
|
|
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-dsl-swt'
|
23
|
+
|
24
|
+
class Metronome
|
25
|
+
class Beat
|
26
|
+
attr_accessor :on
|
27
|
+
|
28
|
+
def off!
|
29
|
+
self.on = false
|
30
|
+
end
|
31
|
+
|
32
|
+
def on!
|
33
|
+
self.on = true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Rhythm
|
38
|
+
attr_reader :beat_count
|
39
|
+
attr_accessor :beats, :bpm
|
40
|
+
|
41
|
+
def initialize(beat_count)
|
42
|
+
self.beat_count = beat_count
|
43
|
+
@bpm = 120
|
44
|
+
end
|
45
|
+
|
46
|
+
def beat_count=(value)
|
47
|
+
@beat_count = value
|
48
|
+
reset_beats!
|
49
|
+
end
|
50
|
+
|
51
|
+
def reset_beats!
|
52
|
+
@beats = beat_count.times.map {Beat.new}
|
53
|
+
@beats.first.on!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
include Glimmer::UI::CustomShell
|
58
|
+
|
59
|
+
import 'javax.sound.sampled'
|
60
|
+
|
61
|
+
GEM_ROOT = File.expand_path(File.join('..', '..'), __dir__)
|
62
|
+
FILE_SOUND_METRONOME_UP = File.join(GEM_ROOT, 'sounds', 'metronome-up.wav')
|
63
|
+
FILE_SOUND_METRONOME_DOWN = File.join(GEM_ROOT, 'sounds', 'metronome-down.wav')
|
64
|
+
|
65
|
+
attr_accessor :rhythm
|
66
|
+
|
67
|
+
before_body {
|
68
|
+
@rhythm = Rhythm.new(4)
|
69
|
+
}
|
70
|
+
|
71
|
+
body {
|
72
|
+
shell {
|
73
|
+
row_layout(:vertical) {
|
74
|
+
center true
|
75
|
+
}
|
76
|
+
text 'Glimmer Metronome'
|
77
|
+
|
78
|
+
label {
|
79
|
+
text 'Beat Count'
|
80
|
+
font height: 30, style: :bold
|
81
|
+
}
|
82
|
+
|
83
|
+
spinner {
|
84
|
+
minimum 1
|
85
|
+
maximum 64
|
86
|
+
selection bind(self, 'rhythm.beat_count', after_write: ->(v) {restart_metronome})
|
87
|
+
font height: 30
|
88
|
+
}
|
89
|
+
|
90
|
+
label {
|
91
|
+
text 'BPM'
|
92
|
+
font height: 30, style: :bold
|
93
|
+
}
|
94
|
+
|
95
|
+
spinner {
|
96
|
+
minimum 30
|
97
|
+
maximum 1000
|
98
|
+
selection bind(self, 'rhythm.bpm')
|
99
|
+
font height: 30
|
100
|
+
}
|
101
|
+
|
102
|
+
@beat_container = beat_container
|
103
|
+
|
104
|
+
on_swt_show {
|
105
|
+
start_metronome
|
106
|
+
}
|
107
|
+
|
108
|
+
on_widget_disposed {
|
109
|
+
stop_metronome
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
def beat_container
|
115
|
+
composite {
|
116
|
+
grid_layout(@rhythm.beat_count, true)
|
117
|
+
|
118
|
+
@rhythm.beat_count.times { |n|
|
119
|
+
canvas {
|
120
|
+
layout_data {
|
121
|
+
width_hint 50
|
122
|
+
height_hint 50
|
123
|
+
}
|
124
|
+
rectangle(0, 0, :default, :default, 36, 36) {
|
125
|
+
background bind(self, "rhythm.beats[#{n}].on") {|on| on ? :red : :yellow}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
def start_metronome
|
133
|
+
@thread ||= Thread.new {
|
134
|
+
@rhythm.beat_count.times.cycle { |n|
|
135
|
+
sleep(60.0/@rhythm.bpm.to_f)
|
136
|
+
@rhythm.beats.each(&:off!)
|
137
|
+
@rhythm.beats[n].on!
|
138
|
+
sound_file = n == 0 ? FILE_SOUND_METRONOME_UP : FILE_SOUND_METRONOME_DOWN
|
139
|
+
play_sound(sound_file)
|
140
|
+
}
|
141
|
+
}
|
142
|
+
if @beat_container.nil?
|
143
|
+
body_root.content {
|
144
|
+
@beat_container = beat_container
|
145
|
+
}
|
146
|
+
body_root.layout(true, true)
|
147
|
+
body_root.pack(true)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def stop_metronome
|
152
|
+
@thread&.kill # safe since no stored data is involved
|
153
|
+
@thread = nil
|
154
|
+
@beat_container&.dispose
|
155
|
+
@beat_container = nil
|
156
|
+
end
|
157
|
+
|
158
|
+
def restart_metronome
|
159
|
+
stop_metronome
|
160
|
+
start_metronome
|
161
|
+
end
|
162
|
+
|
163
|
+
# Play sound with the Java Sound library
|
164
|
+
def play_sound(sound_file)
|
165
|
+
begin
|
166
|
+
file_or_stream = java.io.File.new(sound_file)
|
167
|
+
audio_stream = AudioSystem.get_audio_input_stream(file_or_stream)
|
168
|
+
clip = AudioSystem.clip
|
169
|
+
clip.open(audio_stream)
|
170
|
+
clip.start
|
171
|
+
rescue => e
|
172
|
+
puts e.full_message
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
Metronome.launch
|
@@ -146,7 +146,6 @@ class StockTicker
|
|
146
146
|
text 'Stock Ticker'
|
147
147
|
minimum_size 650, 650
|
148
148
|
background :white
|
149
|
-
|
150
149
|
@tab_folder = tab_folder {
|
151
150
|
@tabs.each do |tab|
|
152
151
|
tab_item {
|
@@ -202,11 +201,6 @@ class StockTicker
|
|
202
201
|
on_swt_show {
|
203
202
|
Stock.price_min = 25
|
204
203
|
Stock.price_max = @tabs.first[:canvas].bounds.height - 6
|
205
|
-
# pre-initialize all tabs by selecting them so that they render content when they are later in the background
|
206
|
-
@tab_folder.items.each do |item|
|
207
|
-
@tab_folder.selection = item
|
208
|
-
end
|
209
|
-
@tab_folder.selection = @tab_folder.items.first
|
210
204
|
}
|
211
205
|
|
212
206
|
on_widget_disposed {
|
data/samples/elaborate/tetris.rb
CHANGED
@@ -158,18 +158,7 @@ class Tetris
|
|
158
158
|
y = row * icon_block_size
|
159
159
|
rectangle(x, y, icon_block_size, icon_block_size) {
|
160
160
|
background color
|
161
|
-
|
162
|
-
polygon(x, y, x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
163
|
-
background rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
164
|
-
}
|
165
|
-
polygon(x + icon_block_size, y, x + icon_block_size - icon_bevel_pixel_size, y + icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size, y + icon_block_size) {
|
166
|
-
background rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
167
|
-
}
|
168
|
-
polygon(x + icon_block_size, y + icon_block_size, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_block_size - icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size) {
|
169
|
-
background rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
170
|
-
}
|
171
|
-
polygon(x, y, x, y + icon_block_size, x + icon_bevel_pixel_size, y + icon_block_size - icon_bevel_pixel_size, x + icon_bevel_pixel_size, y + icon_bevel_pixel_size) {
|
172
|
-
background rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
161
|
+
bevel(base_color: color, size: icon_block_size)
|
173
162
|
}
|
174
163
|
}
|
175
164
|
}
|
@@ -33,6 +33,8 @@ class Tetris
|
|
33
33
|
class Game
|
34
34
|
PLAYFIELD_WIDTH = 10
|
35
35
|
PLAYFIELD_HEIGHT = 20
|
36
|
+
# PLAYFIELD_WIDTH = 5
|
37
|
+
# PLAYFIELD_HEIGHT = 5
|
36
38
|
PREVIEW_PLAYFIELD_WIDTH = 4
|
37
39
|
PREVIEW_PLAYFIELD_HEIGHT = 2
|
38
40
|
SCORE_MULTIPLIER = {1 => 40, 2 => 100, 3 => 300, 4 => 1200}
|
@@ -199,6 +201,7 @@ class Tetris
|
|
199
201
|
|
200
202
|
def delay
|
201
203
|
[1.1 - (level.to_i * 0.1), 0.001].max
|
204
|
+
# 99999
|
202
205
|
end
|
203
206
|
|
204
207
|
def beep
|
@@ -0,0 +1,78 @@
|
|
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
|
+
# Creates a class-based custom shape representing the `bevel` keyword by convention
|
23
|
+
class Tetris
|
24
|
+
module View
|
25
|
+
class Bevel
|
26
|
+
include Glimmer::UI::CustomShape
|
27
|
+
|
28
|
+
options :base_color, :size, :bevel_pixel_size
|
29
|
+
|
30
|
+
before_body {
|
31
|
+
self.bevel_pixel_size = 0.16*size.to_f if bevel_pixel_size.nil?
|
32
|
+
}
|
33
|
+
|
34
|
+
body {
|
35
|
+
shape(0, 0, size, size) {
|
36
|
+
polygon(0, 0, size, 0, size - bevel_pixel_size, bevel_pixel_size, bevel_pixel_size, bevel_pixel_size) {
|
37
|
+
background bind(self, :base_color) { |color_value|
|
38
|
+
unless color_value.nil?
|
39
|
+
color = color(color_value)
|
40
|
+
rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
41
|
+
end
|
42
|
+
}
|
43
|
+
}
|
44
|
+
polygon(size, 0, size - bevel_pixel_size, bevel_pixel_size, size - bevel_pixel_size, size - bevel_pixel_size, size, size) {
|
45
|
+
background bind(self, :base_color) { |color_value|
|
46
|
+
unless color_value.nil?
|
47
|
+
color = color(color_value)
|
48
|
+
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
49
|
+
end
|
50
|
+
}
|
51
|
+
}
|
52
|
+
polygon(size, size, 0, size, bevel_pixel_size, size - bevel_pixel_size, size - bevel_pixel_size, size - bevel_pixel_size) {
|
53
|
+
background bind(self, :base_color) { |color_value|
|
54
|
+
unless color_value.nil?
|
55
|
+
color = color(color_value)
|
56
|
+
rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
57
|
+
end
|
58
|
+
}
|
59
|
+
}
|
60
|
+
polygon(0, 0, 0, size, bevel_pixel_size, size - bevel_pixel_size, bevel_pixel_size, bevel_pixel_size) {
|
61
|
+
background bind(self, :base_color) { |color_value|
|
62
|
+
unless color_value.nil?
|
63
|
+
color = color(color_value)
|
64
|
+
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
65
|
+
end
|
66
|
+
}
|
67
|
+
}
|
68
|
+
rectangle(0, 0, size, size) {
|
69
|
+
foreground bind(self, :base_color) { |color_value|
|
70
|
+
# use gray instead of white for the border
|
71
|
+
color_value == Model::Block::COLOR_CLEAR ? :gray : color_value
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -19,6 +19,8 @@
|
|
19
19
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
|
+
require_relative 'bevel'
|
23
|
+
|
22
24
|
class Tetris
|
23
25
|
module View
|
24
26
|
class Block
|
@@ -27,36 +29,11 @@ class Tetris
|
|
27
29
|
options :game_playfield, :block_size, :row, :column
|
28
30
|
|
29
31
|
body {
|
30
|
-
canvas {
|
32
|
+
canvas { |canvas_proxy|
|
31
33
|
background bind(game_playfield[row][column], :color)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
36
|
-
}
|
37
|
-
}
|
38
|
-
polygon(block_size, 0, block_size - 4, 4, block_size - 4, block_size - 4, block_size, block_size) {
|
39
|
-
background bind(game_playfield[row][column], :color) { |color_value|
|
40
|
-
color = color(color_value)
|
41
|
-
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
42
|
-
}
|
43
|
-
}
|
44
|
-
polygon(block_size, block_size, 0, block_size, 4, block_size - 4, block_size - 4, block_size - 4) {
|
45
|
-
background bind(game_playfield[row][column], :color) { |color_value|
|
46
|
-
color = color(color_value)
|
47
|
-
rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
48
|
-
}
|
49
|
-
}
|
50
|
-
polygon(0, 0, 0, block_size, 4, block_size - 4, 4, 4) {
|
51
|
-
background bind(game_playfield[row][column], :color) { |color_value|
|
52
|
-
color = color(color_value)
|
53
|
-
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
54
|
-
}
|
55
|
-
}
|
56
|
-
rectangle(0, 0, block_size, block_size) {
|
57
|
-
foreground bind(game_playfield[row][column], :color) { |color_value|
|
58
|
-
color_value == Model::Block::COLOR_CLEAR ? :gray : color_value
|
59
|
-
}
|
34
|
+
|
35
|
+
bevel(base_color: game_playfield[row][column].color, size: block_size) {
|
36
|
+
base_color bind(game_playfield[row][column], :color)
|
60
37
|
}
|
61
38
|
}
|
62
39
|
}
|
@@ -53,6 +53,9 @@ class HelloCanvas
|
|
53
53
|
}
|
54
54
|
rectangle(50, 20, 300, 150, 30, 50) {
|
55
55
|
background :magenta
|
56
|
+
rectangle(:default, :default, :max, :max, 30, 50) {
|
57
|
+
foreground :yellow
|
58
|
+
}
|
56
59
|
rectangle([:default, -70], :default, :default, [:default, 1]) {
|
57
60
|
foreground :cyan
|
58
61
|
text {
|
@@ -0,0 +1,66 @@
|
|
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-dsl-swt'
|
23
|
+
require 'bigdecimal'
|
24
|
+
|
25
|
+
class HelloAnimationDataBinding
|
26
|
+
include Glimmer::UI::CustomShell
|
27
|
+
|
28
|
+
attr_accessor :delay_time
|
29
|
+
|
30
|
+
before_body {
|
31
|
+
@delay_time = 0.050
|
32
|
+
}
|
33
|
+
|
34
|
+
body {
|
35
|
+
shell {
|
36
|
+
text 'Hello, Canvas Animation Data Binding!'
|
37
|
+
minimum_size 320, 320
|
38
|
+
|
39
|
+
canvas {
|
40
|
+
grid_layout
|
41
|
+
|
42
|
+
spinner {
|
43
|
+
layout_data(:center, :center, true, true) {
|
44
|
+
minimum_width 75
|
45
|
+
}
|
46
|
+
digits 3
|
47
|
+
minimum 1
|
48
|
+
maximum 100
|
49
|
+
selection bind(self, :delay_time, on_read: ->(v) {(BigDecimal(v.to_s)*1000).to_f}, on_write: ->(v) {(BigDecimal(v.to_s)/1000).to_f})
|
50
|
+
}
|
51
|
+
animation {
|
52
|
+
every bind(self, :delay_time)
|
53
|
+
|
54
|
+
frame { |index|
|
55
|
+
background rgb(index%100, index%100 + 100, index%55 + 200)
|
56
|
+
oval(index*3%300, index*3%300, 20, 20) {
|
57
|
+
background :yellow
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
HelloAnimationDataBinding.launch
|