picrate 1.2.4-java → 2.1.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/Gemfile +3 -1
  4. data/README.md +11 -10
  5. data/Rakefile +10 -9
  6. data/bin/picrate +3 -1
  7. data/docs/_config.yml +1 -1
  8. data/docs/_editors/geany.md +1 -0
  9. data/docs/_gems/gems/gems.md +1 -1
  10. data/docs/_methods/alternative_methods.md +2 -1
  11. data/docs/_posts/2018-05-06-getting_started.md +4 -4
  12. data/docs/_posts/2018-05-06-install_jruby.md +5 -11
  13. data/docs/_posts/2018-05-11-arch-linux-arm.md +1 -11
  14. data/docs/_posts/2018-11-18-building-gem.md +2 -2
  15. data/docs/_posts/2018-11-27-getting_started_geany.md +1 -1
  16. data/docs/_posts/2019-11-11-getting_started_buster.md +4 -7
  17. data/docs/_posts/{2018-06-26-auto_install_picrate.md → 2020-03-09-auto_install_picrate.md} +9 -6
  18. data/docs/_posts/2020-05-11-getting_started_manjaro.md +94 -0
  19. data/docs/about.md +1 -1
  20. data/lib/picrate.rb +1 -1
  21. data/lib/picrate/app.rb +11 -3
  22. data/lib/picrate/creators/parameters.rb +8 -8
  23. data/lib/picrate/creators/sketch_factory.rb +5 -3
  24. data/lib/picrate/helper_methods.rb +21 -21
  25. data/lib/picrate/helpers/numeric.rb +2 -0
  26. data/lib/picrate/library.rb +5 -1
  27. data/lib/picrate/library_loader.rb +2 -0
  28. data/lib/picrate/native_folder.rb +2 -1
  29. data/lib/picrate/native_loader.rb +3 -0
  30. data/lib/picrate/runner.rb +1 -0
  31. data/lib/picrate/version.rb +1 -1
  32. data/library/boids/boids.rb +17 -8
  33. data/library/chooser/chooser.rb +10 -9
  34. data/library/color_group/color_group.rb +2 -0
  35. data/library/control_panel/control_panel.rb +7 -4
  36. data/library/dxf/dxf.rb +2 -0
  37. data/library/library_proxy/library_proxy.rb +2 -0
  38. data/library/net/net.rb +2 -0
  39. data/library/slider/slider.rb +24 -23
  40. data/library/vector_utils/vector_utils.rb +4 -0
  41. data/library/video_event/video_event.rb +2 -0
  42. data/picrate.gemspec +13 -14
  43. data/pom.rb +28 -26
  44. data/pom.xml +18 -6
  45. data/src/main/java/monkstone/ColorUtil.java +1 -1
  46. data/src/main/java/monkstone/MathToolModule.java +1 -1
  47. data/src/main/java/monkstone/PicrateLibrary.java +8 -8
  48. data/src/main/java/monkstone/fastmath/Deglut.java +16 -16
  49. data/src/main/java/monkstone/filechooser/Chooser.java +1 -1
  50. data/src/main/java/monkstone/noise/SimplexNoise.java +3 -3
  51. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +1 -1
  52. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
  53. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +12 -12
  54. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +1 -1
  55. data/src/main/java/monkstone/slider/SliderBar.java +1 -1
  56. data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
  57. data/src/main/java/monkstone/slider/WheelHandler.java +1 -1
  58. data/src/main/java/monkstone/vecmath/package-info.java +1 -1
  59. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +1 -1
  60. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -1
  61. data/src/main/java/monkstone/videoevent/CaptureEvent.java +1 -1
  62. data/src/main/java/monkstone/videoevent/MovieEvent.java +1 -1
  63. data/src/main/java/monkstone/videoevent/package-info.java +1 -1
  64. data/src/main/java/processing/awt/PGraphicsJava2D.java +33 -36
  65. data/src/main/java/processing/awt/PImageAWT.java +377 -0
  66. data/src/main/java/processing/awt/PSurfaceAWT.java +0 -20
  67. data/src/main/java/processing/awt/ShimAWT.java +545 -0
  68. data/src/main/java/processing/core/PApplet.java +699 -1523
  69. data/src/main/java/processing/core/PConstants.java +180 -180
  70. data/src/main/java/processing/core/PFont.java +2 -2
  71. data/src/main/java/processing/core/PGraphics.java +190 -176
  72. data/src/main/java/processing/core/PImage.java +1536 -1721
  73. data/src/main/java/processing/core/PMatrix.java +39 -39
  74. data/src/main/java/processing/core/PSurface.java +69 -103
  75. data/src/main/java/processing/core/PSurfaceNone.java +29 -0
  76. data/src/main/java/processing/core/PVector.java +2 -2
  77. data/src/main/java/processing/data/FloatDict.java +251 -284
  78. data/src/main/java/processing/data/TableRow.java +32 -32
  79. data/src/main/java/processing/dxf/RawDXF.java +3 -3
  80. data/src/main/java/processing/net/Client.java +1 -1
  81. data/src/main/java/processing/opengl/PGL.java +1016 -4132
  82. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +223 -184
  83. data/src/main/java/processing/opengl/PJOGL.java +374 -1526
  84. data/src/main/java/processing/opengl/PShapeOpenGL.java +5 -6
  85. data/src/main/java/processing/opengl/PSurfaceJOGL.java +262 -147
  86. data/test/color_group_test.rb +4 -4
  87. data/test/deglut_spec_test.rb +2 -0
  88. data/test/helper_methods_test.rb +41 -13
  89. data/test/math_tool_test.rb +46 -37
  90. data/test/respond_to_test.rb +5 -3
  91. data/test/sketches/key_event.rb +2 -2
  92. data/test/sketches/library/my_library/my_library.rb +3 -0
  93. data/test/test_helper.rb +2 -0
  94. data/test/vecmath_spec_test.rb +30 -19
  95. data/vendors/Rakefile +8 -5
  96. data/vendors/{picrate_sketches.geany → geany.rb} +32 -7
  97. metadata +25 -46
  98. data/src/main/java/processing/opengl/shaders/LightVert-brcm.glsl +0 -154
  99. data/src/main/java/processing/opengl/shaders/LightVert-vc4.glsl +0 -154
  100. data/src/main/java/processing/opengl/shaders/TexLightVert-brcm.glsl +0 -160
  101. data/src/main/java/processing/opengl/shaders/TexLightVert-vc4.glsl +0 -160
