glimmer-dsl-swt 4.18.2.3 → 4.18.3.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +59 -0
- data/README.md +267 -39
- data/VERSION +1 -1
- data/glimmer-dsl-swt.gemspec +14 -6
- data/lib/ext/glimmer/config.rb +24 -7
- data/lib/glimmer/data_binding/widget_binding.rb +14 -4
- data/lib/glimmer/dsl/swt/color_expression.rb +4 -4
- data/lib/glimmer/dsl/swt/data_binding_expression.rb +3 -3
- data/lib/glimmer/dsl/swt/dsl.rb +1 -0
- data/lib/glimmer/dsl/swt/multiply_expression.rb +53 -0
- data/lib/glimmer/dsl/swt/property_expression.rb +4 -2
- data/lib/glimmer/dsl/swt/shape_expression.rb +2 -4
- data/lib/glimmer/dsl/swt/transform_expression.rb +55 -0
- data/lib/glimmer/dsl/swt/widget_expression.rb +2 -1
- data/lib/glimmer/swt/color_proxy.rb +28 -6
- data/lib/glimmer/swt/custom/drawable.rb +8 -0
- data/lib/glimmer/swt/custom/shape.rb +66 -26
- data/lib/glimmer/swt/directory_dialog_proxy.rb +3 -3
- data/lib/glimmer/swt/display_proxy.rb +25 -4
- data/lib/glimmer/swt/file_dialog_proxy.rb +3 -3
- data/lib/glimmer/swt/layout_data_proxy.rb +3 -3
- data/lib/glimmer/swt/shell_proxy.rb +20 -5
- data/lib/glimmer/swt/table_proxy.rb +19 -4
- data/lib/glimmer/swt/transform_proxy.rb +109 -0
- data/lib/glimmer/swt/widget_listener_proxy.rb +14 -5
- data/lib/glimmer/swt/widget_proxy.rb +31 -20
- data/lib/glimmer/ui/custom_shell.rb +13 -11
- data/lib/glimmer/ui/custom_widget.rb +68 -44
- data/samples/elaborate/meta_sample.rb +81 -24
- data/samples/elaborate/tetris.rb +102 -47
- data/samples/elaborate/tetris/model/block.rb +2 -2
- data/samples/elaborate/tetris/model/game.rb +236 -74
- data/samples/elaborate/tetris/model/past_game.rb +26 -0
- data/samples/elaborate/tetris/model/tetromino.rb +123 -35
- data/samples/elaborate/tetris/view/block.rb +34 -9
- data/samples/elaborate/tetris/view/high_score_dialog.rb +114 -0
- data/samples/elaborate/tetris/view/playfield.rb +12 -5
- data/samples/elaborate/tetris/view/score_lane.rb +87 -0
- data/samples/elaborate/tetris/view/tetris_menu_bar.rb +123 -0
- data/samples/elaborate/tic_tac_toe.rb +4 -4
- data/samples/hello/hello_canvas_transform.rb +40 -0
- data/samples/hello/hello_link.rb +1 -1
- metadata +12 -4
@@ -26,10 +26,12 @@ module Glimmer
|
|
26
26
|
# Follows the Proxy Design Pattern
|
27
27
|
class WidgetListenerProxy
|
28
28
|
|
29
|
-
attr_reader :swt_widget, :swt_listener, :widget_add_listener_method, :swt_listener_class, :swt_listener_method, :event_type, :swt_constant
|
29
|
+
attr_reader :swt_widget, :swt_display, :swt_listener, :widget_add_listener_method, :swt_listener_class, :swt_listener_method, :event_type, :swt_constant
|
30
30
|
|
31
|
-
def initialize(swt_widget
|
31
|
+
def initialize(swt_widget:nil, swt_display:nil, swt_listener:, widget_add_listener_method: nil, swt_listener_class: nil, swt_listener_method: nil, event_type: nil, swt_constant: nil, filter: false)
|
32
32
|
@swt_widget = swt_widget
|
33
|
+
@swt_display = swt_display
|
34
|
+
@filter = filter
|
33
35
|
@swt_listener = swt_listener
|
34
36
|
@widget_add_listener_method = widget_add_listener_method
|
35
37
|
@swt_listener_class = swt_listener_class
|
@@ -42,14 +44,21 @@ module Glimmer
|
|
42
44
|
@widget_add_listener_method.sub('add', 'remove')
|
43
45
|
end
|
44
46
|
|
45
|
-
def
|
46
|
-
|
47
|
-
if @
|
47
|
+
def deregister
|
48
|
+
return if @swt_widget&.is_disposed || @swt_display&.is_disposed
|
49
|
+
if @swt_display
|
50
|
+
if @filter
|
51
|
+
@swt_display.removeFilter(@event_type, @swt_listener)
|
52
|
+
else
|
53
|
+
@swt_display.removeListener(@event_type, @swt_listener)
|
54
|
+
end
|
55
|
+
elsif @event_type
|
48
56
|
@swt_widget.removeListener(@event_type, @swt_listener)
|
49
57
|
else
|
50
58
|
@swt_widget.send(widget_remove_listener_method, @swt_listener)
|
51
59
|
end
|
52
60
|
end
|
61
|
+
alias unregister deregister # TODO consider dropping unregister (and in Observer too)
|
53
62
|
end
|
54
63
|
end
|
55
64
|
end
|
@@ -158,7 +158,7 @@ module Glimmer
|
|
158
158
|
underscored_widget_name = self.class.underscored_widget_name(@swt_widget)
|
159
159
|
parent_proxy_class = self.class.widget_proxy_class(self.class.underscored_widget_name(@swt_widget.parent))
|
160
160
|
parent = swt_widget.parent
|
161
|
-
@parent_proxy = parent
|
161
|
+
@parent_proxy = parent&.get_data('proxy') || parent_proxy_class.new(swt_widget: parent)
|
162
162
|
end
|
163
163
|
if @swt_widget&.get_data('proxy').nil?
|
164
164
|
@swt_widget.set_data('proxy', self)
|
@@ -497,26 +497,37 @@ module Glimmer
|
|
497
497
|
|
498
498
|
# This supports widgets in and out of basic SWT
|
499
499
|
def self.swt_widget_class_for(underscored_widget_name)
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
500
|
+
# TODO clear memoization for a keyword if a custom widget was defined with that keyword
|
501
|
+
unless flyweight_swt_widget_classes.keys.include?(underscored_widget_name)
|
502
|
+
begin
|
503
|
+
underscored_widget_name = KEYWORD_ALIASES[underscored_widget_name] if KEYWORD_ALIASES[underscored_widget_name]
|
504
|
+
swt_widget_name = underscored_widget_name.camelcase(:upper)
|
505
|
+
swt_widget_class = eval(swt_widget_name)
|
506
|
+
# TODO fix issue with not detecting DateTime because it's conflicting with the Ruby DateTime
|
507
|
+
unless swt_widget_class.ancestors.include?(org.eclipse.swt.widgets.Widget)
|
508
|
+
swt_widget_class = swt_widget_class_manual_entries[underscored_widget_name]
|
509
|
+
if swt_widget_class.nil?
|
510
|
+
Glimmer::Config.logger.debug {"Class #{swt_widget_class} matching #{underscored_widget_name} is not a subclass of org.eclipse.swt.widgets.Widget"}
|
511
|
+
return nil
|
512
|
+
end
|
513
|
+
end
|
514
|
+
flyweight_swt_widget_classes[underscored_widget_name] = swt_widget_class
|
515
|
+
rescue SyntaxError, NameError => e
|
516
|
+
Glimmer::Config.logger.debug {e.full_message}
|
517
|
+
# Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
|
518
|
+
nil
|
519
|
+
rescue => e
|
520
|
+
Glimmer::Config.logger.debug {e.full_message}
|
521
|
+
# Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
|
522
|
+
nil
|
509
523
|
end
|
510
524
|
end
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
Glimmer::Config.logger.debug {e.full_message}
|
518
|
-
# Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
|
519
|
-
nil
|
525
|
+
flyweight_swt_widget_classes[underscored_widget_name]
|
526
|
+
end
|
527
|
+
|
528
|
+
# Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
|
529
|
+
def self.flyweight_swt_widget_classes
|
530
|
+
@flyweight_swt_widget_classes ||= {}
|
520
531
|
end
|
521
532
|
|
522
533
|
def async_exec(&block)
|
@@ -685,7 +696,7 @@ module Glimmer
|
|
685
696
|
safe_block = lambda { |*args| block.call(*args) unless @swt_widget.isDisposed }
|
686
697
|
listener = listener_class.new(listener_method => safe_block)
|
687
698
|
@swt_widget.send(widget_add_listener_method, listener)
|
688
|
-
|
699
|
+
WidgetListenerProxy.new(swt_widget: @swt_widget, swt_listener: listener, widget_add_listener_method: widget_add_listener_method, swt_listener_class: listener_class, swt_listener_method: listener_method)
|
689
700
|
end
|
690
701
|
|
691
702
|
# Looks through SWT class add***Listener methods till it finds one for which
|
@@ -28,15 +28,12 @@ module Glimmer
|
|
28
28
|
include Glimmer::UI::CustomWidget
|
29
29
|
|
30
30
|
class << self
|
31
|
-
attr_reader :
|
31
|
+
attr_reader :launched_custom_shell
|
32
32
|
|
33
|
-
def launch
|
34
|
-
@
|
35
|
-
@
|
36
|
-
|
37
|
-
|
38
|
-
def shutdown
|
39
|
-
@custom_shell.close
|
33
|
+
def launch(*args, &content)
|
34
|
+
@launched_custom_shell = send(keyword, *args, &content) if @launched_custom_shell.nil? || @launched_custom_shell.disposed?
|
35
|
+
@launched_custom_shell.swt_widget.set_data('launched', true)
|
36
|
+
@launched_custom_shell.open
|
40
37
|
end
|
41
38
|
end
|
42
39
|
|
@@ -45,7 +42,7 @@ module Glimmer
|
|
45
42
|
@swt_widget.set_data('custom_shell', self)
|
46
43
|
raise Error, 'Invalid custom shell body root! Must be a shell or another custom shell.' unless body_root.swt_widget.is_a?(org.eclipse.swt.widgets.Shell)
|
47
44
|
end
|
48
|
-
|
45
|
+
|
49
46
|
# Classes may override
|
50
47
|
def open
|
51
48
|
body_root.open
|
@@ -56,6 +53,7 @@ module Glimmer
|
|
56
53
|
open
|
57
54
|
end
|
58
55
|
|
56
|
+
# TODO consider using Forwardable instead
|
59
57
|
def close
|
60
58
|
body_root.close
|
61
59
|
end
|
@@ -68,8 +66,12 @@ module Glimmer
|
|
68
66
|
body_root.visible?
|
69
67
|
end
|
70
68
|
|
71
|
-
def
|
72
|
-
|
69
|
+
def disposed?
|
70
|
+
swt_widget.is_disposed
|
71
|
+
end
|
72
|
+
|
73
|
+
def center_within_display
|
74
|
+
body_root.center_within_display
|
73
75
|
end
|
74
76
|
|
75
77
|
def start_event_loop
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (c) 2007-2021 Andy Maleh
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
# a copy of this software and associated documentation files (the
|
5
5
|
# "Software"), to deal in the Software without restriction, including
|
@@ -7,10 +7,10 @@
|
|
7
7
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
8
|
# permit persons to whom the Software is furnished to do so, subject to
|
9
9
|
# the following conditions:
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# The above copyright notice and this permission notice shall be
|
12
12
|
# included in all copies or substantial portions of the Software.
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
15
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
16
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
@@ -34,39 +34,60 @@ module Glimmer
|
|
34
34
|
include DataBinding::ObservableModel
|
35
35
|
|
36
36
|
super_module_included do |klass|
|
37
|
+
# TODO clear memoization of WidgetProxy.swt_widget_class_for for a keyword if a custom widget was defined with that keyword
|
37
38
|
klass.include(Glimmer) unless klass.name.include?('Glimmer::UI::CustomShell')
|
38
39
|
Glimmer::UI::CustomWidget.add_custom_widget_namespaces_for(klass) unless klass.name.include?('Glimmer::UI::CustomShell')
|
39
40
|
end
|
40
41
|
|
41
42
|
class << self
|
42
43
|
def for(underscored_custom_widget_name)
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
44
|
+
unless flyweight_custom_widget_classes.keys.include?(underscored_custom_widget_name)
|
45
|
+
begin
|
46
|
+
extracted_namespaces = underscored_custom_widget_name.
|
47
|
+
to_s.
|
48
|
+
split(/__/).map do |namespace|
|
49
|
+
namespace.camelcase(:upper)
|
50
|
+
end
|
51
|
+
custom_widget_namespaces.each do |base|
|
52
|
+
extracted_namespaces.reduce(base) do |result, namespace|
|
53
|
+
if !result.constants.include?(namespace)
|
54
|
+
namespace = result.constants.detect {|c| c.to_s.upcase == namespace.to_s.upcase } || namespace
|
55
|
+
end
|
56
|
+
begin
|
57
|
+
flyweight_custom_widget_classes[underscored_custom_widget_name] = constant = result.const_get(namespace)
|
58
|
+
return constant if constant.ancestors.include?(Glimmer::UI::CustomWidget)
|
59
|
+
flyweight_custom_widget_classes[underscored_custom_widget_name] = constant
|
60
|
+
rescue => e
|
61
|
+
# Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
|
62
|
+
flyweight_custom_widget_classes[underscored_custom_widget_name] = result
|
63
|
+
end
|
64
|
+
end
|
60
65
|
end
|
66
|
+
raise "#{underscored_custom_widget_name} has no custom widget class!"
|
67
|
+
rescue => e
|
68
|
+
Glimmer::Config.logger.debug {e.message}
|
69
|
+
Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
|
70
|
+
flyweight_custom_widget_classes[underscored_custom_widget_name] = nil
|
61
71
|
end
|
62
72
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
73
|
+
flyweight_custom_widget_classes[underscored_custom_widget_name]
|
74
|
+
end
|
75
|
+
|
76
|
+
# Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
|
77
|
+
def flyweight_custom_widget_classes
|
78
|
+
@flyweight_custom_widget_classes ||= {}
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns keyword to use for this custom widget
|
82
|
+
def keyword
|
83
|
+
self.name.underscore.gsub('::', '__')
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns shortcut keyword to use for this custom widget (keyword minus namespace)
|
87
|
+
def shortcut_keyword
|
88
|
+
self.name.underscore.gsub('::', '__').split('__').last
|
68
89
|
end
|
69
|
-
|
90
|
+
|
70
91
|
def add_custom_widget_namespaces_for(klass)
|
71
92
|
Glimmer::UI::CustomWidget.namespaces_for_class(klass).drop(1).each do |namespace|
|
72
93
|
Glimmer::UI::CustomWidget.custom_widget_namespaces << namespace
|
@@ -127,8 +148,7 @@ module Glimmer
|
|
127
148
|
end
|
128
149
|
|
129
150
|
def before_body(&block)
|
130
|
-
@
|
131
|
-
@before_body_blocks << block
|
151
|
+
@before_body_block = block
|
132
152
|
end
|
133
153
|
|
134
154
|
def body(&block)
|
@@ -136,27 +156,27 @@ module Glimmer
|
|
136
156
|
end
|
137
157
|
|
138
158
|
def after_body(&block)
|
139
|
-
@
|
140
|
-
@after_body_blocks << block
|
159
|
+
@after_body_block = block
|
141
160
|
end
|
142
161
|
end
|
143
162
|
|
144
|
-
attr_reader :body_root, :swt_widget, :parent, :swt_style, :options
|
163
|
+
attr_reader :body_root, :swt_widget, :parent, :parent_proxy, :swt_style, :options
|
145
164
|
|
146
165
|
def initialize(parent, *swt_constants, options, &content)
|
147
166
|
@parent = parent
|
167
|
+
@parent_proxy = @parent&.get_data('proxy')
|
148
168
|
@swt_style = SWT::SWTProxy[*swt_constants]
|
149
169
|
options ||= {}
|
150
170
|
@options = self.class.options.merge(options)
|
151
171
|
@content = Util::ProcTracker.new(content) if content
|
152
|
-
|
172
|
+
execute_hook('before_body')
|
153
173
|
body_block = self.class.instance_variable_get("@body_block")
|
154
174
|
raise Glimmer::Error, 'Invalid custom widget for having no body! Please define body block!' if body_block.nil?
|
155
175
|
@body_root = instance_exec(&body_block)
|
156
176
|
raise Glimmer::Error, 'Invalid custom widget for having an empty body! Please fill body block!' if @body_root.nil?
|
157
177
|
@swt_widget = @body_root.swt_widget
|
158
178
|
@swt_widget.set_data('custom_widget', self)
|
159
|
-
|
179
|
+
execute_hook('after_body')
|
160
180
|
end
|
161
181
|
|
162
182
|
# Subclasses may override to perform post initialization work on an added child
|
@@ -211,10 +231,10 @@ module Glimmer
|
|
211
231
|
|
212
232
|
# This method ensures it has an instance method not coming from Glimmer DSL
|
213
233
|
def has_instance_method?(method_name)
|
214
|
-
respond_to?(method_name) and
|
234
|
+
respond_to?(method_name) and
|
215
235
|
!swt_widget&.respond_to?(method_name) and
|
216
236
|
(method(method_name) rescue nil) and
|
217
|
-
!method(method_name)&.source_location&.first&.include?('glimmer/dsl/engine.rb') and
|
237
|
+
!method(method_name)&.source_location&.first&.include?('glimmer/dsl/engine.rb') and
|
218
238
|
!method(method_name)&.source_location&.first&.include?('glimmer/swt/widget_proxy.rb')
|
219
239
|
end
|
220
240
|
|
@@ -233,6 +253,10 @@ module Glimmer
|
|
233
253
|
def has_style?(style)
|
234
254
|
(swt_style & SWT::SWTProxy[style]) == SWT::SWTProxy[style]
|
235
255
|
end
|
256
|
+
|
257
|
+
def pack(*args)
|
258
|
+
body_root.pack(*args)
|
259
|
+
end
|
236
260
|
|
237
261
|
# TODO see if it is worth it to eliminate duplication of async_exec/sync_exec
|
238
262
|
# delegation to DisplayProxy, via a module
|
@@ -265,22 +289,22 @@ module Glimmer
|
|
265
289
|
end
|
266
290
|
end
|
267
291
|
|
268
|
-
alias local_respond_to? respond_to?
|
292
|
+
alias local_respond_to? respond_to?
|
269
293
|
def respond_to?(method, *args, &block)
|
270
294
|
super or
|
271
295
|
can_handle_observation_request?(method) or
|
272
296
|
body_root.respond_to?(method, *args, &block)
|
273
297
|
end
|
274
|
-
|
298
|
+
|
275
299
|
private
|
276
300
|
|
277
|
-
def
|
278
|
-
self.class.instance_variable_get("@#{hook_name}
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
301
|
+
def execute_hook(hook_name)
|
302
|
+
hook_block = self.class.instance_variable_get("@#{hook_name}_block")
|
303
|
+
return if hook_block.nil?
|
304
|
+
temp_method_name = "#{hook_name}_block_#{hook_block.hash.abs}_#{(Time.now.to_f * 1_000_000).to_i}"
|
305
|
+
singleton_class.define_method(temp_method_name, &hook_block)
|
306
|
+
send(temp_method_name)
|
307
|
+
singleton_class.send(:remove_method, temp_method_name)
|
284
308
|
end
|
285
309
|
end
|
286
310
|
end
|
@@ -25,6 +25,24 @@ require 'etc'
|
|
25
25
|
class Sample
|
26
26
|
include Glimmer::DataBinding::ObservableModel
|
27
27
|
|
28
|
+
class << self
|
29
|
+
def glimmer_directory
|
30
|
+
File.expand_path('../../..', __FILE__)
|
31
|
+
end
|
32
|
+
|
33
|
+
def user_glimmer_directory
|
34
|
+
File.join(Etc.getpwuid.dir, '.glimmer-dsl-swt')
|
35
|
+
end
|
36
|
+
|
37
|
+
def ensure_user_glimmer_directory
|
38
|
+
unless @ensured_glimmer_directory
|
39
|
+
FileUtils.rm_rf(user_glimmer_directory)
|
40
|
+
FileUtils.cp_r(glimmer_directory, user_glimmer_directory)
|
41
|
+
@ensured_glimmer_directory = true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
28
46
|
attr_accessor :sample_directory, :file, :selected
|
29
47
|
|
30
48
|
def initialize(file, sample_directory: )
|
@@ -59,25 +77,35 @@ class Sample
|
|
59
77
|
File.basename(file) != 'meta_sample.rb'
|
60
78
|
end
|
61
79
|
alias launchable editable
|
80
|
+
|
81
|
+
def file_relative_path
|
82
|
+
file.sub(self.class.glimmer_directory, '')
|
83
|
+
end
|
84
|
+
|
85
|
+
def user_file
|
86
|
+
File.join(self.class.user_glimmer_directory, file_relative_path)
|
87
|
+
end
|
88
|
+
|
89
|
+
def user_file_parent_directory
|
90
|
+
File.dirname(user_file)
|
91
|
+
end
|
62
92
|
|
93
|
+
def directory
|
94
|
+
file.sub(/\.rb/, '')
|
95
|
+
end
|
96
|
+
|
63
97
|
def launch(modified_code)
|
64
|
-
|
65
|
-
modified_file_parent_directory = File.join(Etc.getpwuid.dir, '.glimmer', 'samples', parent_directory)
|
66
|
-
launch_file = modified_file = File.join(modified_file_parent_directory, File.basename(file))
|
98
|
+
launch_file = user_file
|
67
99
|
begin
|
68
|
-
FileUtils.
|
69
|
-
FileUtils.cp_r(
|
70
|
-
|
71
|
-
File.write(modified_file, modified_code)
|
100
|
+
FileUtils.cp_r(file, user_file_parent_directory)
|
101
|
+
FileUtils.cp_r(directory, user_file_parent_directory) if File.exist?(directory)
|
102
|
+
File.write(user_file, modified_code)
|
72
103
|
rescue => e
|
73
104
|
puts 'Error writing sample modifications. Launching original sample.'
|
74
105
|
puts e.full_message
|
75
106
|
launch_file = file # load original file if failed to write changes
|
76
107
|
end
|
77
108
|
load(launch_file)
|
78
|
-
ensure
|
79
|
-
FileUtils.rm_rf(modified_file)
|
80
|
-
FileUtils.rm_rf(modified_file.sub(/\.rb/, ''))
|
81
109
|
end
|
82
110
|
end
|
83
111
|
|
@@ -162,17 +190,18 @@ class SampleDirectory
|
|
162
190
|
end
|
163
191
|
|
164
192
|
class MetaSampleApplication
|
165
|
-
include Glimmer
|
193
|
+
include Glimmer::UI::CustomShell
|
166
194
|
|
167
|
-
|
195
|
+
before_body {
|
196
|
+
Sample.ensure_user_glimmer_directory
|
168
197
|
selected_sample_directory = SampleDirectory.sample_directories.first
|
169
198
|
selected_sample = selected_sample_directory.samples.first
|
170
199
|
selected_sample_directory.selected_sample_name = selected_sample.name
|
171
|
-
end
|
172
|
-
|
173
|
-
def launch
|
174
200
|
Display.app_name = 'Glimmer Meta-Sample'
|
175
|
-
|
201
|
+
}
|
202
|
+
|
203
|
+
body {
|
204
|
+
shell(:fill_screen) {
|
176
205
|
minimum_size 1280, 768
|
177
206
|
text 'Glimmer Meta-Sample (The Sample of Samples)'
|
178
207
|
image File.expand_path('../../icons/scaffold_app.png', __dir__)
|
@@ -218,11 +247,8 @@ class MetaSampleApplication
|
|
218
247
|
on_widget_selected {
|
219
248
|
begin
|
220
249
|
SampleDirectory.selected_sample.launch(@code_text.text)
|
221
|
-
rescue StandardError, SyntaxError => launch_error
|
222
|
-
|
223
|
-
text 'Error Launching'
|
224
|
-
message launch_error.full_message
|
225
|
-
}.open
|
250
|
+
rescue LoadError, StandardError, SyntaxError => launch_error
|
251
|
+
error_dialog(message: launch_error.full_message).open
|
226
252
|
end
|
227
253
|
}
|
228
254
|
}
|
@@ -243,10 +269,41 @@ class MetaSampleApplication
|
|
243
269
|
editable bind(SampleDirectory, 'selected_sample.editable')
|
244
270
|
}
|
245
271
|
|
246
|
-
weights 4,
|
272
|
+
weights 4, 11
|
273
|
+
}
|
274
|
+
}
|
275
|
+
}
|
276
|
+
|
277
|
+
# Method-based error_dialog custom widget
|
278
|
+
def error_dialog(message:)
|
279
|
+
return if message.nil?
|
280
|
+
dialog(body_root) { |dialog_proxy|
|
281
|
+
row_layout(:vertical) {
|
282
|
+
center true
|
283
|
+
}
|
284
|
+
|
285
|
+
text 'Error Launching'
|
286
|
+
|
287
|
+
styled_text(:border, :h_scroll, :v_scroll) {
|
288
|
+
layout_data {
|
289
|
+
width body_root.bounds.width*0.75
|
290
|
+
height body_root.bounds.height*0.75
|
291
|
+
}
|
292
|
+
|
293
|
+
text message
|
294
|
+
editable false
|
295
|
+
caret nil
|
296
|
+
}
|
297
|
+
|
298
|
+
button {
|
299
|
+
text 'Close'
|
300
|
+
|
301
|
+
on_widget_selected {
|
302
|
+
dialog_proxy.close
|
303
|
+
}
|
247
304
|
}
|
248
|
-
}
|
305
|
+
}
|
249
306
|
end
|
250
307
|
end
|
251
308
|
|
252
|
-
MetaSampleApplication.
|
309
|
+
MetaSampleApplication.launch
|