glimmer-dsl-libui 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,839 @@
1
+ # Copyright (c) 2021-2023 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
+ # Warbler
98
+ Jars.lock
99
+
100
+ # Gladiator (Glimmer Editor)
101
+ .gladiator
102
+ .gladiator-scratchpad
103
+
104
+ # Glimmer
105
+ /dist/
106
+ /packages/
107
+ /vendor/jars/
108
+ MULTI_LINE_STRING
109
+
110
+ GEMFILE_PREFIX = <<~MULTI_LINE_STRING
111
+ # frozen_string_literal: true
112
+
113
+ source 'https://rubygems.org'
114
+
115
+ git_source(:github) {|repo_name| "https://github.com/\#{repo_name}" }
116
+ MULTI_LINE_STRING
117
+ GEMFILE_APP_MIDFIX = <<~MULTI_LINE_STRING
118
+
119
+ gem 'glimmer-dsl-swt', '~> #{VERSION}'
120
+ MULTI_LINE_STRING
121
+ GEMFILE_GEM_MIDFIX = <<~MULTI_LINE_STRING
122
+
123
+ gem 'glimmer-dsl-swt', '~> #{VERSION.split('.')[0...2].join('.')}'
124
+ MULTI_LINE_STRING
125
+ GEMFILE_SUFFIX = <<~MULTI_LINE_STRING
126
+
127
+ group :development do
128
+ gem 'jar-dependencies', '0.4.1'
129
+ gem 'rspec', '~> 3.5.0'
130
+ gem 'juwelier', '2.4.9'
131
+ gem 'warbler', '2.0.5'
132
+ gem 'simplecov', '>= 0'
133
+ end
134
+ MULTI_LINE_STRING
135
+ APP_GEMFILE = GEMFILE_PREFIX + GEMFILE_APP_MIDFIX + GEMFILE_SUFFIX
136
+ GEM_GEMFILE = GEMFILE_PREFIX + GEMFILE_GEM_MIDFIX + GEMFILE_SUFFIX
137
+
138
+ def app(app_name)
139
+ common_app(app_name)
140
+ end
141
+
142
+ def common_app(app_name, shell_type = :app, shell_options = {})
143
+ gem_name = file_name(app_name)
144
+ gem_summary = human_name(app_name)
145
+ return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
146
+ system "jruby -S gem install bundler --no-document" if OS.windows? # resolves freezing issue with warbler and bundler 2.2.29 included in JRuby
147
+ system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exist?
148
+ system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
149
+ 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?
150
+ cd gem_name
151
+ rm_rf 'lib'
152
+ write '.gitignore', GITIGNORE
153
+ write '.ruby-version', RUBY_VERSION
154
+ write '.ruby-gemset', app_name
155
+ write 'VERSION', '1.0.0'
156
+ write 'LICENSE.txt', "Copyright (c) #{Time.now.year} #{app_name}"
157
+ write 'Gemfile', gemfile(shell_type)
158
+ write 'Rakefile', gem_rakefile(app_name, nil, gem_name)
159
+ mkdir 'app'
160
+ write "app/#{file_name(app_name)}.rb", app_main_file(app_name)
161
+ mkdir_p "app/#{file_name(app_name)}/model"
162
+ mkdir_p "app/#{file_name(app_name)}/view"
163
+ custom_shell('AppView', current_dir_name, shell_type)
164
+
165
+ mkdir_p 'icons/windows'
166
+ icon_file = "icons/windows/#{human_name(app_name)}.ico"
167
+ cp File.expand_path('../../../../icons/scaffold_app.ico', __FILE__), icon_file
168
+ puts "Created #{current_dir_name}/#{icon_file}"
169
+
170
+ mkdir_p 'icons/macosx'
171
+ icon_file = "icons/macosx/#{human_name(app_name)}.icns"
172
+ cp File.expand_path('../../../../icons/scaffold_app.icns', __FILE__), icon_file
173
+ puts "Created #{current_dir_name}/#{icon_file}"
174
+
175
+ mkdir_p 'icons/linux'
176
+ icon_file = "icons/linux/#{human_name(app_name)}.png"
177
+ cp File.expand_path('../../../../icons/scaffold_app.png', __FILE__), icon_file
178
+ puts "Created #{current_dir_name}/#{icon_file}"
179
+
180
+ mkdir_p "app/#{file_name(app_name)}"
181
+ write "app/#{file_name(app_name)}/launch.rb", app_launch_file(app_name)
182
+ mkdir_p 'bin'
183
+ write "bin/#{file_name(app_name)}", app_bin_command_file(app_name)
184
+ FileUtils.chmod 0755, "bin/#{file_name(app_name)}"
185
+ if OS.windows?
186
+ system "bundle"
187
+ system "rspec --init"
188
+ else
189
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
190
+ end
191
+ write 'spec/spec_helper.rb', spec_helper_file
192
+ if OS.mac?
193
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n JRUBY_OPTS=\"$JRUBY_OPTS -J-XstartOnFirstThread\" glimmer run\n'"
194
+ elsif OS.linux?
195
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n glimmer run\n'"
196
+ else
197
+ system "glimmer run"
198
+ end
199
+ end
200
+
201
+ def custom_shell(custom_shell_name, namespace, shell_type = nil, shell_options = {})
202
+ namespace ||= current_dir_name
203
+ root_dir = File.exist?('app') ? 'app' : 'lib'
204
+ parent_dir = "#{root_dir}/#{file_name(namespace)}/view"
205
+ 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")
206
+ mkdir_p parent_dir unless File.exist?(parent_dir)
207
+ write "#{parent_dir}/#{file_name(custom_shell_name)}.rb", custom_shell_file(custom_shell_name, namespace, shell_type, shell_options)
208
+ end
209
+
210
+ def custom_widget(custom_widget_name, namespace)
211
+ namespace ||= current_dir_name
212
+ root_dir = File.exist?('app') ? 'app' : 'lib'
213
+ parent_dir = "#{root_dir}/#{file_name(namespace)}/view"
214
+ 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")
215
+ mkdir_p parent_dir unless File.exist?(parent_dir)
216
+ write "#{parent_dir}/#{file_name(custom_widget_name)}.rb", custom_widget_file(custom_widget_name, namespace)
217
+ end
218
+
219
+ def custom_shape(custom_shape_name, namespace)
220
+ namespace ||= current_dir_name
221
+ root_dir = File.exist?('app') ? 'app' : 'lib'
222
+ parent_dir = "#{root_dir}/#{file_name(namespace)}/view"
223
+ return puts("The file '#{parent_dir}/#{file_name(custom_shape_name)}.rb' already exists. Please either remove or pick a different name.") if File.exist?("#{parent_dir}/#{file_name(custom_shape_name)}.rb")
224
+ mkdir_p parent_dir unless File.exist?(parent_dir)
225
+ write "#{parent_dir}/#{file_name(custom_shape_name)}.rb", custom_shape_file(custom_shape_name, namespace)
226
+ end
227
+
228
+ def custom_shell_gem(custom_shell_name, namespace)
229
+ gem_name = "glimmer-cs-#{compact_name(custom_shell_name)}"
230
+ gem_summary = "#{human_name(custom_shell_name)} - Glimmer Custom Shell"
231
+ begin
232
+ custom_shell_keyword = dsl_widget_name(custom_shell_name)
233
+ MAIN_OBJECT.method(custom_shell_keyword)
234
+ return puts("CustomShell keyword `#{custom_shell_keyword}` is unavailable (occupied by a built-in Ruby method)! Please pick a different name.")
235
+ rescue NameError
236
+ # No Op (keyword is not taken by a built in Ruby method)
237
+ end
238
+ if namespace
239
+ gem_name += "-#{compact_name(namespace)}"
240
+ gem_summary += " (#{human_name(namespace)})"
241
+ else
242
+ return puts('Namespace is required! Usage: glimmer scaffold:gem:customshell[name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
243
+ namespace = 'glimmer'
244
+ end
245
+ return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
246
+ system "jruby -S gem install bundler --no-document" if OS.windows? # resolves freezing issue with warbler and bundler 2.2.29 included in JRuby
247
+ system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exist?
248
+ system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
249
+ 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?
250
+ cd gem_name
251
+ write '.gitignore', GITIGNORE
252
+ write '.ruby-version', RUBY_VERSION
253
+ write '.ruby-gemset', gem_name
254
+ write 'VERSION', '1.0.0'
255
+ write 'Gemfile', GEM_GEMFILE
256
+ write 'Rakefile', gem_rakefile(custom_shell_name, namespace, gem_name)
257
+ append "lib/#{gem_name}.rb", gem_main_file(custom_shell_name, namespace)
258
+ custom_shell(custom_shell_name, namespace, :gem)
259
+
260
+ mkdir_p "lib/#{gem_name}"
261
+ write "lib/#{gem_name}/launch.rb", gem_launch_file(gem_name, custom_shell_name, namespace)
262
+ mkdir_p 'bin'
263
+ write "bin/#{file_name(custom_shell_name)}", app_bin_command_file(gem_name, custom_shell_name, namespace)
264
+ FileUtils.chmod 0755, "bin/#{file_name(custom_shell_name)}"
265
+ if OS.windows?
266
+ system "bundle"
267
+ system "rspec --init"
268
+ else
269
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
270
+ end
271
+ write 'spec/spec_helper.rb', spec_helper_file
272
+
273
+ mkdir_p 'icons/windows'
274
+ icon_file = "icons/windows/#{human_name(gem_name)}.ico"
275
+ cp File.expand_path('../../../../icons/scaffold_app.ico', __FILE__), icon_file
276
+ puts "Created #{current_dir_name}/#{icon_file}"
277
+
278
+ mkdir_p 'icons/macosx'
279
+ icon_file = "icons/macosx/#{human_name(gem_name)}.icns"
280
+ cp File.expand_path('../../../../icons/scaffold_app.icns', __FILE__), icon_file
281
+ puts "Created #{current_dir_name}/#{icon_file}"
282
+
283
+ mkdir_p 'icons/linux'
284
+ icon_file = "icons/linux/#{human_name(gem_name)}.png"
285
+ cp File.expand_path('../../../../icons/scaffold_app.png', __FILE__), icon_file
286
+ puts "Created #{current_dir_name}/#{icon_file}"
287
+
288
+ if OS.mac?
289
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n JRUBY_OPTS=\"$JRUBY_OPTS -J-XstartOnFirstThread\" glimmer run\n'"
290
+ elsif OS.linux?
291
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n glimmer run\n'"
292
+ else
293
+ system "glimmer run"
294
+ end
295
+ puts "Finished creating #{gem_name} Ruby gem."
296
+ puts 'Edit Rakefile to configure gem details.'
297
+ puts 'Run `rake` to execute specs.'
298
+ puts 'Run `rake build` to build gem.'
299
+ puts 'Run `rake release` to release into rubygems.org once ready.'
300
+ end
301
+
302
+ def custom_widget_gem(custom_widget_name, namespace)
303
+ gem_name = "glimmer-cw-#{compact_name(custom_widget_name)}"
304
+ gem_summary = "#{human_name(custom_widget_name)} - Glimmer Custom Widget"
305
+ if namespace
306
+ gem_name += "-#{compact_name(namespace)}"
307
+ gem_summary += " (#{human_name(namespace)})"
308
+ else
309
+ 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'
310
+ namespace = 'glimmer'
311
+ end
312
+
313
+ return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
314
+ system "jruby -S gem install bundler --no-document" if OS.windows? # resolves freezing issue with warbler and bundler 2.2.29 included in JRuby
315
+ system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exist?
316
+ system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
317
+ 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?
318
+ cd gem_name
319
+ write '.gitignore', GITIGNORE
320
+ write '.ruby-version', RUBY_VERSION
321
+ write '.ruby-gemset', gem_name
322
+ write 'VERSION', '1.0.0'
323
+ write 'Gemfile', GEM_GEMFILE
324
+ write 'Rakefile', gem_rakefile
325
+ append "lib/#{gem_name}.rb", gem_main_file(custom_widget_name, namespace)
326
+ custom_widget(custom_widget_name, namespace)
327
+ if OS.windows?
328
+ system "bundle"
329
+ system "rspec --init"
330
+ else
331
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
332
+ end
333
+ write 'spec/spec_helper.rb', spec_helper_file
334
+ puts "Finished creating #{gem_name} Ruby gem."
335
+ puts 'Edit Rakefile to configure gem details.'
336
+ puts 'Run `rake` to execute specs.'
337
+ puts 'Run `rake build` to build gem.'
338
+ puts 'Run `rake release` to release into rubygems.org once ready.'
339
+ end
340
+
341
+ def custom_shape_gem(custom_shape_name, namespace)
342
+ gem_name = "glimmer-cp-#{compact_name(custom_shape_name)}"
343
+ gem_summary = "#{human_name(custom_shape_name)} - Glimmer Custom Shape"
344
+ if namespace
345
+ gem_name += "-#{compact_name(namespace)}"
346
+ gem_summary += " (#{human_name(namespace)})"
347
+ else
348
+ return puts('Namespace is required! Usage: glimmer scaffold:custom_shape_gem[custom_shape_name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
349
+ namespace = 'glimmer'
350
+ end
351
+
352
+ return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
353
+ system "jruby -S gem install bundler --no-document" if OS.windows? # resolves freezing issue with warbler and bundler 2.2.29 included in JRuby
354
+ system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exist?
355
+ system "jruby -S juwelier --markdown --rspec --summary '#{gem_summary}' --description '#{gem_summary}' #{gem_name}"
356
+ 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?
357
+ cd gem_name
358
+ write '.gitignore', GITIGNORE
359
+ write '.ruby-version', RUBY_VERSION
360
+ write '.ruby-gemset', gem_name
361
+ write 'VERSION', '1.0.0'
362
+ write 'Gemfile', GEM_GEMFILE
363
+ write 'Rakefile', gem_rakefile
364
+ append "lib/#{gem_name}.rb", gem_main_file(custom_shape_name, namespace)
365
+ custom_shape(custom_shape_name, namespace)
366
+ if OS.windows?
367
+ system "bundle"
368
+ system "rspec --init"
369
+ else
370
+ system "bash -c '#{RVM_FUNCTION}\n cd .\n bundle\n rspec --init\n'"
371
+ end
372
+ write 'spec/spec_helper.rb', spec_helper_file
373
+ puts "Finished creating #{gem_name} Ruby gem."
374
+ puts 'Edit Rakefile to configure gem details.'
375
+ puts 'Run `rake` to execute specs.'
376
+ puts 'Run `rake build` to build gem.'
377
+ puts 'Run `rake release` to release into rubygems.org once ready.'
378
+ end
379
+
380
+ private
381
+
382
+ def juwelier_exist?
383
+ OS.windows? ? system('where juwelier') : system('which juwelier')
384
+ end
385
+
386
+ def write(file, content)
387
+ File.write file, content
388
+ file_path = File.expand_path(file)
389
+ puts "Created #{current_dir_name}/#{file}"
390
+ end
391
+
392
+ def append(file, content)
393
+ File.open(file, 'a') do |f|
394
+ f.write(content)
395
+ end
396
+ end
397
+
398
+ def current_dir_name
399
+ File.basename(File.expand_path('.'))
400
+ end
401
+
402
+ def class_name(app_name)
403
+ app_name.underscore.camelcase(:upper)
404
+ end
405
+
406
+ def file_name(app_name)
407
+ app_name.underscore
408
+ end
409
+ alias dsl_widget_name file_name
410
+
411
+ def human_name(app_name)
412
+ app_name.underscore.titlecase
413
+ end
414
+
415
+ def compact_name(gem_name)
416
+ gem_name.underscore.camelcase.downcase
417
+ end
418
+
419
+ def gemfile(shell_type)
420
+ APP_GEMFILE
421
+ end
422
+
423
+ def app_main_file(app_name)
424
+ <<~MULTI_LINE_STRING
425
+ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
426
+
427
+ begin
428
+ require 'bundler/setup'
429
+ Bundler.require(:default)
430
+ rescue
431
+ # this runs when packaged as a gem (no bundler)
432
+ require 'glimmer-dsl-swt'
433
+ # add more gems if needed
434
+ end
435
+
436
+ class #{class_name(app_name)}
437
+ include Glimmer
438
+
439
+ APP_ROOT = File.expand_path('../..', __FILE__)
440
+ VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
441
+ LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
442
+ Display.app_name = '#{human_name(app_name)}'
443
+ Display.app_version = VERSION
444
+ end
445
+
446
+ require '#{file_name(app_name)}/view/app_view'
447
+ MULTI_LINE_STRING
448
+ end
449
+
450
+ def gem_main_file(custom_widget_name, namespace = nil)
451
+ custom_widget_file_path = ''
452
+ custom_widget_file_path += "#{file_name(namespace)}/" if namespace
453
+ custom_widget_file_path += "view"
454
+ custom_widget_file_path += "/#{file_name(custom_widget_name)}"
455
+
456
+ <<~MULTI_LINE_STRING
457
+ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
458
+
459
+ require 'glimmer-dsl-swt'
460
+ require '#{custom_widget_file_path}'
461
+ MULTI_LINE_STRING
462
+ end
463
+
464
+ def app_launch_file(app_name)
465
+ <<~MULTI_LINE_STRING
466
+ require_relative '../#{file_name(app_name)}'
467
+
468
+ #{class_name(app_name)}::View::AppView.launch
469
+ MULTI_LINE_STRING
470
+ end
471
+
472
+ def app_bin_command_file(app_name_or_gem_name, custom_shell_name=nil, namespace=nil)
473
+ if custom_shell_name.nil?
474
+ runner = "File.expand_path('../../app/#{file_name(app_name_or_gem_name)}/launch.rb', __FILE__)"
475
+ else
476
+ runner = "File.expand_path('../../lib/#{app_name_or_gem_name}/launch.rb', __FILE__)"
477
+ end
478
+ <<~MULTI_LINE_STRING
479
+ #!/usr/bin/env jruby
480
+
481
+ runner = #{runner}
482
+
483
+ # Detect if inside a JAR file or not
484
+ if runner.include?('uri:classloader')
485
+ require runner
486
+ else
487
+ require 'glimmer/launcher'
488
+
489
+ launcher = Glimmer::Launcher.new([runner] + ARGV)
490
+ launcher.launch
491
+ end
492
+ MULTI_LINE_STRING
493
+ end
494
+
495
+ def gem_launch_file(gem_name, custom_shell_name, namespace)
496
+ # TODO change this so that it does not mix Glimmer unto the main object
497
+ <<~MULTI_LINE_STRING
498
+ require_relative '../#{gem_name}'
499
+
500
+ #{class_name(namespace)}::View::#{class_name(custom_shell_name)}.launch
501
+ MULTI_LINE_STRING
502
+ end
503
+
504
+ def gem_rakefile(custom_shell_name = nil, namespace = nil, gem_name = nil)
505
+ rakefile_content = File.read('Rakefile')
506
+ lines = rakefile_content.split("\n")
507
+ require_rake_line_index = lines.index(lines.detect {|l| l.include?("require 'rake'") })
508
+ lines.insert(require_rake_line_index, "require 'glimmer/launcher'")
509
+ gem_files_line_index = lines.index(lines.detect {|l| l.include?('# dependencies defined in Gemfile') })
510
+ if custom_shell_name
511
+ lines.insert(gem_files_line_index, " gem.files = Dir['VERSION', 'LICENSE.txt', 'app/**/*', 'bin/**/*', 'config/**/*', 'db/**/*', 'docs/**/*', 'fonts/**/*', 'icons/**/*', 'images/**/*', 'lib/**/*', 'script/**/*', 'sounds/**/*', 'vendor/**/*', 'videos/**/*']")
512
+ # 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)
513
+ lines.insert(gem_files_line_index+1, " gem.require_paths = ['vendor', 'lib', 'app']")
514
+ lines.insert(gem_files_line_index+2, " gem.executables = ['#{file_name(custom_shell_name)}']") if custom_shell_name
515
+ else
516
+ lines.insert(gem_files_line_index, " gem.files = Dir['VERSION', 'LICENSE.txt', 'lib/**/*']")
517
+ end
518
+ lines << "\nrequire 'glimmer/rake_task'\n"
519
+ file_content = lines.join("\n")
520
+ if custom_shell_name
521
+ file_content << <<~MULTI_LINE_STRING
522
+ Glimmer::RakeTask::Package.jpackage_extra_args =
523
+ " --name '#{human_name(custom_shell_name)}'" +
524
+ " --description '#{human_name(custom_shell_name)}'"
525
+ # You can add more options from https://docs.oracle.com/en/java/javase/16/jpackage/packaging-tool-user-guide.pdf
526
+ MULTI_LINE_STRING
527
+ end
528
+ file_content
529
+ end
530
+
531
+ def spec_helper_file
532
+ content = File.read('spec/spec_helper.rb')
533
+ lines = content.split("\n")
534
+ require_line_index = lines.index(lines.detect {|l| l.include?('RSpec.configure do') })
535
+ lines[require_line_index...require_line_index] = [
536
+ "require 'bundler/setup'",
537
+ 'Bundler.require(:default, :development)',
538
+ ]
539
+ configure_block_line_index = lines.index(lines.detect {|l| l.include?('RSpec.configure do') }) + 1
540
+ lines[configure_block_line_index...configure_block_line_index] = [
541
+ ' # The following ensures rspec tests that instantiate and set Glimmer DSL widgets in @target get cleaned after',
542
+ ' config.after do',
543
+ ' @target.dispose if @target && @target.respond_to?(:dispose)',
544
+ ' Glimmer::DSL::Engine.reset',
545
+ ' end',
546
+ ]
547
+
548
+ lines << "\nrequire 'glimmer/rake_task'\n"
549
+ lines.join("\n")
550
+ end
551
+
552
+ def custom_shell_file(custom_shell_name, namespace, shell_type, shell_options = {})
553
+ namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
554
+
555
+ custom_shell_file_content = <<-MULTI_LINE_STRING
556
+ #{namespace_type} #{class_name(namespace)}
557
+ module View
558
+ class #{class_name(custom_shell_name)}
559
+ include Glimmer::UI::CustomShell
560
+
561
+ MULTI_LINE_STRING
562
+
563
+ if shell_type == :gem
564
+ custom_shell_file_content += <<-MULTI_LINE_STRING
565
+ APP_ROOT = File.expand_path('../../../..', __FILE__)
566
+ VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
567
+ LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
568
+ Display.app_name = '#{human_name(custom_shell_name)}'
569
+ Display.app_version = VERSION
570
+
571
+ MULTI_LINE_STRING
572
+ end
573
+
574
+ custom_shell_file_content += <<-MULTI_LINE_STRING
575
+ ## Add options like the following to configure CustomShell by outside consumers
576
+ #
577
+ # options :title, :background_color
578
+ # option :width, default: 320
579
+ # option :height, default: 240
580
+ option :greeting, default: 'Hello, World!'
581
+
582
+ ## Use before_body block to pre-initialize variables to use in body
583
+ #
584
+ #
585
+ MULTI_LINE_STRING
586
+
587
+ if %i[gem app].include?(shell_type)
588
+ custom_shell_file_content += <<-MULTI_LINE_STRING
589
+ before_body do
590
+ @display = display {
591
+ on_about do
592
+ display_about_dialog
593
+ end
594
+
595
+ on_preferences do
596
+ display_preferences_dialog
597
+ end
598
+ }
599
+ end
600
+ MULTI_LINE_STRING
601
+ else
602
+ custom_shell_file_content += <<-MULTI_LINE_STRING
603
+ # before_body do
604
+ #
605
+ # end
606
+ MULTI_LINE_STRING
607
+ end
608
+
609
+ custom_shell_file_content += <<-MULTI_LINE_STRING
610
+
611
+ ## Use after_body block to setup observers for widgets in body
612
+ #
613
+ # after_body do
614
+ #
615
+ # end
616
+
617
+ ## Add widget content inside custom shell body
618
+ ## Top-most widget must be a shell or another custom shell
619
+ #
620
+ body {
621
+ shell {
622
+ # Replace example content below with custom shell content
623
+ minimum_size '420, 240'
624
+ image File.join(APP_ROOT, 'icons', 'windows', "#{human_name(current_dir_name)}.ico") if OS.windows?
625
+ image File.join(APP_ROOT, 'icons', 'linux', "#{human_name(current_dir_name)}.png") unless OS.windows?
626
+ text "#{human_name(namespace)}#{' - ' + human_name(custom_shell_name)}"
627
+ grid_layout
628
+ label(:center) {
629
+ text <= [self, :greeting]
630
+ font height: 40
631
+ layout_data :fill, :center, true, true
632
+ }
633
+ MULTI_LINE_STRING
634
+
635
+ if %i[gem app].include?(shell_type)
636
+ custom_shell_file_content += <<-MULTI_LINE_STRING
637
+
638
+ menu_bar {
639
+ menu {
640
+ text '&File'
641
+
642
+ menu_item {
643
+ text '&Preferences...'
644
+
645
+ on_widget_selected do
646
+ display_preferences_dialog
647
+ end
648
+ }
649
+ }
650
+ menu {
651
+ text '&Help'
652
+
653
+ menu_item {
654
+ text '&About...'
655
+
656
+ on_widget_selected do
657
+ display_about_dialog
658
+ end
659
+ }
660
+ }
661
+ }
662
+ MULTI_LINE_STRING
663
+ end
664
+
665
+ custom_shell_file_content += <<-MULTI_LINE_STRING
666
+ }
667
+ }
668
+ MULTI_LINE_STRING
669
+
670
+ if %i[gem app].include?(shell_type)
671
+ custom_shell_file_content += <<-MULTI_LINE_STRING
672
+
673
+ def display_about_dialog
674
+ message_box(body_root) {
675
+ text 'About'
676
+ message "#{human_name(namespace)}#{" - #{human_name(custom_shell_name)}" if shell_type == :gem} \#{VERSION}\\n\\n\#{LICENSE}"
677
+ }.open
678
+ end
679
+
680
+ MULTI_LINE_STRING
681
+ end
682
+
683
+ if %i[gem app].include?(shell_type)
684
+ custom_shell_file_content += <<-MULTI_LINE_STRING
685
+ def display_preferences_dialog
686
+ dialog(swt_widget) {
687
+ grid_layout {
688
+ margin_height 5
689
+ margin_width 5
690
+ }
691
+
692
+ text 'Preferences'
693
+
694
+ group {
695
+ row_layout {
696
+ type :vertical
697
+ spacing 10
698
+ }
699
+
700
+ text 'Greeting'
701
+ font style: :bold
702
+
703
+ [
704
+ 'Hello, World!',
705
+ 'Howdy, Partner!'
706
+ ].each do |greeting_text|
707
+ button(:radio) {
708
+ layout_data {
709
+ width 160
710
+ }
711
+
712
+ text greeting_text
713
+ selection <= [self, :greeting, on_read: ->(g) { g == greeting_text }]
714
+
715
+ on_widget_selected do |event|
716
+ self.greeting = event.widget.getText
717
+ end
718
+ }
719
+ end
720
+ }
721
+ }.open
722
+ end
723
+ MULTI_LINE_STRING
724
+ end
725
+
726
+ custom_shell_file_content += <<-MULTI_LINE_STRING
727
+ end
728
+ end
729
+ end
730
+ MULTI_LINE_STRING
731
+ end
732
+
733
+ def custom_widget_file(custom_widget_name, namespace)
734
+ namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
735
+
736
+ <<-MULTI_LINE_STRING
737
+ #{namespace_type} #{class_name(namespace)}
738
+ module View
739
+ class #{class_name(custom_widget_name)}
740
+ include Glimmer::UI::CustomWidget
741
+
742
+ ## Add options like the following to configure CustomWidget by outside consumers
743
+ #
744
+ # options :custom_text, :background_color
745
+ # option :foreground_color, default: :red
746
+
747
+ ## Use before_body block to pre-initialize variables to use in body
748
+ #
749
+ #
750
+ # before_body do
751
+ #
752
+ # end
753
+
754
+ ## Use after_body block to setup observers for widgets in body
755
+ #
756
+ # after_body do
757
+ #
758
+ # end
759
+
760
+ ## Add widget content under custom widget body
761
+ ##
762
+ ## If you want to add a shell as the top-most widget,
763
+ ## consider creating a custom shell instead
764
+ ## (Glimmer::UI::CustomShell offers shell convenience methods, like show and hide)
765
+ #
766
+ body {
767
+ # Replace example content below with custom widget content
768
+ label(*swt_constants) {
769
+ background :red
770
+ }
771
+ }
772
+
773
+ end
774
+ end
775
+ end
776
+ MULTI_LINE_STRING
777
+ end
778
+
779
+ def custom_shape_file(custom_shape_name, namespace)
780
+ namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
781
+
782
+ <<-MULTI_LINE_STRING
783
+ #{namespace_type} #{class_name(namespace)}
784
+ module View
785
+ class #{class_name(custom_shape_name)}
786
+ include Glimmer::UI::CustomShape
787
+
788
+ ## Add options like the following to configure CustomShape by outside consumers
789
+ #
790
+ # options :option1, option2, option3
791
+ option :background_color, default: :red
792
+ option :size_width, default: 100
793
+ option :size_height, default: 100
794
+ option :location_x, default: 0
795
+ option :location_y, default: 0
796
+
797
+ ## Use before_body block to pre-initialize variables to use in body
798
+ #
799
+ #
800
+ # before_body do
801
+ #
802
+ # end
803
+
804
+ ## Use after_body block to setup observers for shapes in body
805
+ #
806
+ # after_body do
807
+ #
808
+ # end
809
+
810
+ ## Add shape content under custom shape body
811
+ #
812
+ body {
813
+ # Replace example content below with custom shape content
814
+ shape(location_x, location_y) {
815
+ path {
816
+ background background_color
817
+ cubic size_width - size_width*0.66, size_height/2 - size_height*0.33, size_width*0.65 - size_width*0.66, 0 - size_height*0.33, size_width/2 - size_width*0.66, size_height*0.75 - size_height*0.33, size_width - size_width*0.66, size_height - size_height*0.33
818
+ }
819
+
820
+ path {
821
+ background background_color
822
+ cubic size_width - size_width*0.66, size_height/2 - size_height*0.33, size_width*1.35 - size_width*0.66, 0 - size_height*0.33, size_width*1.5 - size_width*0.66, size_height*0.75 - size_height*0.33, size_width - size_width*0.66, size_height - size_height*0.33
823
+ }
824
+ }
825
+ }
826
+
827
+ end
828
+ end
829
+ end
830
+ MULTI_LINE_STRING
831
+ end
832
+
833
+ end
834
+
835
+ end
836
+
837
+ end
838
+
839
+ end