glimmer-dsl-swt 4.21.2.4 → 4.22.1.1

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +208 -167
  3. data/README.md +18 -11
  4. data/VERSION +1 -1
  5. data/docs/reference/GLIMMER_COMMAND.md +2 -2
  6. data/docs/reference/GLIMMER_CONFIGURATION.md +14 -3
  7. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +277 -112
  8. data/docs/reference/GLIMMER_SAMPLES.md +26 -0
  9. data/glimmer-dsl-swt.gemspec +0 -0
  10. data/lib/ext/glimmer/config.rb +41 -24
  11. data/lib/glimmer/data_binding/observable_widget.rb +6 -6
  12. data/lib/glimmer/data_binding/widget_binding.rb +4 -3
  13. data/lib/glimmer/dsl/swt/observe_expression.rb +2 -1
  14. data/lib/glimmer/dsl/swt/sync_call_expression.rb +38 -0
  15. data/lib/glimmer/dsl/swt/transform_expression.rb +1 -1
  16. data/lib/glimmer/launcher.rb +15 -14
  17. data/lib/glimmer/rake_task/package.rb +5 -3
  18. data/lib/glimmer/rake_task/scaffold.rb +2 -14
  19. data/lib/glimmer/swt/color_proxy.rb +5 -5
  20. data/lib/glimmer/swt/custom/drawable.rb +8 -2
  21. data/lib/glimmer/swt/custom/shape/line.rb +0 -1
  22. data/lib/glimmer/swt/custom/shape/path.rb +2 -2
  23. data/lib/glimmer/swt/custom/shape/path_segment.rb +2 -2
  24. data/lib/glimmer/swt/custom/shape/point.rb +8 -1
  25. data/lib/glimmer/swt/custom/shape.rb +170 -69
  26. data/lib/glimmer/swt/display_proxy.rb +15 -10
  27. data/lib/glimmer/swt/image_proxy.rb +5 -5
  28. data/lib/glimmer/swt/message_box_proxy.rb +5 -5
  29. data/lib/glimmer/swt/shape_listener_proxy.rb +55 -0
  30. data/lib/glimmer/swt/shell_proxy.rb +1 -1
  31. data/lib/glimmer/swt/transform_proxy.rb +3 -3
  32. data/lib/glimmer/swt/tray_proxy.rb +4 -4
  33. data/lib/glimmer/swt/widget_proxy.rb +14 -10
  34. data/lib/glimmer/ui/custom_shape.rb +34 -10
  35. data/lib/glimmer/ui/custom_widget.rb +7 -10
  36. data/lib/glimmer-dsl-swt.rb +6 -2
  37. data/samples/elaborate/battleship/view/cell.rb +10 -2
  38. data/samples/elaborate/klondike_solitaire/model/column_pile.rb +0 -1
  39. data/samples/elaborate/klondike_solitaire/view/column_pile.rb +3 -16
  40. data/samples/elaborate/klondike_solitaire/view/dealing_pile.rb +1 -1
  41. data/samples/elaborate/klondike_solitaire/view/dealt_pile.rb +12 -5
  42. data/samples/elaborate/klondike_solitaire/view/empty_playing_card.rb +2 -1
  43. data/samples/elaborate/klondike_solitaire/view/foundation_pile.rb +2 -2
  44. data/samples/elaborate/klondike_solitaire/view/hidden_playing_card.rb +2 -2
  45. data/samples/elaborate/klondike_solitaire/view/klondike_solitaire_menu_bar.rb +60 -0
  46. data/samples/elaborate/klondike_solitaire/view/playing_card.rb +3 -2
  47. data/samples/elaborate/klondike_solitaire.rb +13 -55
  48. data/samples/elaborate/mandelbrot_fractal.rb +3 -1
  49. data/samples/elaborate/quarto/model/game.rb +124 -0
  50. data/samples/elaborate/quarto/model/piece/cube.rb +31 -0
  51. data/samples/elaborate/quarto/model/piece/cylinder.rb +31 -0
  52. data/samples/elaborate/quarto/model/piece.rb +70 -0
  53. data/samples/elaborate/quarto/view/available_pieces_area.rb +72 -0
  54. data/samples/elaborate/quarto/view/board.rb +65 -0
  55. data/samples/elaborate/quarto/view/cell.rb +85 -0
  56. data/samples/elaborate/quarto/view/cube.rb +73 -0
  57. data/samples/elaborate/quarto/view/cylinder.rb +72 -0
  58. data/samples/elaborate/quarto/view/message_box_panel.rb +114 -0
  59. data/samples/elaborate/quarto/view/piece.rb +56 -0
  60. data/samples/elaborate/quarto/view/selected_piece_area.rb +69 -0
  61. data/samples/elaborate/quarto.rb +190 -0
  62. data/samples/hello/hello_custom_widget.rb +23 -5
  63. data/samples/hello/hello_scrolled_composite.rb +95 -0
  64. data/samples/hello/hello_world.rb +1 -0
  65. data/vendor/swt/linux/swt.jar +0 -0
  66. data/vendor/swt/linux_aarch64/swt.jar +0 -0
  67. data/vendor/swt/mac/swt.jar +0 -0
  68. data/vendor/swt/mac_aarch64/swt.jar +0 -0
  69. data/vendor/swt/windows/swt.jar +0 -0
  70. metadata +21 -25
  71. data/bin/glimmer_runner.rb +0 -4