@@ -6,7 +6,7 @@ unless defined? PICRATE_ROOT
6
6
  PICRATE_ROOT = File.dirname(__dir__)
7
7
  end
8
8
 
9
- Dir["#{PICRATE_ROOT}/lib/*.jar"].each do |jar|
9
+ Dir["#{PICRATE_ROOT}/lib/*.jar"].sort.each do |jar|
10
10
  require jar
11
11
  end
12
12
  require_relative 'picrate/app'
@@ -1,4 +1,6 @@
1
1
  # frozen_string_literal: false
2
+
3
+ require 'jruby'
2
4
  require_relative 'helper_methods'
3
5
  require_relative 'library_loader'
4
6
  # A wrapper module for the processing App
@@ -49,7 +51,10 @@ module Processing
49
51
 
50
52
  # All sketches extend this class
51
53
  class App < PApplet
52
- include Math, MathTool, HelperMethods, Render
54
+ include Render
55
+ include HelperMethods
56
+ include MathTool
57
+ include Math
53
58
  # Alias some methods for familiarity for Shoes coders.
54
59
  alias oval ellipse
55
60
  alias stroke_width stroke_weight
@@ -101,6 +106,7 @@ module Processing
101
106
  # Processing call them by their expected Java names.
102
107
  def method_added(method_name) #:nodoc:
103
108
  return unless METHODS_TO_ALIAS.key?(method_name)
109
+
104
110
  alias_method METHODS_TO_ALIAS[method_name], method_name
105
111
  end
106
112
  end
@@ -113,6 +119,7 @@ module Processing
113
119
  # Guard against invalid input.
114
120
  proxy_java_fields
115
121
  raise TypeError unless options.is_a?(Hash) && arguments.is_a?(Array)
