glimmer-dsl-swt 4.18.4.5 → 4.18.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/LICENSE.txt +20 -20
  4. data/README.md +4 -4
  5. data/RUBY_VERSION +1 -1
  6. data/VERSION +1 -1
  7. data/bin/girb +31 -31
  8. data/bin/girb_runner.rb +34 -34
  9. data/bin/glimmer +26 -26
  10. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +1 -1
  11. data/docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md +1 -1
  12. data/glimmer-dsl-swt.gemspec +6 -5
  13. data/lib/ext/glimmer.rb +41 -41
  14. data/lib/ext/glimmer/config.rb +167 -167
  15. data/lib/ext/rouge/themes/glimmer.rb +29 -29
  16. data/lib/glimmer-dsl-swt.rb +44 -44
  17. data/lib/glimmer/Rakefile +26 -26
  18. data/lib/glimmer/data_binding/list_selection_binding.rb +72 -72
  19. data/lib/glimmer/data_binding/observable_widget.rb +38 -38
  20. data/lib/glimmer/data_binding/shine.rb +44 -44
  21. data/lib/glimmer/data_binding/table_items_binding.rb +89 -89
  22. data/lib/glimmer/data_binding/tree_items_binding.rb +108 -108
  23. data/lib/glimmer/data_binding/widget_binding.rb +73 -73
  24. data/lib/glimmer/dsl/swt/animation_expression.rb +43 -43
  25. data/lib/glimmer/dsl/swt/async_exec_expression.rb +35 -35
  26. data/lib/glimmer/dsl/swt/bind_expression.rb +58 -58
  27. data/lib/glimmer/dsl/swt/block_property_expression.rb +41 -41
  28. data/lib/glimmer/dsl/swt/checkbox_group_selection_data_binding_expression.rb +61 -61
  29. data/lib/glimmer/dsl/swt/color_expression.rb +40 -40
  30. data/lib/glimmer/dsl/swt/column_properties_expression.rb +45 -45
  31. data/lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb +67 -67
  32. data/lib/glimmer/dsl/swt/cursor_expression.rb +44 -44
  33. data/lib/glimmer/dsl/swt/data_binding_expression.rb +55 -55
  34. data/lib/glimmer/dsl/swt/dialog_expression.rb +48 -48
  35. data/lib/glimmer/dsl/swt/directory_dialog_expression.rb +48 -48
  36. data/lib/glimmer/dsl/swt/display_expression.rb +40 -40
  37. data/lib/glimmer/dsl/swt/dnd_expression.rb +46 -46
  38. data/lib/glimmer/dsl/swt/dsl.rb +63 -63
  39. data/lib/glimmer/dsl/swt/expand_item_expression.rb +60 -60
  40. data/lib/glimmer/dsl/swt/file_dialog_expression.rb +48 -48
  41. data/lib/glimmer/dsl/swt/font_expression.rb +49 -49
  42. data/lib/glimmer/dsl/swt/image_expression.rb +50 -50
  43. data/lib/glimmer/dsl/swt/layout_data_expression.rb +46 -46
  44. data/lib/glimmer/dsl/swt/layout_expression.rb +50 -50
  45. data/lib/glimmer/dsl/swt/list_selection_data_binding_expression.rb +65 -65
  46. data/lib/glimmer/dsl/swt/menu_bar_expression.rb +54 -54
  47. data/lib/glimmer/dsl/swt/menu_expression.rb +53 -53
  48. data/lib/glimmer/dsl/swt/message_box_expression.rb +54 -54
  49. data/lib/glimmer/dsl/swt/multiply_expression.rb +53 -53
  50. data/lib/glimmer/dsl/swt/pixel_expression.rb +38 -0
  51. data/lib/glimmer/dsl/swt/property_expression.rb +46 -46
  52. data/lib/glimmer/dsl/swt/radio_group_selection_data_binding_expression.rb +61 -61
  53. data/lib/glimmer/dsl/swt/rgb_expression.rb +33 -33
  54. data/lib/glimmer/dsl/swt/rgba_expression.rb +33 -33
  55. data/lib/glimmer/dsl/swt/shape_expression.rb +54 -54
  56. data/lib/glimmer/dsl/swt/shell_expression.rb +46 -46
  57. data/lib/glimmer/dsl/swt/swt_expression.rb +46 -46
  58. data/lib/glimmer/dsl/swt/sync_exec_expression.rb +36 -36
  59. data/lib/glimmer/dsl/swt/tab_item_expression.rb +54 -54
  60. data/lib/glimmer/dsl/swt/table_items_data_binding_expression.rb +52 -52
  61. data/lib/glimmer/dsl/swt/transform_expression.rb +55 -55
  62. data/lib/glimmer/dsl/swt/tree_items_data_binding_expression.rb +52 -52
  63. data/lib/glimmer/dsl/swt/tree_properties_expression.rb +47 -47
  64. data/lib/glimmer/dsl/swt/widget_expression.rb +67 -66
  65. data/lib/glimmer/dsl/swt/widget_listener_expression.rb +53 -53
  66. data/lib/glimmer/rake_task.rb +220 -220
  67. data/lib/glimmer/rake_task/list.rb +97 -97
  68. data/lib/glimmer/rake_task/package.rb +139 -139
  69. data/lib/glimmer/rake_task/scaffold.rb +765 -765
  70. data/lib/glimmer/swt/color_proxy.rb +107 -107
  71. data/lib/glimmer/swt/cursor_proxy.rb +66 -66
  72. data/lib/glimmer/swt/custom/animation.rb +2 -5
  73. data/lib/glimmer/swt/custom/checkbox_group.rb +181 -181
  74. data/lib/glimmer/swt/custom/code_text.rb +1 -0
  75. data/lib/glimmer/swt/custom/drawable.rb +65 -49
  76. data/lib/glimmer/swt/custom/radio_group.rb +176 -176
  77. data/lib/glimmer/swt/custom/shape.rb +38 -35
  78. data/lib/glimmer/swt/date_time_proxy.rb +85 -85
  79. data/lib/glimmer/swt/directory_dialog_proxy.rb +65 -65
  80. data/lib/glimmer/swt/dnd_proxy.rb +51 -51
  81. data/lib/glimmer/swt/expand_item_proxy.rb +97 -97
  82. data/lib/glimmer/swt/file_dialog_proxy.rb +66 -66
  83. data/lib/glimmer/swt/font_proxy.rb +94 -94
  84. data/lib/glimmer/swt/image_proxy.rb +184 -184
  85. data/lib/glimmer/swt/layout_data_proxy.rb +105 -105
  86. data/lib/glimmer/swt/layout_proxy.rb +112 -112
  87. data/lib/glimmer/swt/menu_proxy.rb +126 -126
  88. data/lib/glimmer/swt/message_box_proxy.rb +89 -89
  89. data/lib/glimmer/swt/packages.rb +37 -37
  90. data/lib/glimmer/swt/properties.rb +74 -49
  91. data/lib/glimmer/swt/sash_form_proxy.rb +53 -53
  92. data/lib/glimmer/swt/scrolled_composite_proxy.rb +37 -37
  93. data/lib/glimmer/swt/style_constantizable.rb +157 -157
  94. data/lib/glimmer/swt/styled_text_proxy.rb +38 -38
  95. data/lib/glimmer/swt/swt_proxy.rb +59 -59
  96. data/lib/glimmer/swt/tab_item_proxy.rb +91 -91
  97. data/lib/glimmer/swt/table_column_proxy.rb +57 -57
  98. data/lib/glimmer/swt/transform_proxy.rb +109 -109
  99. data/lib/glimmer/swt/tree_proxy.rb +145 -145
  100. data/lib/glimmer/swt/widget_listener_proxy.rb +64 -64
  101. data/lib/glimmer/swt/widget_proxy.rb +9 -3
  102. data/lib/glimmer/ui/custom_shell.rb +82 -82
  103. data/lib/glimmer/util/proc_tracker.rb +39 -39
  104. data/samples/elaborate/contact_manager.rb +142 -142
  105. data/samples/elaborate/contact_manager/contact.rb +32 -32
  106. data/samples/elaborate/contact_manager/contact_manager_presenter.rb +47 -47
  107. data/samples/elaborate/contact_manager/contact_repository.rb +169 -169
  108. data/samples/elaborate/login.rb +123 -123
  109. data/samples/elaborate/mandelbrot_fractal.rb +103 -0
  110. data/samples/elaborate/tetris/model/block.rb +48 -48
  111. data/samples/elaborate/tetris/model/past_game.rb +39 -39
  112. data/samples/elaborate/tetris/view/playfield.rb +1 -1
  113. data/samples/elaborate/tic_tac_toe.rb +76 -76
  114. data/samples/elaborate/tic_tac_toe/board.rb +145 -145
  115. data/samples/elaborate/tic_tac_toe/cell.rb +48 -48
  116. data/samples/elaborate/user_profile.rb +76 -76
  117. data/samples/hello/hello_browser.rb +31 -31
  118. data/samples/hello/hello_button.rb +46 -46
  119. data/samples/hello/hello_canvas.rb +64 -64
  120. data/samples/hello/hello_checkbox.rb +85 -85
  121. data/samples/hello/hello_checkbox_group.rb +71 -71
  122. data/samples/hello/hello_code_text.rb +104 -104
  123. data/samples/hello/hello_combo.rb +63 -63
  124. data/samples/hello/hello_computed.rb +96 -96
  125. data/samples/hello/hello_computed/contact.rb +42 -42
  126. data/samples/hello/hello_custom_shell.rb +155 -155
  127. data/samples/hello/hello_custom_widget.rb +86 -86
  128. data/samples/hello/hello_date_time.rb +63 -63
  129. data/samples/hello/hello_dialog.rb +78 -78
  130. data/samples/hello/hello_directory_dialog.rb +60 -60
  131. data/samples/hello/hello_drag_and_drop.rb +50 -50
  132. data/samples/hello/hello_expand_bar.rb +110 -110
  133. data/samples/hello/hello_file_dialog.rb +60 -60
  134. data/samples/hello/hello_group.rb +104 -104
  135. data/samples/hello/hello_link.rb +80 -80
  136. data/samples/hello/hello_list_multi_selection.rb +74 -74
  137. data/samples/hello/hello_list_single_selection.rb +59 -59
  138. data/samples/hello/hello_menu_bar.rb +241 -241
  139. data/samples/hello/hello_message_box.rb +37 -37
  140. data/samples/hello/hello_pop_up_context_menu.rb +84 -84
  141. data/samples/hello/hello_radio.rb +108 -108
  142. data/samples/hello/hello_radio_group.rb +87 -87
  143. data/samples/hello/hello_sash_form.rb +137 -137
  144. data/samples/hello/hello_spinner.rb +69 -69
  145. data/samples/hello/hello_styled_text.rb +138 -138
  146. data/samples/hello/hello_tab.rb +50 -50
  147. data/samples/hello/hello_world.rb +29 -29
  148. metadata +4 -3