@@ -175,8 +175,10 @@ module Glimmer
175
175
  @keyword = underscored_widget_name.to_s
176
176
  if respond_to?(:on_widget_disposed)
177
177
  on_widget_disposed {
178
- clear_shapes
179
- deregister_shape_painting
178
+ unless shell_proxy.last_shell_closing?
179
+ clear_shapes
180
+ deregister_shape_painting
181
+ end
180
182
  }
181
183
  end
182
184
  end
@@ -199,7 +201,11 @@ module Glimmer
199
201
  end
200
202
 
201
203
  def shell_proxy
202
- @swt_widget.shell.get_data('proxy')
204
+ if @swt_widget.respond_to?(:shell)
205
+ @swt_widget.shell.get_data('proxy')
206
+ else
207
+ @parent_proxy&.shell_proxy
208
+ end
203
209
  end
204
210
 
205
211
  def extract_args(underscored_widget_name, args)
@@ -572,11 +578,9 @@ module Glimmer
572
578
  flyweight_swt_widget_classes[underscored_widget_name] = swt_widget_class
573
579
  rescue SyntaxError, NameError => e
574
580
  Glimmer::Config.logger.debug {e.full_message}
575
- # Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
576
581
  nil
577
582
  rescue => e
578
583
  Glimmer::Config.logger.debug {e.full_message}
579
- # Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
580
584
  nil
581
585
  end
582
586
  end
@@ -772,20 +776,20 @@ module Glimmer
772
776
  end
773
777
  end
774
778
 
775
- def method_missing(method, *args, &block)
779
+ def method_missing(method_name, *args, &block)
776
780
  # TODO push most of this logic down to Properties (and perhaps create Listeners module as well)
777
- if can_handle_observation_request?(method)
778
- handle_observation_request(method, &block)
781
+ if block && can_handle_observation_request?(method_name)
782
+ handle_observation_request(method_name, &block)
779
783
  else
780
784
  super
781
785
  end
782
786
  end
783
787
 
784
- def respond_to?(method, *args, &block)
788
+ def respond_to?(method_name, *args, &block)
785
789
  result = super
786
790
  return true if result
787
791
  auto_exec do
788
- can_handle_observation_request?(method)
792
+ can_handle_observation_request?(method_name)
789
793
  end
790
794
  end
791
795
 
@@ -158,17 +158,12 @@ module Glimmer
158
158
  def after_body(&block)
159
159
  @after_body_block = block
160
160
  end
161
-
162
- # Current custom shapes being rendered. Useful to yoke all observers evaluated during rendering of their custom shapes for automatical disposal on_shape_disposed
163
- def current_custom_shapes
164
- @current_custom_shapes ||= []
165
- end
166
161
  end
