glimmer-dsl-swt 4.18.7.3 → 4.19.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -0
  3. data/README.md +126 -20
  4. data/RUBY_VERSION +1 -1
  5. data/VERSION +1 -1
  6. data/bin/girb +10 -9
  7. data/bin/girb_runner.rb +8 -3
  8. data/bin/glimmer +10 -1
  9. data/bin/glimmer-setup +58 -0
  10. data/bin/glimmer_runner.rb +4 -0
  11. data/docs/reference/GLIMMER_COMMAND.md +98 -32
  12. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +9 -7
  13. data/docs/reference/GLIMMER_PACKAGING_AND_DISTRIBUTION.md +7 -1
  14. data/docs/reference/GLIMMER_SAMPLES.md +25 -0
  15. data/glimmer-dsl-swt.gemspec +0 -0
  16. data/lib/glimmer-dsl-swt.rb +8 -0
  17. data/lib/glimmer/data_binding/widget_binding.rb +1 -1
  18. data/lib/glimmer/dsl/swt/c_tab_item_expression.rb +58 -0
  19. data/lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb +2 -1
  20. data/lib/glimmer/dsl/swt/tab_item_expression.rb +7 -3
  21. data/lib/glimmer/dsl/swt/widget_expression.rb +1 -1
  22. data/lib/glimmer/launcher.rb +27 -51
  23. data/lib/glimmer/rake_task.rb +37 -7
  24. data/lib/glimmer/rake_task/list.rb +8 -0
  25. data/lib/glimmer/rake_task/package.rb +7 -2
  26. data/lib/glimmer/rake_task/scaffold.rb +283 -207
  27. data/lib/glimmer/swt/c_tab_item_proxy.rb +53 -0
  28. data/lib/glimmer/swt/custom/code_text.rb +19 -3
  29. data/lib/glimmer/swt/custom/shape.rb +22 -4
  30. data/lib/glimmer/swt/image_proxy.rb +5 -1
  31. data/lib/glimmer/swt/sash_form_proxy.rb +6 -0
  32. data/lib/glimmer/swt/shell_proxy.rb +3 -1
  33. data/lib/glimmer/swt/tab_folder_proxy.rb +1 -0
  34. data/lib/glimmer/swt/tab_item_proxy.rb +17 -18
  35. data/lib/glimmer/swt/widget_proxy.rb +9 -0
  36. data/samples/elaborate/mandelbrot_fractal.rb +1 -1
  37. data/samples/elaborate/tetris.rb +1 -4
  38. data/samples/elaborate/tetris/view/bevel.rb +4 -1
  39. data/samples/elaborate/tetris/view/block.rb +1 -3
  40. data/samples/hello/hello_c_combo.rb +68 -0
  41. data/samples/hello/hello_c_tab.rb +271 -0
  42. data/samples/hello/hello_code_text.rb +141 -73
  43. data/samples/hello/hello_tab.rb +2 -0
  44. data/vendor/swt/linux/swt.jar +0 -0
  45. data/vendor/swt/mac/swt.jar +0 -0
  46. data/vendor/swt/windows/swt.jar +0 -0
  47. metadata +45 -15
@@ -29,12 +29,13 @@ module Glimmer
29
29
  module SWT
30
30
  class ComboSelectionDataBindingExpression < Expression
31
31
  include_package 'org.eclipse.swt.widgets'
32
+ include_package 'org.eclipse.swt.custom'
32
33
 
33
34
  def can_interpret?(parent, keyword, *args, &block)
34
35
  keyword == 'selection' and
35
36
  block.nil? and
36
37
  parent.respond_to?(:swt_widget) and
37
- parent.swt_widget.is_a?(Combo) and
38
+ (parent.swt_widget.is_a?(Combo) || parent.swt_widget.is_a?(CCombo)) and
38
39
  args.size == 1 and
39
40
  args[0].is_a?(DataBinding::ModelBinding) and
40
41
  args[0].evaluate_options_property.is_a?(Array)
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2021 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -48,7 +48,11 @@ module Glimmer
48
48
  def interpret(parent, keyword, *args, &block)
49
49
  Glimmer::SWT::TabItemProxy.new(parent, args)
50
50
  end
51
+
51
52
  end
53
+
52
54
  end
55
+
53
56
  end
57
+
54
58
  end
@@ -30,7 +30,7 @@ module Glimmer
30
30
  class WidgetExpression < Expression
31
31
  include ParentExpression
32
32
 
33
- EXCLUDED_KEYWORDS = %w[shell display tab_item] + Glimmer::SWT::Custom::Shape.keywords - ['text']
33
+ EXCLUDED_KEYWORDS = %w[shell display tab_item c_tab_item] + Glimmer::SWT::Custom::Shape.keywords - ['text']
34
34
 
35
35
  def can_interpret?(parent, keyword, *args, &block)
36
36
  !EXCLUDED_KEYWORDS.include?(keyword) and
@@ -35,7 +35,7 @@ module Glimmer
35
35
 
36
36
  TEXT_USAGE = <<~MULTI_LINE_STRING
37
37
  Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v#{File.read(File.expand_path('../../../VERSION', __FILE__))}
38
- Usage: glimmer [--bundler] [--pd] [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-jruby-option]...] (application.rb or task[task_args]) [[application2.rb]...]
38
+ Usage: glimmer [--bundler] [--pd] [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-jruby-option]...] (application.rb or task[task_args])
39
39
 
40
40
  Runs Glimmer applications and tasks.
41
41
 
@@ -67,8 +67,6 @@ module Glimmer
67
67
  }
68
68
  REGEX_RAKE_TASK_WITH_ARGS = /^([^\[]+)\[?([^\]]*)\]?$/