122
+
116
123
  # Set up the sketch.
117
124
  super()
118
125
  post_initialize(options)
@@ -132,8 +139,7 @@ module Processing
132
139
  super(*args)
133
140
  end
134
141
 
135
- def post_initialize(_args)
136
- end
142
+ def post_initialize(_args); end
137
143
 
138
144
  def data_path(dat)
139
145
  dat_root = File.join(SKETCH_ROOT, 'data')
@@ -162,6 +168,7 @@ module Processing
162
168
  # Processing call them by their expected Java names.
163
169
  def method_added(method_name) #:nodoc:
164
170
  return unless METHODS_TO_ALIAS.key?(method_name)
171
+
165
172
  alias_method METHODS_TO_ALIAS[method_name], method_name
166
173
  end
167
174
  end
@@ -179,6 +186,7 @@ module Processing
179
186
 
180
187
  def method_missing(name, *args, &block)
181
188
  return Processing.app.send(name, *args) if Processing.app.respond_to? name
189
+
182
190
  super
183
191
  end
184
192
  end # Processing::Proxy
@@ -11,13 +11,13 @@ module Parameters
11
11
  PARAM = { 'sketch' =>
12
12
  { 'width' => 640, 'height' => 480, 'mode' => 'P2D' } }.freeze
13
13
 
14
- def self.write
15
- FileUtils.mkdir_p PATH
16
- File.write(FILE, PARAM.to_yaml)
17
- end
14
+ def self.write
15
+ FileUtils.mkdir_p PATH
16
+ File.write(FILE, PARAM.to_yaml)
17
+ end
18
18
 
19
- def self.read
20
- write unless File.exist?(FILE)
21
- YAML.load_file(FILE)
22
- end
19
+ def self.read
20
+ write unless File.exist?(FILE)
21
+ YAML.load_file(FILE)
23
22
  end
23
+ end
@@ -1,8 +1,10 @@
1
- require_relative 'sketch_writer'
1
+ # frozen_string_literal: true
2
2
 
3
+ require_relative 'sketch_writer'
4
+ # Sketch Factory
3
5
  class SketchFactory
4
- NAMES = %w[One Two Three]
5
- def initialize(argc)
6
+ NAMES = %w[One Two Three].freeze
7
+ def initialize(_argc)
6
8
  NAMES.each do |name|
7
9
  SketchWriter.new(File.basename(name, '.rb')).write
8
10
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: false
2
+
2
3
  # processing module wrapper
3
4
  require_relative 'helpers/numeric'
4
5
  module Processing
@@ -52,6 +53,7 @@ module Processing
52
53
 
53
54
  def color(*args)
54
55
  return super(*args) unless args.length == 1
56
+
55
57
  super(hex_color(args[0]))
56
58
  end
57
59
 
@@ -66,11 +68,8 @@ module Processing
66
68
  # Overrides Processing convenience function thread, which takes a String
67
69
  # arg (for a function) to more rubylike version, takes a block...
68
70
  def thread(&block)
69
- if block_given?
70
- Thread.new(&block)
71
- else
72
- raise ArgumentError, 'thread must be called with a block', caller
73
- end
71
+ warn 'you must provide a block' unless block_given?
72
+ Java::JavaLang::Thread.new(&block).start
74
73
  end
75
74
 
76
75
  # explicitly provide 'processing.org' min instance method
@@ -94,9 +93,9 @@ module Processing
94
93
  def dist(*args)
95
94
  case args.length
96
95
  when 4
97
- return dist2d(*args)
96
+ dist2d(*args)
98
97
  when 6
99
- return dist3d(*args)
98
+ dist3d(*args)
100
99
  else
101
100
  raise ArgumentError, 'takes 4 or 6 parameters'
102
101
  end
@@ -111,13 +110,13 @@ module Processing
111
110
  # Here's a convenient way to look for them.
112
111
  def find_method(method_name)
113
112
  reg = Regexp.new(method_name.to_s, true)
114
- methods.sort.select { |meth| reg.match(meth) }
113
+ methods.sort.select { |meth| reg.match?(meth) }
115
114
  end
116
115
 
117
116
  # Proxy over a list of Java declared fields that have the same name as
