glimmer-dsl-swt 4.20.13.9 → 4.20.13.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/README.md +5 -5
  4. data/VERSION +1 -1
  5. data/docs/reference/GLIMMER_SAMPLES.md +37 -3
  6. data/docs/reference/GLIMMER_STYLE_GUIDE.md +2 -1
  7. data/glimmer-dsl-swt.gemspec +0 -0
  8. data/lib/glimmer-dsl-swt.rb +1 -0
  9. data/lib/glimmer/rake_task/scaffold.rb +14 -14
  10. data/lib/glimmer/swt/custom/code_text.rb +4 -4
  11. data/lib/glimmer/swt/custom/drawable.rb +1 -0
  12. data/lib/glimmer/swt/custom/shape.rb +20 -1
  13. data/lib/glimmer/swt/custom/shape/arc.rb +2 -0
  14. data/lib/glimmer/swt/custom/shape/cubic.rb +1 -0
  15. data/lib/glimmer/swt/custom/shape/line.rb +1 -0
  16. data/lib/glimmer/swt/custom/shape/oval.rb +2 -0
  17. data/lib/glimmer/swt/custom/shape/path.rb +1 -5
  18. data/lib/glimmer/swt/custom/shape/point.rb +1 -0
  19. data/lib/glimmer/swt/custom/shape/polygon.rb +2 -0
  20. data/lib/glimmer/swt/custom/shape/polyline.rb +1 -0
  21. data/lib/glimmer/swt/custom/shape/rectangle.rb +1 -0
  22. data/samples/elaborate/calculator.rb +2 -2
  23. data/samples/elaborate/contact_manager.rb +2 -2
  24. data/samples/elaborate/game_of_life.rb +111 -0
  25. data/samples/elaborate/game_of_life/model/cell.rb +72 -0
  26. data/samples/elaborate/game_of_life/model/grid.rb +97 -0
  27. data/samples/elaborate/klondike_solitaire.rb +3 -22
  28. data/samples/elaborate/klondike_solitaire/view/empty_playing_card.rb +8 -3
  29. data/samples/elaborate/klondike_solitaire/view/foundation_pile.rb +4 -4
  30. data/samples/elaborate/klondike_solitaire/view/hidden_playing_card.rb +8 -1
  31. data/samples/elaborate/klondike_solitaire/view/playing_card.rb +2 -2
  32. data/samples/elaborate/login.rb +2 -2
  33. data/samples/elaborate/mandelbrot_fractal.rb +12 -12
  34. data/samples/elaborate/meta_sample.rb +2 -2
  35. data/samples/elaborate/metronome.rb +2 -2
  36. data/samples/elaborate/parking.rb +146 -0
  37. data/samples/elaborate/parking/model/parking_floor.rb +41 -0
  38. data/samples/elaborate/parking/model/parking_presenter.rb +42 -0
  39. data/samples/elaborate/parking/model/parking_spot.rb +46 -0
  40. data/samples/elaborate/stock_ticker.rb +8 -8
  41. data/samples/elaborate/tetris.rb +4 -4
  42. data/samples/elaborate/tetris/view/bevel.rb +2 -2
  43. data/samples/elaborate/tetris/view/score_lane.rb +2 -2
  44. data/samples/elaborate/tic_tac_toe.rb +6 -6
  45. data/samples/elaborate/timer.rb +4 -4
  46. data/samples/elaborate/weather.rb +4 -4
  47. data/samples/hello/hello_button.rb +2 -2
  48. data/samples/hello/hello_c_combo.rb +2 -2
  49. data/samples/hello/hello_canvas.rb +4 -4
  50. data/samples/hello/hello_canvas_animation.rb +2 -2
  51. data/samples/hello/hello_canvas_data_binding.rb +2 -2
  52. data/samples/hello/hello_checkbox.rb +2 -2
  53. data/samples/hello/hello_checkbox_group.rb +2 -2
  54. data/samples/hello/hello_code_text.rb +2 -2
  55. data/samples/hello/hello_color_dialog.rb +2 -2
  56. data/samples/hello/hello_combo.rb +2 -2
  57. data/samples/hello/hello_computed.rb +14 -22
  58. data/samples/hello/hello_cool_bar.rb +2 -2
  59. data/samples/hello/hello_cursor.rb +2 -2
  60. data/samples/hello/hello_custom_shape.rb +2 -2
  61. data/samples/hello/hello_custom_shell.rb +2 -2
  62. data/samples/hello/hello_custom_widget.rb +4 -4
  63. data/samples/hello/hello_date_time.rb +2 -2
  64. data/samples/hello/hello_directory_dialog.rb +2 -2
  65. data/samples/hello/hello_file_dialog.rb +2 -2
  66. data/samples/hello/hello_font_dialog.rb +2 -2
  67. data/samples/hello/hello_group.rb +2 -2
  68. data/samples/hello/hello_list_multi_selection.rb +2 -2
  69. data/samples/hello/hello_list_single_selection.rb +2 -2
  70. data/samples/hello/hello_progress_bar.rb +2 -2
  71. data/samples/hello/hello_radio.rb +2 -2
  72. data/samples/hello/hello_radio_group.rb +2 -2
  73. data/samples/hello/hello_scale.rb +2 -2
  74. data/samples/hello/hello_spinner.rb +2 -2
  75. data/samples/hello/hello_table.rb +2 -2
  76. data/samples/hello/hello_text.rb +2 -2
  77. data/samples/hello/hello_tool_bar.rb +2 -2
  78. data/samples/hello/hello_tray_item.rb +2 -2
  79. data/samples/hello/hello_tree.rb +4 -4
  80. metadata +9 -2