167
162
 
168
163
  attr_reader :body_root, :args, :parent, :parent_proxy, :options
169
164
 
170
165
  def initialize(parent, *args, options, &content)
171
- Glimmer::UI::CustomShape.current_custom_shapes << self
166
+ SWT::DisplayProxy.current_custom_widgets_and_shapes << self
172
167
  @parent_proxy = @parent = parent
173
168
  @parent_proxy = @parent&.get_data('proxy') if @parent.respond_to?(:get_data) && @parent.get_data('proxy')
174
169
  @args = args
@@ -183,13 +178,26 @@ module Glimmer
183
178
  auto_exec do # TODO is this necessary given shape is a lightweight construct (not SWT widget) ?
184
179
  @body_root.set_data('custom_shape', self)
185
180
  end
181
+ auto_exec do
182
+ @dispose_listener_registration = @body_root.on_shape_disposed do
183
+ unless @body_root.shell_proxy.last_shell_closing?
184
+ observer_registrations.compact.each(&:deregister)
185
+ observer_registrations.clear
186
+ end
187
+ end
188
+ end
186
189
  execute_hook('after_body')
190
+ post_add_content if content.nil?
187
191
  end
188
192
 
189
193
  # Subclasses may override to perform post initialization work on an added child
190
194
  def post_initialize_child(child)
191
195
  # No Op by default
192
196
  end
197
+
198
+ def post_add_content
199
+ SWT::DisplayProxy.current_custom_widgets_and_shapes.delete(self)
200
+ end
193
201
 
194
202
  def observer_registrations
195
203
  @observer_registrations ||= []
@@ -276,17 +284,33 @@ module Glimmer
276
284
  end
277
285
  alias getData get_data # for compatibility with SWT APIs
278
286
  alias data get_data # for compatibility with SWT APIs
287
+
288
+ def dispose(dispose_images: true, dispose_patterns: true, redraw: true)
289
+ body_root.dispose(dispose_images: dispose_images, dispose_patterns: dispose_patterns, redraw: redraw)
290
+ # @dispose_listener_registration.deregister # TODO enable once returning a true listener object or observer proc registration
291
+ end
292
+
293
+ def disposed
294
+ body_root.disposed
295
+ end
296
+ alias disposed? disposed
297
+ alias is_disposed disposed
279
298
 
280
- def method_missing(method, *args, &block)
299
+ def method_missing(method_name, *args, &block)
281
300
  # TODO Consider supporting a glimmer error silencing option for methods defined here
282
301
  # but fail the glimmer DSL for the right reason to avoid seeing noise in the log output
283
- body_root.send(method, *args, &block)
302
+ if block && can_handle_observation_request?(method_name)
303
+ handle_observation_request(method_name, &block)
304
+ else
305
+ body_root.send(method_name, *args, &block)
306
+ end
284
307
  end
285
308
 
286
309
  alias local_respond_to? respond_to?
287
- def respond_to?(method, *args, &block)
310
+ def respond_to?(method_name, *args, &block)
288
311
  super or
289
- body_root.respond_to?(method, *args, &block)
312
+ can_handle_observation_request?(method_name) or
313
+ body_root.respond_to?(method_name, *args, &block)
290
314
  end
291
315
 
292
316
  private
@@ -159,17 +159,12 @@ module Glimmer
159
159
  def after_body(&block)
160
160
  @after_body_block = block
161
161
  end
162
-
163
- # Current custom widgets being rendered. Useful to yoke all observers evaluated during rendering of their custom widgets for automatical disposal on_widget_disposed
164
- def current_custom_widgets
165
- @current_custom_widgets ||= []
166
- end
167
162
  end
168
163
 
169
164
  attr_reader :body_root, :swt_widget, :parent, :parent_proxy, :swt_style, :options
170
165
 
171
166
  def initialize(parent, *swt_constants, options, &content)
172
- Glimmer::UI::CustomWidget.current_custom_widgets << self
167
+ SWT::DisplayProxy.current_custom_widgets_and_shapes << self
173
168
  @parent_proxy = @parent = parent