69
69
 
70
- @@mutex = Mutex.new
71
-
72
70
  class << self
73
71
  def platform_os
74
72
  OPERATING_SYSTEMS_SUPPORTED.detect {|os| OS.send("#{os}?")}
@@ -83,14 +81,12 @@ module Glimmer
83
81
  end
84
82
 
85
83
  def glimmer_lib
86
- @@mutex.synchronize do
87
- unless @glimmer_lib
88
- @glimmer_lib = GLIMMER_LIB_GEM
89
- glimmer_gem_listing = `jgem list #{GLIMMER_LIB_GEM}`.split("\n").map {|l| l.split.first}
90
- if !glimmer_gem_listing.include?(GLIMMER_LIB_GEM) && File.exists?(GLIMMER_LIB_LOCAL)
91
- @glimmer_lib = GLIMMER_LIB_LOCAL
92
- puts "[DEVELOPMENT MODE] (detected #{@glimmer_lib})"
93
- end
84
+ unless @glimmer_lib
85
+ @glimmer_lib = GLIMMER_LIB_GEM
86
+ glimmer_gem_listing = `jgem list #{GLIMMER_LIB_GEM}`.split("\n").map {|l| l.split.first}
87
+ if !glimmer_gem_listing.include?(GLIMMER_LIB_GEM) && File.exists?(GLIMMER_LIB_LOCAL)
88
+ @glimmer_lib = GLIMMER_LIB_LOCAL
89
+ puts "[DEVELOPMENT MODE] (detected #{@glimmer_lib})"
94
90
  end
95
91
  end
96
92
  @glimmer_lib
@@ -115,17 +111,12 @@ module Glimmer
115
111
  def launch(application, jruby_options: [], env_vars: {}, glimmer_options: {})
116
112
  jruby_options_string = jruby_options.join(' ') + ' ' if jruby_options.any?
117
113
  env_vars = env_vars.merge(glimmer_option_env_vars(glimmer_options))
118
- env_vars_string = env_vars.map do |k,v|
119
- if OS.windows? && ENV['PROMPT'] # detect command prompt (or powershell)
120
- "set #{k}=#{v} && "
121
- else
122
- "export #{k}=#{v} && "
123
- end
124
- end.join
114
+ env_vars.each do |k,v|
115
+ ENV[k] = v
116
+ end
125
117
  the_glimmer_lib = glimmer_lib
126
- devmode_require = nil
127
118
  if the_glimmer_lib == GLIMMER_LIB_LOCAL
128
- devmode_require = '-r puts_debuggerer '
119
+ require 'puts_debuggerer'
129
120
  end
130
121
  require_relative 'rake_task'
131
122
  rake_tasks = Rake.application.tasks.map(&:to_s).map {|t| t.sub('glimmer:', '')}
@@ -142,20 +133,9 @@ module Glimmer
142
133
  puts "Running Glimmer rake task: #{rake_task}" if jruby_options_string.to_s.include?('--debug')
143
134
  Rake::Task[rake_task].invoke(*rake_task_args)
144
135
  else
145
- @@mutex.synchronize do
146
- puts "Launching Glimmer Application: #{application}" if jruby_options_string.to_s.include?('--debug') || glimmer_options['--quiet'].to_s.downcase != 'true'
147
- end
148
- command = "#{env_vars_string} jruby #{jruby_options_string}#{jruby_os_specific_options} #{devmode_require}-r #{the_glimmer_lib} -S #{application}"
149
- if !env_vars_string.empty? && OS.windows?
150
- command = "bash -c \"#{command}\"" if ENV['SHELL'] # do in Windows Git Bash only
151
- command = "cmd /C \"#{command}\"" if ENV['PROMPT'] # do in Windows Command Prompt only (or Powershell)
152
- end
153
- puts command if jruby_options_string.to_s.include?('--debug')
154
- if command.include?(' irb ')
155
- exec command
156
- else
157
- system command
158
- end
136
+ puts "Launching Glimmer Application: #{application}" if jruby_options_string.to_s.include?('--debug') || glimmer_options['--quiet'].to_s.downcase != 'true'
137
+ require the_glimmer_lib
138
+ load File.expand_path(application)
159
139
  end
160
140
  end
161
141
  end
@@ -168,14 +148,14 @@ module Glimmer
168
148
  def initialize(raw_options)
169
149
  raw_options << '--quiet' if !caller.join("\n").include?('/bin/glimmer:') && !raw_options.join.include?('--quiet=')
170
150
  raw_options << '--log-level=DEBUG' if raw_options.join.include?('--debug') && !raw_options.join.include?('--log-level=')
171
- @application_paths = extract_application_paths(raw_options)
151
+ @application_path = extract_application_path(raw_options)
172
152
  @env_vars = extract_env_vars(raw_options)
173
153
  @glimmer_options = extract_glimmer_options(raw_options)
174
154
  @jruby_options = raw_options
175
155
  end
176
156
 
177
157
  def launch
178
- if @application_paths.empty?
158
+ if @application_path.nil?
179
159
  display_usage
180
160
  else
181
161
  launch_application
@@ -185,18 +165,13 @@ module Glimmer
185
165
  private
186
166
 
187
167
  def launch_application
188
- load File.expand_path('./Rakefile') if File.exist?(File.expand_path('./Rakefile')) && caller.join("\n").include?('/bin/glimmer:')
189
- threads = @application_paths.map do |application_path|
190
- Thread.new do
191
- self.class.launch(
192
- application_path,
193
- jruby_options: @jruby_options,
194
- env_vars: @env_vars,
195
- glimmer_options: @glimmer_options
196
- )
197
- end
198
- end
199
- threads.each(&:join)
168
+ load File.expand_path('./Rakefile') if File.exist?(File.expand_path('./Rakefile')) && caller.join("\n").include?('/bin/glimmer_runner.rb:')
169
+ self.class.launch(
170
+ @application_path,
171
+ jruby_options: @jruby_options,
172
+ env_vars: @env_vars,
173
+ glimmer_options: @glimmer_options
174
+ )
200
175
  end