@@ -15,7 +15,7 @@ class Calculator
15
15
 
16
16
  attr_reader :presenter
17
17
 
18
- before_body {
18
+ before_body do
19
19
  @presenter = Model::Presenter.new
20
20
 
21
21
  Display.setAppName('Glimmer Calculator')
@@ -30,7 +30,7 @@ class Calculator
30
30
  display_about_dialog
31
31
  }
32
32
  }
33
- }
33
+ end
34
34
 
35
35
  body {
36
36
  shell {
@@ -26,10 +26,10 @@ require_relative "contact_manager/contact_manager_presenter"
26
26
  class ContactManager
27
27
  include Glimmer::UI::CustomShell
28
28
 
29
- before_body {
29
+ before_body do
30
30
  @contact_manager_presenter = ContactManagerPresenter.new
31
31
  @contact_manager_presenter.list
32
- }
32
+ end
33
33
 
34
34
  body {
35
35
  shell {
@@ -0,0 +1,111 @@
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 'glimmer-dsl-swt'
23
+
24
+ require_relative 'game_of_life/model/grid'
25
+
26
+ class GameOfLife
27
+ include Glimmer::UI::CustomShell
28
+
29
+ WIDTH = 20
30
+ HEIGHT = 20
31
+ CELL_WIDTH = 25
32
+ CELL_HEIGHT = 25
33
+
34
+ before_body do
35
+ @grid = GameOfLife::Model::Grid.new(WIDTH, HEIGHT)
36
+ end
37
+
38
+ body {
39
+ shell {
40
+ row_layout :vertical
41
+ text "Conway's Game of Life (Glimmer Edition)"
42
+
43
+ canvas {
44
+ layout_data {
45
+ width WIDTH*CELL_WIDTH
46
+ height HEIGHT*CELL_HEIGHT
47
+ }
48
+ (0...HEIGHT).each do |row_index|
49
+ (0...WIDTH).each do |column_index|
50
+ rectangle(column_index*CELL_WIDTH, row_index*CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT) {
51
+ background <= [@grid.cell_rows[row_index][column_index], "alive", on_read: ->(a) {a ? :black : :white}]
52
+
53
+ on_mouse_down {
54
+ @grid.cell_rows[row_index][column_index].toggle_aliveness!
55
+ }
56
+ }
57
+ end
58
+ end
59
+ }
60
+
61
+ composite {
62
+ row_layout(:horizontal) {
63
+ margin_width 0
64
+ }
65
+
66
+ button {
67
+ text 'Step'
68
+ enabled <= [@grid, :playing, on_read: :! ]
69
+
70
+ on_widget_selected {
71
+ @grid.step!
72
+ }
73
+ }
74
+
75
+ button {
76
+ text 'Clear'
77
+ enabled <= [@grid, :playing, on_read: :! ]
78
+
79
+ on_widget_selected {
80
+ @grid.clear!
81
+ }
82
+ }
83
+
84
+ button {
85
+ text <= [@grid, :playing, on_read: ->(p) { p ? 'Stop' : 'Play' }]
86
+
87
+ on_widget_selected {
88
+ @grid.toggle_playback!
89
+ }
90
+ }
91
+
92
+ label {
93
+ text 'Slower'
94
+ }
95
+
96
+ scale {
97
+ minimum 1
98
+ maximum 100
99
+ selection <=> [@grid, :speed]
100
+ }
101
+
102
+ label {
103
+ text 'Faster'
104
+ }
105
+
106
+ }
107
+ }
108
+ }
109
+ end
110
+
111
+ GameOfLife.launch
@@ -0,0 +1,72 @@
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 GameOfLife
23
+ module Model
24
+ class Cell
25
+ attr_reader :grid, :row_index, :column_index
26
+ attr_accessor :alive
27
+ alias alive? alive
28
+
29
+ def initialize(grid, row_index, column_index, alive=false)
30
+ @grid = grid
31
+ @row_index = row_index
32
+ @column_index = column_index
33
+ @alive = alive
34
+ end
35
+
36
+ def live!
37
+ self.alive = true
38
+ end
39
+
40
+ def die!
41
+ self.alive = false
42
+ end
43
+
44
+ def toggle_aliveness!
45
+ return if grid.playing?
46
+ dead ? live! : die!
47
+ end
48
+
49
+ def dead?
50
+ !alive?
51
+ end
52
+ alias dead dead?
53
+
54
+ # step into the next generation
55
+ def step!
56
+ self.alive = (alive? && alive_neighbor_count.between?(2, 3)) || (dead? && alive_neighbor_count == 3)
57
+ end
58
+
59
+ def alive_neighbor_count
60
+ [row_index - 1, 0].max.upto([row_index + 1, grid.row_count - 1].min).map do |current_row_index|
61
+ [column_index - 1, 0].max.upto([column_index + 1, grid.column_count - 1].min).map do |current_column_index|
62
+ if current_row_index == row_index && current_column_index == column_index
63
+ 0
64
+ else
65
+ grid.previous_cell_rows[current_row_index][current_column_index].alive? ? 1 : 0
66
+ end
67
+ end
68
+ end.flatten.reduce(:+)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,97 @@
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 'cell'
23
+
24
+ class GameOfLife
25
+ module Model
26
+ class Grid
27
+ include Glimmer # included only to utilize sync_exec/async_exec
28
+ DEFAULT_ROW_COUNT = 100
29
+ DEFAULT_COLUMN_COUNT = 100
30
+
31
+ attr_reader :row_count, :column_count
32
+ attr_accessor :cell_rows, :previous_cell_rows, :playing, :speed
33
+ alias playing? playing
34
+
35
+ def initialize(row_count=DEFAULT_ROW_COUNT, column_count=DEFAULT_COLUMN_COUNT)
36
+ @row_count = row_count
37
+ @column_count = column_count
38
+ @speed = 1.0
39
+ build_cells
40
+ end
41
+
42
+ def clear!
43
+ cell_rows.each do |row|
44
+ row.each do |cell|
45
+ cell.die!
46
+ end
47
+ end
48
+ end
49
+
50
+ # steps into the next generation of cells given their current neighbors
51
+ def step!
52
+ self.previous_cell_rows = cell_rows.map do |row|
53
+ row.map do |cell|
54
+ cell.clone
55
+ end
56
+ end
57
+ cell_rows.each do |row|
58
+ row.each do |cell|
59
+ cell.step!
60
+ end
61
+ end
62
+ end
63
+
64
+ def toggle_playback!
65
+ if playing?
66
+ stop!
67
+ else
68
+ play!
69
+ end
70
+ end
71
+
72
+ def play!
73
+ self.playing = true
74
+ Thread.new do
75
+ while @playing
76
+ sync_exec { step! }
77
+ sleep(1.0/@speed)
78
+ end
79
+ end
80
+ end
81
+
82
+ def stop!
83
+ self.playing = false
84
+ end
85
+
86
+ private
87
+
88
+ def build_cells
89
+ @cell_rows = @row_count.times.map do |row_index|
90
+ @column_count.times.map do |column_index|
91
+ Cell.new(self, row_index, column_index)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -15,17 +15,7 @@ class KlondikeSolitaire
15
15
  TABLEAU_WIDTH = 2*MARGIN + 7*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING)
16
16
  TABLEAU_HEIGHT = 400
17
17
 
18
-
19
- ## Add options like the following to configure CustomShell by outside consumers
20
- #
21
- # options :title, :background_color
22
- # option :width, default: 320
23
- # option :height, default: 240
24
-
25
- ## Use before_body block to pre-initialize variables to use in body
26
- #
27
- #
28
- before_body {
18
+ before_body do
29
19
  @game = Model::Game.new
30
20
  Display.app_name = 'Glimmer Klondike Solitaire'
31
21
  @display = display {
@@ -36,19 +26,10 @@ class KlondikeSolitaire
36
26
  display_about_dialog
37
27
  }
38
28
  }
39
- }
40
-
41
- ## Use after_body block to setup observers for widgets in body
42
- #
43
- # after_body {
44
- #
45
- # }
29
+ end
46
30
 
47
- ## Add widget content inside custom shell body
48
- ## Top-most widget must be a shell or another custom shell
49
- #
50
31
  body {
51
- shell(:no_resize) {
32
+ shell {
52
33
  row_layout(:vertical) {
53
34
  fill true
54
35
  center true
@@ -5,10 +5,15 @@ class KlondikeSolitaire
5
5
  class EmptyPlayingCard
6
6
  include Glimmer::UI::CustomShape
7
7
 
8
- option :suit
9
-
8
+ options :card_x, :card_y, :suit
9
+
10
+ before_body do
11
+ self.card_x ||= 0
12
+ self.card_y ||= 0
13
+ end
14
+
10
15
  body {
11
- rectangle(0, 0, 49, 79, 15, 15) {
16
+ rectangle(card_x, card_y, 49, 79, 15, 15) {
12
17
  foreground :gray
13
18
 
14
19
  if suit
@@ -10,12 +10,12 @@ class KlondikeSolitaire
10
10
 
11
11
  attr_accessor :current_image, :model
12
12
 
13
- before_body {
13
+ before_body do
14
14
  self.current_image = image(50, 80) {empty_playing_card(suit: suit)}
15
15
  self.model = game.foundation_piles[Model::PlayingCard::SUITS.index(suit)]
16
- }
16
+ end
17
17
 
18
- after_body {
18
+ after_body do
19
19
  observe(model, 'playing_cards.last') do |last_card|
20
20
  if last_card
21
21
  body_root.content {
@@ -28,7 +28,7 @@ class KlondikeSolitaire
28
28
  }
29
29
  end
30
30
  end
31
- }
31
+ end
32
32
 
33
33
  body {
34
34
  shape(pile_x, pile_y) {
@@ -3,8 +3,15 @@ class KlondikeSolitaire
3
3
  class HiddenPlayingCard
4
4
  include Glimmer::UI::CustomShape
5
5
 
6
+ options :card_x, :card_y
7
+
8
+ before_body do
9
+ self.card_x ||= 0
10
+ self.card_y ||= 0
11
+ end
12
+
6
13
  body {
7
- rectangle(0, 0, 49, 79, 15, 15) {
14
+ rectangle(card_x, card_y, 49, 79, 15, 15) {
8
15
  background :red
9
16
 
10
17
  # border
@@ -5,10 +5,10 @@ class KlondikeSolitaire
5
5
 
6
6
  options :card_x, :card_y, :model, :parent_pile
7
7
 
8
- before_body {
8
+ before_body do
9
9
  self.card_x ||= 0
10
10
  self.card_y ||= 0
11
- }
11
+ end
12
12
 
13
13
  body {
14
14
  rectangle(card_x, card_y, 49, 79, 15, 15) {
@@ -65,9 +65,9 @@ end
65
65
  class Login
66
66
  include Glimmer::UI::CustomShell
67
67
 
68
- before_body {
68
+ before_body do
69
69
  @presenter = LoginPresenter.new
70
- }
70
+ end
71
71
 
72
72
  body {
73
73
  shell {