glimmer_tetris 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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