glimmer-dsl-opal 0.25.4 → 0.26.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,41 @@
1
+ # Copyright (c) 2007-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 'bevel'
23
+
24
+ class Tetris
25
+ module View
26
+ class Block
27
+ include Glimmer::UI::CustomWidget
28
+
29
+ options :game_playfield, :block_size, :row, :column
30
+
31
+ body {
32
+ canvas { |canvas_proxy|
33
+ background <= [game_playfield[row][column], :color]
34
+ # bevel(size: block_size) {
35
+ # base_color <= [game_playfield[row][column], :color]
36
+ # }
37
+ }
38
+ }
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,122 @@
1
+ # Copyright (c) 2007-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 Tetris
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 'Glimmer Tetris'
44
+
45
+ tetris_menu_bar(game: game)
46
+
47
+ label(:center) {
48
+ text <= [game, :game_over, on_read: ->(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 <=> [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 <= [game, :game_over, on_read: ->(game_over) { game_over ? 'Play Again?' : 'Close'}]
76
+ focus true # initial focus
77
+
78
+ on_widget_selected {
79
+ 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
+ @high_score_table.edit_table_item(
92
+ @high_score_table.items.first, # row item
93
+ 0, # column
94
+ write_on_cancel: true,
95
+ after_write: -> {
96
+ @play_close_button.set_focus
97
+ },
98
+ )
99
+ end
100
+ }
101
+
102
+ on_shell_closed {
103
+ # guard is needed because there is an observer in Tetris closing on
104
+ # game.show_high_scores change, which gets set below
105
+ unless @closing
106
+ @closing = true
107
+ @high_score_table.cancel_edit!
108
+ game.paused = @game_paused
109
+ game.show_high_scores = false
110
+ else
111
+ @closing = false
112
+ end
113
+ }
114
+
115
+ on_widget_disposed {
116
+ @game_over_observer.deregister
117
+ }
118
+ }
119
+ }
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,56 @@
1
+ # Copyright (c) 2007-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 Tetris
25
+ module View
26
+ class Playfield
27
+ include Glimmer::UI::CustomWidget
28
+
29
+ options :game_playfield, :playfield_width, :playfield_height, :block_size
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 { |row|
43
+ playfield_width.times { |column|
44
+ block(game_playfield: game_playfield, block_size: block_size, row: row, column: column) {
45
+ layout_data {
46
+ width_hint block_size
47
+ height_hint block_size
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,87 @@
1
+ # Copyright (c) 2007-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
+ require_relative 'playfield'
24
+
25
+ class Tetris
26
+ module View
27
+ class ScoreLane
28
+ include Glimmer::UI::CustomWidget
29
+
30
+ options :block_size, :game
31
+
32
+ before_body do
33
+ @font_name = FONT_NAME
34
+ @font_height = FONT_TITLE_HEIGHT
35
+ end
36
+
37
+ body {
38
+ composite {
39
+ row_layout {
40
+ type :vertical
41
+ center true
42
+ # fill true
43
+ # margin_width 0
44
+ # margin_right block_size
45
+ # margin_height block_size
46
+ }
47
+ label(:center) {
48
+ text 'Next'
49
+ font name: @font_name, height: @font_height, style: FONT_TITLE_STYLE
50
+ }
51
+ playfield(game_playfield: game.preview_playfield, playfield_width: Model::Game::PREVIEW_PLAYFIELD_WIDTH, playfield_height: Model::Game::PREVIEW_PLAYFIELD_HEIGHT, block_size: block_size)
52
+
53
+ label(:center) {
54
+ text 'Score'
55
+ font name: @font_name, height: @font_height, style: FONT_TITLE_STYLE
56
+ }
57
+ label(:center) {
58
+ text <= [game, :score]
59
+ font height: @font_height
60
+ }
61
+
62
+ label # spacer
63
+
64
+ label(:center) {
65
+ text 'Lines'
66
+ font name: @font_name, height: @font_height, style: FONT_TITLE_STYLE
67
+ }
68
+ label(:center) {
69
+ text <= [game, :lines]
70
+ font height: @font_height
71
+ }
72
+
73
+ label # spacer
74
+
75
+ label(:center) {
76
+ text 'Level'
77
+ font name: @font_name, height: @font_height, style: FONT_TITLE_STYLE
78
+ }
79
+ label(:center) {
80
+ text <= [game, :level]
81
+ font height: @font_height
82
+ }
83
+ }
84
+ }
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,136 @@
1
+ # Copyright (c) 2007-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 Tetris
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 <= [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 <= [game, :game_over, on_read: ->(value) { !value && !game.show_high_scores }]
49
+ enabled <= [game, :show_high_scores, on_read: ->(value) { !value && !game.game_over }]
50
+ selection <=> [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 <=> [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 {
95
+ text 'Up Action'
96
+ menu_item(:radio) {
97
+ text '&Instant Down'
98
+ accelerator COMMAND_KEY, :shift, :i
99
+ selection <=> [game, :instant_down_on_up, computed_by: :up_arrow_action]
100
+ }
101
+ menu_item(:radio) {
102
+ text 'Rotate &Right'
103
+ accelerator COMMAND_KEY, :shift, :r
104
+ selection <=> [game, :rotate_right_on_up, computed_by: :up_arrow_action]
105
+ }
106
+ menu_item(:radio) {
107
+ text 'Rotate &Left'
108
+ accelerator COMMAND_KEY, :shift, :l
109
+ selection <=> [game, :rotate_left_on_up, computed_by: :up_arrow_action]
110
+ }
111
+ }
112
+ } # end of menu
113
+
114
+ menu {
115
+ text '&Help'
116
+
117
+ menu_item {
118
+ text '&About'
119
+ accelerator COMMAND_KEY, :shift, :a
120
+
121
+ on_widget_selected {
122
+ parent_custom_shell&.show_about_dialog
123
+ }
124
+ }
125
+ } # end of menu
126
+ }
127
+ }
128
+
129
+ def parent_custom_shell
130
+ # grab custom shell widget wrapping parent widget proxy (i.e. Tetris) and invoke method on it
131
+ the_parent_custom_shell = parent_proxy&.get_data('custom_shell')
132
+ the_parent_custom_shell if the_parent_custom_shell&.visible?
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,166 @@
1
+ # Copyright (c) 2007-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/model/game'
23
+
24
+ require_relative 'tetris/view/playfield'
25
+ require_relative 'tetris/view/score_lane'
26
+ require_relative 'tetris/view/high_score_dialog'
27
+ require_relative 'tetris/view/tetris_menu_bar'
28
+
29
+ # Tetris App View Custom Shell (represents `tetris` keyword)
30
+ class Tetris
31
+ include Glimmer::UI::CustomShell
32
+
33
+ BLOCK_SIZE = 7
34
+ FONT_NAME = 'Menlo'
35
+ FONT_TITLE_HEIGHT = 32
36
+ FONT_TITLE_STYLE = :bold
37
+ BEVEL_CONSTANT = 20
38
+
39
+ option :playfield_width, default: Model::Game::PLAYFIELD_WIDTH
40
+ option :playfield_height, default: Model::Game::PLAYFIELD_HEIGHT
41
+
42
+ attr_reader :game
43
+
44
+ before_body do
45
+ @game = Model::Game.new(playfield_width, playfield_height)
46
+
47
+ Display.app_name = 'Glimmer Tetris'
48
+
49
+ display {
50
+ on_swt_keydown do |key_event|
51
+ case key_event.keyCode
52
+ when 'w'.bytes.first
53
+ case game.up_arrow_action
54
+ when :instant_down
55
+ game.down!(instant: true)
56
+ when :rotate_right
57
+ game.rotate!(:right)
58
+ when :rotate_left
59
+ game.rotate!(:left)
60
+ end
61
+ when 's'.bytes.first
62
+ game.down!
63
+ when 'a'.bytes.first
64
+ game.left!
65
+ when 'd'.bytes.first
66
+ game.right!
67
+ when 'q'.bytes.first
68
+ game.rotate!(:left)
69
+ when 'e'.bytes.first
70
+ game.rotate!(:right)
71
+ end
72
+ end
73
+ }
74
+ end
75
+
76
+ after_body do
77
+ observe(@game, :game_over) do |game_over|
78
+ if game_over
79
+ show_high_score_dialog
80
+ else
81
+ start_moving_tetrominos_down
82
+ end
83
+ end
84
+ observe(@game, :show_high_scores) do |show_high_scores|
85
+ if show_high_scores
86
+ show_high_score_dialog
87
+ else
88
+ @high_score_dialog.close unless @high_score_dialog.nil? || @high_score_dialog.disposed? || !@high_score_dialog.visible?
89
+ end
90
+ end
91
+ @game.start!
92
+ end
93
+
94
+ body {
95
+ shell(:no_resize) {
96
+ grid_layout {
97
+ num_columns 2
98
+ make_columns_equal_width false
99
+ margin_width 0
100
+ margin_height 0
101
+ horizontal_spacing 0
102
+ }
103
+
104
+ text 'Glimmer Tetris'
105
+ # minimum_size 475, 500
106
+ # image tetris_icon
107
+ background rgb(236, 236, 236)
108
+
109
+ tetris_menu_bar(game: game)
110
+
111
+ playfield(game_playfield: game.playfield, playfield_width: playfield_width, playfield_height: playfield_height, block_size: BLOCK_SIZE) {
112
+ layout_data {
113
+ width_hint 370
114
+ }
115
+ }
116
+
117
+ score_lane(game: game, block_size: BLOCK_SIZE) {
118
+ layout_data(:fill, :fill, true, true)
119
+ }
120
+ }
121
+ }
122
+
123
+ # def tetris_icon
124
+ # icon_block_size = 64
125
+ # icon_bevel_size = icon_block_size.to_f / 25.to_f
126
+ # icon_bevel_pixel_size = 0.16*icon_block_size.to_f
127
+ # icon_size = 8
128
+ # icon_pixel_size = icon_block_size * icon_size
129
+ # image(icon_pixel_size, icon_pixel_size) {
130
+ # icon_size.times { |row|
131
+ # icon_size.times { |column|
132
+ # colored = row >= 1 && column.between?(1, 6)
133
+ # color = colored ? color(([:white] + Model::Tetromino::LETTER_COLORS.values).sample) : color(:white)
134
+ # x = column * icon_block_size
135
+ # y = row * icon_block_size
136
+ # bevel(x: x, y: y, base_color: color, size: icon_block_size)
137
+ # }
138
+ # }
139
+ # }
140
+ # end
141
+
142
+ def start_moving_tetrominos_down
143
+ Async::Task.new do
144
+ work = lambda do
145
+ @game.down! # unless @game.paused?
146
+ Async::Task.new(delay: @game.delay * 1000.0, &work) unless @game.game_over? || body_root.disposed?
147
+ end
148
+ Async::Task.new(delay: @game.delay * 1000.0, &work)
149
+ end
150
+ end
151
+
152
+ def show_high_score_dialog
153
+ return if @high_score_dialog&.visible?
154
+ @high_score_dialog = high_score_dialog(parent_shell: body_root, game: @game) #if @high_score_dialog.nil? || @high_score_dialog.disposed?
155
+ @high_score_dialog.show
156
+ end
157
+
158
+ def show_about_dialog
159
+ message_box {
160
+ text 'Glimmer Tetris'
161
+ message "Glimmer Tetris\n\nGlimmer DSL for SWT Sample\n\nLeft is A\nRight is D\nDown is S\nUp is W\nRotate Left is Q\nRotate Right is E\n\n for Left, Down, Right, Up\n\nCopyright (c) 2007-2021 Andy Maleh"
162
+ }.open
163
+ end
164
+ end
165
+
166
+ Tetris.launch