118
117
  # some methods. Add to this list as needed.
119
118
  def proxy_java_fields
120
- fields = %w(key frameRate mousePressed keyPressed)
119
+ fields = %w[key frameRate mousePressed keyPressed]
121
120
  methods = fields.map { |field| java_class.declared_field(field) }
122
121
  @declared_fields = Hash[fields.zip(methods)]
123
122
  end
@@ -163,6 +162,7 @@ module Processing
163
162
  # frame_rate needs to support reading and writing
164
163
  def frame_rate(fps = nil)
165
164
  return @declared_fields['frameRate'].value(java_self) unless fps
165
+
166
166
  super(fps)
167
167
  end
168
168
 
@@ -178,19 +178,17 @@ module Processing
178
178
 
179
179
  private
180
180
 
181
- INTEGER_COL = -> (x) { x.is_a?(Integer) }
182
- STRING_COL = -> (x) { x.is_a?(String) }
183
- FLOAT_COL = -> (x) { x.is_a?(Float) }
184
181
  # parse single argument color int/double/String
185
- def hex_color(a)
186
- case a
187
- when INTEGER_COL
188
- Java::Monkstone::ColorUtil.colorLong(a)
189
- when STRING_COL
190
- return Java::Monkstone::ColorUtil.colorString(a) if a =~ /#\h+/
191
- raise StandardError, 'Dodgy Hexstring'
192
- when FLOAT_COL
193
- Java::Monkstone::ColorUtil.colorDouble(a)
182
+ def hex_color(arg)
183
+ case arg
184
+ when Integer
185
+ Java::Monkstone::ColorUtil.colorLong(arg)
186
+ when String
187
+ raise StandardError, 'Dodgy Hexstring' unless arg.match(/#\h{6}$/)
188
+
189
+ Java::Monkstone::ColorUtil.colorString(arg)
190
+ when Float
191
+ Java::Monkstone::ColorUtil.colorDouble(arg)
194
192
  else
195
193
  raise StandardError, 'Dodgy Color Conversion'
196
194
  end
@@ -200,6 +198,7 @@ module Processing
200
198
  dx = args[0] - args[2]
201
199
  dy = args[1] - args[3]
202
200
  return 0 if dx.abs < EPSILON && dy.abs < EPSILON
201
+
203
202
  Math.hypot(dx, dy)
204
203
  end
205
204
 
@@ -208,6 +207,7 @@ module Processing
208
207
  dy = args[1] - args[4]
209
208
  dz = args[2] - args[5]
210
209
  return 0 if dx.abs < EPSILON && dy.abs < EPSILON && dz.abs < EPSILON
210
+
211
211
  Math.sqrt(dx * dx + dy * dy + dz * dz)
212
212
  end
213
213
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Numeric #:nodoc:
2
4
  def degrees
3
5
  self * 57.29577951308232
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'native_folder'
2
4
  require_relative 'native_loader'
3
5
  require 'pathname'
@@ -18,6 +20,7 @@ class Library
18
20
  return if (@path = Pathname.new(
19
21
  File.join(PICRATE_ROOT, 'library', name, "#{name}.rb")
20
22
  )).exist?
23
+
21
24
  locate_java
22
25
  end
23
26
 
@@ -46,10 +49,11 @@ class Library
46
49
  end
47
50
 
48
51
  def load_jars
49
- Dir.glob("#{dir}/*.jar").each do |jar|
52
+ Dir.glob("#{dir}/*.jar").sort.each do |jar|
50
53
  require jar
51
54
  end
52
55
  return true unless native_binaries?
56
+
53
57
  add_binaries_to_classpath
54
58
  end
55
59
 
@@ -33,10 +33,12 @@ module Processing
33
33
 
34
34
  def loader(name)
35
35
  return true if @loaded_libraries.include?(name)
36
+
36
37
  fname = name.to_s
37
38
  library = Library.new(fname)
38
39
  library.locate
39
40
  return require_library(library, name) if library.ruby?
41
+
40
42
  warn("Not found library: #{fname}") unless library.exist?
41
43
  load_jars(library, name)
42
44
  end
@@ -7,7 +7,7 @@ class NativeFolder
7
7
 
8
8
  LINUX_FORMAT = 'linux%s'.freeze
9
9
  ARM32 = '-armv6hf'.freeze
10
- # ARM64 = '-aarch64'.freeze
10
+ ARM64 = '-aarch64'.freeze
11
11
 
12
12
  def initialize
13
13
  @os = RbConfig::CONFIG['host_os'].downcase
@@ -18,6 +18,7 @@ class NativeFolder
18
18
  if /linux/.match?(os)
19
19
  return format(LINUX_FORMAT, '64') if /amd64/.match?(bit)
20
20
  return format(LINUX_FORMAT, ARM32) if /arm/.match?(bit)
21
+ return format(LINUX_FORMAT, ARM64) if /aarch/.match?(bit)
21
22
  end
22
23
  raise RuntimeError, "Unsupported Architecture"
23
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This class knows how to dynamically set the 'java' native library path
2
4
  # It might not work with java 9?
3
5
  class NativeLoader
@@ -21,6 +23,7 @@ class NativeLoader
21
23
  field = JC::Class.for_name('java.lang.ClassLoader')
22
24
  .get_declared_field('sys_paths')
23
25
  return unless field
26
+
24
27
  field.accessible = true # some jruby magic
25
28
  field.set(JC::Class.for_name('java.lang.System').get_class_loader, nil)
26
29
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: false
2
+
2
3
  require 'optparse'
3
4
  require_relative 'version'
4
5
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PiCrate
4
- VERSION = '1.2.4'
4
+ VERSION = '2.1.1'
5
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Boids -- after Tom de Smedt.
3
4
  # See his Python version: http://nodebox.net/code/index.php/Boids
4
5
  # This is an example of how a pure-Ruby library can work. Original for
@@ -8,7 +9,8 @@ class Boid
8
9
  attr_reader :boids
9
10
  attr_accessor :vel, :pos, :is_perching, :perch_time
10
11
  def initialize(boids, pos)
11
- @boids, @flock = boids, boids
12
+ @boids = boids
13
+ @flock = boids
12
14
  @pos = pos
13
15
  @vel = Vec2D.new
14
16
  @is_perching = false
@@ -54,6 +56,7 @@ class Boid
54
56
  # Tweet, Tweet! The boid police will bust you for breaking the speed limit.
55
57
  most = [vel.x.abs, vel.y.abs].max
56
58
  return if most < max
59
+
57
60
  scale = max / most.to_f
58
61
  @vel *= scale
59
62
  end
@@ -76,7 +79,7 @@ class Boids
76
79
  extend Forwardable
77
80
  def_delegators(:@boids, :reject, :<<, :each, :shuffle!, :length, :next)
78
81
 
79
- attr_reader :has_goal, :perch, :perch_tm, :perch_y
82
+ attr_reader :has_goal, :perchance, :perch_tm, :perch_y
80
83
 
81
84
  def initialize
82
85
  @boids = []
@@ -89,15 +92,19 @@ class Boids
89
92
 
90
93
  def setup(n, x, y, w, h)
91
94
  n.times do
92
- dx, dy = rand(w), rand(h)
95
+ dx = rand(w)
96
+ dy = rand(h)
93
97
  self << Boid.new(self, Vec2D.new(x + dx, y + dy))
94
98
  end
95
- @x, @y, @w, @h = x, y, w, h
99
+ @x = x
100
+ @y = y
101
+ @w = w
102
+ @h = h
96
103
  @scattered = false
97
104
  @scatter = 0.005
98
105
  @scatter_time = 50.0
99
106
  @scatter_i = 0.0
100
- @perch = 1.0 # Lower this number to divebomb.
107
+ @perchance = 1.0 # Lower this number to divebomb.
101
108
  @perch_y = h
102
109
  @perch_tm = -> { 25.0 + rand(50.0) }
103
110
  @has_goal = false
@@ -118,11 +125,11 @@ class Boids
118
125
  def perch(ground = nil, chance = 1.0, frames = nil)
119
126
  @perch_tm = frames.nil? ? -> { 25.0 + rand(50.0) } : frames
120
127
  @perch_y = ground.nil? ? @h : ground
121
- @perch = chance
128
+ @perchance = chance
122
129
  end
123
130
 
124
131
  def no_perch
125
- @perch = 0.0
132
+ @perchance= 0.0
126
133
  end
127
134
 
128
135
  def reset_goal(target)
@@ -145,13 +152,15 @@ class Boids
145
152
 
146
153
  def constrain
147
154
  # Put them boids in a cage.
148
- dx, dy = @w * 0.1, @h * 0.1
155
+ dx = @w * 0.1
156
+ dy = @h * 0.1
149
157
  each do |b|
150
158
  b.vel.x += rand(dx) if b.pos.x < @x - dx
151
159
  b.vel.y += rand(dy) if b.pos.y < @y - dy
152
160
  b.vel.x -= rand(dx) if b.pos.x > @x + @w + dx
153
161
  b.vel.y -= rand(dy) if b.pos.y > @y + @h + dy
154
162
  next unless b.pos.y > perch_y && rand < perch
163
+
155
164
  b.pos.y = perch_y
156
165
  b.vel.y = b.vel.y.abs * -0.2
157
166
  b.is_perching = true
@@ -1,18 +1,19 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Usage:
3
4
  # load_library :chooser
4
- #
5
+ #
5
6
  # def setup
6
- # java_signature 'void selectInput(String, String)'
7
- # selectInput('Select a file to process:', 'fileSelected')
7
+ # java_signature 'void selectInput(String, String)'
8
+ # selectInput('Select a file to process:', 'fileSelected')
8
9
  # end
9
- #
10
+ #
10
11
  # def fileSelected(selection)
11
- # if selection.nil?
12
- # puts 'Window was closed or the user hit cancel.'
13
- # else
14
- # puts format('User selected %s', selection.get_absolute_path)
15
- # end
12
+ # if selection.nil?
13
+ # puts 'Window was closed or the user hit cancel.'
14
+ # else
15
+ # puts format('User selected %s', selection.get_absolute_path)
16
+ # end
16
17
  # end
17
18
  class Processing::App
18
19
  include Java::MonkstoneFilechooser::Chooser
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  java_import Java::Monkstone::ColorUtil
2
4
 
3
5
  # class wraps a java color array (of signed int), supports shuffle!, last and
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Here's a little library for quickly hooking up controls to sketches.
2
4
  # For messing with the parameters and such.
3
5
  # These controls will set instance variables on the sketches.
@@ -25,7 +27,7 @@ module ControlPanel
25
27
  add_change_listener do
26
28
  update_label(label, name, value)
27
29
  ControlPanel.app_value(name, value)
28
- proc.call(value) if proc
30
+ proc&.call(value)
29
31
  end
30
32
  ControlPanel.app_value(name, val)
31
33
  end
@@ -49,7 +51,7 @@ module ControlPanel
49
51
  control_panel.add_element(self, name)
50
52
  add_action_listener do
51
53
  ControlPanel.app_value(name, value) unless value.nil?
52
- proc.call(value) if proc
54
+ proc&.call(value)
53
55
  end
54
56
  set_selected_index(initial_value ? elements.index(initial_value) : 0)
55
57
  end
@@ -69,7 +71,7 @@ module ControlPanel
69
71
  control_panel.add_element(self, name, false)
70
72
  add_action_listener do
71
73
  ControlPanel.app_value(name, value)
72
- proc.call(value) if proc
74
+ proc&.call(value)
73
75
  end
74
76
  end
75
77
 
@@ -87,7 +89,7 @@ module ControlPanel
87
89
  control_panel.add_element(self, name, false, true)
88
90
  add_action_listener do
89
91
  Processing.app.send(name)
90
- proc.call(value) if proc
92
+ proc&.call(value)
91
93
  end
92
94
  end
93
95
  end
@@ -171,6 +173,7 @@ module ControlPanel
171
173
  def control_panel
172
174
  @control_panel ||= ControlPanel::Panel.new
173
175
  return @control_panel unless block_given?
176
+
174
177
  yield(@control_panel)
175
178
  @control_panel.display
176
179
  @control_panel.set_visible true