@@ -1,765 +1,765 @@
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 'fileutils'
23
- require 'os'
24
- require 'facets'
25
-
26
- # TODO refactor to nest under RakeTask namespace
27
-
28
- MAIN_OBJECT = self
29
-
30
- module Glimmer
31
- module RakeTask
32
- class Scaffold
33
- class << self
34
- include FileUtils
35
-
36
- VERSION = File.read(File.expand_path('../../../../VERSION', __FILE__)).strip
37
- RUBY_VERSION = File.read(File.expand_path('../../../../RUBY_VERSION', __FILE__)).strip
38
-
39
- # TODO externalize all constants into scaffold/files
40
-
41
- GITIGNORE = <<~MULTI_LINE_STRING
42
- *.gem
43
- *.rbc
44
- /.config
45
- /.mvn/
46
- /coverage/
47
- /InstalledFiles
48
- /pkg/
49
- /spec/reports/
50
- /spec/examples.txt
51
- /test/tmp/
52
- /test/version_tmp/
53
- /tmp/
54
-
55
- # Used by dotenv library to load environment variables.
56
- # .env
57
-
58
- ## Specific to RubyMotion:
59
- .dat*
60
- .repl_history
61
- build/
62
- *.bridgesupport
63
- build-iPhoneOS/
64
- build-iPhoneSimulator/
65
-
66
- ## Specific to RubyMotion (use of CocoaPods):
67
- #
68
- # We recommend against adding the Pods directory to your .gitignore. However
69
- # you should judge for yourself, the pros and cons are mentioned at:
70
- # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
71
- #
72
- # vendor/Pods/
73
-
74
- ## Documentation cache and generated files:
75
- /.yardoc/
76
- /_yardoc/
77
- /doc/
78
- /rdoc/
79
-
80
- ## Environment normalization:
81
- /.bundle/
82
- /vendor/bundle
83
- /lib/bundler/man/
84
-
85
- # for a library or gem, you might want to ignore these files since the code is
86
- # intended to run in multiple environments; otherwise, check them in:
87
- # Gemfile.lock
88
- # .ruby-version
89
- # .ruby-gemset
90
-
91
- # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
92
- .rvmrc
93
-
94
- # Mac
95
- .DS_Store
96
-
97
- # Gladiator (Glimmer Editor)
98
- .gladiator
99
-
100
- # Glimmer
101
- /dist/
102
- /packages/
103
- /vendor/jars/
104
- MULTI_LINE_STRING
105
-
106
- GEMFILE = <<~MULTI_LINE_STRING
107
- # frozen_string_literal: true
108
-
109
- source 'https://rubygems.org'
110
-
111
- git_source(:github) {|repo_name| "https://github.com/\#{repo_name}" }
112
-
113
- gem 'glimmer-dsl-swt', '~> #{VERSION}'
114
-
115
- group :development do
116
- gem 'rspec', '~> 3.5.0'
117
- gem 'juwelier', '2.4.9'
118
- gem 'warbler', '2.0.5'
119
- gem 'simplecov', '>= 0'
120
- end
121
- MULTI_LINE_STRING
122
-
123
- def app(app_name)
124
- common_app(app_name)
125
- end
126
-
127
- def desktopify(app_name, website)
128
- common_app(app_name, :desktopify, website: website)
129
- end
130
-
131
- def common_app(app_name, shell_type = :app, shell_options = {})
132
- gem_name = file_name(app_name)
133
- gem_summary = human_name(app_name)
134
- return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
135
- system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
136
- system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
137
- return puts('Your Git user.name and/or github.user are missing! Please add in for Juwelier to help Glimmer with Scaffolding.') if `git config --get github.user`.strip.empty? && `git config --get user.name`.strip.empty?
138
- cd gem_name
139
- rm_rf 'lib'
140
- write '.gitignore', GITIGNORE
141
- write '.ruby-version', RUBY_VERSION
142
- write '.ruby-gemset', app_name
143
- write 'VERSION', '1.0.0'
144
- write 'LICENSE.txt', "Copyright (c) #{Time.now.year} #{app_name}"
145
- write 'Gemfile', gemfile(shell_type)
146
- write 'Rakefile', gem_rakefile(app_name, nil, gem_name)
147
- mkdir 'app'
148
- write "app/#{file_name(app_name)}.rb", app_main_file(app_name)
149
- mkdir 'app/models'
150
- mkdir 'app/views'
151
- if shell_type == :desktopify
152
- custom_shell('AppView', current_dir_name, shell_type, shell_options)
153
- else
154
- custom_shell('AppView', current_dir_name, shell_type)
155
- end
156
-
157
- mkdir_p 'package/windows'
158
- icon_file = "package/windows/#{human_name(app_name)}.ico"
159
- cp File.expand_path('../../../../icons/scaffold_app.ico', __FILE__), icon_file
160
- puts "Created #{current_dir_name}/#{icon_file}"
161
-
162
- mkdir_p 'package/macosx'
163
- icon_file = "package/macosx/#{human_name(app_name)}.icns"
164
- cp File.expand_path('../../../../icons/scaffold_app.icns', __FILE__), icon_file
165
- puts "Created #{current_dir_name}/#{icon_file}"
166
-
167
- mkdir_p 'package/linux'
168
- icon_file = "package/linux/#{human_name(app_name)}.png"
169
- cp File.expand_path('../../../../icons/scaffold_app.png', __FILE__), icon_file
170
- puts "Created #{current_dir_name}/#{icon_file}"
171
-
172
- mkdir_p "app/#{file_name(app_name)}"
173
- write "app/#{file_name(app_name)}/launch.rb", app_launch_file(app_name)
174
- mkdir_p 'bin'
175
- write "bin/#{file_name(app_name)}", app_bin_command_file(app_name)
176
- FileUtils.chmod 0755, "bin/#{file_name(app_name)}"
177
- if OS.windows?
178
- system "bundle"
179
- system "rspec --init"
180
- else
181
- system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
182
- end
183
- write 'spec/spec_helper.rb', spec_helper_file
184
- if OS.windows?
185
- system "glimmer package[image]"
186
- system "\"packages/bundles/#{human_name(app_name)}/#{human_name(app_name)}.exe\""
187
- else
188
- system "bash -c '#{RVM_FUNCTION}\n cd .\n glimmer package\n'"
189
- if OS.mac?
190
- system "open packages/bundles/#{human_name(app_name).gsub(' ', '\ ')}.app"
191
- else
192
- system "glimmer run"
193
- end
194
- end
195
- end
196
-
197
- def custom_shell(custom_shell_name, namespace, shell_type = nil, shell_options = {})
198
- namespace ||= current_dir_name
199
- root_dir = File.exists?('app') ? 'app' : 'lib'
200
- parent_dir = "#{root_dir}/views/#{file_name(namespace)}"
201
- return puts("The file '#{parent_dir}/#{file_name(custom_shell_name)}.rb' already exists. Please either remove or pick a different name.") if File.exist?("#{parent_dir}/#{file_name(custom_shell_name)}.rb")
202
- mkdir_p parent_dir unless File.exists?(parent_dir)
203
- write "#{parent_dir}/#{file_name(custom_shell_name)}.rb", custom_shell_file(custom_shell_name, namespace, shell_type, shell_options)
204
- end
205
-
206
- def custom_widget(custom_widget_name, namespace)
207
- namespace ||= current_dir_name
208
- root_dir = File.exists?('app') ? 'app' : 'lib'
209
- parent_dir = "#{root_dir}/views/#{file_name(namespace)}"
210
- return puts("The file '#{parent_dir}/#{file_name(custom_widget_name)}.rb' already exists. Please either remove or pick a different name.") if File.exist?("#{parent_dir}/#{file_name(custom_widget_name)}.rb")
211
- mkdir_p parent_dir unless File.exists?(parent_dir)
212
- write "#{parent_dir}/#{file_name(custom_widget_name)}.rb", custom_widget_file(custom_widget_name, namespace)
213
- end
214
-
215
- def custom_shell_gem(custom_shell_name, namespace)
216
- gem_name = "glimmer-cs-#{compact_name(custom_shell_name)}"
217
- gem_summary = "#{human_name(custom_shell_name)} - Glimmer Custom Shell"
218
- begin
219
- custom_shell_keyword = dsl_widget_name(custom_shell_name)
220
- MAIN_OBJECT.method(custom_shell_keyword)
221
- return puts("CustomShell keyword `#{custom_shell_keyword}` is unavailable (occupied by a built-in Ruby method)! Please pick a different name.")
222
- rescue NameError
223
- # No Op (keyword is not taken by a built in Ruby method)
224
- end
225
- if namespace
226
- gem_name += "-#{compact_name(namespace)}"
227
- gem_summary += " (#{human_name(namespace)})"
228
- else
229
- return puts('Namespace is required! Usage: glimmer scaffold:gem:customshell[name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
230
- namespace = 'glimmer'
231
- end
232
- return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
233
- system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
234
- system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
235
- return puts('Your Git user.name and/or github.user are missing! Please add in for Juwelier to help Glimmer with Scaffolding.') if `git config --get github.user`.strip.empty? && `git config --get user.name`.strip.empty?
236
- cd gem_name
237
- write '.gitignore', GITIGNORE
238
- write '.ruby-version', RUBY_VERSION
239
- write '.ruby-gemset', gem_name
240
- write 'VERSION', '1.0.0'
241
- write 'Gemfile', GEMFILE
242
- write 'Rakefile', gem_rakefile(custom_shell_name, namespace, gem_name)
243
- append "lib/#{gem_name}.rb", gem_main_file(custom_shell_name, namespace)
244
- mkdir 'lib/views'
245
- custom_shell(custom_shell_name, namespace, :gem)
246
-
247
- mkdir_p "lib/#{file_name(namespace)}/#{file_name(custom_shell_name)}"
248
- write "lib/#{file_name(namespace)}/#{file_name(custom_shell_name)}/launch.rb", gem_launch_file(gem_name, custom_shell_name, namespace)
249
- mkdir_p 'bin'
250
- write "bin/#{gem_name}", gem_bin_command_file(gem_name, custom_shell_name, namespace)
251
- FileUtils.chmod 0755, "bin/#{gem_name}"
252
- write "bin/#{file_name(custom_shell_name)}", gem_bin_command_file(gem_name, custom_shell_name, namespace)
253
- FileUtils.chmod 0755, "bin/#{file_name(custom_shell_name)}"
254
- if OS.windows?
255
- system "bundle"
256
- system "rspec --init"
257
- else
258
- system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
259
- end
260
- write 'spec/spec_helper.rb', spec_helper_file
261
-
262
- mkdir_p 'package/windows'
263
- icon_file = "package/windows/#{human_name(custom_shell_name)}.ico"
264
- cp File.expand_path('../../../../icons/scaffold_app.ico', __FILE__), icon_file
265
- puts "Created #{current_dir_name}/#{icon_file}"
266
-
267
- mkdir_p 'package/macosx'
268
- icon_file = "package/macosx/#{human_name(custom_shell_name)}.icns"
269
- cp File.expand_path('../../../../icons/scaffold_app.icns', __FILE__), icon_file
270
- puts "Created #{current_dir_name}/#{icon_file}"
271
-
272
- mkdir_p 'package/linux'
273
- icon_file = "package/linux/#{human_name(custom_shell_name)}.png"
274
- cp File.expand_path('../../../../icons/scaffold_app.png', __FILE__), icon_file
275
- puts "Created #{current_dir_name}/#{icon_file}"
276
-
277
- if OS.windows?
278
- system "glimmer package[image]"
279
- system "\"packages/bundles/#{human_name(custom_shell_name)}/#{human_name(custom_shell_name)}.exe\""
280
- else
281
- system "bash -c '#{RVM_FUNCTION}\n cd .\n glimmer package\n'"
282
- if OS.mac?
283
- system "open packages/bundles/#{human_name(custom_shell_name).gsub(' ', '\ ')}.app" if OS.mac?
284
- else
285
- system "glimmer run"
286
- end
287
- end
288
- puts "Finished creating #{gem_name} Ruby gem."
289
- puts 'Edit Rakefile to configure gem details.'
290
- puts 'Run `rake` to execute specs.'
291
- puts 'Run `rake build` to build gem.'
292
- puts 'Run `rake release` to release into rubygems.org once ready.'
293
- end
294
-
295
- def custom_widget_gem(custom_widget_name, namespace)
296
- return puts('Namespace is required! Usage: glimmer scaffold:custom_widget_gem[custom_widget_name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
297
- gem_name = "glimmer-cw-#{compact_name(custom_widget_name)}"
298
- gem_summary = "#{human_name(custom_widget_name)} - Glimmer Custom Widget"
299
- if namespace
300
- gem_name += "-#{compact_name(namespace)}"
301
- gem_summary += " (#{human_name(namespace)})"
302
- else
303
- namespace = 'glimmer'
304
- end
305
-
306
- return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
307
- system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
308
- system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
309
- return puts('Your Git user.name and/or github.user are missing! Please add in for Juwelier to help Glimmer with Scaffolding.') if `git config --get github.user`.strip.empty? && `git config --get user.name`.strip.empty?
310
- cd gem_name
311
- write '.gitignore', GITIGNORE
312
- write '.ruby-version', RUBY_VERSION
313
- write '.ruby-gemset', gem_name
314
- write 'VERSION', '1.0.0'
315
- write 'Gemfile', GEMFILE
316
- write 'Rakefile', gem_rakefile
317
- append "lib/#{gem_name}.rb", gem_main_file(custom_widget_name, namespace)
318
- mkdir 'lib/views'
319
- custom_widget(custom_widget_name, namespace)
320
- if OS.windows?
321
- system "bundle"
322
- system "rspec --init"
323
- else
324
- system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
325
- end
326
- write 'spec/spec_helper.rb', spec_helper_file
327
- puts "Finished creating #{gem_name} Ruby gem."
328
- puts 'Edit Rakefile to configure gem details.'
329
- puts 'Run `rake` to execute specs.'
330
- puts 'Run `rake build` to build gem.'
331
- puts 'Run `rake release` to release into rubygems.org once ready.'
332
- end
333
-
334
- private
335
-
336
- def juwelier_exists?
337
- OS.windows? ? system('where juwelier') : system('which juwelier')
338
- end
339
-
340
- def write(file, content)
341
- File.write file, content
342
- file_path = File.expand_path(file)
343
- puts "Created #{current_dir_name}/#{file}"
344
- end
345
-
346
- def append(file, content)
347
- File.open(file, 'a') do |f|
348
- f.write(content)
349
- end
350
- end
351
-
352
- def current_dir_name
353
- File.basename(File.expand_path('.'))
354
- end
355
-
356
- def class_name(app_name)
357
- app_name.underscore.camelcase(:upper)
358
- end
359
-
360
- def file_name(app_name)
361
- app_name.underscore
362
- end
363
- alias dsl_widget_name file_name
364
-
365
- def human_name(app_name)
366
- app_name.underscore.titlecase
367
- end
368
-
369
- def compact_name(gem_name)
370
- gem_name.underscore.camelcase.downcase
371
- end
372
-
373
- def gemfile(shell_type)
374
- if shell_type == :desktopify
375
- lines = GEMFILE.split("\n")
376
- require_glimmer_dsl_swt_index = lines.index(lines.detect {|l| l.include?("gem 'glimmer-dsl-swt'") })
377
- lines[(require_glimmer_dsl_swt_index + 1)..(require_glimmer_dsl_swt_index + 1)] = [
378
- "",
379
- "# Enable Chromium Browser Glimmer Custom Widget gem if needed (e.g. Linux needs it to support HTML5 Video), and use `browser(:chromium)` in GUI.",
380
- "# gem 'glimmer-cw-browser-chromium', '>= 0'",
381
- "",
382
- ]
383
- lines.join("\n")
384
- else
385
- GEMFILE
386
- end
387
- end
388
-
389
- def app_main_file(app_name)
390
- <<~MULTI_LINE_STRING
391
- $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
392
-
393
- require 'bundler/setup'
394
- Bundler.require(:default)
395
- require 'views/#{file_name(app_name)}/app_view'
396
-
397
- class #{class_name(app_name)}
398
- include Glimmer
399
-
400
- APP_ROOT = File.expand_path('../..', __FILE__)
401
- VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
402
- LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
403
-
404
- def open
405
- app_view.open
406
- end
407
- end
408
- MULTI_LINE_STRING
409
- end
410
-
411
- def gem_main_file(custom_widget_name, namespace = nil)
412
- custom_widget_file_path = "views"
413
- custom_widget_file_path += "/#{file_name(namespace)}" if namespace
414
- custom_widget_file_path += "/#{file_name(custom_widget_name)}"
415
-
416
- <<~MULTI_LINE_STRING
417
- $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
418
-
419
- require 'glimmer-dsl-swt'
420
- require '#{custom_widget_file_path}'
421
- MULTI_LINE_STRING
422
- end
423
-
424
- def app_launch_file(app_name)
425
- <<~MULTI_LINE_STRING
426
- require_relative '../#{file_name(app_name)}'
427
-
428
- #{class_name(app_name)}.new.open
429
- MULTI_LINE_STRING
430
- end
431
-
432
- def app_bin_command_file(app_name)
433
- <<~MULTI_LINE_STRING
434
- #!/usr/bin/env jruby
435
-
436
- runner = File.expand_path("../../app/#{file_name(app_name)}/launch.rb", __FILE__)
437
-
438
- # Detect if inside a JAR file or not
439
- if runner.include?('uri:classloader')
440
- require runner
441
- else
442
- require 'glimmer/launcher'
443
-
444
- launcher = Glimmer::Launcher.new([runner] + ARGV)
445
- launcher.launch
446
- end
447
- MULTI_LINE_STRING
448
- end
449
-
450
- def gem_launch_file(gem_name, custom_shell_name, namespace)
451
- # TODO change this so that it does not mix Glimmer unto the main object
452
- <<~MULTI_LINE_STRING
453
- require_relative '../../#{gem_name}'
454
-
455
- module #{class_name(namespace)}
456
- class #{class_name(custom_shell_name)}
457
- class App
458
- include Glimmer
459
-
460
- def open
461
- #{dsl_widget_name(custom_shell_name)}.open
462
- end
463
- end
464
- end
465
- end
466
-
467
- #{class_name(namespace)}::#{class_name(custom_shell_name)}::App.new.open
468
- MULTI_LINE_STRING
469
- end
470
-
471
- def gem_bin_command_file(gem_name, custom_shell_name, namespace)
472
- <<~MULTI_LINE_STRING
473
- #!/usr/bin/env jruby
474
-
475
- runner = File.expand_path("../../lib/#{file_name(namespace)}/#{file_name(custom_shell_name)}/launch.rb", __FILE__)
476
-
477
- # Detect if inside a JAR file or not
478
- if runner.include?('uri:classloader')
479
- require runner
480
- else
481
- require 'glimmer/launcher'
482
-
483
- launcher = Glimmer::Launcher.new([runner] + ARGV)
484
- launcher.launch
485
- end
486
- MULTI_LINE_STRING
487
- end
488
-
489
- def gem_rakefile(custom_shell_name = nil, namespace = nil, gem_name = nil)
490
- rakefile_content = File.read('Rakefile')
491
- lines = rakefile_content.split("\n")
492
- require_rake_line_index = lines.index(lines.detect {|l| l.include?("require 'rake'") })
493
- lines.insert(require_rake_line_index, "require 'glimmer/launcher'")
494
- gem_files_line_index = lines.index(lines.detect {|l| l.include?('# dependencies defined in Gemfile') })
495
- if custom_shell_name
496
- lines.insert(gem_files_line_index, " gem.files = Dir['VERSION', 'LICENSE.txt', 'app/**/*', 'bin/**/*', 'config/**/*', 'db/**/*', 'docs/**/*', 'fonts/**/*', 'icons/**/*', 'images/**/*', 'lib/**/*', 'package/**/*', 'script/**/*', 'sounds/**/*', 'vendor/**/*', 'videos/**/*']")
497
- # the second executable is needed for warbler as it matches the gem name, which is the default expected file (alternatively in the future, we could do away with it and configure warbler to use the other file)
498
- lines.insert(gem_files_line_index+1, " gem.executables = ['#{gem_name}', '#{file_name(custom_shell_name)}']")
499
- lines.insert(gem_files_line_index+2, " gem.require_paths = ['vendor', 'lib', 'app']")
500
- else
501
- lines.insert(gem_files_line_index, " gem.files = Dir['VERSION', 'LICENSE.txt', 'lib/**/*']")
502
- end
503
- spec_pattern_line_index = lines.index(lines.detect {|l| l.include?('spec.pattern =') })
504
- lines.insert(spec_pattern_line_index+1, " spec.ruby_opts = [Glimmer::Launcher.jruby_os_specific_options]")
505
- lines << "\nrequire 'glimmer/rake_task'\n"
506
- file_content = lines.join("\n")
507
- if custom_shell_name
508
- file_content << <<~MULTI_LINE_STRING
509
- Glimmer::RakeTask::Package.javapackager_extra_args =
510
- " -name '#{human_name(custom_shell_name)}'" +
511
- " -title '#{human_name(custom_shell_name)}'" +
512
- " -Bmac.CFBundleName='#{human_name(custom_shell_name)}'" +
513
- " -Bmac.CFBundleIdentifier='org.#{namespace ? compact_name(namespace) : compact_name(custom_shell_name)}.application.#{compact_name(custom_shell_name).camelcase(:upper)}'"
514
- # " -BlicenseType=" +
515
- # " -Bmac.category=" +
516
- # " -Bmac.signing-key-developer-id-app="
517
- MULTI_LINE_STRING
518
- end
519
- file_content
520
- end
521
-
522
- def spec_helper_file
523
- content = File.read('spec/spec_helper.rb')
524
- lines = content.split("\n")
525
- require_line_index = lines.index(lines.detect {|l| l.include?('RSpec.configure do') })
526
- lines[require_line_index...require_line_index] = [
527
- "require 'bundler/setup'",
528
- 'Bundler.require(:default, :development)',
529
- ]
530
- configure_block_line_index = lines.index(lines.detect {|l| l.include?('RSpec.configure do') }) + 1
531
- lines[configure_block_line_index...configure_block_line_index] = [
532
- ' # The following ensures rspec tests that instantiate and set Glimmer DSL widgets in @target get cleaned after',
533
- ' config.after do',
534
- ' @target.dispose if @target && @target.respond_to?(:dispose)',
535
- ' Glimmer::DSL::Engine.reset',
536
- ' end',
537
- ]
538
-
539
- lines << "\nrequire 'glimmer/rake_task'\n"
540
- lines.join("\n")
541
- end
542
-
543
- def custom_shell_file(custom_shell_name, namespace, shell_type, shell_options = {})
544
- namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
545
-
546
- custom_shell_file_content = <<-MULTI_LINE_STRING
547
- #{namespace_type} #{class_name(namespace)}
548
- class #{class_name(custom_shell_name)}
549
- include Glimmer::UI::CustomShell
550
-
551
- MULTI_LINE_STRING
552
-
553
- if shell_type == :gem
554
- custom_shell_file_content += <<-MULTI_LINE_STRING
555
- APP_ROOT = File.expand_path('../../../..', __FILE__)
556
- VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
557
- LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
558
-
559
- MULTI_LINE_STRING
560
- end
561
-
562
- custom_shell_file_content += <<-MULTI_LINE_STRING
563
- ## Add options like the following to configure CustomShell by outside consumers
564
- #
565
- # options :title, :background_color
566
- # option :width, default: 320
567
- # option :height, default: 240
568
- #{'# ' if shell_type == :desktopify}option :greeting, default: 'Hello, World!'
569
-
570
- ## Use before_body block to pre-initialize variables to use in body
571
- #
572
- #
573
- MULTI_LINE_STRING
574
-
575
- if %i[gem app desktopify].include?(shell_type)
576
- custom_shell_file_content += <<-MULTI_LINE_STRING
577
- before_body {
578
- Display.app_name = '#{shell_type == :gem ? human_name(custom_shell_name) : human_name(namespace)}'
579
- Display.app_version = VERSION
580
- @display = display {
581
- on_about {
582
- display_about_dialog
583
- }
584
- on_preferences {
585
- #{shell_type == :desktopify ? 'display_about_dialog' : 'display_preferences_dialog'}
586
- }
587
- }
588
- }
589
- MULTI_LINE_STRING
590
- else
591
- custom_shell_file_content += <<-MULTI_LINE_STRING
592
- # before_body {
593
- #
594
- # }
595
- MULTI_LINE_STRING
596
- end
597
-
598
- custom_shell_file_content += <<-MULTI_LINE_STRING
599
-
600
- ## Use after_body block to setup observers for widgets in body
601
- #
602
- # after_body {
603
- #
604
- # }
605
-
606
- ## Add widget content inside custom shell body
607
- ## Top-most widget must be a shell or another custom shell
608
- #
609
- body {
610
- shell {
611
- # Replace example content below with custom shell content
612
- minimum_size #{shell_type == :desktopify ? '1024, 768' : '320, 240'}
613
- image File.join(APP_ROOT, 'package', 'windows', "#{human_name(shell_type == :gem ? custom_shell_name : current_dir_name)}.ico") if OS.windows?
614
- text "#{human_name(namespace)} - #{human_name(custom_shell_name)}"
615
-
616
- MULTI_LINE_STRING
617
-
618
- if shell_type == :desktopify
619
- custom_shell_file_content += <<-MULTI_LINE_STRING
620
- browser {
621
- url "#{shell_options[:website]}"
622
- }
623
- MULTI_LINE_STRING
624
- else
625
- custom_shell_file_content += <<-MULTI_LINE_STRING
626
- grid_layout
627
- label(:center) {
628
- text bind(self, :greeting)
629
- font height: 40
630
- layout_data :fill, :center, true, true
631
- }
632
- MULTI_LINE_STRING
633
- end
634
-
635
- if %i[gem app desktopify].include?(shell_type)
636
- custom_shell_file_content += <<-MULTI_LINE_STRING
637
-
638
- menu_bar {
639
- menu {
640
- text '&File'
641
- menu_item {
642
- text '&About...'
643
- on_widget_selected {
644
- display_about_dialog
645
- }
646
- }
647
- menu_item {
648
- text '&Preferences...'
649
- on_widget_selected {
650
- #{shell_type == :desktopify ? 'display_about_dialog' : 'display_preferences_dialog'}
651
- }
652
- }
653
- }
654
- }
655
- MULTI_LINE_STRING
656
- end
657
-
658
- custom_shell_file_content += <<-MULTI_LINE_STRING
659
- }
660
- }
661
- MULTI_LINE_STRING
662
-
663
- if %i[gem app desktopify].include?(shell_type)
664
- custom_shell_file_content += <<-MULTI_LINE_STRING
665
-
666
- def display_about_dialog
667
- message_box(body_root) {
668
- text 'About'
669
- message "#{human_name(namespace)}#{" - #{human_name(custom_shell_name)}" if shell_type == :gem} \#{VERSION}\\n\\n\#{LICENSE}"
670
- }.open
671
- end
672
-
673
- MULTI_LINE_STRING
674
- end
675
-
676
- if %i[gem app].include?(shell_type)
677
- custom_shell_file_content += <<-MULTI_LINE_STRING
678
- def display_preferences_dialog
679
- dialog(swt_widget) {
680
- text 'Preferences'
681
- grid_layout {
682
- margin_height 5
683
- margin_width 5
684
- }
685
- group {
686
- row_layout {
687
- type :vertical
688
- spacing 10
689
- }
690
- text 'Greeting'
691
- font style: :bold
692
- [
693
- 'Hello, World!',
694
- 'Howdy, Partner!'
695
- ].each do |greeting_text|
696
- button(:radio) {
697
- text greeting_text
698
- selection bind(self, :greeting) { |g| g == greeting_text }
699
- layout_data {
700
- width 160
701
- }
702
- on_widget_selected { |event|
703
- self.greeting = event.widget.getText
704
- }
705
- }
706
- end
707
- }
708
- }.open
709
- end
710
- MULTI_LINE_STRING
711
- end
712
-
713
- custom_shell_file_content += <<-MULTI_LINE_STRING
714
- end
715
- end
716
- MULTI_LINE_STRING
717
- end
718
-
719
- def custom_widget_file(custom_widget_name, namespace)
720
- namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
721
-
722
- <<~MULTI_LINE_STRING
723
- #{namespace_type} #{class_name(namespace)}
724
- class #{class_name(custom_widget_name)}
725
- include Glimmer::UI::CustomWidget
726
-
727
- ## Add options like the following to configure CustomWidget by outside consumers
728
- #
729
- # options :custom_text, :background_color
730
- # option :foreground_color, default: :red
731
-
732
- ## Use before_body block to pre-initialize variables to use in body
733
- #
734
- #
735
- # before_body {
736
- #
737
- # }
738
-
739
- ## Use after_body block to setup observers for widgets in body
740
- #
741
- # after_body {
742
- #
743
- # }
744
-
745
- ## Add widget content under custom widget body
746
- ##
747
- ## If you want to add a shell as the top-most widget,
748
- ## consider creating a custom shell instead
749
- ## (Glimmer::UI::CustomShell offers shell convenience methods, like show and hide)
750
- #
751
- body {
752
- # Replace example content below with custom widget content
753
- label {
754
- background :red
755
- }
756
- }
757
-
758
- end
759
- end
760
- MULTI_LINE_STRING
761
- end
762
- end
763
- end
764
- end
765
- end
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 'fileutils'
23
+ require 'os'
24
+ require 'facets'
25
+
26
+ # TODO refactor to nest under RakeTask namespace
27
+
28
+ MAIN_OBJECT = self
29
+
30
+ module Glimmer
31
+ module RakeTask
32
+ class Scaffold
33
+ class << self
34
+ include FileUtils
35
+
36
+ VERSION = File.read(File.expand_path('../../../../VERSION', __FILE__)).strip
37
+ RUBY_VERSION = File.read(File.expand_path('../../../../RUBY_VERSION', __FILE__)).strip
38
+
39
+ # TODO externalize all constants into scaffold/files
40
+
41
+ GITIGNORE = <<~MULTI_LINE_STRING
42
+ *.gem
43
+ *.rbc
44
+ /.config
45
+ /.mvn/
46
+ /coverage/
47
+ /InstalledFiles
48
+ /pkg/
49
+ /spec/reports/
50
+ /spec/examples.txt
51
+ /test/tmp/
52
+ /test/version_tmp/
53
+ /tmp/
54
+
55
+ # Used by dotenv library to load environment variables.
56
+ # .env
57
+
58
+ ## Specific to RubyMotion:
59
+ .dat*
60
+ .repl_history
61
+ build/
62
+ *.bridgesupport
63
+ build-iPhoneOS/
64
+ build-iPhoneSimulator/
65
+
66
+ ## Specific to RubyMotion (use of CocoaPods):
67
+ #
68
+ # We recommend against adding the Pods directory to your .gitignore. However
69
+ # you should judge for yourself, the pros and cons are mentioned at:
70
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
71
+ #
72
+ # vendor/Pods/
73
+
74
+ ## Documentation cache and generated files:
75
+ /.yardoc/
76
+ /_yardoc/
77
+ /doc/
78
+ /rdoc/
79
+
80
+ ## Environment normalization:
81
+ /.bundle/
82
+ /vendor/bundle
83
+ /lib/bundler/man/
84
+
85
+ # for a library or gem, you might want to ignore these files since the code is
86
+ # intended to run in multiple environments; otherwise, check them in:
87
+ # Gemfile.lock
88
+ # .ruby-version
89
+ # .ruby-gemset
90
+
91
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
92
+ .rvmrc
93
+
94
+ # Mac
95
+ .DS_Store
96
+
97
+ # Gladiator (Glimmer Editor)
98
+ .gladiator
99
+
100
+ # Glimmer
101
+ /dist/
102
+ /packages/
103
+ /vendor/jars/
104
+ MULTI_LINE_STRING
105
+
106
+ GEMFILE = <<~MULTI_LINE_STRING
107
+ # frozen_string_literal: true
108
+
109
+ source 'https://rubygems.org'
110
+
111
+ git_source(:github) {|repo_name| "https://github.com/\#{repo_name}" }
112
+
113
+ gem 'glimmer-dsl-swt', '~> #{VERSION}'
114
+
115
+ group :development do
116
+ gem 'rspec', '~> 3.5.0'
117
+ gem 'juwelier', '2.4.9'
118
+ gem 'warbler', '2.0.5'
119
+ gem 'simplecov', '>= 0'
120
+ end
121
+ MULTI_LINE_STRING
122
+
123
+ def app(app_name)
124
+ common_app(app_name)
125
+ end
126
+
127
+ def desktopify(app_name, website)
128
+ common_app(app_name, :desktopify, website: website)
129
+ end
130
+
131
+ def common_app(app_name, shell_type = :app, shell_options = {})
132
+ gem_name = file_name(app_name)
133
+ gem_summary = human_name(app_name)
134
+ return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
135
+ system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
136
+ system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
137
+ return puts('Your Git user.name and/or github.user are missing! Please add in for Juwelier to help Glimmer with Scaffolding.') if `git config --get github.user`.strip.empty? && `git config --get user.name`.strip.empty?
138
+ cd gem_name
139
+ rm_rf 'lib'
140
+ write '.gitignore', GITIGNORE
141
+ write '.ruby-version', RUBY_VERSION
142
+ write '.ruby-gemset', app_name
143
+ write 'VERSION', '1.0.0'
144
+ write 'LICENSE.txt', "Copyright (c) #{Time.now.year} #{app_name}"
145
+ write 'Gemfile', gemfile(shell_type)
146
+ write 'Rakefile', gem_rakefile(app_name, nil, gem_name)
147
+ mkdir 'app'
148
+ write "app/#{file_name(app_name)}.rb", app_main_file(app_name)
149
+ mkdir 'app/models'
150
+ mkdir 'app/views'
151
+ if shell_type == :desktopify
152
+ custom_shell('AppView', current_dir_name, shell_type, shell_options)
153
+ else
154
+ custom_shell('AppView', current_dir_name, shell_type)
155
+ end
156
+
157
+ mkdir_p 'package/windows'
158
+ icon_file = "package/windows/#{human_name(app_name)}.ico"
159
+ cp File.expand_path('../../../../icons/scaffold_app.ico', __FILE__), icon_file
160
+ puts "Created #{current_dir_name}/#{icon_file}"
161
+
162
+ mkdir_p 'package/macosx'
163
+ icon_file = "package/macosx/#{human_name(app_name)}.icns"
164
+ cp File.expand_path('../../../../icons/scaffold_app.icns', __FILE__), icon_file
165
+ puts "Created #{current_dir_name}/#{icon_file}"
166
+
167
+ mkdir_p 'package/linux'
168
+ icon_file = "package/linux/#{human_name(app_name)}.png"
169
+ cp File.expand_path('../../../../icons/scaffold_app.png', __FILE__), icon_file
170
+ puts "Created #{current_dir_name}/#{icon_file}"
171
+
172
+ mkdir_p "app/#{file_name(app_name)}"
173
+ write "app/#{file_name(app_name)}/launch.rb", app_launch_file(app_name)
174
+ mkdir_p 'bin'
175
+ write "bin/#{file_name(app_name)}", app_bin_command_file(app_name)
176
+ FileUtils.chmod 0755, "bin/#{file_name(app_name)}"
177
+ if OS.windows?
178
+ system "bundle"
179
+ system "rspec --init"
180
+ else
181
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
182
+ end
183
+ write 'spec/spec_helper.rb', spec_helper_file
184
+ if OS.windows?
185
+ system "glimmer package[image]"
186
+ system "\"packages/bundles/#{human_name(app_name)}/#{human_name(app_name)}.exe\""
187
+ else
188
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n glimmer package\n'"
189
+ if OS.mac?
190
+ system "open packages/bundles/#{human_name(app_name).gsub(' ', '\ ')}.app"
191
+ else
192
+ system "glimmer run"
193
+ end
194
+ end
195
+ end
196
+
197
+ def custom_shell(custom_shell_name, namespace, shell_type = nil, shell_options = {})
198
+ namespace ||= current_dir_name
199
+ root_dir = File.exists?('app') ? 'app' : 'lib'
200
+ parent_dir = "#{root_dir}/views/#{file_name(namespace)}"
201
+ return puts("The file '#{parent_dir}/#{file_name(custom_shell_name)}.rb' already exists. Please either remove or pick a different name.") if File.exist?("#{parent_dir}/#{file_name(custom_shell_name)}.rb")
202
+ mkdir_p parent_dir unless File.exists?(parent_dir)
203
+ write "#{parent_dir}/#{file_name(custom_shell_name)}.rb", custom_shell_file(custom_shell_name, namespace, shell_type, shell_options)
204
+ end
205
+
206
+ def custom_widget(custom_widget_name, namespace)
207
+ namespace ||= current_dir_name
208
+ root_dir = File.exists?('app') ? 'app' : 'lib'
209
+ parent_dir = "#{root_dir}/views/#{file_name(namespace)}"
210
+ return puts("The file '#{parent_dir}/#{file_name(custom_widget_name)}.rb' already exists. Please either remove or pick a different name.") if File.exist?("#{parent_dir}/#{file_name(custom_widget_name)}.rb")
211
+ mkdir_p parent_dir unless File.exists?(parent_dir)
212
+ write "#{parent_dir}/#{file_name(custom_widget_name)}.rb", custom_widget_file(custom_widget_name, namespace)
213
+ end
214
+
215
+ def custom_shell_gem(custom_shell_name, namespace)
216
+ gem_name = "glimmer-cs-#{compact_name(custom_shell_name)}"
217
+ gem_summary = "#{human_name(custom_shell_name)} - Glimmer Custom Shell"
218
+ begin
219
+ custom_shell_keyword = dsl_widget_name(custom_shell_name)
220
+ MAIN_OBJECT.method(custom_shell_keyword)
221
+ return puts("CustomShell keyword `#{custom_shell_keyword}` is unavailable (occupied by a built-in Ruby method)! Please pick a different name.")
222
+ rescue NameError
223
+ # No Op (keyword is not taken by a built in Ruby method)
224
+ end
225
+ if namespace
226
+ gem_name += "-#{compact_name(namespace)}"
227
+ gem_summary += " (#{human_name(namespace)})"
228
+ else
229
+ return puts('Namespace is required! Usage: glimmer scaffold:gem:customshell[name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
230
+ namespace = 'glimmer'
231
+ end
232
+ return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
233
+ system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
234
+ system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
235
+ return puts('Your Git user.name and/or github.user are missing! Please add in for Juwelier to help Glimmer with Scaffolding.') if `git config --get github.user`.strip.empty? && `git config --get user.name`.strip.empty?
236
+ cd gem_name
237
+ write '.gitignore', GITIGNORE
238
+ write '.ruby-version', RUBY_VERSION
239
+ write '.ruby-gemset', gem_name
240
+ write 'VERSION', '1.0.0'
241
+ write 'Gemfile', GEMFILE
242
+ write 'Rakefile', gem_rakefile(custom_shell_name, namespace, gem_name)
243
+ append "lib/#{gem_name}.rb", gem_main_file(custom_shell_name, namespace)
244
+ mkdir 'lib/views'
245
+ custom_shell(custom_shell_name, namespace, :gem)
246
+
247
+ mkdir_p "lib/#{file_name(namespace)}/#{file_name(custom_shell_name)}"
248
+ write "lib/#{file_name(namespace)}/#{file_name(custom_shell_name)}/launch.rb", gem_launch_file(gem_name, custom_shell_name, namespace)
249
+ mkdir_p 'bin'
250
+ write "bin/#{gem_name}", gem_bin_command_file(gem_name, custom_shell_name, namespace)
251
+ FileUtils.chmod 0755, "bin/#{gem_name}"
252
+ write "bin/#{file_name(custom_shell_name)}", gem_bin_command_file(gem_name, custom_shell_name, namespace)
253
+ FileUtils.chmod 0755, "bin/#{file_name(custom_shell_name)}"
254
+ if OS.windows?
255
+ system "bundle"
256
+ system "rspec --init"
257
+ else
258
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
259
+ end
260
+ write 'spec/spec_helper.rb', spec_helper_file
261
+
262
+ mkdir_p 'package/windows'
263
+ icon_file = "package/windows/#{human_name(custom_shell_name)}.ico"
264
+ cp File.expand_path('../../../../icons/scaffold_app.ico', __FILE__), icon_file
265
+ puts "Created #{current_dir_name}/#{icon_file}"
266
+
267
+ mkdir_p 'package/macosx'
268
+ icon_file = "package/macosx/#{human_name(custom_shell_name)}.icns"
269
+ cp File.expand_path('../../../../icons/scaffold_app.icns', __FILE__), icon_file
270
+ puts "Created #{current_dir_name}/#{icon_file}"
271
+
272
+ mkdir_p 'package/linux'
273
+ icon_file = "package/linux/#{human_name(custom_shell_name)}.png"
274
+ cp File.expand_path('../../../../icons/scaffold_app.png', __FILE__), icon_file
275
+ puts "Created #{current_dir_name}/#{icon_file}"
276
+
277
+ if OS.windows?
278
+ system "glimmer package[image]"
279
+ system "\"packages/bundles/#{human_name(custom_shell_name)}/#{human_name(custom_shell_name)}.exe\""
280
+ else
281
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n glimmer package\n'"
282
+ if OS.mac?
283
+ system "open packages/bundles/#{human_name(custom_shell_name).gsub(' ', '\ ')}.app" if OS.mac?
284
+ else
285
+ system "glimmer run"
286
+ end
287
+ end
288
+ puts "Finished creating #{gem_name} Ruby gem."
289
+ puts 'Edit Rakefile to configure gem details.'
290
+ puts 'Run `rake` to execute specs.'
291
+ puts 'Run `rake build` to build gem.'
292
+ puts 'Run `rake release` to release into rubygems.org once ready.'
293
+ end
294
+
295
+ def custom_widget_gem(custom_widget_name, namespace)
296
+ return puts('Namespace is required! Usage: glimmer scaffold:custom_widget_gem[custom_widget_name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
297
+ gem_name = "glimmer-cw-#{compact_name(custom_widget_name)}"
298
+ gem_summary = "#{human_name(custom_widget_name)} - Glimmer Custom Widget"
299
+ if namespace
300
+ gem_name += "-#{compact_name(namespace)}"
301
+ gem_summary += " (#{human_name(namespace)})"
302
+ else
303
+ namespace = 'glimmer'
304
+ end
305
+
306
+ return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
307
+ system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
308
+ system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
309
+ return puts('Your Git user.name and/or github.user are missing! Please add in for Juwelier to help Glimmer with Scaffolding.') if `git config --get github.user`.strip.empty? && `git config --get user.name`.strip.empty?
310
+ cd gem_name
311
+ write '.gitignore', GITIGNORE
312
+ write '.ruby-version', RUBY_VERSION
313
+ write '.ruby-gemset', gem_name
314
+ write 'VERSION', '1.0.0'
315
+ write 'Gemfile', GEMFILE
316
+ write 'Rakefile', gem_rakefile
317
+ append "lib/#{gem_name}.rb", gem_main_file(custom_widget_name, namespace)
318
+ mkdir 'lib/views'
319
+ custom_widget(custom_widget_name, namespace)
320
+ if OS.windows?
321
+ system "bundle"
322
+ system "rspec --init"
323
+ else
324
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
325
+ end
326
+ write 'spec/spec_helper.rb', spec_helper_file
327
+ puts "Finished creating #{gem_name} Ruby gem."
328
+ puts 'Edit Rakefile to configure gem details.'
329
+ puts 'Run `rake` to execute specs.'
330
+ puts 'Run `rake build` to build gem.'
331
+ puts 'Run `rake release` to release into rubygems.org once ready.'
332
+ end
333
+
334
+ private
335
+
336
+ def juwelier_exists?
337
+ OS.windows? ? system('where juwelier') : system('which juwelier')
338
+ end
339
+
340
+ def write(file, content)
341
+ File.write file, content
342
+ file_path = File.expand_path(file)
343
+ puts "Created #{current_dir_name}/#{file}"
344
+ end
345
+
346
+ def append(file, content)
347
+ File.open(file, 'a') do |f|
348
+ f.write(content)
349
+ end
350
+ end
351
+
352
+ def current_dir_name
353
+ File.basename(File.expand_path('.'))
354
+ end
355
+
356
+ def class_name(app_name)
357
+ app_name.underscore.camelcase(:upper)
358
+ end
359
+
360
+ def file_name(app_name)
361
+ app_name.underscore
362
+ end
363
+ alias dsl_widget_name file_name
364
+
365
+ def human_name(app_name)
366
+ app_name.underscore.titlecase
367
+ end
368
+
369
+ def compact_name(gem_name)
370
+ gem_name.underscore.camelcase.downcase
371
+ end
372
+
373
+ def gemfile(shell_type)
374
+ if shell_type == :desktopify
375
+ lines = GEMFILE.split("\n")
376
+ require_glimmer_dsl_swt_index = lines.index(lines.detect {|l| l.include?("gem 'glimmer-dsl-swt'") })
377
+ lines[(require_glimmer_dsl_swt_index + 1)..(require_glimmer_dsl_swt_index + 1)] = [
378
+ "",
379
+ "# Enable Chromium Browser Glimmer Custom Widget gem if needed (e.g. Linux needs it to support HTML5 Video), and use `browser(:chromium)` in GUI.",
380
+ "# gem 'glimmer-cw-browser-chromium', '>= 0'",
381
+ "",
382
+ ]
383
+ lines.join("\n")
384
+ else
385
+ GEMFILE
386
+ end
387
+ end
388
+
389
+ def app_main_file(app_name)
390
+ <<~MULTI_LINE_STRING
391
+ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
392
+
393
+ require 'bundler/setup'
394
+ Bundler.require(:default)
395
+ require 'views/#{file_name(app_name)}/app_view'
396
+
397
+ class #{class_name(app_name)}
398
+ include Glimmer
399
+
400
+ APP_ROOT = File.expand_path('../..', __FILE__)
401
+ VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
402
+ LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
403
+
404
+ def open
405
+ app_view.open
406
+ end
407
+ end
408
+ MULTI_LINE_STRING
409
+ end
410
+
411
+ def gem_main_file(custom_widget_name, namespace = nil)
412
+ custom_widget_file_path = "views"
413
+ custom_widget_file_path += "/#{file_name(namespace)}" if namespace
414
+ custom_widget_file_path += "/#{file_name(custom_widget_name)}"
415
+
416
+ <<~MULTI_LINE_STRING
417
+ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
418
+
419
+ require 'glimmer-dsl-swt'
420
+ require '#{custom_widget_file_path}'
421
+ MULTI_LINE_STRING
422
+ end
423
+
424
+ def app_launch_file(app_name)
425
+ <<~MULTI_LINE_STRING
426
+ require_relative '../#{file_name(app_name)}'
427
+
428
+ #{class_name(app_name)}.new.open
429
+ MULTI_LINE_STRING
430
+ end
431
+
432
+ def app_bin_command_file(app_name)
433
+ <<~MULTI_LINE_STRING
434
+ #!/usr/bin/env jruby
435
+
436
+ runner = File.expand_path("../../app/#{file_name(app_name)}/launch.rb", __FILE__)
437
+
438
+ # Detect if inside a JAR file or not
439
+ if runner.include?('uri:classloader')
440
+ require runner
441
+ else
442
+ require 'glimmer/launcher'
443
+
444
+ launcher = Glimmer::Launcher.new([runner] + ARGV)
445
+ launcher.launch
446
+ end
447
+ MULTI_LINE_STRING
448
+ end
449
+
450
+ def gem_launch_file(gem_name, custom_shell_name, namespace)
451
+ # TODO change this so that it does not mix Glimmer unto the main object
452
+ <<~MULTI_LINE_STRING
453
+ require_relative '../../#{gem_name}'
454
+
455
+ module #{class_name(namespace)}
456
+ class #{class_name(custom_shell_name)}
457
+ class App
458
+ include Glimmer
459
+
460
+ def open
461
+ #{dsl_widget_name(custom_shell_name)}.open
462
+ end
463
+ end
464
+ end
465
+ end
466
+
467
+ #{class_name(namespace)}::#{class_name(custom_shell_name)}::App.new.open
468
+ MULTI_LINE_STRING
469
+ end
470
+
471
+ def gem_bin_command_file(gem_name, custom_shell_name, namespace)
472
+ <<~MULTI_LINE_STRING
473
+ #!/usr/bin/env jruby
474
+
475
+ runner = File.expand_path("../../lib/#{file_name(namespace)}/#{file_name(custom_shell_name)}/launch.rb", __FILE__)
476
+
477
+ # Detect if inside a JAR file or not
478
+ if runner.include?('uri:classloader')
479
+ require runner
480
+ else
481
+ require 'glimmer/launcher'
482
+
483
+ launcher = Glimmer::Launcher.new([runner] + ARGV)
484
+ launcher.launch
485
+ end
486
+ MULTI_LINE_STRING
487
+ end
488
+
489
+ def gem_rakefile(custom_shell_name = nil, namespace = nil, gem_name = nil)
490
+ rakefile_content = File.read('Rakefile')
491
+ lines = rakefile_content.split("\n")
492
+ require_rake_line_index = lines.index(lines.detect {|l| l.include?("require 'rake'") })
493
+ lines.insert(require_rake_line_index, "require 'glimmer/launcher'")
494
+ gem_files_line_index = lines.index(lines.detect {|l| l.include?('# dependencies defined in Gemfile') })
495
+ if custom_shell_name
496
+ lines.insert(gem_files_line_index, " gem.files = Dir['VERSION', 'LICENSE.txt', 'app/**/*', 'bin/**/*', 'config/**/*', 'db/**/*', 'docs/**/*', 'fonts/**/*', 'icons/**/*', 'images/**/*', 'lib/**/*', 'package/**/*', 'script/**/*', 'sounds/**/*', 'vendor/**/*', 'videos/**/*']")
497
+ # the second executable is needed for warbler as it matches the gem name, which is the default expected file (alternatively in the future, we could do away with it and configure warbler to use the other file)
498
+ lines.insert(gem_files_line_index+1, " gem.executables = ['#{gem_name}', '#{file_name(custom_shell_name)}']")
499
+ lines.insert(gem_files_line_index+2, " gem.require_paths = ['vendor', 'lib', 'app']")
500
+ else
501
+ lines.insert(gem_files_line_index, " gem.files = Dir['VERSION', 'LICENSE.txt', 'lib/**/*']")
502
+ end
503
+ spec_pattern_line_index = lines.index(lines.detect {|l| l.include?('spec.pattern =') })
504
+ lines.insert(spec_pattern_line_index+1, " spec.ruby_opts = [Glimmer::Launcher.jruby_os_specific_options]")
505
+ lines << "\nrequire 'glimmer/rake_task'\n"
506
+ file_content = lines.join("\n")
507
+ if custom_shell_name
508
+ file_content << <<~MULTI_LINE_STRING
509
+ Glimmer::RakeTask::Package.javapackager_extra_args =
510
+ " -name '#{human_name(custom_shell_name)}'" +
511
+ " -title '#{human_name(custom_shell_name)}'" +
512
+ " -Bmac.CFBundleName='#{human_name(custom_shell_name)}'" +
513
+ " -Bmac.CFBundleIdentifier='org.#{namespace ? compact_name(namespace) : compact_name(custom_shell_name)}.application.#{compact_name(custom_shell_name).camelcase(:upper)}'"
514
+ # " -BlicenseType=" +
515
+ # " -Bmac.category=" +
516
+ # " -Bmac.signing-key-developer-id-app="
517
+ MULTI_LINE_STRING
518
+ end
519
+ file_content
520
+ end
521
+
522
+ def spec_helper_file
523
+ content = File.read('spec/spec_helper.rb')
524
+ lines = content.split("\n")
525
+ require_line_index = lines.index(lines.detect {|l| l.include?('RSpec.configure do') })
526
+ lines[require_line_index...require_line_index] = [
527
+ "require 'bundler/setup'",
528
+ 'Bundler.require(:default, :development)',
529
+ ]
530
+ configure_block_line_index = lines.index(lines.detect {|l| l.include?('RSpec.configure do') }) + 1
531
+ lines[configure_block_line_index...configure_block_line_index] = [
532
+ ' # The following ensures rspec tests that instantiate and set Glimmer DSL widgets in @target get cleaned after',
533
+ ' config.after do',
534
+ ' @target.dispose if @target && @target.respond_to?(:dispose)',
535
+ ' Glimmer::DSL::Engine.reset',
536
+ ' end',
537
+ ]
538
+
539
+ lines << "\nrequire 'glimmer/rake_task'\n"
540
+ lines.join("\n")
541
+ end
542
+
543
+ def custom_shell_file(custom_shell_name, namespace, shell_type, shell_options = {})
544
+ namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
545
+
546
+ custom_shell_file_content = <<-MULTI_LINE_STRING
547
+ #{namespace_type} #{class_name(namespace)}
548
+ class #{class_name(custom_shell_name)}
549
+ include Glimmer::UI::CustomShell
550
+
551
+ MULTI_LINE_STRING
552
+
553
+ if shell_type == :gem
554
+ custom_shell_file_content += <<-MULTI_LINE_STRING
555
+ APP_ROOT = File.expand_path('../../../..', __FILE__)
556
+ VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
557
+ LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
558
+
559
+ MULTI_LINE_STRING
560
+ end
561
+
562
+ custom_shell_file_content += <<-MULTI_LINE_STRING
563
+ ## Add options like the following to configure CustomShell by outside consumers
564
+ #
565
+ # options :title, :background_color
566
+ # option :width, default: 320
567
+ # option :height, default: 240
568
+ #{'# ' if shell_type == :desktopify}option :greeting, default: 'Hello, World!'
569
+
570
+ ## Use before_body block to pre-initialize variables to use in body
571
+ #
572
+ #
573
+ MULTI_LINE_STRING
574
+
575
+ if %i[gem app desktopify].include?(shell_type)
576
+ custom_shell_file_content += <<-MULTI_LINE_STRING
577
+ before_body {
578
+ Display.app_name = '#{shell_type == :gem ? human_name(custom_shell_name) : human_name(namespace)}'
579
+ Display.app_version = VERSION
580
+ @display = display {
581
+ on_about {
582
+ display_about_dialog
583
+ }
584
+ on_preferences {
585
+ #{shell_type == :desktopify ? 'display_about_dialog' : 'display_preferences_dialog'}
586
+ }
587
+ }
588
+ }
589
+ MULTI_LINE_STRING
590
+ else
591
+ custom_shell_file_content += <<-MULTI_LINE_STRING
592
+ # before_body {
593
+ #
594
+ # }
595
+ MULTI_LINE_STRING
596
+ end
597
+
598
+ custom_shell_file_content += <<-MULTI_LINE_STRING
599
+
600
+ ## Use after_body block to setup observers for widgets in body
601
+ #
602
+ # after_body {
603
+ #
604
+ # }
605
+
606
+ ## Add widget content inside custom shell body
607
+ ## Top-most widget must be a shell or another custom shell
608
+ #
609
+ body {
610
+ shell {
611
+ # Replace example content below with custom shell content
612
+ minimum_size #{shell_type == :desktopify ? '1024, 768' : '320, 240'}
613
+ image File.join(APP_ROOT, 'package', 'windows', "#{human_name(shell_type == :gem ? custom_shell_name : current_dir_name)}.ico") if OS.windows?
614
+ text "#{human_name(namespace)} - #{human_name(custom_shell_name)}"
615
+
616
+ MULTI_LINE_STRING
617
+
618
+ if shell_type == :desktopify
619
+ custom_shell_file_content += <<-MULTI_LINE_STRING
620
+ browser {
621
+ url "#{shell_options[:website]}"
622
+ }
623
+ MULTI_LINE_STRING
624
+ else
625
+ custom_shell_file_content += <<-MULTI_LINE_STRING
626
+ grid_layout
627
+ label(:center) {
628
+ text bind(self, :greeting)
629
+ font height: 40
630
+ layout_data :fill, :center, true, true
631
+ }
632
+ MULTI_LINE_STRING
633
+ end
634
+
635
+ if %i[gem app desktopify].include?(shell_type)
636
+ custom_shell_file_content += <<-MULTI_LINE_STRING
637
+
638
+ menu_bar {
639
+ menu {
640
+ text '&File'
641
+ menu_item {
642
+ text '&About...'
643
+ on_widget_selected {
644
+ display_about_dialog
645
+ }
646
+ }
647
+ menu_item {
648
+ text '&Preferences...'
649
+ on_widget_selected {
650
+ #{shell_type == :desktopify ? 'display_about_dialog' : 'display_preferences_dialog'}
651
+ }
652
+ }
653
+ }
654
+ }
655
+ MULTI_LINE_STRING
656
+ end
657
+
658
+ custom_shell_file_content += <<-MULTI_LINE_STRING
659
+ }
660
+ }
661
+ MULTI_LINE_STRING
662
+
663
+ if %i[gem app desktopify].include?(shell_type)
664
+ custom_shell_file_content += <<-MULTI_LINE_STRING
665
+
666
+ def display_about_dialog
667
+ message_box(body_root) {
668
+ text 'About'
669
+ message "#{human_name(namespace)}#{" - #{human_name(custom_shell_name)}" if shell_type == :gem} \#{VERSION}\\n\\n\#{LICENSE}"
670
+ }.open
671
+ end
672
+
673
+ MULTI_LINE_STRING
674
+ end
675
+
676
+ if %i[gem app].include?(shell_type)
677
+ custom_shell_file_content += <<-MULTI_LINE_STRING
678
+ def display_preferences_dialog
679
+ dialog(swt_widget) {
680
+ text 'Preferences'
681
+ grid_layout {
682
+ margin_height 5
683
+ margin_width 5
684
+ }
685
+ group {
686
+ row_layout {
687
+ type :vertical
688
+ spacing 10
689
+ }
690
+ text 'Greeting'
691
+ font style: :bold
692
+ [
693
+ 'Hello, World!',
694
+ 'Howdy, Partner!'
695
+ ].each do |greeting_text|
696
+ button(:radio) {
697
+ text greeting_text
698
+ selection bind(self, :greeting) { |g| g == greeting_text }
699
+ layout_data {
700
+ width 160
701
+ }
702
+ on_widget_selected { |event|
703
+ self.greeting = event.widget.getText
704
+ }
705
+ }
706
+ end
707
+ }
708
+ }.open
709
+ end
710
+ MULTI_LINE_STRING
711
+ end
712
+
713
+ custom_shell_file_content += <<-MULTI_LINE_STRING
714
+ end
715
+ end
716
+ MULTI_LINE_STRING
717
+ end
718
+
719
+ def custom_widget_file(custom_widget_name, namespace)
720
+ namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
721
+
722
+ <<~MULTI_LINE_STRING
723
+ #{namespace_type} #{class_name(namespace)}
724
+ class #{class_name(custom_widget_name)}
725
+ include Glimmer::UI::CustomWidget
726
+
727
+ ## Add options like the following to configure CustomWidget by outside consumers
728
+ #
729
+ # options :custom_text, :background_color
730
+ # option :foreground_color, default: :red
731
+
732
+ ## Use before_body block to pre-initialize variables to use in body
733
+ #
734
+ #
735
+ # before_body {
736
+ #
737
+ # }
738
+
739
+ ## Use after_body block to setup observers for widgets in body
740
+ #
741
+ # after_body {
742
+ #
743
+ # }
744
+
745
+ ## Add widget content under custom widget body
746
+ ##
747
+ ## If you want to add a shell as the top-most widget,
748
+ ## consider creating a custom shell instead
749
+ ## (Glimmer::UI::CustomShell offers shell convenience methods, like show and hide)
750
+ #
751
+ body {
752
+ # Replace example content below with custom widget content
753
+ label {
754
+ background :red
755
+ }
756
+ }
757
+
758
+ end
759
+ end
760
+ MULTI_LINE_STRING
761
+ end
762
+ end
763
+ end
764
+ end
765
+ end