glimmer-dsl-swt 4.18.3.3 → 4.18.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +55 -0
- data/README.md +673 -325
- data/VERSION +1 -1
- data/glimmer-dsl-swt.gemspec +8 -3
- data/lib/ext/rouge/themes/glimmer.rb +29 -0
- data/lib/glimmer-dsl-swt.rb +0 -1
- data/lib/glimmer/data_binding/widget_binding.rb +1 -1
- data/lib/glimmer/dsl/swt/image_expression.rb +14 -6
- data/lib/glimmer/dsl/swt/layout_data_expression.rb +4 -4
- data/lib/glimmer/dsl/swt/layout_expression.rb +5 -3
- data/lib/glimmer/swt/custom/code_text.rb +200 -51
- data/lib/glimmer/swt/custom/drawable.rb +4 -6
- data/lib/glimmer/swt/custom/shape.rb +69 -12
- data/lib/glimmer/swt/date_time_proxy.rb +1 -3
- data/lib/glimmer/swt/display_proxy.rb +11 -0
- data/lib/glimmer/swt/font_proxy.rb +1 -0
- data/lib/glimmer/swt/image_proxy.rb +79 -1
- data/lib/glimmer/swt/layout_proxy.rb +4 -1
- data/lib/glimmer/swt/shell_proxy.rb +3 -0
- data/lib/glimmer/swt/table_proxy.rb +17 -13
- data/lib/glimmer/swt/widget_proxy.rb +12 -4
- data/lib/glimmer/ui/custom_widget.rb +2 -2
- data/samples/elaborate/meta_sample.rb +15 -4
- data/samples/elaborate/meta_sample/meta_sample_logo.png +0 -0
- data/samples/elaborate/tetris.rb +45 -6
- data/samples/elaborate/tetris/model/game.rb +30 -5
- data/samples/elaborate/tetris/model/past_game.rb +14 -1
- data/samples/elaborate/tetris/model/tetromino.rb +2 -2
- data/samples/elaborate/tetris/view/block.rb +8 -13
- data/samples/elaborate/tetris/view/high_score_dialog.rb +1 -10
- data/samples/elaborate/tetris/view/playfield.rb +1 -1
- data/samples/elaborate/tetris/view/tetris_menu_bar.rb +18 -0
- data/samples/hello/hello_canvas.rb +10 -9
- data/samples/hello/hello_canvas_animation.rb +5 -5
- data/samples/hello/hello_canvas_transform.rb +1 -1
- data/samples/hello/hello_canvas_transform/hello_canvas_transform_image.png +0 -0
- data/samples/hello/hello_code_text.rb +104 -0
- data/samples/hello/hello_table.rb +7 -4
- data/samples/hello/hello_table/baseball_park.png +0 -0
- metadata +7 -2
@@ -163,8 +163,8 @@ module Glimmer
|
|
163
163
|
attr_reader :body_root, :swt_widget, :parent, :parent_proxy, :swt_style, :options
|
164
164
|
|
165
165
|
def initialize(parent, *swt_constants, options, &content)
|
166
|
-
@parent = parent
|
167
|
-
@parent_proxy = @parent&.get_data('proxy')
|
166
|
+
@parent_proxy = @parent = parent
|
167
|
+
@parent_proxy = @parent&.get_data('proxy') if @parent.respond_to?(:get_data) && @parent.get_data('proxy')
|
168
168
|
@swt_style = SWT::SWTProxy[*swt_constants]
|
169
169
|
options ||= {}
|
170
170
|
@options = self.class.options.merge(options)
|
@@ -20,7 +20,6 @@
|
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
22
|
require 'fileutils'
|
23
|
-
require 'etc'
|
24
23
|
|
25
24
|
class Sample
|
26
25
|
include Glimmer::DataBinding::ObservableModel
|
@@ -31,7 +30,7 @@ class Sample
|
|
31
30
|
end
|
32
31
|
|
33
32
|
def user_glimmer_directory
|
34
|
-
File.join(
|
33
|
+
File.join(File.expand_path('~'), '.glimmer-dsl-swt')
|
35
34
|
end
|
36
35
|
|
37
36
|
def ensure_user_glimmer_directory
|
@@ -204,7 +203,7 @@ class MetaSampleApplication
|
|
204
203
|
shell(:fill_screen) {
|
205
204
|
minimum_size 1280, 768
|
206
205
|
text 'Glimmer Meta-Sample (The Sample of Samples)'
|
207
|
-
image File.expand_path('
|
206
|
+
image File.expand_path('meta_sample/meta_sample_logo.png', __dir__)
|
208
207
|
|
209
208
|
sash_form {
|
210
209
|
composite {
|
@@ -264,9 +263,21 @@ class MetaSampleApplication
|
|
264
263
|
}
|
265
264
|
}
|
266
265
|
|
267
|
-
@code_text = code_text {
|
266
|
+
@code_text = code_text(lines: {width: 3}) {
|
267
|
+
root {
|
268
|
+
grid_layout(2, false) {
|
269
|
+
horizontal_spacing 0
|
270
|
+
margin_width 0
|
271
|
+
margin_height 0
|
272
|
+
}
|
273
|
+
}
|
274
|
+
line_numbers {
|
275
|
+
background :white
|
276
|
+
}
|
268
277
|
text bind(SampleDirectory, 'selected_sample.code', read_only: true)
|
269
278
|
editable bind(SampleDirectory, 'selected_sample.editable')
|
279
|
+
left_margin 7
|
280
|
+
right_margin 7
|
270
281
|
}
|
271
282
|
|
272
283
|
weights 4, 11
|
Binary file
|
data/samples/elaborate/tetris.rb
CHANGED
@@ -35,6 +35,7 @@ class Tetris
|
|
35
35
|
FONT_NAME = 'Menlo'
|
36
36
|
FONT_TITLE_HEIGHT = 32
|
37
37
|
FONT_TITLE_STYLE = :bold
|
38
|
+
BEVEL_CONSTANT = 20
|
38
39
|
|
39
40
|
option :playfield_width, default: Model::Game::PLAYFIELD_WIDTH
|
40
41
|
option :playfield_height, default: Model::Game::PLAYFIELD_HEIGHT
|
@@ -56,19 +57,24 @@ class Tetris
|
|
56
57
|
when swt(:arrow_down), 's'.bytes.first
|
57
58
|
game.down!
|
58
59
|
when swt(:arrow_up)
|
59
|
-
game.
|
60
|
+
case game.up_arrow_action
|
61
|
+
when :instant_down
|
62
|
+
game.down!(instant: true)
|
63
|
+
when :rotate_right
|
64
|
+
game.rotate!(:right)
|
65
|
+
when :rotate_left
|
66
|
+
game.rotate!(:left)
|
67
|
+
end
|
60
68
|
when swt(:arrow_left), 'a'.bytes.first
|
61
69
|
game.left!
|
62
70
|
when swt(:arrow_right), 'd'.bytes.first
|
63
71
|
game.right!
|
64
|
-
when swt(:shift), swt(:alt)
|
72
|
+
when swt(:shift), swt(:alt), swt(:ctrl)
|
65
73
|
if key_event.keyLocation == swt(:right) # right shift key
|
66
74
|
game.rotate!(:right)
|
67
75
|
elsif key_event.keyLocation == swt(:left) # left shift key
|
68
76
|
game.rotate!(:left)
|
69
77
|
end
|
70
|
-
when swt(:ctrl)
|
71
|
-
game.rotate!(:left)
|
72
78
|
end
|
73
79
|
}
|
74
80
|
|
@@ -110,10 +116,10 @@ class Tetris
|
|
110
116
|
margin_height 0
|
111
117
|
horizontal_spacing 0
|
112
118
|
}
|
113
|
-
|
119
|
+
|
114
120
|
text 'Glimmer Tetris'
|
115
121
|
minimum_size 475, 500
|
116
|
-
|
122
|
+
image tetris_icon
|
117
123
|
|
118
124
|
tetris_menu_bar(game: game)
|
119
125
|
|
@@ -129,6 +135,39 @@ class Tetris
|
|
129
135
|
}
|
130
136
|
}
|
131
137
|
|
138
|
+
def tetris_icon
|
139
|
+
icon_block_size = 64
|
140
|
+
icon_bevel_size = icon_block_size.to_f / 25.to_f
|
141
|
+
icon_bevel_pixel_size = 0.16*icon_block_size.to_f
|
142
|
+
icon_size = 8
|
143
|
+
icon_pixel_size = icon_block_size * icon_size
|
144
|
+
image(icon_pixel_size, icon_pixel_size) {
|
145
|
+
icon_size.times { |row|
|
146
|
+
icon_size.times { |column|
|
147
|
+
colored = row >= 1 && column.between?(1, 6)
|
148
|
+
color = colored ? color(([:white] + Model::Tetromino::LETTER_COLORS.values).sample) : color(:white)
|
149
|
+
x = column * icon_block_size
|
150
|
+
y = row * icon_block_size
|
151
|
+
rectangle(x, y, icon_block_size, icon_block_size, fill: true) {
|
152
|
+
background color
|
153
|
+
}
|
154
|
+
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, fill: true) {
|
155
|
+
background rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
156
|
+
}
|
157
|
+
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, fill: true) {
|
158
|
+
background rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
159
|
+
}
|
160
|
+
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, fill: true) {
|
161
|
+
background rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
162
|
+
}
|
163
|
+
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, fill: true) {
|
164
|
+
background rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
165
|
+
}
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
end
|
170
|
+
|
132
171
|
def start_moving_tetrominos_down
|
133
172
|
Thread.new do
|
134
173
|
@mutex.synchronize do
|
@@ -20,7 +20,7 @@
|
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
22
|
require 'fileutils'
|
23
|
-
require '
|
23
|
+
require 'json'
|
24
24
|
require 'glimmer/data_binding/observer'
|
25
25
|
require 'glimmer/config'
|
26
26
|
|
@@ -38,7 +38,7 @@ class Tetris
|
|
38
38
|
SCORE_MULTIPLIER = {1 => 40, 2 => 100, 3 => 300, 4 => 1200}
|
39
39
|
|
40
40
|
attr_reader :playfield_width, :playfield_height
|
41
|
-
attr_accessor :game_over, :paused, :preview_tetromino, :lines, :score, :level, :high_scores, :beeping, :added_high_score, :show_high_scores
|
41
|
+
attr_accessor :game_over, :paused, :preview_tetromino, :lines, :score, :level, :high_scores, :beeping, :added_high_score, :show_high_scores, :up_arrow_action
|
42
42
|
alias game_over? game_over
|
43
43
|
alias paused? paused
|
44
44
|
alias beeping? beeping
|
@@ -50,6 +50,7 @@ class Tetris
|
|
50
50
|
@high_scores = []
|
51
51
|
@show_high_scores = false
|
52
52
|
@beeping = true
|
53
|
+
@up_arrow_action = :rotate_left
|
53
54
|
load_high_scores!
|
54
55
|
end
|
55
56
|
|
@@ -110,16 +111,16 @@ class Tetris
|
|
110
111
|
end
|
111
112
|
|
112
113
|
def tetris_dir
|
113
|
-
@tetris_dir ||= File.join(
|
114
|
+
@tetris_dir ||= File.join(File.expand_path('~'), '.glimmer-tetris')
|
114
115
|
end
|
115
116
|
|
116
117
|
def tetris_high_score_file
|
117
118
|
File.join(tetris_dir, "high_scores.txt")
|
118
119
|
end
|
119
120
|
|
120
|
-
def down!(
|
121
|
+
def down!(instant: false)
|
121
122
|
return unless game_in_progress?
|
122
|
-
current_tetromino.down!(
|
123
|
+
current_tetromino.down!(instant: instant)
|
123
124
|
game_over! if current_tetromino.row <= 0 && current_tetromino.stopped?
|
124
125
|
end
|
125
126
|
|
@@ -204,6 +205,30 @@ class Tetris
|
|
204
205
|
@beeper&.call if beeping
|
205
206
|
end
|
206
207
|
|
208
|
+
def instant_down_on_up=(value)
|
209
|
+
self.up_arrow_action = :instant_down if value
|
210
|
+
end
|
211
|
+
|
212
|
+
def instant_down_on_up
|
213
|
+
self.up_arrow_action == :instant_down
|
214
|
+
end
|
215
|
+
|
216
|
+
def rotate_right_on_up=(value)
|
217
|
+
self.up_arrow_action = :rotate_right if value
|
218
|
+
end
|
219
|
+
|
220
|
+
def rotate_right_on_up
|
221
|
+
self.up_arrow_action == :rotate_right
|
222
|
+
end
|
223
|
+
|
224
|
+
def rotate_left_on_up=(value)
|
225
|
+
self.up_arrow_action = :rotate_left if value
|
226
|
+
end
|
227
|
+
|
228
|
+
def rotate_left_on_up
|
229
|
+
self.up_arrow_action == :rotate_left
|
230
|
+
end
|
231
|
+
|
207
232
|
def reset_tetrominoes
|
208
233
|
@tetrominoes = []
|
209
234
|
end
|
@@ -21,6 +21,19 @@
|
|
21
21
|
|
22
22
|
class Tetris
|
23
23
|
module Model
|
24
|
-
PastGame
|
24
|
+
class PastGame
|
25
|
+
attr_accessor :name, :score, :lines, :level
|
26
|
+
|
27
|
+
def initialize(name, score, lines, level)
|
28
|
+
@name = name
|
29
|
+
@score = score.to_i
|
30
|
+
@lines = lines.to_i
|
31
|
+
@level = level.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_a
|
35
|
+
[@name, @score, @lines, @level]
|
36
|
+
end
|
37
|
+
end
|
25
38
|
end
|
26
39
|
end
|
@@ -182,11 +182,11 @@ class Tetris
|
|
182
182
|
@blocks.size
|
183
183
|
end
|
184
184
|
|
185
|
-
def down!(
|
185
|
+
def down!(instant: false)
|
186
186
|
launch! if preview?
|
187
187
|
unless stopped?
|
188
188
|
block_count = 1
|
189
|
-
if
|
189
|
+
if instant
|
190
190
|
remaining_height, bottom_touching_block = remaining_height_and_bottom_touching_block
|
191
191
|
block_count = remaining_height - @row
|
192
192
|
end
|
@@ -26,36 +26,31 @@ class Tetris
|
|
26
26
|
|
27
27
|
options :game_playfield, :block_size, :row, :column
|
28
28
|
|
29
|
-
before_body {
|
30
|
-
@bevel_constant = 20
|
31
|
-
}
|
32
|
-
|
33
29
|
body {
|
34
30
|
canvas {
|
35
|
-
layout nil
|
36
31
|
background bind(game_playfield[row][column], :color)
|
37
|
-
polygon(0, 0, block_size, 0, block_size - 4, 4, 4, 4
|
32
|
+
polygon(0, 0, block_size, 0, block_size - 4, 4, 4, 4) {
|
38
33
|
background bind(game_playfield[row][column], :color) { |color_value|
|
39
34
|
color = color(color_value)
|
40
|
-
rgb(color.red + 4
|
35
|
+
rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
41
36
|
}
|
42
37
|
}
|
43
|
-
polygon(block_size, 0, block_size - 4, 4, block_size - 4, block_size - 4, block_size, block_size
|
38
|
+
polygon(block_size, 0, block_size - 4, 4, block_size - 4, block_size - 4, block_size, block_size) {
|
44
39
|
background bind(game_playfield[row][column], :color) { |color_value|
|
45
40
|
color = color(color_value)
|
46
|
-
rgb(color.red -
|
41
|
+
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
47
42
|
}
|
48
43
|
}
|
49
|
-
polygon(block_size, block_size, 0, block_size, 4, block_size - 4, block_size - 4, block_size - 4
|
44
|
+
polygon(block_size, block_size, 0, block_size, 4, block_size - 4, block_size - 4, block_size - 4) {
|
50
45
|
background bind(game_playfield[row][column], :color) { |color_value|
|
51
46
|
color = color(color_value)
|
52
|
-
rgb(color.red - 2
|
47
|
+
rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
53
48
|
}
|
54
49
|
}
|
55
|
-
polygon(0, 0, 0, block_size, 4, block_size - 4, 4, 4
|
50
|
+
polygon(0, 0, 0, block_size, 4, block_size - 4, 4, 4) {
|
56
51
|
background bind(game_playfield[row][column], :color) { |color_value|
|
57
52
|
color = color(color_value)
|
58
|
-
rgb(color.red -
|
53
|
+
rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
59
54
|
}
|
60
55
|
}
|
61
56
|
rectangle(0, 0, block_size, block_size) {
|
@@ -71,13 +71,6 @@ class Tetris
|
|
71
71
|
composite {
|
72
72
|
row_layout :horizontal
|
73
73
|
|
74
|
-
button {
|
75
|
-
text 'Clear'
|
76
|
-
|
77
|
-
on_widget_selected {
|
78
|
-
game.clear_high_scores!
|
79
|
-
}
|
80
|
-
}
|
81
74
|
@play_close_button = button {
|
82
75
|
text bind(game, :game_over) {|game_over| game_over ? 'Play Again?' : 'Close'}
|
83
76
|
focus true # initial focus
|
@@ -99,13 +92,11 @@ class Tetris
|
|
99
92
|
@high_score_table.edit_table_item(
|
100
93
|
@high_score_table.items.first, # row item
|
101
94
|
0, # column
|
95
|
+
write_on_cancel: true,
|
102
96
|
after_write: -> {
|
103
97
|
game.save_high_scores!
|
104
98
|
@play_close_button.set_focus
|
105
99
|
},
|
106
|
-
after_cancel: -> {
|
107
|
-
@play_close_button.set_focus
|
108
|
-
},
|
109
100
|
)
|
110
101
|
end
|
111
102
|
}
|
@@ -94,6 +94,24 @@ class Tetris
|
|
94
94
|
accelerator :command, :b
|
95
95
|
selection bind(game, :beeping)
|
96
96
|
}
|
97
|
+
menu {
|
98
|
+
text 'Up Arrow'
|
99
|
+
menu_item(:radio) {
|
100
|
+
text '&Instant Down'
|
101
|
+
accelerator :command, :shift, :i
|
102
|
+
selection bind(game, :instant_down_on_up, computed_by: :up_arrow_action)
|
103
|
+
}
|
104
|
+
menu_item(:radio) {
|
105
|
+
text 'Rotate &Right'
|
106
|
+
accelerator :command, :shift, :r
|
107
|
+
selection bind(game, :rotate_right_on_up, computed_by: :up_arrow_action)
|
108
|
+
}
|
109
|
+
menu_item(:radio) {
|
110
|
+
text 'Rotate &Left'
|
111
|
+
accelerator :command, :shift, :l
|
112
|
+
selection bind(game, :rotate_left_on_up, computed_by: :up_arrow_action)
|
113
|
+
}
|
114
|
+
}
|
97
115
|
} # end of menu
|
98
116
|
|
99
117
|
menu {
|
@@ -22,22 +22,22 @@
|
|
22
22
|
include Glimmer
|
23
23
|
|
24
24
|
shell {
|
25
|
-
text 'Hello, Canvas!'
|
25
|
+
text 'Hello, Canvas Image Icon!'
|
26
26
|
minimum_size 320, 400
|
27
27
|
|
28
28
|
canvas {
|
29
29
|
background :yellow
|
30
|
-
rectangle(0, 0, 220, 400
|
30
|
+
rectangle(0, 0, 220, 400) {
|
31
31
|
background :red
|
32
32
|
}
|
33
|
-
rectangle(50, 20, 300, 150, 30, 50
|
33
|
+
rectangle(50, 20, 300, 150, 30, 50) {
|
34
34
|
background :magenta
|
35
35
|
}
|
36
|
-
rectangle(150, 200, 100, 70, true
|
36
|
+
rectangle(150, 200, 100, 70, true) {
|
37
37
|
background :dark_magenta
|
38
38
|
foreground :yellow
|
39
39
|
}
|
40
|
-
rectangle(50, 200, 30, 70, false
|
40
|
+
rectangle(50, 200, 30, 70, false) {
|
41
41
|
background :magenta
|
42
42
|
foreground :dark_blue
|
43
43
|
}
|
@@ -49,13 +49,14 @@ shell {
|
|
49
49
|
foreground :dark_magenta
|
50
50
|
font name: 'Courier', height: 30
|
51
51
|
}
|
52
|
-
oval(110, 310, 100, 100
|
53
|
-
|
52
|
+
oval(110, 310, 100, 100) {
|
53
|
+
# patterns provide a differnet way to make gradients
|
54
|
+
background_pattern 0, 0, 105, 0, :yellow, rgb(128, 138, 248)
|
54
55
|
}
|
55
|
-
arc(210, 210, 100, 100, 30, -77
|
56
|
+
arc(210, 210, 100, 100, 30, -77) {
|
56
57
|
background :red
|
57
58
|
}
|
58
|
-
polygon(250, 210, 260, 170, 270, 210, 290, 230
|
59
|
+
polygon(250, 210, 260, 170, 270, 210, 290, 230) {
|
59
60
|
background :dark_yellow
|
60
61
|
}
|
61
62
|
polyline(250, 110, 260, 70, 270, 110, 290, 130, 250, 110)
|
@@ -35,7 +35,7 @@ shell {
|
|
35
35
|
oval(0, 0, 400, 400) { # x, y, width, height
|
36
36
|
foreground :black # sets oval background color
|
37
37
|
}
|
38
|
-
arc(0, 0, 400, 400, -1.4*index%360, 10
|
38
|
+
arc(0, 0, 400, 400, -1.4*index%360, 10) { # x, y, width, height, start angle, arc angle
|
39
39
|
background rgb(200, 200, 50) # sets arc background color
|
40
40
|
}
|
41
41
|
}
|
@@ -51,13 +51,13 @@ shell {
|
|
51
51
|
frame { |index, color| # frame block loops indefinitely (unless frame_count or cycle_count is set to an integer)
|
52
52
|
outside_color = colors[index % 2]
|
53
53
|
inside_color = colors[(index + 1) % 2]
|
54
|
-
|
54
|
+
|
55
55
|
background outside_color # sets canvas background color
|
56
|
-
|
57
|
-
rectangle(0, 0, 200, 200
|
56
|
+
|
57
|
+
rectangle(0, 0, 200, 200) {
|
58
58
|
background inside_color # sets rectangle background color
|
59
59
|
}
|
60
|
-
rectangle(200, 200, 200, 200
|
60
|
+
rectangle(200, 200, 200, 200) {
|
61
61
|
background inside_color # sets rectangle background color
|
62
62
|
}
|
63
63
|
}
|