174
169
  @parent_proxy = @parent&.get_data('proxy') if @parent.respond_to?(:get_data) && @parent.get_data('proxy')
175
170
  @swt_style = SWT::SWTProxy[*swt_constants]
@@ -188,8 +183,10 @@ module Glimmer
188
183
  auto_exec { execute_hook('after_body') }
189
184
  auto_exec do
190
185
  @dispose_listener_registration = @body_root.on_widget_disposed do
191
- observer_registrations.compact.each(&:deregister)
192
- observer_registrations.clear
186
+ unless @body_root.shell_proxy.last_shell_closing?
187
+ observer_registrations.compact.each(&:deregister)
188
+ observer_registrations.clear
189
+ end
193
190
  end
194
191
  end
195
192
  post_add_content if content.nil?
@@ -201,7 +198,7 @@ module Glimmer
201
198
  end
202
199
 
203
200
  def post_add_content
204
- Glimmer::UI::CustomWidget.current_custom_widgets.delete(self)
201
+ SWT::DisplayProxy.current_custom_widgets_and_shapes.delete(self)
205
202
  end
206
203
 
207
204
  def observer_registrations
@@ -310,7 +307,7 @@ module Glimmer
310
307
  def method_missing(method, *args, &block)
311
308
  # TODO Consider supporting a glimmer error silencing option for methods defined here
312
309
  # but fail the glimmer DSL for the right reason to avoid seeing noise in the log output
313
- if can_handle_observation_request?(method)
310
+ if block && can_handle_observation_request?(method)
314
311
  handle_observation_request(method, &block)
315
312
  else
316
313
  body_root.send(method, *args, &block)
@@ -30,9 +30,13 @@ if !['', 'false'].include?(ENV['GLIMMER_BUNDLER_SETUP'].to_s.strip.downcase)
30
30
  end
31
31
  require 'java'
32
32
  require 'puts_debuggerer' if ("#{ENV['pd']}#{ENV['PD']}").to_s.downcase.include?('true')
33
- require 'concurrent-ruby' # ensures glimmer relies on Concurrent data-structure classes (e.g. Concurrent::Array)
33
+
34
+ # concurrent-ruby gem ensures glimmer relies on Concurrent data-structure classes
35
+ require 'concurrent/array'
36
+ require 'concurrent/hash'
37
+ require 'concurrent/set'
34
38
  require 'glimmer'
35
- require 'logging'
39
+
36
40
  require 'nested_inherited_jruby_include_package'
37
41
  require 'super_module'
38
42
  require 'date'
@@ -54,10 +54,18 @@ class Battleship
54
54
 
55
55
  rectangle(0, 0, [:max, -1], [:max, -1])
56
56
  oval(:default, :default, 10, 10) {
57
- foreground <= [model, :hit, on_read: ->(h) {h == nil ? COLOR_EMPTY : (h ? COLOR_HIT : COLOR_NO_HIT)}]
57
+ if model.nil?
58
+ foreground COLOR_EMPTY
59
+ else
60
+ foreground <= [model, :hit, on_read: ->(h) {h == nil ? COLOR_EMPTY : (h ? COLOR_HIT : COLOR_NO_HIT)}]
61
+ end
58
62
  }
59
63
  oval(:default, :default, 5, 5) {
60
- background <= [model, :hit, on_read: ->(h) {h == nil ? COLOR_EMPTY : (h ? COLOR_HIT : COLOR_NO_HIT)}]
64
+ if model.nil?
65
+ background COLOR_EMPTY
66
+ else
67
+ background <= [model, :hit, on_read: ->(h) {h == nil ? COLOR_EMPTY : (h ? COLOR_HIT : COLOR_NO_HIT)}]
68
+ end
61
69
  }
62
70
 
63
71
  on_mouse_move do |event|
@@ -13,7 +13,6 @@ class KlondikeSolitaire
13
13
  def reset!
14
14
  playing_cards.clear
15
15
  populate!(count.times.map { @game.deck.pop })
16
- notify_observers(:playing_cards)
17
16
  end
