glimmer-dsl-swt 4.18.3.2 → 4.18.4.1
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 +52 -0
- data/README.md +674 -323
- data/VERSION +1 -1
- data/glimmer-dsl-swt.gemspec +7 -3
- data/lib/ext/rouge/themes/glimmer.rb +29 -0
- data/lib/glimmer-dsl-swt.rb +0 -1
- data/lib/glimmer/data_binding/table_items_binding.rb +8 -5
- data/lib/glimmer/data_binding/widget_binding.rb +9 -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 +196 -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 +12 -1
- 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 +10 -1
- data/lib/glimmer/swt/table_proxy.rb +27 -14
- data/lib/glimmer/swt/widget_proxy.rb +12 -2
- data/lib/glimmer/ui/custom_widget.rb +6 -2
- data/samples/elaborate/meta_sample.rb +5 -2
- data/samples/elaborate/meta_sample/meta_sample_logo.png +0 -0
- data/samples/elaborate/tetris.rb +60 -7
- data/samples/elaborate/tetris/model/game.rb +36 -7
- data/samples/elaborate/tetris/model/past_game.rb +14 -1
- data/samples/elaborate/tetris/model/tetromino.rb +18 -5
- data/samples/elaborate/tetris/view/block.rb +8 -13
- data/samples/elaborate/tetris/view/high_score_dialog.rb +23 -6
- data/samples/elaborate/tetris/view/playfield.rb +1 -1
- data/samples/elaborate/tetris/view/tetris_menu_bar.rb +22 -6
- data/samples/hello/hello_canvas.rb +10 -9
- data/samples/hello/hello_canvas_animation.rb +5 -5
- data/samples/hello/hello_code_text.rb +104 -0
- data/samples/hello/hello_table.rb +6 -4
- data/samples/hello/hello_table/baseball_park.png +0 -0
- metadata +6 -2
@@ -77,7 +77,7 @@ module Glimmer
|
|
77
77
|
composite.layout = GridLayout.new if composite.get_layout.nil?
|
78
78
|
end,
|
79
79
|
canvas: lambda do |canvas|
|
80
|
-
canvas.layout = nil
|
80
|
+
canvas.layout = nil if canvas.respond_to?('layout=') && !canvas.get_layout.nil?
|
81
81
|
end,
|
82
82
|
scrolled_composite: lambda do |scrolled_composite|
|
83
83
|
scrolled_composite.expand_horizontal = true
|
@@ -165,6 +165,12 @@ module Glimmer
|
|
165
165
|
DEFAULT_INITIALIZERS[underscored_widget_name.to_s.to_sym]&.call(@swt_widget)
|
166
166
|
@parent_proxy.post_initialize_child(self)
|
167
167
|
end
|
168
|
+
@keyword = underscored_widget_name.to_s
|
169
|
+
if respond_to?(:on_widget_disposed)
|
170
|
+
on_widget_disposed {
|
171
|
+
clear_shapes
|
172
|
+
}
|
173
|
+
end
|
168
174
|
end
|
169
175
|
|
170
176
|
# Subclasses may override to perform post initialization work on an added child
|
@@ -547,6 +553,10 @@ module Glimmer
|
|
547
553
|
@swt_widget.dispose
|
548
554
|
end
|
549
555
|
|
556
|
+
def disposed?
|
557
|
+
@swt_widget.isDisposed
|
558
|
+
end
|
559
|
+
|
550
560
|
# TODO Consider renaming these methods as they are mainly used for data-binding
|
551
561
|
|
552
562
|
def can_add_observer?(property_name)
|
@@ -663,7 +673,7 @@ module Glimmer
|
|
663
673
|
can_handle_observation_request?(method) ||
|
664
674
|
swt_widget.respond_to?(method, *args, &block)
|
665
675
|
end
|
666
|
-
|
676
|
+
|
667
677
|
private
|
668
678
|
|
669
679
|
def style(underscored_widget_name, styles)
|
@@ -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)
|
@@ -249,6 +249,10 @@ module Glimmer
|
|
249
249
|
def attribute_setter(attribute_name)
|
250
250
|
"#{attribute_name}="
|
251
251
|
end
|
252
|
+
|
253
|
+
def disposed?
|
254
|
+
swt_widget.isDisposed
|
255
|
+
end
|
252
256
|
|
253
257
|
def has_style?(style)
|
254
258
|
(swt_style & SWT::SWTProxy[style]) == SWT::SWTProxy[style]
|
@@ -204,7 +204,7 @@ class MetaSampleApplication
|
|
204
204
|
shell(:fill_screen) {
|
205
205
|
minimum_size 1280, 768
|
206
206
|
text 'Glimmer Meta-Sample (The Sample of Samples)'
|
207
|
-
image File.expand_path('
|
207
|
+
image File.expand_path('meta_sample/meta_sample_logo.png', __dir__)
|
208
208
|
|
209
209
|
sash_form {
|
210
210
|
composite {
|
@@ -264,9 +264,12 @@ class MetaSampleApplication
|
|
264
264
|
}
|
265
265
|
}
|
266
266
|
|
267
|
-
@code_text = code_text {
|
267
|
+
@code_text = code_text(lines: {width: 2}) {
|
268
268
|
text bind(SampleDirectory, 'selected_sample.code', read_only: true)
|
269
269
|
editable bind(SampleDirectory, 'selected_sample.editable')
|
270
|
+
line_numbers {
|
271
|
+
background :white
|
272
|
+
}
|
270
273
|
}
|
271
274
|
|
272
275
|
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
|
@@ -55,6 +56,15 @@ class Tetris
|
|
55
56
|
case key_event.keyCode
|
56
57
|
when swt(:arrow_down), 's'.bytes.first
|
57
58
|
game.down!
|
59
|
+
when swt(:arrow_up)
|
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
|
58
68
|
when swt(:arrow_left), 'a'.bytes.first
|
59
69
|
game.left!
|
60
70
|
when swt(:arrow_right), 'd'.bytes.first
|
@@ -65,8 +75,6 @@ class Tetris
|
|
65
75
|
elsif key_event.keyLocation == swt(:left) # left shift key
|
66
76
|
game.rotate!(:left)
|
67
77
|
end
|
68
|
-
when swt(:arrow_up)
|
69
|
-
game.rotate!(:right)
|
70
78
|
when swt(:ctrl)
|
71
79
|
game.rotate!(:left)
|
72
80
|
end
|
@@ -76,6 +84,10 @@ class Tetris
|
|
76
84
|
@about_observer = on_about {
|
77
85
|
show_about_dialog
|
78
86
|
}
|
87
|
+
|
88
|
+
@quit_observer = on_quit {
|
89
|
+
exit(0)
|
90
|
+
}
|
79
91
|
}
|
80
92
|
}
|
81
93
|
|
@@ -87,6 +99,13 @@ class Tetris
|
|
87
99
|
start_moving_tetrominos_down
|
88
100
|
end
|
89
101
|
end
|
102
|
+
@show_high_scores_observer = observe(@game, :show_high_scores) do |show_high_scores|
|
103
|
+
if show_high_scores
|
104
|
+
show_high_score_dialog
|
105
|
+
else
|
106
|
+
@high_score_dialog.close unless @high_score_dialog.nil? || @high_score_dialog.disposed? || !@high_score_dialog.visible?
|
107
|
+
end
|
108
|
+
end
|
90
109
|
@game.start!
|
91
110
|
}
|
92
111
|
|
@@ -99,10 +118,10 @@ class Tetris
|
|
99
118
|
margin_height 0
|
100
119
|
horizontal_spacing 0
|
101
120
|
}
|
102
|
-
|
121
|
+
|
103
122
|
text 'Glimmer Tetris'
|
104
123
|
minimum_size 475, 500
|
105
|
-
|
124
|
+
image tetris_icon
|
106
125
|
|
107
126
|
tetris_menu_bar(game: game)
|
108
127
|
|
@@ -118,6 +137,39 @@ class Tetris
|
|
118
137
|
}
|
119
138
|
}
|
120
139
|
|
140
|
+
def tetris_icon
|
141
|
+
icon_block_size = 64
|
142
|
+
icon_bevel_size = icon_block_size.to_f / 25.to_f
|
143
|
+
icon_bevel_pixel_size = 0.16*icon_block_size.to_f
|
144
|
+
icon_size = 8
|
145
|
+
icon_pixel_size = icon_block_size * icon_size
|
146
|
+
image(icon_pixel_size, icon_pixel_size) {
|
147
|
+
icon_size.times { |row|
|
148
|
+
icon_size.times { |column|
|
149
|
+
colored = row >= 1 && column.between?(1, 6)
|
150
|
+
color = colored ? color(([:white] + Model::Tetromino::LETTER_COLORS.values).sample) : color(:white)
|
151
|
+
x = column * icon_block_size
|
152
|
+
y = row * icon_block_size
|
153
|
+
rectangle(x, y, icon_block_size, icon_block_size, fill: true) {
|
154
|
+
background color
|
155
|
+
}
|
156
|
+
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) {
|
157
|
+
background rgb(color.red + 4*BEVEL_CONSTANT, color.green + 4*BEVEL_CONSTANT, color.blue + 4*BEVEL_CONSTANT)
|
158
|
+
}
|
159
|
+
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) {
|
160
|
+
background rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
161
|
+
}
|
162
|
+
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) {
|
163
|
+
background rgb(color.red - 2*BEVEL_CONSTANT, color.green - 2*BEVEL_CONSTANT, color.blue - 2*BEVEL_CONSTANT)
|
164
|
+
}
|
165
|
+
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) {
|
166
|
+
background rgb(color.red - BEVEL_CONSTANT, color.green - BEVEL_CONSTANT, color.blue - BEVEL_CONSTANT)
|
167
|
+
}
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
end
|
172
|
+
|
121
173
|
def start_moving_tetrominos_down
|
122
174
|
Thread.new do
|
123
175
|
@mutex.synchronize do
|
@@ -147,10 +199,11 @@ class Tetris
|
|
147
199
|
end
|
148
200
|
|
149
201
|
def deregister_observers
|
150
|
-
@show_high_scores_observer
|
151
|
-
@game_over_observer
|
152
|
-
@keyboard_listener
|
202
|
+
@show_high_scores_observer&.deregister
|
203
|
+
@game_over_observer&.deregister
|
204
|
+
@keyboard_listener&.deregister
|
153
205
|
@about_observer&.deregister
|
206
|
+
@quit_observer&.deregister
|
154
207
|
end
|
155
208
|
end
|
156
209
|
|
@@ -21,6 +21,7 @@
|
|
21
21
|
|
22
22
|
require 'fileutils'
|
23
23
|
require 'etc'
|
24
|
+
require 'json'
|
24
25
|
require 'glimmer/data_binding/observer'
|
25
26
|
require 'glimmer/config'
|
26
27
|
|
@@ -38,7 +39,7 @@ class Tetris
|
|
38
39
|
SCORE_MULTIPLIER = {1 => 40, 2 => 100, 3 => 300, 4 => 1200}
|
39
40
|
|
40
41
|
attr_reader :playfield_width, :playfield_height
|
41
|
-
attr_accessor :game_over, :paused, :preview_tetromino, :lines, :score, :level, :high_scores, :beeping, :added_high_score
|
42
|
+
attr_accessor :game_over, :paused, :preview_tetromino, :lines, :score, :level, :high_scores, :beeping, :added_high_score, :show_high_scores, :up_arrow_action
|
42
43
|
alias game_over? game_over
|
43
44
|
alias paused? paused
|
44
45
|
alias beeping? beeping
|
@@ -48,10 +49,12 @@ class Tetris
|
|
48
49
|
@playfield_width = playfield_width
|
49
50
|
@playfield_height = playfield_height
|
50
51
|
@high_scores = []
|
52
|
+
@show_high_scores = false
|
51
53
|
@beeping = true
|
54
|
+
@up_arrow_action = :rotate_left
|
52
55
|
load_high_scores!
|
53
56
|
end
|
54
|
-
|
57
|
+
|
55
58
|
def configure_beeper(&beeper)
|
56
59
|
@beeper = beeper
|
57
60
|
end
|
@@ -61,6 +64,7 @@ class Tetris
|
|
61
64
|
end
|
62
65
|
|
63
66
|
def start!
|
67
|
+
self.show_high_scores = false
|
64
68
|
self.paused = false
|
65
69
|
self.level = 1
|
66
70
|
self.score = 0
|
@@ -86,7 +90,7 @@ class Tetris
|
|
86
90
|
|
87
91
|
def add_high_score!
|
88
92
|
self.added_high_score = true
|
89
|
-
high_scores.prepend(PastGame.new("Player #{high_scores.count + 1}", score))
|
93
|
+
high_scores.prepend(PastGame.new("Player #{high_scores.count + 1}", score, lines, level))
|
90
94
|
end
|
91
95
|
|
92
96
|
def save_high_scores!
|
@@ -115,9 +119,9 @@ class Tetris
|
|
115
119
|
File.join(tetris_dir, "high_scores.txt")
|
116
120
|
end
|
117
121
|
|
118
|
-
def down!
|
122
|
+
def down!(instant: false)
|
119
123
|
return unless game_in_progress?
|
120
|
-
current_tetromino.down!
|
124
|
+
current_tetromino.down!(instant: instant)
|
121
125
|
game_over! if current_tetromino.row <= 0 && current_tetromino.stopped?
|
122
126
|
end
|
123
127
|
|
@@ -202,6 +206,30 @@ class Tetris
|
|
202
206
|
@beeper&.call if beeping
|
203
207
|
end
|
204
208
|
|
209
|
+
def instant_down_on_up=(value)
|
210
|
+
self.up_arrow_action = :instant_down if value
|
211
|
+
end
|
212
|
+
|
213
|
+
def instant_down_on_up
|
214
|
+
self.up_arrow_action == :instant_down
|
215
|
+
end
|
216
|
+
|
217
|
+
def rotate_right_on_up=(value)
|
218
|
+
self.up_arrow_action = :rotate_right if value
|
219
|
+
end
|
220
|
+
|
221
|
+
def rotate_right_on_up
|
222
|
+
self.up_arrow_action == :rotate_right
|
223
|
+
end
|
224
|
+
|
225
|
+
def rotate_left_on_up=(value)
|
226
|
+
self.up_arrow_action = :rotate_left if value
|
227
|
+
end
|
228
|
+
|
229
|
+
def rotate_left_on_up
|
230
|
+
self.up_arrow_action == :rotate_left
|
231
|
+
end
|
232
|
+
|
205
233
|
def reset_tetrominoes
|
206
234
|
@tetrominoes = []
|
207
235
|
end
|
@@ -247,12 +275,13 @@ class Tetris
|
|
247
275
|
|
248
276
|
def playfield_remaining_heights(tetromino = nil)
|
249
277
|
@playfield_width.times.map do |playfield_column|
|
278
|
+
bottom_most_block = tetromino.bottom_most_block_for_column(playfield_column)
|
250
279
|
(playfield.each_with_index.detect do |row, playfield_row|
|
251
280
|
!row[playfield_column].clear? &&
|
252
281
|
(
|
253
282
|
tetromino.nil? ||
|
254
|
-
|
255
|
-
(playfield_row > tetromino.row + bottom_most_block[:
|
283
|
+
bottom_most_block.nil? ||
|
284
|
+
(playfield_row > tetromino.row + bottom_most_block[:row_index])
|
256
285
|
)
|
257
286
|
end || [nil, @playfield_height])[1]
|
258
287
|
end.to_a
|
@@ -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
|
@@ -93,8 +93,8 @@ class Tetris
|
|
93
93
|
playfield_remaining_heights = game.playfield_remaining_heights(self)
|
94
94
|
result = bottom_most_blocks.any? do |bottom_most_block|
|
95
95
|
playfield_column = @column + bottom_most_block[:column_index]
|
96
|
-
|
97
|
-
@row + bottom_most_block[:
|
96
|
+
playfield_remaining_heights[playfield_column] &&
|
97
|
+
@row + bottom_most_block[:row_index] >= playfield_remaining_heights[playfield_column] - 1
|
98
98
|
end
|
99
99
|
if result && !game.hypothetical?
|
100
100
|
@stopped = result
|
@@ -114,7 +114,7 @@ class Tetris
|
|
114
114
|
bottom_most_block_row = row_blocks_with_row_index[1]
|
115
115
|
{
|
116
116
|
block: bottom_most_block,
|
117
|
-
|
117
|
+
row_index: bottom_most_block_row,
|
118
118
|
column_index: column_index
|
119
119
|
}
|
120
120
|
end
|
@@ -182,10 +182,15 @@ 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 instant
|
190
|
+
remaining_height, bottom_touching_block = remaining_height_and_bottom_touching_block
|
191
|
+
block_count = remaining_height - @row
|
192
|
+
end
|
193
|
+
new_row = @row + block_count
|
189
194
|
update_playfield(new_row, @column)
|
190
195
|
end
|
191
196
|
end
|
@@ -245,6 +250,14 @@ class Tetris
|
|
245
250
|
end
|
246
251
|
end
|
247
252
|
|
253
|
+
def remaining_height_and_bottom_touching_block
|
254
|
+
playfield_remaining_heights = game.playfield_remaining_heights(self)
|
255
|
+
bottom_most_blocks.map do |bottom_most_block|
|
256
|
+
playfield_column = @column + bottom_most_block[:column_index]
|
257
|
+
[playfield_remaining_heights[playfield_column] - (bottom_most_block[:row_index] + 1), bottom_most_block]
|
258
|
+
end.min_by(&:first)
|
259
|
+
end
|
260
|
+
|
248
261
|
def default_blocks
|
249
262
|
case @letter
|
250
263
|
when :I
|
@@ -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) {
|
@@ -59,8 +59,14 @@ class Tetris
|
|
59
59
|
table_column {
|
60
60
|
text 'Score'
|
61
61
|
}
|
62
|
+
table_column {
|
63
|
+
text 'Lines'
|
64
|
+
}
|
65
|
+
table_column {
|
66
|
+
text 'Level'
|
67
|
+
}
|
62
68
|
|
63
|
-
items bind(game, :high_scores), column_properties(:name, :score)
|
69
|
+
items bind(game, :high_scores, read_only_sort: true), column_properties(:name, :score, :lines, :level)
|
64
70
|
}
|
65
71
|
composite {
|
66
72
|
row_layout :horizontal
|
@@ -77,31 +83,42 @@ class Tetris
|
|
77
83
|
focus true # initial focus
|
78
84
|
|
79
85
|
on_widget_selected {
|
80
|
-
close
|
86
|
+
async_exec { close }
|
87
|
+
game.paused = @game_paused
|
81
88
|
game.restart! if game.game_over?
|
82
89
|
}
|
83
90
|
}
|
84
91
|
}
|
85
92
|
|
86
93
|
on_swt_show {
|
94
|
+
@game_paused = game.paused?
|
95
|
+
game.paused = true
|
87
96
|
if game.game_over? && game.added_high_score?
|
88
97
|
game.added_high_score = false
|
98
|
+
game.save_high_scores!
|
89
99
|
@high_score_table.edit_table_item(
|
90
100
|
@high_score_table.items.first, # row item
|
91
101
|
0, # column
|
102
|
+
write_on_cancel: true,
|
92
103
|
after_write: -> {
|
93
104
|
game.save_high_scores!
|
94
105
|
@play_close_button.set_focus
|
95
106
|
},
|
96
|
-
after_cancel: -> {
|
97
|
-
@play_close_button.set_focus
|
98
|
-
},
|
99
107
|
)
|
100
108
|
end
|
101
109
|
}
|
102
110
|
|
103
111
|
on_shell_closed {
|
104
|
-
|
112
|
+
# guard is needed because there is an observer in Tetris closing on
|
113
|
+
# game.show_high_scores change, which gets set below
|
114
|
+
unless @closing
|
115
|
+
@closing = true
|
116
|
+
@high_score_table.cancel_edit!
|
117
|
+
game.paused = @game_paused
|
118
|
+
game.show_high_scores = false
|
119
|
+
else
|
120
|
+
@closing = false
|
121
|
+
end
|
105
122
|
}
|
106
123
|
|
107
124
|
on_widget_disposed {
|