glimmer-dsl-swt 4.18.3.2 → 4.18.3.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 +12 -0
- data/README.md +8 -5
- data/VERSION +1 -1
- data/glimmer-dsl-swt.gemspec +3 -3
- data/lib/glimmer/data_binding/table_items_binding.rb +8 -5
- data/lib/glimmer/data_binding/widget_binding.rb +8 -0
- data/lib/glimmer/swt/display_proxy.rb +1 -1
- data/lib/glimmer/swt/shell_proxy.rb +7 -1
- data/lib/glimmer/swt/table_proxy.rb +12 -3
- data/lib/glimmer/swt/widget_proxy.rb +5 -1
- data/lib/glimmer/ui/custom_widget.rb +4 -0
- data/samples/elaborate/tetris.rb +17 -5
- data/samples/elaborate/tetris/model/game.rb +10 -7
- data/samples/elaborate/tetris/model/past_game.rb +1 -1
- data/samples/elaborate/tetris/model/tetromino.rb +18 -5
- data/samples/elaborate/tetris/view/high_score_dialog.rb +22 -3
- data/samples/elaborate/tetris/view/tetris_menu_bar.rb +4 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59c5aae689604e6024a5bffb1053cd50cc05c1598dca6fc3a01510f17371deab
|
4
|
+
data.tar.gz: 5fc97483b96bf334b1e25b30b8455ad41af3e6f56ae6f5310ac31504ce87c41d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdf5681c5632aa64d15c9e2037757d4e7599fbcaeacc14acc1af1dd1669c205ca7a8730551277ae0a3cff5bb435a802dcbdb824e7dbc749f75471ba15079e999
|
7
|
+
data.tar.gz: 5f96f41c1bdd491da20ae87ad1b2a5f072eeaca78c6e8f15a1a942390c2cc23b07259465452b242e0d61111a6881954458b5fe5214d77bfd4f45dd365ae0eb14
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
### 4.18.3.3
|
4
|
+
|
5
|
+
- Support Table data binding read_only_sort: true option to allow visual sorting without affecting model data
|
6
|
+
- Tetris Add lines and level to High Score Dialog
|
7
|
+
- Tetris Immediate Drop on Arrow Up
|
8
|
+
- Tetris Pause on showing High Score Dialog
|
9
|
+
- Tetris Make High Scores -> Show a check menu item
|
10
|
+
- Tetris Disable pause button upon showing High Score Dialog
|
11
|
+
- Fix Quit Tetris CMD+Q shortcut by adding on_quit event to display
|
12
|
+
- Tetris Fix escape button upon entering high score name
|
13
|
+
- If WidgetBinding encounters a disposed widget, it deregisters all observables that it is observing
|
14
|
+
|
3
15
|
### 4.18.3.2
|
4
16
|
|
5
17
|
- Tetris High Scores
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 4.18.3.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 4.18.3.3
|
2
2
|
## JRuby Desktop Development GUI Framework
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
|
4
4
|
[![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
|
@@ -493,7 +493,7 @@ jgem install glimmer-dsl-swt
|
|
493
493
|
|
494
494
|
Or this command if you want a specific version:
|
495
495
|
```
|
496
|
-
jgem install glimmer-dsl-swt -v 4.18.3.
|
496
|
+
jgem install glimmer-dsl-swt -v 4.18.3.3
|
497
497
|
|
498
498
|
|
499
499
|
```
|
@@ -513,7 +513,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
|
|
513
513
|
|
514
514
|
Add the following to `Gemfile`:
|
515
515
|
```
|
516
|
-
gem 'glimmer-dsl-swt', '~> 4.18.3.
|
516
|
+
gem 'glimmer-dsl-swt', '~> 4.18.3.3
|
517
517
|
'
|
518
518
|
```
|
519
519
|
|
@@ -572,7 +572,7 @@ bin/glimmer samples
|
|
572
572
|
Below are the full usage instructions that come up when running `glimmer` without args.
|
573
573
|
|
574
574
|
```
|
575
|
-
Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.3.
|
575
|
+
Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.18.3.3
|
576
576
|
|
577
577
|
|
578
578
|
|
@@ -1053,7 +1053,7 @@ Output:
|
|
1053
1053
|
|
1054
1054
|
Css glimmer-dsl-css 1.1.0 AndyMaleh Glimmer DSL for CSS
|
1055
1055
|
Opal glimmer-dsl-opal 0.10.2 AndyMaleh Glimmer DSL for Opal
|
1056
|
-
Swt glimmer-dsl-swt 4.18.3.
|
1056
|
+
Swt glimmer-dsl-swt 4.18.3.3
|
1057
1057
|
|
1058
1058
|
AndyMaleh Glimmer DSL for SWT
|
1059
1059
|
Tk glimmer-dsl-tk 0.0.6 AndyMaleh Glimmer DSL for Tk
|
@@ -3025,6 +3025,7 @@ Here is an explanation of the example above:
|
|
3025
3025
|
- Task Start Date table column has a custom sort comparator block
|
3026
3026
|
- Additional (secondary) sort properties are applied when sorting by Task, Project, or Duration in the order specified
|
3027
3027
|
|
3028
|
+
`bind(model, :property, read_only_sort: true)` could be used with items to make sorting not propagate sorting changes to model.
|
3028
3029
|
|
3029
3030
|
#### Tree
|
3030
3031
|
|
@@ -4860,6 +4861,8 @@ Code:
|
|
4860
4861
|
|
4861
4862
|
![Tetris Game Over](images/glimmer-tetris-game-over.png)
|
4862
4863
|
|
4864
|
+
![Tetris Game Over](images/glimmer-tetris-game-over-sorted-by-score.png)
|
4865
|
+
|
4863
4866
|
![Tetris High Scores](images/glimmer-tetris-high-score-dialog.png)
|
4864
4867
|
|
4865
4868
|
![Tetris Game Menu](images/glimmer-tetris-game-menu.png)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.18.3.
|
1
|
+
4.18.3.3
|
data/glimmer-dsl-swt.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-dsl-swt 4.18.3.
|
5
|
+
# stub: glimmer-dsl-swt 4.18.3.3 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-swt".freeze
|
9
|
-
s.version = "4.18.3.
|
9
|
+
s.version = "4.18.3.3"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["AndyMaleh".freeze]
|
14
|
-
s.date = "2021-01-
|
14
|
+
s.date = "2021-01-29"
|
15
15
|
s.description = "Glimmer DSL for SWT (JRuby Desktop Development GUI Framework) is a native-GUI cross-platform desktop development library written in JRuby, an OS-threaded faster JVM version of Ruby. Glimmer's main innovation is a declarative Ruby DSL that enables productive and efficient authoring of desktop application user-interfaces by relying on the robust Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support, which greatly facilitates synchronizing the GUI with domain models, thus achieving true decoupling of object oriented components and enabling developers to solve business problems (test-first) without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models (test-first) afterwards. Not only does Glimmer provide a large set of GUI widgets, but it also supports drawing Canvas Graphics like Shapes and Animations. To get started quickly, Glimmer offers scaffolding options for Apps, Gems, and Custom Widgets. Glimmer also includes native-executable packaging support, sorely lacking in other libraries, thus enabling the delivery of desktop apps written in Ruby as truly native DMG/PKG/APP files on the Mac + App Store, MSI/EXE files on Windows, and Gem Packaged Shell Scripts on Linux.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.executables = ["glimmer".freeze, "girb".freeze]
|
@@ -36,7 +36,9 @@ module Glimmer
|
|
36
36
|
def initialize(parent, model_binding, column_properties)
|
37
37
|
@table = parent
|
38
38
|
@model_binding = model_binding
|
39
|
+
@read_only_sort = @model_binding.binding_options[:read_only_sort]
|
39
40
|
@table.swt_widget.data = @model_binding
|
41
|
+
@table.swt_widget.set_data('table_items_binding', self)
|
40
42
|
@column_properties = column_properties
|
41
43
|
@table.on_widget_disposed do |dispose_event|
|
42
44
|
unregister_all_observables
|
@@ -50,8 +52,8 @@ module Glimmer
|
|
50
52
|
call
|
51
53
|
end
|
52
54
|
|
53
|
-
def call(new_model_collection=nil)
|
54
|
-
new_model_collection = @model_binding.evaluate_property # this ensures applying converters (e.g. :on_read)
|
55
|
+
def call(new_model_collection=nil, internal_sort: false)
|
56
|
+
new_model_collection = model_binding_evaluated_property = @model_binding.evaluate_property unless internal_sort # this ensures applying converters (e.g. :on_read)
|
55
57
|
table_cells = @table.swt_widget.items.map {|item| @table.column_properties.size.times.map {|i| item.get_text(i)} }
|
56
58
|
model_cells = new_model_collection.to_a.map {|m| @table.cells_for(m)}
|
57
59
|
return if table_cells == model_cells
|
@@ -61,10 +63,10 @@ module Glimmer
|
|
61
63
|
add_dependent(@table_observer_registration => @table_items_observer_registration)
|
62
64
|
@model_collection = new_model_collection
|
63
65
|
end
|
64
|
-
populate_table(@model_collection, @table, @column_properties)
|
66
|
+
populate_table(@model_collection, @table, @column_properties, internal_sort: internal_sort)
|
65
67
|
end
|
66
68
|
|
67
|
-
def populate_table(model_collection, parent, column_properties)
|
69
|
+
def populate_table(model_collection, parent, column_properties, internal_sort: false)
|
68
70
|
selected_table_item_models = parent.swt_widget.getSelection.map(&:get_data)
|
69
71
|
parent.finish_edit!
|
70
72
|
parent.swt_widget.items.each(&:dispose)
|
@@ -78,7 +80,8 @@ module Glimmer
|
|
78
80
|
end
|
79
81
|
selected_table_items = parent.search {|item| selected_table_item_models.include?(item.get_data) }
|
80
82
|
parent.swt_widget.setSelection(selected_table_items)
|
81
|
-
parent.sort!
|
83
|
+
sorted_model_collection = parent.sort!(internal_sort: internal_sort)
|
84
|
+
call(sorted_model_collection, internal_sort: true) if @read_only_sort && !internal_sort && !sorted_model_collection.nil?
|
82
85
|
parent.swt_widget.redraw if parent&.swt_widget&.respond_to?(:redraw)
|
83
86
|
end
|
84
87
|
end
|
@@ -48,6 +48,10 @@ module Glimmer
|
|
48
48
|
converted_value = translated_value = @translator.call(value)
|
49
49
|
|
50
50
|
update_operation = lambda do
|
51
|
+
if @widget.respond_to?(:disposed?) && @widget.disposed?
|
52
|
+
unregister_all_observables
|
53
|
+
return
|
54
|
+
end
|
51
55
|
@widget.set_attribute(@property, converted_value) unless evaluate_property == converted_value
|
52
56
|
end
|
53
57
|
if Config.auto_sync_exec? && Config.require_sync_exec?
|
@@ -58,6 +62,10 @@ module Glimmer
|
|
58
62
|
end
|
59
63
|
|
60
64
|
def evaluate_property
|
65
|
+
if @widget.respond_to?(:disposed?) && @widget.disposed?
|
66
|
+
unregister_all_observables
|
67
|
+
return
|
68
|
+
end
|
61
69
|
@widget.get_attribute(@property)
|
62
70
|
end
|
63
71
|
end
|
@@ -124,8 +124,14 @@ module Glimmer
|
|
124
124
|
end
|
125
125
|
alias disposed disposed?
|
126
126
|
|
127
|
+
# Hides shell. Automatically checks if widget is disposed to avoid crashing.
|
127
128
|
def hide
|
128
|
-
@swt_widget.setVisible(false)
|
129
|
+
@swt_widget.setVisible(false) unless @swt_widget.isDisposed
|
130
|
+
end
|
131
|
+
|
132
|
+
# Closes shell. Automatically checks if widget is disposed to avoid crashing.
|
133
|
+
def close
|
134
|
+
@swt_widget.close unless @swt_widget.isDisposed
|
129
135
|
end
|
130
136
|
|
131
137
|
def visible?
|
@@ -273,6 +273,10 @@ module Glimmer
|
|
273
273
|
swt_widget.data
|
274
274
|
end
|
275
275
|
|
276
|
+
def table_items_binding
|
277
|
+
swt_widget.get_data('table_items_binding')
|
278
|
+
end
|
279
|
+
|
276
280
|
def sort_block=(comparator)
|
277
281
|
@sort_block = comparator
|
278
282
|
end
|
@@ -357,9 +361,9 @@ module Glimmer
|
|
357
361
|
@additional_sort_properties = args unless args.empty?
|
358
362
|
end
|
359
363
|
|
360
|
-
def sort!
|
364
|
+
def sort!(internal_sort: false)
|
361
365
|
return unless sort_property && (sort_type || sort_block || sort_by_block)
|
362
|
-
array = model_binding.evaluate_property
|
366
|
+
original_array = array = model_binding.evaluate_property
|
363
367
|
array = array.sort_by(&:hash) # this ensures consistent subsequent sorting in case there are equivalent sorts to avoid an infinite loop
|
364
368
|
# Converting value to_s first to handle nil cases. Should work with numeric, boolean, and date fields
|
365
369
|
if sort_block
|
@@ -383,7 +387,12 @@ module Glimmer
|
|
383
387
|
end
|
384
388
|
end
|
385
389
|
sorted_array = sorted_array.reverse if sort_direction == :descending
|
386
|
-
model_binding.
|
390
|
+
if model_binding.binding_options.symbolize_keys[:read_only_sort]
|
391
|
+
table_items_binding.call(sorted_array, internal_sort: true) unless internal_sort
|
392
|
+
else
|
393
|
+
model_binding.call(sorted_array)
|
394
|
+
end
|
395
|
+
sorted_array
|
387
396
|
end
|
388
397
|
|
389
398
|
def editor=(args)
|
@@ -547,6 +547,10 @@ module Glimmer
|
|
547
547
|
@swt_widget.dispose
|
548
548
|
end
|
549
549
|
|
550
|
+
def disposed?
|
551
|
+
@swt_widget.isDisposed
|
552
|
+
end
|
553
|
+
|
550
554
|
# TODO Consider renaming these methods as they are mainly used for data-binding
|
551
555
|
|
552
556
|
def can_add_observer?(property_name)
|
@@ -663,7 +667,7 @@ module Glimmer
|
|
663
667
|
can_handle_observation_request?(method) ||
|
664
668
|
swt_widget.respond_to?(method, *args, &block)
|
665
669
|
end
|
666
|
-
|
670
|
+
|
667
671
|
private
|
668
672
|
|
669
673
|
def style(underscored_widget_name, styles)
|
data/samples/elaborate/tetris.rb
CHANGED
@@ -55,6 +55,8 @@ class Tetris
|
|
55
55
|
case key_event.keyCode
|
56
56
|
when swt(:arrow_down), 's'.bytes.first
|
57
57
|
game.down!
|
58
|
+
when swt(:arrow_up)
|
59
|
+
game.down!(immediate: true)
|
58
60
|
when swt(:arrow_left), 'a'.bytes.first
|
59
61
|
game.left!
|
60
62
|
when swt(:arrow_right), 'd'.bytes.first
|
@@ -65,8 +67,6 @@ class Tetris
|
|
65
67
|
elsif key_event.keyLocation == swt(:left) # left shift key
|
66
68
|
game.rotate!(:left)
|
67
69
|
end
|
68
|
-
when swt(:arrow_up)
|
69
|
-
game.rotate!(:right)
|
70
70
|
when swt(:ctrl)
|
71
71
|
game.rotate!(:left)
|
72
72
|
end
|
@@ -76,6 +76,10 @@ class Tetris
|
|
76
76
|
@about_observer = on_about {
|
77
77
|
show_about_dialog
|
78
78
|
}
|
79
|
+
|
80
|
+
@quit_observer = on_quit {
|
81
|
+
exit(0)
|
82
|
+
}
|
79
83
|
}
|
80
84
|
}
|
81
85
|
|
@@ -87,6 +91,13 @@ class Tetris
|
|
87
91
|
start_moving_tetrominos_down
|
88
92
|
end
|
89
93
|
end
|
94
|
+
@show_high_scores_observer = observe(@game, :show_high_scores) do |show_high_scores|
|
95
|
+
if show_high_scores
|
96
|
+
show_high_score_dialog
|
97
|
+
else
|
98
|
+
@high_score_dialog.close unless @high_score_dialog.nil? || @high_score_dialog.disposed? || !@high_score_dialog.visible?
|
99
|
+
end
|
100
|
+
end
|
90
101
|
@game.start!
|
91
102
|
}
|
92
103
|
|
@@ -147,10 +158,11 @@ class Tetris
|
|
147
158
|
end
|
148
159
|
|
149
160
|
def deregister_observers
|
150
|
-
@show_high_scores_observer
|
151
|
-
@game_over_observer
|
152
|
-
@keyboard_listener
|
161
|
+
@show_high_scores_observer&.deregister
|
162
|
+
@game_over_observer&.deregister
|
163
|
+
@keyboard_listener&.deregister
|
153
164
|
@about_observer&.deregister
|
165
|
+
@quit_observer&.deregister
|
154
166
|
end
|
155
167
|
end
|
156
168
|
|
@@ -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
|
41
|
+
attr_accessor :game_over, :paused, :preview_tetromino, :lines, :score, :level, :high_scores, :beeping, :added_high_score, :show_high_scores
|
42
42
|
alias game_over? game_over
|
43
43
|
alias paused? paused
|
44
44
|
alias beeping? beeping
|
@@ -48,10 +48,11 @@ class Tetris
|
|
48
48
|
@playfield_width = playfield_width
|
49
49
|
@playfield_height = playfield_height
|
50
50
|
@high_scores = []
|
51
|
+
@show_high_scores = false
|
51
52
|
@beeping = true
|
52
53
|
load_high_scores!
|
53
54
|
end
|
54
|
-
|
55
|
+
|
55
56
|
def configure_beeper(&beeper)
|
56
57
|
@beeper = beeper
|
57
58
|
end
|
@@ -61,6 +62,7 @@ class Tetris
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def start!
|
65
|
+
self.show_high_scores = false
|
64
66
|
self.paused = false
|
65
67
|
self.level = 1
|
66
68
|
self.score = 0
|
@@ -86,7 +88,7 @@ class Tetris
|
|
86
88
|
|
87
89
|
def add_high_score!
|
88
90
|
self.added_high_score = true
|
89
|
-
high_scores.prepend(PastGame.new("Player #{high_scores.count + 1}", score))
|
91
|
+
high_scores.prepend(PastGame.new("Player #{high_scores.count + 1}", score, lines, level))
|
90
92
|
end
|
91
93
|
|
92
94
|
def save_high_scores!
|
@@ -115,9 +117,9 @@ class Tetris
|
|
115
117
|
File.join(tetris_dir, "high_scores.txt")
|
116
118
|
end
|
117
119
|
|
118
|
-
def down!
|
120
|
+
def down!(immediate: false)
|
119
121
|
return unless game_in_progress?
|
120
|
-
current_tetromino.down!
|
122
|
+
current_tetromino.down!(immediate: immediate)
|
121
123
|
game_over! if current_tetromino.row <= 0 && current_tetromino.stopped?
|
122
124
|
end
|
123
125
|
|
@@ -247,12 +249,13 @@ class Tetris
|
|
247
249
|
|
248
250
|
def playfield_remaining_heights(tetromino = nil)
|
249
251
|
@playfield_width.times.map do |playfield_column|
|
252
|
+
bottom_most_block = tetromino.bottom_most_block_for_column(playfield_column)
|
250
253
|
(playfield.each_with_index.detect do |row, playfield_row|
|
251
254
|
!row[playfield_column].clear? &&
|
252
255
|
(
|
253
256
|
tetromino.nil? ||
|
254
|
-
|
255
|
-
(playfield_row > tetromino.row + bottom_most_block[:
|
257
|
+
bottom_most_block.nil? ||
|
258
|
+
(playfield_row > tetromino.row + bottom_most_block[:row_index])
|
256
259
|
)
|
257
260
|
end || [nil, @playfield_height])[1]
|
258
261
|
end.to_a
|
@@ -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!(immediate: false)
|
186
186
|
launch! if preview?
|
187
187
|
unless stopped?
|
188
|
-
|
188
|
+
block_count = 1
|
189
|
+
if immediate
|
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
|
@@ -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,15 +83,19 @@ 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
|
@@ -101,7 +111,16 @@ class Tetris
|
|
101
111
|
}
|
102
112
|
|
103
113
|
on_shell_closed {
|
104
|
-
|
114
|
+
# guard is needed because there is an observer in Tetris closing on
|
115
|
+
# game.show_high_scores change, which gets set below
|
116
|
+
unless @closing
|
117
|
+
@closing = true
|
118
|
+
@high_score_table.cancel_edit!
|
119
|
+
game.paused = @game_paused
|
120
|
+
game.show_high_scores = false
|
121
|
+
else
|
122
|
+
@closing = false
|
123
|
+
end
|
105
124
|
}
|
106
125
|
|
107
126
|
on_widget_disposed {
|
@@ -43,7 +43,8 @@ class Tetris
|
|
43
43
|
menu_item(:check) {
|
44
44
|
text '&Pause'
|
45
45
|
accelerator :command, :p
|
46
|
-
enabled bind(game, :game_over, on_read: :!)
|
46
|
+
enabled bind(game, :game_over, on_read: :!) {|value| value && !game.show_high_scores}
|
47
|
+
enabled bind(game, :show_high_scores, on_read: :!) {|value| value && !game.game_over}
|
47
48
|
selection bind(game, :paused)
|
48
49
|
}
|
49
50
|
menu_item {
|
@@ -70,13 +71,10 @@ class Tetris
|
|
70
71
|
|
71
72
|
menu {
|
72
73
|
text '&High Scores'
|
73
|
-
menu_item {
|
74
|
+
menu_item(:check) {
|
74
75
|
text '&Show'
|
75
76
|
accelerator :command, :shift, :h
|
76
|
-
|
77
|
-
on_widget_selected {
|
78
|
-
parent_custom_shell&.show_high_score_dialog
|
79
|
-
}
|
77
|
+
selection bind(game, :show_high_scores)
|
80
78
|
}
|
81
79
|
menu_item {
|
82
80
|
text '&Clear'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-swt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.18.3.
|
4
|
+
version: 4.18.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|