18
17
 
19
18
  # this method does not validate
@@ -7,16 +7,6 @@ class KlondikeSolitaire
7
7
  class ColumnPile
8
8
  include Glimmer::UI::CustomShape
9
9
 
10
- IMAGE_EMPTY = image(50, 80) {
11
- rectangle(0, 0, 50, 80) {
12
- background :dark_green
13
-
14
- rectangle(0, 0, 49, 79, 15, 15) {
15
- foreground :gray
16
- }
17
- }
18
- }
19
-
20
10
  options :pile_x, :pile_y, :model
21
11
 
22
12
  after_body {
@@ -36,13 +26,10 @@ class KlondikeSolitaire
36
26
  card_parent_pile = card_shape.parent_pile
37
27
  card_source_model = card_parent_pile.model
38
28
  cards = card_source_model.remove!(card)
39
- if cards.is_a?(Array) # if it is a column pile
40
- cards[1..-1].each do |card|
41
- model.add!(card)
42
- end
43
- end
29
+ cards[1..-1].each { |card| model.add!(card) } if cards.is_a?(Array) # if it is a column pile
44
30
  drop_event.dragged_shape.dispose
45
31
  rescue => e
32
+ Glimmer::Config.logger.debug { "Error encountered on drop of a card to a column pile: #{e.full_message}" }
46
33
  drop_event.doit = false
47
34
  end
48
35
  end
@@ -50,7 +37,7 @@ class KlondikeSolitaire
50
37
  }
51
38
 
52
39
  def build_column_pile(playing_cards)
53
- body_root.shapes.to_a.each(&:dispose)
40
+ body_root.shapes.to_a.dup.each { |shape| shape.dispose(redraw: false) }
54
41
  current_parent = body_root
55
42
  playing_cards.each_with_index do |card, i|
