glimmer_tetris 1.0.0

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.
@@ -0,0 +1,39 @@
1
+ # Copyright (c) 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
+ class GlimmerTetris
23
+ module View
24
+ class Block
25
+ include Glimmer::UI::CustomWidget
26
+
27
+ option :game_block
28
+
29
+ body {
30
+ canvas { |canvas_proxy|
31
+ bevel(size: BLOCK_SIZE) {
32
+ base_color bind(game_block, :color)
33
+ }
34
+ }
35
+ }
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,124 @@
1
+ # Copyright (c) 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_relative 'tetris_menu_bar'
23
+
24
+ class GlimmerTetris
25
+ module View
26
+ class HighScoreDialog
27
+ include Glimmer::UI::CustomShell
28
+
29
+ options :parent_shell, :game
30
+
31
+ after_body {
32
+ @game_over_observer = observe(game, :game_over) do |game_over|
33
+ close if !game_over
34
+ end
35
+ }
36
+
37
+ body {
38
+ dialog(parent_shell) {
39
+ row_layout {
40
+ type :vertical
41
+ center true
42
+ }
43
+ text 'Tetris'
44
+
45
+ tetris_menu_bar(game: game)
46
+
47
+ label(:center) {
48
+ text bind(game, :game_over) {|game_over| game_over ? 'Game Over!' : 'High Scores'}
49
+ font name: FONT_NAME, height: FONT_TITLE_HEIGHT, style: FONT_TITLE_STYLE
50
+ }
51
+ @high_score_table = table {
52
+ layout_data {
53
+ height 100
54
+ }
55
+
56
+ table_column {
57
+ text 'Name'
58
+ }
59
+ table_column {
60
+ text 'Score'
61
+ }
62
+ table_column {
63
+ text 'Lines'
64
+ }
65
+ table_column {
66
+ text 'Level'
67
+ }
68
+
69
+ items bind(game, :high_scores, read_only_sort: true), column_properties(:name, :score, :lines, :level)
70
+ }
71
+ composite {
72
+ row_layout :horizontal
73
+
74
+ @play_close_button = button {
75
+ text bind(game, :game_over) {|game_over| game_over ? 'Play Again?' : 'Close'}
76
+ focus true # initial focus
77
+
78
+ on_widget_selected {
79
+ async_exec { close }
80
+ game.paused = @game_paused
81
+ game.restart! if game.game_over?
82
+ }
83
+ }
84
+ }
85
+
86
+ on_swt_show {
87
+ @game_paused = game.paused?
88
+ game.paused = true
89
+ if game.game_over? && game.added_high_score?
90
+ game.added_high_score = false
91
+ game.save_high_scores!
92
+ @high_score_table.edit_table_item(
93
+ @high_score_table.items.first, # row item
94
+ 0, # column
95
+ write_on_cancel: true,
96
+ after_write: -> {
97
+ game.save_high_scores!
98
+ @play_close_button.set_focus
99
+ },
100
+ )
101
+ end
102
+ }
103
+
104
+ on_shell_closed {
105
+ # guard is needed because there is an observer in Tetris closing on
106
+ # game.show_high_scores change, which gets set below
107
+ unless @closing
108
+ @closing = true
109
+ @high_score_table.cancel_edit!
110
+ game.paused = @game_paused
111
+ game.show_high_scores = false
112
+ else
113
+ @closing = false
114
+ end
115
+ }
116
+
117
+ on_widget_disposed {
118
+ @game_over_observer.deregister
119
+ }
120
+ }
121
+ }
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 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_relative 'block'
23
+
24
+ class GlimmerTetris
25
+ module View
26
+ class Playfield
27
+ include Glimmer::UI::CustomWidget
28
+
29
+ options :game_playfield, :playfield_width, :playfield_height
30
+
31
+ body {
32
+ composite((:double_buffered unless OS.mac?)) {
33
+ grid_layout {
34
+ num_columns playfield_width
35
+ make_columns_equal_width true
36
+ margin_width BLOCK_SIZE
37
+ margin_height BLOCK_SIZE
38
+ horizontal_spacing 0
39
+ vertical_spacing 0
40
+ }
41
+
42
+ playfield_height.times do |row|
43
+ playfield_width.times do |column|
44
+ block(game_block: game_playfield[row][column]) {
45
+ layout_data {
46
+ width_hint BLOCK_SIZE
47
+ height_hint BLOCK_SIZE
48
+ }
49
+ }
50
+ end
51
+ end
52
+ }
53
+ }
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,81 @@
1
+ # Copyright (c) 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_relative 'playfield'
23
+
24
+ class GlimmerTetris
25
+ module View
26
+ class ScoreLane
27
+ include Glimmer::UI::CustomWidget
28
+
29
+ options :game
30
+
31
+ body {
32
+ composite {
33
+ row_layout {
34
+ type :vertical
35
+ center true
36
+ fill true
37
+ margin_width 0
38
+ margin_right BLOCK_SIZE
39
+ margin_height BLOCK_SIZE
40
+ }
41
+ label(:center) {
42
+ text 'Next'
43
+ font name: FONT_NAME, height: FONT_TITLE_HEIGHT, style: FONT_TITLE_STYLE
44
+ }
45
+ playfield(game_playfield: game.preview_playfield, playfield_width: Model::Game::PREVIEW_PLAYFIELD_WIDTH, playfield_height: Model::Game::PREVIEW_PLAYFIELD_HEIGHT)
46
+
47
+ label(:center) {
48
+ text 'Score'
49
+ font name: FONT_NAME, height: FONT_TITLE_HEIGHT, style: FONT_TITLE_STYLE
50
+ }
51
+ label(:center) {
52
+ text bind(game, :score)
53
+ font height: FONT_TITLE_HEIGHT
54
+ }
55
+
56
+ label # spacer
57
+
58
+ label(:center) {
59
+ text 'Lines'
60
+ font name: FONT_NAME, height: FONT_TITLE_HEIGHT, style: FONT_TITLE_STYLE
61
+ }
62
+ label(:center) {
63
+ text bind(game, :lines)
64
+ font height: FONT_TITLE_HEIGHT
65
+ }
66
+
67
+ label # spacer
68
+
69
+ label(:center) {
70
+ text 'Level'
71
+ font name: FONT_NAME, height: FONT_TITLE_HEIGHT, style: FONT_TITLE_STYLE
72
+ }
73
+ label(:center) {
74
+ text bind(game, :level)
75
+ font height: FONT_TITLE_HEIGHT
76
+ }
77
+ }
78
+ }
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,142 @@
1
+ # Copyright (c) 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
+ class GlimmerTetris
23
+ module View
24
+ class TetrisMenuBar
25
+ include Glimmer::UI::CustomWidget
26
+
27
+ COMMAND_KEY = OS.mac? ? :command : :ctrl
28
+
29
+ options :game
30
+
31
+ body {
32
+ menu_bar {
33
+ menu {
34
+ text '&Game'
35
+
36
+ menu_item {
37
+ text '&Start'
38
+ enabled bind(game, :game_over)
39
+ accelerator COMMAND_KEY, :s
40
+
41
+ on_widget_selected {
42
+ game.start!
43
+ }
44
+ }
45
+ menu_item(:check) {
46
+ text '&Pause'
47
+ accelerator COMMAND_KEY, :p
48
+ enabled bind(game, :game_over, on_read: :!) {|value| value && !game.show_high_scores}
49
+ enabled bind(game, :show_high_scores, on_read: :!) {|value| value && !game.game_over}
50
+ selection bind(game, :paused)
51
+ }
52
+ menu_item {
53
+ text '&Restart'
54
+ accelerator COMMAND_KEY, :r
55
+
56
+ on_widget_selected {
57
+ game.restart!
58
+ }
59
+ }
60
+ menu_item(:separator)
61
+ menu_item {
62
+ text '&Exit'
63
+ accelerator COMMAND_KEY, :x
64
+
65
+ on_widget_selected {
66
+ parent_proxy.close
67
+ }
68
+ }
69
+ } # end of menu
70
+
71
+ menu {
72
+ text '&View'
73
+
74
+ menu {
75
+ text '&High Scores'
76
+ menu_item(:check) {
77
+ text '&Show'
78
+ accelerator COMMAND_KEY, :shift, :h
79
+ selection bind(game, :show_high_scores)
80
+ }
81
+ menu_item {
82
+ text '&Clear'
83
+ accelerator COMMAND_KEY, :shift, :c
84
+
85
+ on_widget_selected {
86
+ game.clear_high_scores!
87
+ }
88
+ }
89
+ }
90
+ } # end of menu
91
+
92
+ menu {
93
+ text '&Options'
94
+ menu_item(:check) {
95
+ text '&Beeping'
96
+ accelerator COMMAND_KEY, :b
97
+ selection bind(game, :beeping)
98
+ }
99
+ menu {
100
+ text 'Up Arrow'
101
+ menu_item(:radio) {
102
+ text '&Instant Down'
103
+ accelerator COMMAND_KEY, :shift, :i
104
+ selection bind(game, :instant_down_on_up, computed_by: :up_arrow_action)
105
+ }
106
+ menu_item(:radio) {
107
+ text 'Rotate &Right'
108
+ accelerator COMMAND_KEY, :shift, :r
109
+ selection bind(game, :rotate_right_on_up, computed_by: :up_arrow_action)
110
+ }
111
+ menu_item(:radio) {
112
+ text 'Rotate &Left'
113
+ accelerator COMMAND_KEY, :shift, :l
114
+ selection bind(game, :rotate_left_on_up, computed_by: :up_arrow_action)
115
+ }
116
+ }
117
+ } # end of menu
118
+
119
+ menu {
120
+ text '&Help'
121
+
122
+ menu_item {
123
+ text '&About'
124
+ accelerator COMMAND_KEY, :shift, :a
125
+
126
+ on_widget_selected {
127
+ parent_custom_shell&.show_about_dialog
128
+ }
129
+ }
130
+ } # end of menu
131
+ }
132
+ }
133
+
134
+ def parent_custom_shell
135
+ # grab custom shell widget wrapping parent widget proxy (i.e. Tetris) and invoke method on it
136
+ the_parent_custom_shell = parent_proxy&.get_data('custom_shell')
137
+ the_parent_custom_shell if the_parent_custom_shell&.visible?
138
+ end
139
+
140
+ end
141
+ end
142
+ end