201
176
 
202
177
  def display_usage
@@ -232,10 +207,11 @@ module Glimmer
232
207
  end
233
208
  end
234
209
 
235
- def extract_application_paths(options)
236
- options.select do |option|
210
+ # Extract application path (which can also be a rake task, basically a non-arg)
211
+ def extract_application_path(options)
212
+ application_path = options.detect do |option|
237
213
  !option.start_with?('-') && !option.include?('=')
238
- end.each do |application_path|
214
+ end.tap do
239
215
  options.delete(application_path)
240
216
  end
241
217
  end
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2007-2021 Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -54,7 +54,7 @@ namespace :glimmer do
54
54
  if args[:app_path].nil?
55
55
  require 'fileutils'
56
56
  current_directory_name = File.basename(FileUtils.pwd)
57
- assumed_shell_script = File.join('.', 'bin', current_directory_name)
57
+ assumed_shell_script = File.join('.', 'bin', current_directory_name)
58
58
  assumed_shell_script = Dir.glob('./bin/*').detect {|f| File.file?(f)} if !File.exist?(assumed_shell_script)
59
59
  Glimmer::Launcher.new([assumed_shell_script]).launch
60
60
  else
@@ -100,7 +100,7 @@ namespace :glimmer do
100
100
 
101
101
  desc 'Generate Native files. type can be dmg/pkg on the Mac, msi/exe on Windows, and rpm/deb on Linux (type is optional)'
102
102
  task :native, [:type] do |t, args|
103
- extra_args = ARGV.partition {|arg| arg.include?('package:native')}.last.to_a.join(' ')
103
+ extra_args = ARGV.partition {|arg| arg.start_with?('package')}.last.to_a.join(' ')
104
104
  Glimmer::RakeTask::Package.native(args[:type], extra_args)
105
105
  end
106
106
  end
@@ -145,6 +145,16 @@ namespace :glimmer do
145
145
  task :custom_widget, [:name, :namespace] => :customwidget
146
146
  task :"custom-widget", [:name, :namespace] => :customwidget
147
147
 
148
+ desc 'Scaffold Glimmer::UI::CustomShape subclass (part of a view) under app/views (namespace is optional) [alt: scaffold:cp]'
149
+ task :customshape, [:name, :namespace] do |t, args|
150
+ require_relative 'rake_task/scaffold'
151
+ Glimmer::RakeTask::Scaffold.custom_shape(args[:name], args[:namespace])
152
+ end
153
+
154
+ task :cp, [:name, :namespace] => :customshape
155
+ task :custom_shape, [:name, :namespace] => :customshape
156
+ task :"custom-shape", [:name, :namespace] => :customshape
157
+
148
158
  desc 'Desktopify a web app'
149
159
  task :desktopify, [:app_name, :website] do |t, args|
150
160
  require_relative 'rake_task/scaffold'
@@ -170,13 +180,24 @@ namespace :glimmer do
170
180
 
171
181
  task :cw, [:name, :namespace] => :customwidget
172
182
  task :custom_widget, [:name, :namespace] => :customwidget
173
- task :"custom-widget", [:name, :namespace] => :customwidget
183
+ task :"custom-widget", [:name, :namespace] => :customwidget
184
+
185
+ desc 'Scaffold Glimmer::UI::CustomShape subclass (part of a view) under its own Ruby gem project (namespace is required) [alt: scaffold:gem:cp]'
186
+ task :customshape, [:name, :namespace] do |t, args|
187
+ require_relative 'rake_task/scaffold'
188
+ Glimmer::RakeTask::Scaffold.custom_shape_gem(args[:name], args[:namespace])
189
+ end
190
+
191
+ task :cp, [:name, :namespace] => :customshape
192
+ task :custom_shape, [:name, :namespace] => :customshape
193
+ task :"custom-shape", [:name, :namespace] => :customshape
174
194
  end
175
195
 
176
196
  # legacy support
177
197
 
178
198
  task :custom_shell_gem, [:name, :namespace] => 'gem:customshell'
179
199
  task :custom_widget_gem, [:name, :namespace] => 'gem:customwidget'
200
+ task :custom_shape_gem, [:name, :namespace] => 'gem:customshape'
180
201
 
181
202
  end
182
203
 
@@ -204,6 +225,15 @@ namespace :glimmer do
204
225
  task :custom_shell, [:query] => :customshell
205
226
  task :"custom-shell", [:query] => :customshell
206
227
 
228
+ desc 'List Glimmer custom shape gems available at rubygems.org (query is optional) [alt: list:gems:cp]'
229
+ task :customshape, [:query] => :list_require do |t, args|
230
+ Glimmer::RakeTask::List.custom_shape_gems(args[:query])
231
+ end
232
+
233
+ task :cp, [:query] => :customshape
234
+ task :custom_shape, [:query] => :customshape
235
+ task :"custom-shape", [:query] => :customshape
236
+
207
237
  desc 'List Glimmer DSL gems available at rubygems.org (query is optional)'
208
238
  task :dsl, [:query] => :list_require do |t, args|
209
239
  Glimmer::RakeTask::List.dsl_gems(args[:query])
@@ -214,7 +244,7 @@ namespace :glimmer do
214
244
  # legacy support
215
245
 
