glimmer-dsl-swt 0.6.8 → 4.17.2.0

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