56
43
  current_parent.content {
@@ -12,7 +12,7 @@ class KlondikeSolitaire
12
12
 
13
13
  after_body {
14
14
  observe(model, 'playing_cards.empty?') do |empty_value|
15
- body_root.shapes.to_a.each(&:dispose)
15
+ body_root.shapes.to_a.each { |shape| shape.dispose(redraw: false) }
16
16
  if empty_value
17
17
  body_root.content {
18
18
  empty_playing_card
@@ -13,16 +13,23 @@ class KlondikeSolitaire
13
13
  after_body do
14
14
  observe(model, 'playing_cards.empty?') do |empty_value|
15
15
  if empty_value
16
- body_root.shapes.to_a.dup.each(&:dispose)
16
+ body_root.shapes.to_a.dup.each { |shape| shape.dispose(redraw: false) }
17
17
  body_root.content {
18
18
  empty_playing_card
19
19
  }
20
20
  else
21
- body_root.content {
22
- playing_card(model: model.playing_cards.last, parent_pile: self) {
23
- drag_source true
21
+ body_root.shapes.each { |shape| shape.drag_source = false }
22
+ before_last_shape = body_root.shapes[-2] && body_root.shapes[-2].get_data('custom_shape').respond_to?(:model) && body_root.shapes[-2].get_data('custom_shape').model
23
+ if model.playing_cards.last == before_last_shape # happens when dragging card out
24
+ body_root.shapes.last.dispose
25
+ body_root.shapes.last.drag_source = true
26
+ else
27
+ body_root.content {
28
+ playing_card(model: model.playing_cards.last, parent_pile: self) {
29
+ drag_source true
30
+ }
24
31
  }
25
- }
32
+ end
26
33
  end
27
34
  end
28
35
  end
@@ -13,12 +13,13 @@ class KlondikeSolitaire
13
13
  end
14
14
 
15
15
  body {
16
- rectangle(card_x, card_y, 49, 79, 15, 15) {
16
+ rectangle(card_x, card_y, PLAYING_CARD_WIDTH - 1, PLAYING_CARD_HEIGHT - 1, 15, 15) {
17
17
  foreground :gray
18
18
 
19
19
  if suit
20
20
  text {
21
21
  string Model::PlayingCard.suit_text(suit)
22
+ font height: 20
22
23
  x :default
23
24
  y :default
24
25
  is_transparent true
@@ -8,10 +8,9 @@ class KlondikeSolitaire
8
8
 
9
9
  options :pile_x, :pile_y, :game, :suit
10
10
 
11
- attr_accessor :current_image, :model
11
+ attr_accessor :model
12
12
 
13
13
  before_body do
14
- self.current_image = image(50, 80) {empty_playing_card(suit: suit)}
15
14
  self.model = game.foundation_piles[Model::PlayingCard::SUITS.index(suit)]
16
15
  end
17
16
 
@@ -45,6 +44,7 @@ class KlondikeSolitaire
45
44
  card_source_model.remove!(card)
46
45
  drop_event.dragged_shape.dispose
47
46
  rescue => e
47
+ Glimmer::Config.logger.debug { "Error encountered on drop of a card to a foundation pile: #{e.full_message}" }
48
48
  drop_event.doit = false
49
49
  end
50
50
  end
@@ -11,11 +11,11 @@ class KlondikeSolitaire
11
11
  end
12
12
 
13
13
  body {
14
- rectangle(card_x, card_y, 49, 79, 15, 15) {
14
+ rectangle(card_x, card_y, PLAYING_CARD_WIDTH - 1, PLAYING_CARD_HEIGHT - 1, 15, 15) {
15
15
  background :red
16
16
 
17
17
  # border
18
- rectangle(0, 0, 49, 79, 15, 15) {
18
+ rectangle(0, 0, PLAYING_CARD_WIDTH - 1, PLAYING_CARD_HEIGHT - 1, 15, 15) {
19
19
  foreground :black
20
20
  }
21
21
  }
@@ -0,0 +1,60 @@
1
+ class KlondikeSolitaire
2
+ module View
3
+ class KlondikeSolitaireMenuBar
4
+ include Glimmer::UI::CustomWidget
5
+
6
+ option :game
7
+
8
+ before_body do
9
+ @display = display {
10
+ on_about {
11
+ display_about_dialog
12
+ }
13
+ on_preferences {
14
+ display_about_dialog
15
+ }
16
+ }
17
+ end
18
+
19
+ body {
20
+ menu_bar {
21
+ menu {
22
+ text '&Game'
23
+ menu_item {
24
+ text '&Restart'
25
+ accelerator (OS.mac? ? :command : :ctrl), :r
26
+
27
+ on_widget_selected {
28
+ game.restart!
29
+ }
30
+ }
31
+ menu_item {
32
+ text 'E&xit'
33
+ accelerator :alt, :f4
34
+
35
+ on_widget_selected {
36
+ exit(0)
37
+ }
38
+ }
39
+ }
40
+ menu {
41
+ text '&Help'
42
+ menu_item {
43
+ text '&About...'
44
+ on_widget_selected {
45
+ display_about_dialog
46
+ }
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ def display_about_dialog
53
+ message_box(body_root) {
54
+ text 'About'
55
+ message "Glimmer Klondike Solitaire\nGlimmer DSL for SWT Elaborate Sample"
56
+ }.open
57
+ end
58
+ end
59
+ end
60
+ end
@@ -11,17 +11,18 @@ class KlondikeSolitaire
11
11
  end
12
12
 
13
13
  body {
14
- rectangle(card_x, card_y, 49, 79, 15, 15) {
14
+ rectangle(card_x, card_y, PLAYING_CARD_WIDTH - 1, PLAYING_CARD_HEIGHT - 1, 15, 15) {
15
15
  background model.hidden ? :red : :white
16
16
 
17
17
  # border
18
- rectangle(0, 0, 49, 79, 15, 15) {
18
+ rectangle(0, 0, PLAYING_CARD_WIDTH - 1, PLAYING_CARD_HEIGHT - 1, 15, 15) {
19
19
  foreground :black
20
20
  }
21
21
 
22
22
  unless model.hidden?
23
23
  text {
24
24
  string model ? "#{model.rank_text}#{model.suit_text}" : ""
25
+ font height: PLAYING_CARD_FONT_HEIGHT
25
26
  x 5
26
27
  y 5
27
28
  foreground model ? model.color : :transparent
@@ -4,35 +4,26 @@ require_relative 'klondike_solitaire/model/game'
4
4
 
5
5
  require_relative 'klondike_solitaire/view/action_panel'
6
6
  require_relative 'klondike_solitaire/view/tableau'
7
+ require_relative 'klondike_solitaire/view/klondike_solitaire_menu_bar'
7
8
 
8
9
  class KlondikeSolitaire
9
10
  include Glimmer::UI::CustomShell
10
11
 
11
12
  PLAYING_CARD_WIDTH = 50
12
- PLAYING_CARD_HEIGHT = 80
13
+ PLAYING_CARD_HEIGHT = 76
13
14
  PLAYING_CARD_SPACING = 5
15
+ PLAYING_CARD_FONT_HEIGHT = 16
14
16
  MARGIN = 15
15
17
  TABLEAU_WIDTH = 2*MARGIN + 7*(PLAYING_CARD_WIDTH + PLAYING_CARD_SPACING)
16
- TABLEAU_HEIGHT = 400
18
+ TABLEAU_HEIGHT = 420
17
19
 
18
20
  before_body do
19
21
  @game = Model::Game.new
20
- Display.app_name = 'Glimmer Klondike Solitaire'
21
- @display = display {
22
- on_about {
23
- display_about_dialog
24
- }
25
- on_preferences {
26
- display_about_dialog
27
- }
28
- }
29
22
  end
30
23
 
31
24
  body {
32
25
  shell {
33
- row_layout(:vertical) {
34
- fill true
35
- center true
26
+ grid_layout {
36
27
  margin_width 0
37
28
  margin_height 0
38
29
  margin_top 15
@@ -41,53 +32,20 @@ class KlondikeSolitaire
41
32
  text "Glimmer Klondike Solitaire"
42
33
  background :dark_green
43
34
 
44
- action_panel(game: @game)
45
- tableau(game: @game) {
46
- layout_data {
47
- width TABLEAU_WIDTH
48
- height TABLEAU_HEIGHT
49
- }
35
+ klondike_solitaire_menu_bar(game: @game)
36
+
37
+ action_panel(game: @game) {
38
+ layout_data(:fill, :center, true, false)
50
39
  }
51
40
 
52
- menu_bar {
53
- menu {
54
- text '&Game'
55
- menu_item {
56
- text '&Restart'
57
- accelerator (OS.mac? ? :command : :ctrl), :r
58
-
59
- on_widget_selected {
60
- @game.restart!
61
- }
62
- }
63
- menu_item {
64
- text 'E&xit'
65
- accelerator :alt, :f4
66
-
67
- on_widget_selected {
68
- body_root.close
69
- }
70
- }
71
- }
72
- menu {
73
- text '&Help'
74
- menu_item {
75
- text '&About...'
76
- on_widget_selected {
77
- display_about_dialog
78
- }
79
- }
41
+ tableau(game: @game) {
42
+ layout_data(:fill, :fill, true, true) {
43
+ width_hint TABLEAU_WIDTH
44
+ height_hint TABLEAU_HEIGHT
80
45
  }
81
46
  }
82
47
  }
83
48
  }
84
-
85
- def display_about_dialog
86
- message_box(body_root) {
87
- text 'About'
88
- message "Glimmer Klondike Solitaire\nGlimmer DSL for SWT Elaborate Sample"
89
- }.open
90
- end
91
49
  end
92
50
 
93
51
  KlondikeSolitaire.launch
@@ -21,7 +21,9 @@
21
21
 
22
22
  require 'glimmer-dsl-swt'
23
23
  require 'complex'
24
- require 'concurrent-ruby'
24
+ require 'concurrent/executor/fixed_thread_pool'
25
+ require 'concurrent/utility/processor_counter'
26
+ require 'concurrent/array'
25
27
 
26
28
  # Mandelbrot multi-threaded implementation leveraging all processor cores.
27
29
  class Mandelbrot