216
246
  task :custom_shell_gems, [:name, :namespace] => 'gems:customshell'
217
- task :custom_widget_gems, [:name, :namespace] => 'gems:customwidget'
247
+ task :custom_widget_gems, [:name, :namespace] => 'gems:customwidget'
218
248
 
219
249
  end
220
250
  end
@@ -45,6 +45,14 @@ module Glimmer
45
45
  end
46
46
  end
47
47
 
48
+ def custom_shape_gems(query=nil)
49
+ list_gems('glimmer-cp-', query) do |result|
50
+ puts
51
+ puts " Glimmer Custom Shape Gems#{" matching [#{query}]" if query} at rubygems.org:"
52
+ puts result
53
+ end
54
+ end
55
+
48
56
  def dsl_gems(query=nil)
49
57
  list_gems('glimmer-dsl-', query) do |result|
50
58
  puts
@@ -90,8 +90,12 @@ module Glimmer
90
90
 
91
91
  def native(native_type=nil, native_extra_args)
92
92
  puts "Generating native executable with javapackager/jpackage..."
93
- java_version = `java -version`
94
- puts "WARNING! Glimmer Packaging Pre-Requisite Java Version 1.8.0_241 Is Not Found!" unless java_version.include?('1.8.0_241')
93
+ java_version = `jruby -v`
94
+ if java_version.include?('1.8.0_241')
95
+ puts "Java Version 1.8.0_241 Detected!"
96
+ else
97
+ puts "WARNING! Glimmer Packaging Pre-Requisite Java Version 1.8.0_241 Is Not Found!"
98
+ end
95
99
  require 'facets/string/titlecase'
96
100
  require 'facets/string/underscore'
97
101
  require 'facets/string/camelcase'
@@ -121,6 +125,7 @@ module Glimmer
121
125
  puts "Neither javapackager nor jpackage exist in your Java installation. Please ensure javapackager or jpackage is available in PATH environment variable."
122
126
  return
123
127
  end
128
+ Rake.application.load_rakefile # make sure to load potential javapackager_extra_args config in app Rakefile
124
129
  command += " #{javapackager_extra_args} " if javapackager_extra_args
125
130
  command += " #{ENV['JAVAPACKAGER_EXTRA_ARGS']} " if ENV['JAVAPACKAGER_EXTRA_ARGS']
126
131
  command += " #{native_extra_args} " if native_extra_args
@@ -149,8 +149,8 @@ module Glimmer
149
149
  write 'Rakefile', gem_rakefile(app_name, nil, gem_name)
150
150
  mkdir 'app'
151
151
  write "app/#{file_name(app_name)}.rb", app_main_file(app_name)
152
- mkdir 'app/models'
153
- mkdir 'app/views'
152
+ mkdir_p "app/#{file_name(app_name)}/model"
153
+ mkdir_p "app/#{file_name(app_name)}/view"
154
154
  if shell_type == :desktopify
155
155
  custom_shell('AppView', current_dir_name, shell_type, shell_options)
156
156
  else
@@ -185,7 +185,7 @@ module Glimmer
185
185
  end
186
186
  write 'spec/spec_helper.rb', spec_helper_file
187
187
  if OS.windows?
188
- system "glimmer package[image]"
188
+ system "glimmer \"package[image]\"" # TODO handle Windows with batch file
189
189
  system "\"packages/bundles/#{human_name(app_name)}/#{human_name(app_name)}.exe\""
190
190
  else
191
191
  system "bash -c '#{RVM_FUNCTION}\n cd .\n glimmer package\n'"
@@ -200,7 +200,7 @@ module Glimmer
200
200
  def custom_shell(custom_shell_name, namespace, shell_type = nil, shell_options = {})
201
201
  namespace ||= current_dir_name
202
202
  root_dir = File.exists?('app') ? 'app' : 'lib'
203
- parent_dir = "#{root_dir}/views/#{file_name(namespace)}"
203
+ parent_dir = "#{root_dir}/#{file_name(namespace)}/view"
204
204
  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")
205
205
  mkdir_p parent_dir unless File.exists?(parent_dir)
206
206
  write "#{parent_dir}/#{file_name(custom_shell_name)}.rb", custom_shell_file(custom_shell_name, namespace, shell_type, shell_options)
@@ -209,12 +209,21 @@ module Glimmer
209
209
  def custom_widget(custom_widget_name, namespace)
210
210
  namespace ||= current_dir_name
211
211
  root_dir = File.exists?('app') ? 'app' : 'lib'
212
- parent_dir = "#{root_dir}/views/#{file_name(namespace)}"
212
+ parent_dir = "#{root_dir}/#{file_name(namespace)}/view"
213
213
  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")
214
214
  mkdir_p parent_dir unless File.exists?(parent_dir)
215
215
  write "#{parent_dir}/#{file_name(custom_widget_name)}.rb", custom_widget_file(custom_widget_name, namespace)
216
216
  end
217
217
 
218
+ def custom_shape(custom_shape_name, namespace)
219
+ namespace ||= current_dir_name
220
+ root_dir = File.exists?('app') ? 'app' : 'lib'
221
+ parent_dir = "#{root_dir}/#{file_name(namespace)}/view"
222
+ 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")
223
+ mkdir_p parent_dir unless File.exists?(parent_dir)
224
+ write "#{parent_dir}/#{file_name(custom_shape_name)}.rb", custom_shape_file(custom_shape_name, namespace)
225
+ end
226
+
218
227
  def custom_shell_gem(custom_shell_name, namespace)
219
228
  gem_name = "glimmer-cs-#{compact_name(custom_shell_name)}"
220
229
  gem_summary = "#{human_name(custom_shell_name)} - Glimmer Custom Shell"
@@ -244,15 +253,12 @@ module Glimmer
244
253
  write 'Gemfile', GEMFILE
245
254
  write 'Rakefile', gem_rakefile(custom_shell_name, namespace, gem_name)
246
255
  append "lib/#{gem_name}.rb", gem_main_file(custom_shell_name, namespace)
247
- mkdir 'lib/views'
248
256
  custom_shell(custom_shell_name, namespace, :gem)
249
257
 
250
- mkdir_p "lib/#{file_name(namespace)}/#{file_name(custom_shell_name)}"
251
- write "lib/#{file_name(namespace)}/#{file_name(custom_shell_name)}/launch.rb", gem_launch_file(gem_name, custom_shell_name, namespace)
258
+ mkdir_p "lib/#{gem_name}"
259
+ write "lib/#{gem_name}/launch.rb", gem_launch_file(gem_name, custom_shell_name, namespace)
252
260
  mkdir_p 'bin'
253
- write "bin/#{gem_name}", gem_bin_command_file(gem_name, custom_shell_name, namespace)
254
- FileUtils.chmod 0755, "bin/#{gem_name}"
255
- write "bin/#{file_name(custom_shell_name)}", gem_bin_command_file(gem_name, custom_shell_name, namespace)
261
+ write "bin/#{file_name(custom_shell_name)}", app_bin_command_file(gem_name, custom_shell_name, namespace)
256
262
  FileUtils.chmod 0755, "bin/#{file_name(custom_shell_name)}"
257
263
  if OS.windows?
258
264
  system "bundle"
@@ -278,12 +284,12 @@ module Glimmer
278
284
  puts "Created #{current_dir_name}/#{icon_file}"
279
285
 
280
286
  if OS.windows?
281
- system "glimmer package[image]"
287
+ system "glimmer package[image]" # TODO handle windows properly with batch file
282
288
  system "\"packages/bundles/#{human_name(custom_shell_name)}/#{human_name(custom_shell_name)}.exe\""
283
289
  else
284
290
  system "bash -c '#{RVM_FUNCTION}\n cd .\n glimmer package\n'"
285
291
  if OS.mac?
286
- system "open packages/bundles/#{human_name(custom_shell_name).gsub(' ', '\ ')}.app" if OS.mac?
292
+ system "open packages/bundles/#{human_name(custom_shell_name).gsub(' ', '\ ')}.app"
287
293
  else
288
294
  system "glimmer run"
289
295
  end
@@ -318,7 +324,6 @@ module Glimmer
318
324
  write 'Gemfile', GEMFILE
319
325
  write 'Rakefile', gem_rakefile
320
326
  append "lib/#{gem_name}.rb", gem_main_file(custom_widget_name, namespace)
321
- mkdir 'lib/views'
322
327
  custom_widget(custom_widget_name, namespace)
323
328
  if OS.windows?
324
329
  system "bundle"
@@ -334,6 +339,44 @@ module Glimmer
334
339
  puts 'Run `rake release` to release into rubygems.org once ready.'
335
340
  end
336
341
 
342
+ def custom_shape_gem(custom_shape_name, namespace)
343
+ 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'
344
+ gem_name = "glimmer-cp-#{compact_name(custom_shape_name)}"
345
+ gem_summary = "#{human_name(custom_shape_name)} - Glimmer Custom Shape"
346
+ if namespace
347
+ gem_name += "-#{compact_name(namespace)}"
348
+ gem_summary += " (#{human_name(namespace)})"
349
+ else
350
+ namespace = 'glimmer'
351
+ end
352
+
353
+ return puts("The directory '#{gem_name}' already exists. Please either remove or pick a different name.") if Dir.exist?(gem_name)
354
+ system "jruby -S gem install juwelier -v2.4.9 --no-document" unless juwelier_exists?
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', 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
+
337
380
  private
338
381
 
339
382
  def juwelier_exists?
@@ -395,7 +438,7 @@ module Glimmer
395
438
 
396
439
  require 'bundler/setup'
397
440
  Bundler.require(:default)
398
- require 'views/#{file_name(app_name)}/app_view'
441
+ require '#{file_name(app_name)}/view/app_view'
399
442
 
400
443
  class #{class_name(app_name)}
401
444
  include Glimmer
@@ -403,17 +446,14 @@ module Glimmer
403
446
  APP_ROOT = File.expand_path('../..', __FILE__)
404
447
  VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
405
448
  LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
406
-
407
- def open
408
- app_view.open
409
- end
410
449
  end
411
450
  MULTI_LINE_STRING
412
451
  end
413
452
 
414
453
  def gem_main_file(custom_widget_name, namespace = nil)
415
- custom_widget_file_path = "views"
416
- custom_widget_file_path += "/#{file_name(namespace)}" if namespace
454
+ custom_widget_file_path = ''
455
+ custom_widget_file_path += "#{file_name(namespace)}/" if namespace
456
+ custom_widget_file_path += "view"
417
457
  custom_widget_file_path += "/#{file_name(custom_widget_name)}"
418
458
 
419
459
  <<~MULTI_LINE_STRING
@@ -428,15 +468,20 @@ module Glimmer
428
468
  <<~MULTI_LINE_STRING
429
469
  require_relative '../#{file_name(app_name)}'
430
470
 
431
- #{class_name(app_name)}.new.open
471
+ #{class_name(app_name)}::View::AppView.launch
432
472
  MULTI_LINE_STRING
433
473
  end
434
474
 
435
- def app_bin_command_file(app_name)
475
+ def app_bin_command_file(app_name_or_gem_name, custom_shell_name=nil, namespace=nil)
476
+ if custom_shell_name.nil?
477
+ runner = "File.expand_path('../../app/#{file_name(app_name_or_gem_name)}/launch.rb', __FILE__)"
478
+ else
479
+ runner = "File.expand_path('../../lib/#{app_name_or_gem_name}/launch.rb', __FILE__)"
480
+ end
436
481
  <<~MULTI_LINE_STRING
437
482
  #!/usr/bin/env jruby
438
483
 
439
- runner = File.expand_path("../../app/#{file_name(app_name)}/launch.rb", __FILE__)
484
+ runner = #{runner}
440
485
 
441
486
  # Detect if inside a JAR file or not
442
487
  if runner.include?('uri:classloader')
@@ -453,39 +498,9 @@ module Glimmer
453
498
  def gem_launch_file(gem_name, custom_shell_name, namespace)
454
499
  # TODO change this so that it does not mix Glimmer unto the main object
455
500
  <<~MULTI_LINE_STRING
456
- require_relative '../../#{gem_name}'
457
-
458
- module #{class_name(namespace)}
459
- class #{class_name(custom_shell_name)}
460
- class App
461
- include Glimmer
462
-
463
- def open
464
- #{dsl_widget_name(custom_shell_name)}.open
465
- end
466
- end
467
- end
468
- end
501
+ require_relative '../#{gem_name}'
469
502
 
470
- #{class_name(namespace)}::#{class_name(custom_shell_name)}::App.new.open
471
- MULTI_LINE_STRING
472
- end
473
-
474
- def gem_bin_command_file(gem_name, custom_shell_name, namespace)
475
- <<~MULTI_LINE_STRING
476
- #!/usr/bin/env jruby
477
-
478
- runner = File.expand_path("../../lib/#{file_name(namespace)}/#{file_name(custom_shell_name)}/launch.rb", __FILE__)
479
-
480
- # Detect if inside a JAR file or not
481
- if runner.include?('uri:classloader')
482
- require runner
483
- else
484
- require 'glimmer/launcher'
485
-
486
- launcher = Glimmer::Launcher.new([runner] + ARGV)
487
- launcher.launch
488
- end
503
+ #{class_name(namespace)}::View::#{class_name(custom_shell_name)}.launch
489
504
  MULTI_LINE_STRING
490
505
  end
491
506
 
@@ -498,8 +513,8 @@ module Glimmer
498
513
  if custom_shell_name
499
514
  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/**/*']")
500
515
  # 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)
501
- lines.insert(gem_files_line_index+1, " gem.executables = ['#{gem_name}', '#{file_name(custom_shell_name)}']")
502
- lines.insert(gem_files_line_index+2, " gem.require_paths = ['vendor', 'lib', 'app']")
516
+ lines.insert(gem_files_line_index+1, " gem.require_paths = ['vendor', 'lib', 'app']")
517
+ lines.insert(gem_files_line_index+2, " gem.executables = ['#{file_name(custom_shell_name)}']") if custom_shell_name
503
518
  else
504
519
  lines.insert(gem_files_line_index, " gem.files = Dir['VERSION', 'LICENSE.txt', 'lib/**/*']")
505
520
  end
@@ -547,222 +562,283 @@ module Glimmer
547
562
  namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
548
563
 
549
564
  custom_shell_file_content = <<-MULTI_LINE_STRING
550
- #{namespace_type} #{class_name(namespace)}
551
- class #{class_name(custom_shell_name)}
552
- include Glimmer::UI::CustomShell
553
-
565
+ #{namespace_type} #{class_name(namespace)}
566
+ module View
567
+ class #{class_name(custom_shell_name)}
568
+ include Glimmer::UI::CustomShell
569
+
554
570
  MULTI_LINE_STRING
555
571
 
556
572
  if shell_type == :gem
557
573
  custom_shell_file_content += <<-MULTI_LINE_STRING
558
- APP_ROOT = File.expand_path('../../../..', __FILE__)
559
- VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
560
- LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
561
-
574
+ APP_ROOT = File.expand_path('../../../..', __FILE__)
575
+ VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
576
+ LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
577
+
562
578
  MULTI_LINE_STRING
563
579
  end
564
580
 
565
581
  custom_shell_file_content += <<-MULTI_LINE_STRING
566
- ## Add options like the following to configure CustomShell by outside consumers
567
- #
568
- # options :title, :background_color
569
- # option :width, default: 320
570
- # option :height, default: 240
571
- #{'# ' if shell_type == :desktopify}option :greeting, default: 'Hello, World!'
572
-
573
- ## Use before_body block to pre-initialize variables to use in body
574
- #
575
- #
582
+ ## Add options like the following to configure CustomShell by outside consumers
583
+ #
584
+ # options :title, :background_color
585
+ # option :width, default: 320
586
+ # option :height, default: 240
587
+ #{'# ' if shell_type == :desktopify}option :greeting, default: 'Hello, World!'
588
+
589
+ ## Use before_body block to pre-initialize variables to use in body
590
+ #
591
+ #
576
592
  MULTI_LINE_STRING
577
593
 
578
594
  if %i[gem app desktopify].include?(shell_type)
579
595
  custom_shell_file_content += <<-MULTI_LINE_STRING
580
- before_body {
581
- Display.app_name = '#{shell_type == :gem ? human_name(custom_shell_name) : human_name(namespace)}'
582
- Display.app_version = VERSION
583
- @display = display {
584
- on_about {
585
- display_about_dialog
586
- }
587
- on_preferences {
588
- #{shell_type == :desktopify ? 'display_about_dialog' : 'display_preferences_dialog'}
589
- }
596
+ before_body {
597
+ Display.app_name = '#{shell_type == :gem ? human_name(custom_shell_name) : human_name(namespace)}'
598
+ Display.app_version = VERSION
599
+ @display = display {
600
+ on_about {
601
+ display_about_dialog
602
+ }
603
+ on_preferences {
604
+ #{shell_type == :desktopify ? 'display_about_dialog' : 'display_preferences_dialog'}
590
605
  }
591
606
  }
607
+ }
592
608
  MULTI_LINE_STRING
593
609
  else
594
610
  custom_shell_file_content += <<-MULTI_LINE_STRING
595
- # before_body {
596
- #
597
- # }
611
+ # before_body {
612
+ #
613
+ # }
598
614
  MULTI_LINE_STRING
599
615
  end
600
616
 
601
617
  custom_shell_file_content += <<-MULTI_LINE_STRING
602
-
603
- ## Use after_body block to setup observers for widgets in body
604
- #
605
- # after_body {
606
- #
607
- # }
608
-
609
- ## Add widget content inside custom shell body
610
- ## Top-most widget must be a shell or another custom shell
611
- #
612
- body {
613
- shell {
614
- # Replace example content below with custom shell content
615
- minimum_size #{shell_type == :desktopify ? '1024, 768' : '320, 240'}
616
- image File.join(APP_ROOT, 'package', 'windows', "#{human_name(shell_type == :gem ? custom_shell_name : current_dir_name)}.ico") if OS.windows?
617
- text "#{human_name(namespace)} - #{human_name(custom_shell_name)}"
618
-
618
+
619
+ ## Use after_body block to setup observers for widgets in body
620
+ #
621
+ # after_body {
622
+ #
623
+ # }
624
+
625
+ ## Add widget content inside custom shell body
626
+ ## Top-most widget must be a shell or another custom shell
627
+ #
628
+ body {
629
+ shell(#{':fill_screen' if shell_type == :desktopify}) {
630
+ # Replace example content below with custom shell content
631
+ minimum_size #{shell_type == :desktopify ? '768, 432' : '420, 240'}
632
+ image File.join(APP_ROOT, 'package', 'windows', "#{human_name(shell_type == :gem ? custom_shell_name : current_dir_name)}.ico") if OS.windows?
633
+ text "#{human_name(namespace)} - #{human_name(custom_shell_name)}"
634
+
619
635
  MULTI_LINE_STRING
620
636
 
621
637
  if shell_type == :desktopify
622
638
  custom_shell_file_content += <<-MULTI_LINE_STRING
623
- browser {
624
- url "#{shell_options[:website]}"
625
- }
639
+ browser {
640
+ url "#{shell_options[:website]}"
641
+ }
626
642
  MULTI_LINE_STRING
627
643
  else
628
644
  custom_shell_file_content += <<-MULTI_LINE_STRING
629
- grid_layout
630
- label(:center) {
631
- text bind(self, :greeting)
632
- font height: 40
633
- layout_data :fill, :center, true, true
634
- }
645
+ grid_layout
646
+ label(:center) {
647
+ text bind(self, :greeting)
648
+ font height: 40
649
+ layout_data :fill, :center, true, true
650
+ }
635
651
  MULTI_LINE_STRING
636
652
  end
637
653
 
638
654
  if %i[gem app desktopify].include?(shell_type)
639
655
  custom_shell_file_content += <<-MULTI_LINE_STRING
640
-
641
- menu_bar {
642
- menu {
643
- text '&File'
644
- menu_item {
645
- text '&About...'
646
- on_widget_selected {
647
- display_about_dialog
648
- }
656
+
657
+ menu_bar {
658
+ menu {
659
+ text '&File'
660
+ menu_item {
661
+ text '&About...'
662
+ on_widget_selected {
663
+ display_about_dialog
649
664
  }
650
- menu_item {
651
- text '&Preferences...'
652
- on_widget_selected {
653
- #{shell_type == :desktopify ? 'display_about_dialog' : 'display_preferences_dialog'}
654
- }
665
+ }
666
+ menu_item {
667
+ text '&Preferences...'
668
+ on_widget_selected {
669
+ #{shell_type == :desktopify ? 'display_about_dialog' : 'display_preferences_dialog'}
655
670
  }
656
671
  }
657
672
  }
673
+ }
658
674
  MULTI_LINE_STRING
659
675
  end
660
676
 
661
677
  custom_shell_file_content += <<-MULTI_LINE_STRING
662
- }
663
678
  }
679
+ }
664
680
  MULTI_LINE_STRING
665
681
 
666
682
  if %i[gem app desktopify].include?(shell_type)
667
683
  custom_shell_file_content += <<-MULTI_LINE_STRING
668
-
669
- def display_about_dialog
670
- message_box(body_root) {
671
- text 'About'
672
- message "#{human_name(namespace)}#{" - #{human_name(custom_shell_name)}" if shell_type == :gem} \#{VERSION}\\n\\n\#{LICENSE}"
673
- }.open
674
- end
675
-
684
+
685
+ def display_about_dialog
686
+ message_box(body_root) {
687
+ text 'About'
688
+ message "#{human_name(namespace)}#{" - #{human_name(custom_shell_name)}" if shell_type == :gem} \#{VERSION}\\n\\n\#{LICENSE}"
689
+ }.open
690
+ end
691
+
676
692
  MULTI_LINE_STRING
677
693
  end
678
694
 
679
695
  if %i[gem app].include?(shell_type)
680
696
  custom_shell_file_content += <<-MULTI_LINE_STRING
681
- def display_preferences_dialog
682
- dialog(swt_widget) {
683
- text 'Preferences'
684
- grid_layout {
685
- margin_height 5
686
- margin_width 5
697
+ def display_preferences_dialog
698
+ dialog(swt_widget) {
699
+ text 'Preferences'
700
+ grid_layout {
701
+ margin_height 5
702
+ margin_width 5
703
+ }
704
+ group {
705
+ row_layout {
706
+ type :vertical
707
+ spacing 10
687
708
  }
688
- group {
689
- row_layout {
690
- type :vertical
691
- spacing 10
692
- }
693
- text 'Greeting'
694
- font style: :bold
695
- [
696
- 'Hello, World!',
697
- 'Howdy, Partner!'
698
- ].each do |greeting_text|
699
- button(:radio) {
700
- text greeting_text
701
- selection bind(self, :greeting) { |g| g == greeting_text }
702
- layout_data {
703
- width 160
704
- }
705
- on_widget_selected { |event|
706
- self.greeting = event.widget.getText
707
- }
709
+ text 'Greeting'
710
+ font style: :bold
711
+ [
712
+ 'Hello, World!',
713
+ 'Howdy, Partner!'
714
+ ].each do |greeting_text|
715
+ button(:radio) {
716
+ text greeting_text
717
+ selection bind(self, :greeting) { |g| g == greeting_text }
718
+ layout_data {
719
+ width 160
708
720
  }
709
- end
710
- }
711
- }.open
712
- end
721
+ on_widget_selected { |event|
722
+ self.greeting = event.widget.getText
723
+ }
724
+ }
725
+ end
726
+ }
727
+ }.open
728
+ end
713
729
  MULTI_LINE_STRING
714
730
  end
715
731
 
716
732
  custom_shell_file_content += <<-MULTI_LINE_STRING
717
- end
718
733
  end
734
+ end
735
+ end
719
736
  MULTI_LINE_STRING
720
737
  end
721
738
 
722
739
  def custom_widget_file(custom_widget_name, namespace)
723
740
  namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
724
741
 
725
- <<~MULTI_LINE_STRING
726
- #{namespace_type} #{class_name(namespace)}
727
- class #{class_name(custom_widget_name)}
728
- include Glimmer::UI::CustomWidget
729
-
730
- ## Add options like the following to configure CustomWidget by outside consumers
731
- #
732
- # options :custom_text, :background_color
733
- # option :foreground_color, default: :red
734
-
735
- ## Use before_body block to pre-initialize variables to use in body
736
- #
737
- #
738
- # before_body {
739
- #
740
- # }
741
-
742
- ## Use after_body block to setup observers for widgets in body
743
- #
744
- # after_body {
745
- #
746
- # }
747
-
748
- ## Add widget content under custom widget body
749
- ##
750
- ## If you want to add a shell as the top-most widget,
751
- ## consider creating a custom shell instead
752
- ## (Glimmer::UI::CustomShell offers shell convenience methods, like show and hide)
753
- #
754
- body {
755
- # Replace example content below with custom widget content
756
- label {
757
- background :red
758
- }
759
- }
760
-
761
- end
762
- end
742
+ <<-MULTI_LINE_STRING
743
+ #{namespace_type} #{class_name(namespace)}
744
+ module View
745
+ class #{class_name(custom_widget_name)}
746
+ include Glimmer::UI::CustomWidget
747
+
748
+ ## Add options like the following to configure CustomWidget by outside consumers
749
+ #
750
+ # options :custom_text, :background_color
751
+ # option :foreground_color, default: :red
752
+
753
+ ## Use before_body block to pre-initialize variables to use in body
754
+ #
755
+ #
756
+ # before_body {
757
+ #
758
+ # }
759
+
760
+ ## Use after_body block to setup observers for widgets in body
761
+ #
762
+ # after_body {
763
+ #
764
+ # }
765
+
766
+ ## Add widget content under custom widget body
767
+ ##
768
+ ## If you want to add a shell as the top-most widget,
769
+ ## consider creating a custom shell instead
770
+ ## (Glimmer::UI::CustomShell offers shell convenience methods, like show and hide)
771
+ #
772
+ body {
773
+ # Replace example content below with custom widget content
774
+ label {
775
+ background :red
776
+ }
777
+ }
778
+
779
+ end
780
+ end
781
+ end
782
+ MULTI_LINE_STRING
783
+ end
784
+
785
+ def custom_shape_file(custom_shape_name, namespace)
786
+ namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
787
+
788
+ <<-MULTI_LINE_STRING
789
+ #{namespace_type} #{class_name(namespace)}
790
+ module View
791
+ class #{class_name(custom_shape_name)}
792
+ include Glimmer::UI::CustomShape
793
+
794
+ ## Add options like the following to configure CustomShape by outside consumers
795
+ #
796
+ # options :option1, option2, option3
797
+ option :background_color, default: :red
798
+ option :size_width, default: 100
799
+ option :size_height, default: 100
800
+ option :location_x, default: 0
801
+ option :location_y, default: 0
802
+
803
+ ## Use before_body block to pre-initialize variables to use in body
804
+ #
805
+ #
806
+ # before_body {
807
+ #
808
+ # }
809
+
810
+ ## Use after_body block to setup observers for shapes in body
811
+ #
812
+ # after_body {
813
+ #
814
+ # }
815
+
816
+ ## Add shape content under custom shape body
817
+ #
818
+ body {
819
+ # Replace example content below with custom shape content
820
+ shape(location_x, location_y) {
821
+ path {
822
+ background background_color
823
+ 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
824
+ }
825
+ path {
826
+ background background_color
827
+ 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
828
+ }
829
+ }
830
+ }
831
+
832
+ end
833
+ end
834
+ end
763
835
  MULTI_LINE_STRING
764
836
  end
837
+
765
838
  end
839
+
766
840
  end
841
+
767
842
  end
843
+
768
844
  end