glimmer-dsl-swt 4.18.6.2 → 4.18.7.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/README.md +4 -4
- data/VERSION +1 -1
- data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +64 -6
- data/docs/reference/GLIMMER_SAMPLES.md +71 -0
- data/glimmer-dsl-swt.gemspec +16 -6
- data/lib/glimmer/dsl/swt/animation_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/custom_shape_expression.rb +61 -0
- data/lib/glimmer/dsl/swt/custom_widget_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/dsl.rb +1 -0
- data/lib/glimmer/dsl/swt/expand_item_expression.rb +4 -4
- data/lib/glimmer/dsl/swt/image_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/multiply_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/shape_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/transform_expression.rb +1 -1
- data/lib/glimmer/dsl/swt/widget_expression.rb +2 -1
- data/lib/glimmer/swt/custom/shape.rb +473 -180
- data/lib/glimmer/swt/custom/shape/image.rb +7 -9
- data/lib/glimmer/swt/custom/shape/path.rb +38 -29
- data/lib/glimmer/swt/custom/shape/path_segment.rb +21 -19
- data/lib/glimmer/swt/custom/shape/polygon.rb +24 -8
- data/lib/glimmer/swt/custom/shape/polyline.rb +5 -0
- data/lib/glimmer/swt/custom/shape/rectangle.rb +10 -19
- data/lib/glimmer/swt/display_proxy.rb +1 -1
- data/lib/glimmer/swt/message_box_proxy.rb +1 -1
- data/lib/glimmer/swt/shell_proxy.rb +1 -1
- data/lib/glimmer/swt/tab_folder_proxy.rb +52 -0
- data/lib/glimmer/swt/transform_proxy.rb +1 -1
- data/lib/glimmer/swt/widget_proxy.rb +1 -1
- data/lib/glimmer/ui/custom_shape.rb +281 -0
- data/samples/elaborate/meta_sample.rb +5 -5
- data/samples/elaborate/metronome.rb +177 -0
- data/samples/elaborate/stock_ticker.rb +0 -6
- data/samples/elaborate/tetris.rb +1 -12
- data/samples/elaborate/tetris/model/game.rb +3 -0
- data/samples/elaborate/tetris/view/bevel.rb +78 -0
- data/samples/elaborate/tetris/view/block.rb +6 -29
- data/samples/hello/hello_canvas.rb +3 -0
- data/samples/hello/hello_canvas_animation_data_binding.rb +66 -0
- data/samples/hello/hello_canvas_data_binding.rb +24 -3
- data/samples/hello/hello_canvas_path.rb +1 -1
- data/samples/hello/hello_custom_shape.rb +78 -0
- data/samples/hello/hello_shape.rb +71 -0
- data/samples/hello/hello_spinner.rb +7 -2
- data/sounds/metronome-down.wav +0 -0
- data/sounds/metronome-up.wav +0 -0
- metadata +14 -4
@@ -0,0 +1,61 @@
|
|
1
|
+
# Copyright (c) 2007-2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'glimmer'
|
23
|
+
require 'glimmer/dsl/expression'
|
24
|
+
require 'glimmer/dsl/parent_expression'
|
25
|
+
require 'glimmer/dsl/top_level_expression'
|
26
|
+
require 'glimmer/ui/custom_shape'
|
27
|
+
require 'glimmer/swt/custom/code_text'
|
28
|
+
require 'glimmer/swt/custom/checkbox_group'
|
29
|
+
|
30
|
+
module Glimmer
|
31
|
+
module DSL
|
32
|
+
module SWT
|
33
|
+
class CustomShapeExpression < Expression
|
34
|
+
# TODO Make custom shapes automatically generate static expressions
|
35
|
+
include ParentExpression
|
36
|
+
include TopLevelExpression
|
37
|
+
|
38
|
+
def can_interpret?(parent, keyword, *args, &block)
|
39
|
+
!!UI::CustomShape.for(keyword)
|
40
|
+
end
|
41
|
+
|
42
|
+
def interpret(parent, keyword, *args, &block)
|
43
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
44
|
+
UI::CustomShape.for(keyword).new(parent, *args, options, &block).tap do |new_custom_shape|
|
45
|
+
new_custom_shape.body_root.paint_pixel_by_pixel(&block) if block&.parameters&.count == 2
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_content(parent, keyword, *args, &block)
|
50
|
+
# TODO consider avoiding source_location
|
51
|
+
return if block&.parameters&.count == 2
|
52
|
+
if block.source_location == parent.content&.__getobj__.source_location
|
53
|
+
parent.content.call(parent) unless parent.content.called?
|
54
|
+
else
|
55
|
+
super
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -51,7 +51,7 @@ module Glimmer
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
def add_content(parent, &block)
|
54
|
+
def add_content(parent, keyword, *args, &block)
|
55
55
|
# TODO consider avoiding source_location
|
56
56
|
return if block&.parameters&.count == 2
|
57
57
|
if block.source_location == parent.content&.__getobj__.source_location
|
data/lib/glimmer/dsl/swt/dsl.rb
CHANGED
@@ -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
|
@@ -49,7 +49,7 @@ module Glimmer
|
|
49
49
|
Glimmer::SWT::ExpandItemProxy.new(parent, args)
|
50
50
|
end
|
51
51
|
|
52
|
-
def add_content(parent, &block)
|
52
|
+
def add_content(parent, keyword, *args, &block)
|
53
53
|
super
|
54
54
|
parent.post_add_content
|
55
55
|
end
|
@@ -46,7 +46,7 @@ module Glimmer
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def add_content(parent, &block)
|
49
|
+
def add_content(parent, keyword, *args, &block)
|
50
50
|
return if block&.parameters&.count == 2
|
51
51
|
super
|
52
52
|
parent.post_add_content
|
@@ -69,3 +69,4 @@ require 'glimmer/swt/table_column_proxy'
|
|
69
69
|
require 'glimmer/swt/sash_form_proxy'
|
70
70
|
require 'glimmer/swt/styled_text_proxy'
|
71
71
|
require 'glimmer/swt/date_time_proxy'
|
72
|
+
require 'glimmer/swt/tab_folder_proxy'
|
@@ -73,6 +73,7 @@ module Glimmer
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def valid?(parent, keyword, *args, &block)
|
76
|
+
return true if keyword.to_s == 'shape'
|
76
77
|
gc_instance_methods.include?(method_name(keyword, arg_options(args))) ||
|
77
78
|
constants.include?(keyword.to_s.camelcase(:upper).to_sym)
|
78
79
|
end
|
@@ -126,7 +127,7 @@ module Glimmer
|
|
126
127
|
end
|
127
128
|
end
|
128
129
|
|
129
|
-
attr_reader :drawable, :parent, :name, :args, :options, :shapes
|
130
|
+
attr_reader :drawable, :parent, :name, :args, :options, :shapes, :properties
|
130
131
|
attr_accessor :extent
|
131
132
|
|
132
133
|
def initialize(parent, keyword, *args, &property_block)
|
@@ -134,7 +135,7 @@ module Glimmer
|
|
134
135
|
@drawable = @parent.is_a?(Drawable) ? @parent : @parent.drawable
|
135
136
|
@name = keyword
|
136
137
|
@options = self.class.arg_options(args, extract: true)
|
137
|
-
@method_name = self.class.method_name(keyword, @options)
|
138
|
+
@method_name = self.class.method_name(keyword, @options) unless keyword.to_s == 'shape'
|
138
139
|
@args = args
|
139
140
|
@properties = {}
|
140
141
|
@shapes = [] # nested shapes
|
@@ -170,7 +171,13 @@ module Glimmer
|
|
170
171
|
|
171
172
|
# The bounding box top-left x, y, width, height in absolute positioning
|
172
173
|
def bounds
|
173
|
-
|
174
|
+
bounds_dependencies = [absolute_x, absolute_y, calculated_width, calculated_height]
|
175
|
+
if bounds_dependencies != @bounds_dependencies
|
176
|
+
# avoid repeating calculations
|
177
|
+
absolute_x, absolute_y, calculated_width, calculated_height = @bounds_dependencies = bounds_dependencies
|
178
|
+
@bounds = org.eclipse.swt.graphics.Rectangle.new(absolute_x, absolute_y, calculated_width, calculated_height)
|
179
|
+
end
|
180
|
+
@bounds
|
174
181
|
end
|
175
182
|
|
176
183
|
# The bounding box top-left x and y
|
@@ -180,7 +187,13 @@ module Glimmer
|
|
180
187
|
|
181
188
|
# The bounding box width and height (as a Point object with x being width and y being height)
|
182
189
|
def size
|
183
|
-
|
190
|
+
size_dependencies = [calculated_width, calculated_height]
|
191
|
+
if size_dependencies != @size_dependencies
|
192
|
+
# avoid repeating calculations
|
193
|
+
calculated_width, calculated_height = @size_dependencies = size_dependencies
|
194
|
+
@size = org.eclipse.swt.graphics.Point.new(calculated_width, calculated_height)
|
195
|
+
end
|
196
|
+
@size
|
184
197
|
end
|
185
198
|
|
186
199
|
def extent
|
@@ -213,12 +226,12 @@ module Glimmer
|
|
213
226
|
def move_by(x_delta, y_delta)
|
214
227
|
if respond_to?(:x) && respond_to?(:y) && respond_to?(:x=) && respond_to?(:y=)
|
215
228
|
if default_x?
|
216
|
-
self.
|
229
|
+
self.x_delta += x_delta
|
217
230
|
else
|
218
231
|
self.x += x_delta
|
219
232
|
end
|
220
233
|
if default_y?
|
221
|
-
self.
|
234
|
+
self.y_delta += y_delta
|
222
235
|
else
|
223
236
|
self.y += y_delta
|
224
237
|
end
|
@@ -227,7 +240,7 @@ module Glimmer
|
|
227
240
|
|
228
241
|
def content(&block)
|
229
242
|
Glimmer::SWT::DisplayProxy.instance.auto_exec do
|
230
|
-
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::ShapeExpression.new, &block)
|
243
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::ShapeExpression.new, @name, &block)
|
231
244
|
calculated_args_changed!(children: false)
|
232
245
|
end
|
233
246
|
end
|
@@ -248,7 +261,8 @@ module Glimmer
|
|
248
261
|
end
|
249
262
|
end
|
250
263
|
|
251
|
-
def apply_property_arg_conversions(
|
264
|
+
def apply_property_arg_conversions(property, args)
|
265
|
+
method_name = attribute_setter(property)
|
252
266
|
args = args.dup
|
253
267
|
the_java_method = org.eclipse.swt.graphics.GC.java_class.declared_instance_methods.detect {|m| m.name == method_name}
|
254
268
|
return args if the_java_method.nil?
|
@@ -262,10 +276,23 @@ module Glimmer
|
|
262
276
|
args[0] = args.dup
|
263
277
|
args[1..-1] = []
|
264
278
|
end
|
279
|
+
if method_name.to_s == 'setAntialias' && [nil, true, false].include?(args.first)
|
280
|
+
args[0] = case args.first
|
281
|
+
when true
|
282
|
+
args[0] = :on
|
283
|
+
when false
|
284
|
+
args[0] = :off
|
285
|
+
when nil
|
286
|
+
args[0] = :default
|
287
|
+
end
|
288
|
+
end
|
265
289
|
if args.first.is_a?(Symbol) || args.first.is_a?(::String)
|
266
290
|
if the_java_method.parameter_types.first == org.eclipse.swt.graphics.Color.java_class
|
267
291
|
args[0] = ColorProxy.new(args[0])
|
268
292
|
end
|
293
|
+
if method_name.to_s == 'setLineStyle'
|
294
|
+
args[0] = "line_#{args[0]}" if !args[0].to_s.downcase.start_with?('line_')
|
295
|
+
end
|
269
296
|
if the_java_method.parameter_types.first == Java::int.java_class
|
270
297
|
args[0] = SWTProxy.constant(args[0])
|
271
298
|
end
|
@@ -293,10 +320,10 @@ module Glimmer
|
|
293
320
|
end
|
294
321
|
@pattern_args ||= {}
|
295
322
|
pattern_type = method_name.to_s.match(/set(.+)Pattern/)[1]
|
296
|
-
if args.first.is_a?(Pattern)
|
323
|
+
if args.first.is_a?(org.eclipse.swt.graphics.Pattern)
|
297
324
|
new_args = @pattern_args[pattern_type]
|
298
325
|
else
|
299
|
-
new_args = args.first.is_a?(Display) ? args : ([DisplayProxy.instance.swt_display] + args)
|
326
|
+
new_args = args.first.is_a?(org.eclipse.swt.widgets.Display) ? args : ([DisplayProxy.instance.swt_display] + args)
|
300
327
|
@pattern_args[pattern_type] = new_args.dup
|
301
328
|
end
|
302
329
|
args[0] = pattern(*new_args, type: pattern_type)
|
@@ -335,10 +362,16 @@ module Glimmer
|
|
335
362
|
end
|
336
363
|
|
337
364
|
def apply_shape_arg_defaults!
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
365
|
+
if current_parameter_name?(:dest_x) && dest_x.nil?
|
366
|
+
self.dest_x = :default
|
367
|
+
elsif parameter_name?(:x) && x.nil?
|
368
|
+
self.x = :default
|
369
|
+
end
|
370
|
+
if current_parameter_name?(:dest_y) && dest_y.nil?
|
371
|
+
self.dest_y = :default
|
372
|
+
elsif parameter_name?(:y) && y.nil?
|
373
|
+
self.y = :default
|
374
|
+
end
|
342
375
|
self.width = :default if current_parameter_name?(:width) && width.nil?
|
343
376
|
self.height = :default if current_parameter_name?(:height) && height.nil?
|
344
377
|
if @name.include?('rectangle') && round? && @args.size.between?(4, 5)
|
@@ -383,7 +416,7 @@ module Glimmer
|
|
383
416
|
|
384
417
|
# parameter names for arguments to pass to SWT GC.xyz method for rendering shape (e.g. draw_image(image, x, y) yields :image, :x, :y parameter names)
|
385
418
|
def parameter_names
|
386
|
-
[]
|
419
|
+
[:x, :y, :width, :height]
|
387
420
|
end
|
388
421
|
|
389
422
|
# subclasses may override to specify location parameter names if different from x and y (e.g. all polygon points are location parameters)
|
@@ -408,6 +441,10 @@ module Glimmer
|
|
408
441
|
parameter_names.index(attribute_name.to_s.to_sym)
|
409
442
|
end
|
410
443
|
|
444
|
+
def get_parameter_attribute(attribute_name)
|
445
|
+
@args[parameter_index(ruby_attribute_getter(attribute_name))]
|
446
|
+
end
|
447
|
+
|
411
448
|
def set_parameter_attribute(attribute_name, *args)
|
412
449
|
@args[parameter_index(ruby_attribute_getter(attribute_name))] = args.size == 1 ? args.first : args
|
413
450
|
end
|
@@ -423,31 +460,43 @@ module Glimmer
|
|
423
460
|
args.pop if !options.nil? && !options[:redraw].nil?
|
424
461
|
perform_redraw = @perform_redraw
|
425
462
|
perform_redraw = options[:redraw] if perform_redraw.nil? && !options.nil?
|
426
|
-
perform_redraw
|
463
|
+
perform_redraw ||= true
|
464
|
+
property_change = nil
|
465
|
+
ruby_attribute_getter_name = ruby_attribute_getter(attribute_name)
|
466
|
+
ruby_attribute_setter_name = ruby_attribute_setter(attribute_name)
|
427
467
|
if parameter_name?(attribute_name)
|
428
|
-
|
429
|
-
|
430
|
-
|
468
|
+
return if ruby_attribute_getter_name == (args.size == 1 ? args.first : args)
|
469
|
+
set_parameter_attribute(ruby_attribute_getter_name, *args)
|
470
|
+
elsif (respond_to?(attribute_name, super: true) and respond_to?(ruby_attribute_setter_name, super: true))
|
471
|
+
return if self.send(ruby_attribute_getter_name) == (args.size == 1 ? args.first : args)
|
472
|
+
self.send(ruby_attribute_setter_name, *args)
|
431
473
|
else
|
432
|
-
|
474
|
+
# TODO consider this optimization of preconverting args (removing conversion from other methods) to reject equal args
|
475
|
+
args = apply_property_arg_conversions(ruby_attribute_getter_name, args)
|
476
|
+
return if @properties[ruby_attribute_getter_name] == args
|
477
|
+
@properties[ruby_attribute_getter_name] = args
|
478
|
+
property_change = true
|
433
479
|
end
|
434
480
|
if @content_added && perform_redraw && !drawable.is_disposed
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
481
|
+
redrawn = false
|
482
|
+
unless property_change
|
483
|
+
@calculated_paint_args = false
|
484
|
+
if is_a?(PathSegment)
|
485
|
+
root_path&.calculated_path_args = @calculated_path_args = false
|
486
|
+
calculated_args_changed!
|
487
|
+
root_path&.calculated_args_changed!
|
488
|
+
end
|
489
|
+
if location_parameter_names.map(&:to_s).include?(ruby_attribute_getter_name)
|
490
|
+
calculated_args_changed!(children: true)
|
491
|
+
redrawn = parent.calculated_args_changed_for_defaults! if parent.is_a?(Shape)
|
492
|
+
end
|
493
|
+
if ['width', 'height'].include?(ruby_attribute_getter_name)
|
494
|
+
redrawn = calculated_args_changed_for_defaults!
|
495
|
+
end
|
448
496
|
end
|
449
497
|
# TODO consider redrawing an image proxy's gc in the future
|
450
|
-
|
498
|
+
# TODO consider ensuring only a single redraw happens for a hierarchy of nested shapes
|
499
|
+
drawable.redraw unless redrawn || drawable.is_a?(ImageProxy)
|
451
500
|
end
|
452
501
|
end
|
453
502
|
|
@@ -458,10 +507,25 @@ module Glimmer
|
|
458
507
|
elsif (respond_to?(attribute_name, super: true) and respond_to?(ruby_attribute_setter(attribute_name), super: true))
|
459
508
|
self.send(attribute_name)
|
460
509
|
else
|
461
|
-
@properties
|
510
|
+
@properties[attribute_name.to_s]
|
462
511
|
end
|
463
512
|
end
|
464
513
|
|
514
|
+
# Sets data just like SWT widgets
|
515
|
+
def set_data(key=nil, value)
|
516
|
+
@data ||= {}
|
517
|
+
@data[key] = value
|
518
|
+
end
|
519
|
+
alias setData set_data # for compatibility with SWT APIs
|
520
|
+
|
521
|
+
# Gets data just like SWT widgets
|
522
|
+
def get_data(key=nil)
|
523
|
+
@data ||= {}
|
524
|
+
@data[key]
|
525
|
+
end
|
526
|
+
alias getData get_data # for compatibility with SWT APIs
|
527
|
+
alias data get_data # for compatibility with SWT APIs
|
528
|
+
|
465
529
|
def method_missing(method_name, *args, &block)
|
466
530
|
if method_name.to_s.end_with?('=')
|
467
531
|
set_attribute(method_name, *args)
|
@@ -503,7 +567,7 @@ module Glimmer
|
|
503
567
|
pattern_args(type: 'foreground')
|
504
568
|
end
|
505
569
|
|
506
|
-
def dispose(dispose_images: true, dispose_patterns: true)
|
570
|
+
def dispose(dispose_images: true, dispose_patterns: true, redraw: true)
|
507
571
|
shapes.each { |shape| shape.is_a?(Shape::Path) && shape.dispose }
|
508
572
|
if dispose_patterns
|
509
573
|
@background_pattern&.dispose
|
@@ -516,10 +580,80 @@ module Glimmer
|
|
516
580
|
@image = nil
|
517
581
|
end
|
518
582
|
@parent.shapes.delete(self)
|
583
|
+
drawable.redraw if redraw && !drawable.is_a?(ImageProxy)
|
584
|
+
end
|
585
|
+
|
586
|
+
# Indicate if this is a container shape (meaning a shape bag that is just there to contain nested shapes, but doesn't render anything of its own)
|
587
|
+
def container?
|
588
|
+
@name == 'shape'
|
589
|
+
end
|
590
|
+
|
591
|
+
# Indicate if this is a composite shape (meaning a shape that contains nested shapes like a rectangle with ovals inside it)
|
592
|
+
def composite?
|
593
|
+
!shapes.empty?
|
594
|
+
end
|
595
|
+
|
596
|
+
# ordered from closest to farthest parent
|
597
|
+
def parent_shapes
|
598
|
+
if @parent_shapes.nil?
|
599
|
+
if parent.is_a?(Drawable)
|
600
|
+
@parent_shapes = []
|
601
|
+
else
|
602
|
+
@parent_shapes = parent.parent_shapes + [parent]
|
603
|
+
end
|
604
|
+
end
|
605
|
+
@parent_shapes
|
606
|
+
end
|
607
|
+
|
608
|
+
# ordered from closest to farthest parent
|
609
|
+
def parent_shape_containers
|
610
|
+
if @parent_shape_containers.nil?
|
611
|
+
if parent.is_a?(Drawable)
|
612
|
+
@parent_shape_containers = []
|
613
|
+
elsif !parent.container?
|
614
|
+
@parent_shape_containers = parent.parent_shape_containers
|
615
|
+
else
|
616
|
+
@parent_shape_containers = parent.parent_shape_containers + [parent]
|
617
|
+
end
|
618
|
+
end
|
619
|
+
@parent_shape_containers
|
620
|
+
end
|
621
|
+
|
622
|
+
# ordered from closest to farthest parent
|
623
|
+
def parent_shape_composites
|
624
|
+
if @parent_shape_composites.nil?
|
625
|
+
if parent.is_a?(Drawable)
|
626
|
+
@parent_shape_composites = []
|
627
|
+
elsif !parent.container?
|
628
|
+
@parent_shape_composites = parent.parent_shape_composites
|
629
|
+
else
|
630
|
+
@parent_shape_composites = parent.parent_shape_composites + [parent]
|
631
|
+
end
|
632
|
+
end
|
633
|
+
@parent_shape_composites
|
634
|
+
end
|
635
|
+
|
636
|
+
def convert_properties!
|
637
|
+
if @properties != @converted_properties
|
638
|
+
@properties.each do |property, args|
|
639
|
+
@properties[property] = apply_property_arg_conversions(property, args)
|
640
|
+
end
|
641
|
+
@converted_properties = @properties.dup
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
def converted_properties
|
646
|
+
convert_properties!
|
647
|
+
@properties
|
648
|
+
end
|
649
|
+
|
650
|
+
def all_parent_properties
|
651
|
+
@all_parent_properties ||= parent_shape_containers.reverse.reduce({}) do |all_properties, parent_shape|
|
652
|
+
all_properties.merge(parent_shape.converted_properties)
|
653
|
+
end
|
519
654
|
end
|
520
655
|
|
521
656
|
def paint(paint_event)
|
522
|
-
# pre-paint children an extra-time first when default width/height need to be calculated for defaults
|
523
657
|
paint_children(paint_event) if default_width? || default_height?
|
524
658
|
paint_self(paint_event)
|
525
659
|
# re-paint children from scratch in the special case of pre-calculating parent width/height to re-center within new parent dimensions
|
@@ -532,28 +666,30 @@ module Glimmer
|
|
532
666
|
|
533
667
|
def paint_self(paint_event)
|
534
668
|
@painting = true
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
args.first.
|
669
|
+
unless container?
|
670
|
+
calculate_paint_args!
|
671
|
+
@original_gc_properties = {} # this stores GC properties before making calls to updates TODO avoid using in pixel graphics
|
672
|
+
@properties.each do |property, args|
|
673
|
+
method_name = attribute_setter(property)
|
674
|
+
@original_gc_properties[method_name] = paint_event.gc.send(method_name.sub('set', 'get')) rescue nil
|
675
|
+
paint_event.gc.send(method_name, *args)
|
676
|
+
if property == 'transform' && args.first.is_a?(TransformProxy)
|
677
|
+
args.first.swt_transform.dispose
|
678
|
+
end
|
543
679
|
end
|
680
|
+
ensure_extent(paint_event)
|
544
681
|
end
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
paint_event.gc.send(method_name, value)
|
682
|
+
@calculated_args ||= calculate_args!
|
683
|
+
unless container?
|
684
|
+
# paint unless parent's calculated args are not calculated yet, meaning it is about to get painted and trigger a paint on this child anyways
|
685
|
+
paint_event.gc.send(@method_name, *@calculated_args) unless (parent.is_a?(Shape) && !parent.calculated_args?)
|
686
|
+
@original_gc_properties.each do |method_name, value|
|
687
|
+
paint_event.gc.send(method_name, value)
|
688
|
+
end
|
553
689
|
end
|
554
690
|
@painting = false
|
555
691
|
rescue => e
|
556
|
-
Glimmer::Config.logger.error {"Error encountered in painting shape (#{self.inspect}) with calculated args (#{@calculated_args}) and args (#{@args})"}
|
692
|
+
Glimmer::Config.logger.error {"Error encountered in painting shape (#{self.inspect}) with method (#{@method_name}) calculated args (#{@calculated_args}) and args (#{@args})"}
|
557
693
|
Glimmer::Config.logger.error {e.full_message}
|
558
694
|
ensure
|
559
695
|
@painting = false
|
@@ -590,26 +726,27 @@ module Glimmer
|
|
590
726
|
end
|
591
727
|
end
|
592
728
|
|
593
|
-
def parent_shape_absolute_location_changed?
|
594
|
-
(parent.is_a?(Shape) && (parent.absolute_x != @parent_absolute_x || parent.absolute_y != @parent_absolute_y))
|
595
|
-
end
|
596
|
-
|
597
729
|
def calculated_args_changed!(children: true)
|
598
730
|
# TODO add a children: true option to enable setting to false to avoid recalculating children args
|
599
731
|
@calculated_args = nil
|
600
732
|
shapes.each(&:calculated_args_changed!) if children
|
601
733
|
end
|
602
734
|
|
735
|
+
# Notifies object that calculated args changed for defaults. Returns true if redrawing and false otherwise.
|
603
736
|
def calculated_args_changed_for_defaults!
|
604
737
|
has_default_dimensions = default_width? || default_height?
|
605
738
|
parent_calculated_args_changed_for_defaults = has_default_dimensions
|
606
|
-
|
739
|
+
calculated_args_changed!(children: false) if default_x? || default_y? || has_default_dimensions
|
607
740
|
if has_default_dimensions && parent.is_a?(Shape)
|
608
741
|
parent.calculated_args_changed_for_defaults!
|
609
742
|
elsif @content_added && !drawable.is_disposed
|
610
743
|
# TODO consider optimizing in the future if needed by ensuring one redraw for all parents in the hierarchy at the end instead of doing one per parent that needs it
|
611
|
-
|
744
|
+
if !@painting && !drawable.is_a?(ImageProxy)
|
745
|
+
drawable.redraw
|
746
|
+
return true
|
747
|
+
end
|
612
748
|
end
|
749
|
+
false
|
613
750
|
end
|
614
751
|
|
615
752
|
def calculated_args?
|
@@ -617,68 +754,101 @@ module Glimmer
|
|
617
754
|
end
|
618
755
|
|
619
756
|
# args translated to absolute coordinates
|
620
|
-
def
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
757
|
+
def calculate_args!
|
758
|
+
# TODO add conditions for parent having default width/height too
|
759
|
+
return @args if parent.is_a?(Drawable) && !default_x? && !default_y? && !default_width? && !default_height? && !max_width? && !max_height?
|
760
|
+
calculated_args_dependencies = [
|
761
|
+
x,
|
762
|
+
y,
|
763
|
+
parent.is_a?(Shape) && parent.absolute_x,
|
764
|
+
parent.is_a?(Shape) && parent.absolute_y,
|
765
|
+
default_width? && default_width,
|
766
|
+
default_width? && width_delta,
|
767
|
+
default_height? && default_height,
|
768
|
+
default_height? && height_delta,
|
769
|
+
max_width? && max_width,
|
770
|
+
max_width? && width_delta,
|
771
|
+
max_height? && max_height,
|
772
|
+
max_height? && height_delta,
|
773
|
+
default_x? && default_x,
|
774
|
+
default_x? && x_delta,
|
775
|
+
default_y? && default_y,
|
776
|
+
default_y? && y_delta,
|
777
|
+
]
|
778
|
+
if calculated_args_dependencies != @calculated_args_dependencies
|
779
|
+
# avoid recalculating values again
|
780
|
+
x, y, parent_absolute_x, parent_absolute_y, default_width, default_width_delta, default_height, default_height_delta, max_width, max_width_delta, max_height, max_height_delta, default_x, default_x_delta, default_y, default_y_delta = @calculated_args_dependencies = calculated_args_dependencies
|
781
|
+
# Note: Must set x and move_by because not all shapes have a real x and some must translate all their points with move_by
|
782
|
+
# TODO change that by setting a bounding box for all shapes with a calculated top-left x, y and
|
783
|
+
# a setter that does the moving inside them instead so that I could rely on absolute_x and absolute_y
|
784
|
+
# here to get the job done of calculating absolute args
|
785
|
+
@perform_redraw = false
|
786
|
+
original_x = nil
|
787
|
+
original_y = nil
|
788
|
+
original_width = nil
|
789
|
+
original_height = nil
|
790
|
+
if parent.is_a?(Shape)
|
791
|
+
@parent_absolute_x = parent_absolute_x
|
792
|
+
@parent_absolute_y = parent_absolute_y
|
793
|
+
end
|
794
|
+
if default_width?
|
795
|
+
original_width = width
|
796
|
+
self.width = default_width + default_width_delta
|
797
|
+
end
|
798
|
+
if default_height?
|
799
|
+
original_height = height
|
800
|
+
self.height = default_height + default_height_delta
|
801
|
+
end
|
802
|
+
if max_width?
|
803
|
+
original_width = width
|
804
|
+
self.width = max_width + max_width_delta
|
805
|
+
end
|
806
|
+
if max_height?
|
807
|
+
original_height = height
|
808
|
+
self.height = max_height + max_height_delta
|
809
|
+
end
|
810
|
+
if default_x?
|
811
|
+
original_x = x
|
812
|
+
self.x = default_x + default_x_delta
|
813
|
+
end
|
814
|
+
if default_y?
|
815
|
+
original_y = y
|
816
|
+
self.y = default_y + default_y_delta
|
817
|
+
end
|
818
|
+
if parent.is_a?(Shape)
|
819
|
+
move_by(@parent_absolute_x, @parent_absolute_y)
|
820
|
+
@result_calculated_args = @args.clone
|
821
|
+
move_by(-1*@parent_absolute_x, -1*@parent_absolute_y)
|
822
|
+
else
|
823
|
+
@result_calculated_args = @args.clone
|
824
|
+
end
|
825
|
+
if original_x
|
826
|
+
self.x = original_x
|
827
|
+
end
|
828
|
+
if original_y
|
829
|
+
self.y = original_y
|
830
|
+
end
|
831
|
+
if original_width
|
832
|
+
self.width = original_width
|
833
|
+
end
|
834
|
+
if original_height
|
835
|
+
self.height = original_height
|
836
|
+
end
|
837
|
+
@perform_redraw = true
|
669
838
|
end
|
670
|
-
@
|
671
|
-
result_args
|
839
|
+
@result_calculated_args
|
672
840
|
end
|
673
841
|
|
674
842
|
def default_x?
|
675
|
-
current_parameter_name?(:x)
|
676
|
-
|
843
|
+
return false unless current_parameter_name?(:x)
|
844
|
+
x = self.x
|
845
|
+
x.nil? || x.to_s == 'default' || (x.is_a?(Array) && x.first.to_s == 'default')
|
677
846
|
end
|
678
847
|
|
679
848
|
def default_y?
|
680
|
-
current_parameter_name?(:y)
|
681
|
-
|
849
|
+
return false unless current_parameter_name?(:y)
|
850
|
+
y = self.y
|
851
|
+
y.nil? || y.to_s == 'default' || (y.is_a?(Array) && y.first.to_s == 'default')
|
682
852
|
end
|
683
853
|
|
684
854
|
def default_width?
|
@@ -693,120 +863,248 @@ module Glimmer
|
|
693
863
|
(height.nil? || height == :default || height == 'default' || (height.is_a?(Array) && (height.first.to_s == :default || height.first.to_s == 'default')))
|
694
864
|
end
|
695
865
|
|
866
|
+
def max_width?
|
867
|
+
return false unless current_parameter_name?(:width)
|
868
|
+
width = self.width
|
869
|
+
(width.nil? || width.to_s == 'max' || (width.is_a?(Array) && width.first.to_s == 'max'))
|
870
|
+
end
|
871
|
+
|
872
|
+
def max_height?
|
873
|
+
return false unless current_parameter_name?(:height)
|
874
|
+
height = self.height
|
875
|
+
(height.nil? || height.to_s == 'max' || (height.is_a?(Array) && height.first.to_s == 'max'))
|
876
|
+
end
|
877
|
+
|
696
878
|
def default_x
|
697
|
-
|
698
|
-
|
699
|
-
|
879
|
+
default_x_dependencies = [parent.size.x, size.x, parent.is_a?(Shape) && parent.irregular? && parent.bounds.x, parent.is_a?(Shape) && parent.irregular? && parent.absolute_x]
|
880
|
+
if default_x_dependencies != @default_x_dependencies
|
881
|
+
@default_x_dependencies = default_x_dependencies
|
882
|
+
result = ((parent.size.x - size.x) / 2)
|
883
|
+
result += parent.bounds.x - parent.absolute_x if parent.is_a?(Shape) && parent.irregular?
|
884
|
+
@default_x = result
|
885
|
+
end
|
886
|
+
@default_x
|
700
887
|
end
|
701
888
|
|
702
889
|
def default_y
|
703
|
-
|
704
|
-
|
705
|
-
|
890
|
+
default_y_dependencies = [parent.size.y, size.y, parent.is_a?(Shape) && parent.irregular? && parent.bounds.y, parent.is_a?(Shape) && parent.irregular? && parent.absolute_y]
|
891
|
+
if default_y_dependencies != @default_y_dependencies
|
892
|
+
result = ((parent.size.y - size.y) / 2)
|
893
|
+
result += parent.bounds.y - parent.absolute_y if parent.is_a?(Shape) && parent.irregular?
|
894
|
+
@default_y = result
|
895
|
+
end
|
896
|
+
@default_y
|
897
|
+
end
|
898
|
+
|
899
|
+
# right-most x coordinate in this shape (adding up its width and location)
|
900
|
+
def x_end
|
901
|
+
x_end_dependencies = [calculated_width, default_x?, !default_x? && x]
|
902
|
+
if x_end_dependencies != @x_end_dependencies
|
903
|
+
# avoid recalculation of dependencies
|
904
|
+
calculated_width, is_default_x, x = @x_end_dependencies = x_end_dependencies
|
905
|
+
shape_width = calculated_width.to_f
|
906
|
+
shape_x = is_default_x ? 0 : x.to_f
|
907
|
+
@x_end = shape_x + shape_width
|
908
|
+
end
|
909
|
+
@x_end
|
910
|
+
end
|
911
|
+
|
912
|
+
# right-most y coordinate in this shape (adding up its height and location)
|
913
|
+
def y_end
|
914
|
+
y_end_dependencies = [calculated_height, default_y?, !default_y? && y]
|
915
|
+
if y_end_dependencies != @y_end_dependencies
|
916
|
+
# avoid recalculation of dependencies
|
917
|
+
calculated_height, is_default_y, y = @y_end_dependencies = y_end_dependencies
|
918
|
+
shape_height = calculated_height.to_f
|
919
|
+
shape_y = is_default_y ? 0 : y.to_f
|
920
|
+
@y_end = shape_y + shape_height
|
921
|
+
end
|
922
|
+
@y_end
|
706
923
|
end
|
707
924
|
|
708
925
|
def default_width
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
926
|
+
default_width_dependencies = [shapes.empty? && max_width, shapes.size == 1 && shapes.first.max_width? && parent.size.x, shapes.size >= 1 && !shapes.first.max_width? && shapes.map {|s| s.max_width? ? 0 : s.x_end}]
|
927
|
+
if default_width_dependencies != @default_width_dependencies
|
928
|
+
# Do not repeat calculations
|
929
|
+
max_width, parent_size_x, x_ends = @default_width_dependencies = default_width_dependencies
|
930
|
+
@default_width = if shapes.empty?
|
931
|
+
max_width
|
932
|
+
elsif shapes.size == 1 && shapes.first.max_width?
|
933
|
+
parent_size_x
|
934
|
+
else
|
935
|
+
x_ends.max.to_f
|
936
|
+
end
|
714
937
|
end
|
715
|
-
|
938
|
+
@default_width
|
716
939
|
end
|
717
940
|
|
718
941
|
def default_height
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
942
|
+
default_height_dependencies = [shapes.empty? && max_height, shapes.size == 1 && shapes.first.max_height? && parent.size.y, shapes.size >= 1 && !shapes.first.max_height? && shapes.map {|s| s.max_height? ? 0 : s.y_end}]
|
943
|
+
if default_height_dependencies != @default_height_dependencies
|
944
|
+
# Do not repeat calculations
|
945
|
+
max_height, parent_size_y, y_ends = @default_height_dependencies = default_height_dependencies
|
946
|
+
@default_height = if shapes.empty?
|
947
|
+
max_height
|
948
|
+
elsif shapes.size == 1 && shapes.first.max_height?
|
949
|
+
parent_size_y
|
950
|
+
else
|
951
|
+
y_ends.max.to_f
|
952
|
+
end
|
953
|
+
end
|
954
|
+
@default_height
|
955
|
+
end
|
956
|
+
|
957
|
+
def max_width
|
958
|
+
max_width_dependencies = [parent.is_a?(Drawable) && parent.size.x, !parent.is_a?(Drawable) && parent.calculated_width]
|
959
|
+
if max_width_dependencies != @max_width_dependencies
|
960
|
+
# do not repeat calculations
|
961
|
+
parent_size_x, parent_calculated_width = @max_width_dependencies = max_width_dependencies
|
962
|
+
@max_width = parent.is_a?(Drawable) ? parent_size_x : parent_calculated_width
|
963
|
+
end
|
964
|
+
@max_width
|
965
|
+
end
|
966
|
+
|
967
|
+
def max_height
|
968
|
+
max_height_dependencies = [parent.is_a?(Drawable) && parent.size.y, !parent.is_a?(Drawable) && parent.calculated_height]
|
969
|
+
if max_height_dependencies != @max_height_dependencies
|
970
|
+
# do not repeat calculations
|
971
|
+
parent_size_y, parent_calculated_height = @max_height_dependencies = max_height_dependencies
|
972
|
+
@max_height = parent.is_a?(Drawable) ? parent_size_y : parent_calculated_height
|
724
973
|
end
|
725
|
-
|
974
|
+
@max_height
|
726
975
|
end
|
727
976
|
|
728
977
|
def calculated_width
|
729
|
-
default_width?
|
978
|
+
calculated_width_dependencies = [width, default_width? && (default_width + width_delta), max_width? && (max_width + width_delta)]
|
979
|
+
if calculated_width_dependencies != @calculated_width_dependencies
|
980
|
+
@calculated_width_dependencies = calculated_width_dependencies
|
981
|
+
result_width = width
|
982
|
+
result_width = (default_width + width_delta) if default_width?
|
983
|
+
result_width = (max_width + width_delta) if max_width?
|
984
|
+
@calculated_width = result_width
|
985
|
+
end
|
986
|
+
@calculated_width
|
730
987
|
end
|
731
988
|
|
732
989
|
def calculated_height
|
733
|
-
default_height?
|
990
|
+
calculated_height_dependencies = [height, default_height? && (default_height + height_delta), max_height? && (max_height + height_delta)]
|
991
|
+
if calculated_height_dependencies != @calculated_height_dependencies
|
992
|
+
@calculated_height_dependencies = calculated_height_dependencies
|
993
|
+
result_height = height
|
994
|
+
result_height = (default_height + height_delta) if default_height?
|
995
|
+
result_height = (max_height + height_delta) if max_height?
|
996
|
+
@calculated_height = result_height
|
997
|
+
end
|
998
|
+
@calculated_height
|
734
999
|
end
|
735
1000
|
|
736
|
-
def
|
737
|
-
return 0 unless
|
1001
|
+
def x_delta
|
1002
|
+
return 0 unless x.is_a?(Array) && default_x?
|
738
1003
|
x[1].to_f
|
739
1004
|
end
|
740
1005
|
|
741
|
-
def
|
742
|
-
return 0 unless
|
1006
|
+
def y_delta
|
1007
|
+
return 0 unless y.is_a?(Array) && default_y?
|
743
1008
|
y[1].to_f
|
744
1009
|
end
|
745
1010
|
|
746
|
-
def
|
747
|
-
return 0 unless
|
1011
|
+
def width_delta
|
1012
|
+
return 0 unless width.is_a?(Array) && (default_width? || max_width?)
|
748
1013
|
width[1].to_f
|
749
1014
|
end
|
750
1015
|
|
751
|
-
def
|
752
|
-
return 0 unless
|
1016
|
+
def height_delta
|
1017
|
+
return 0 unless height.is_a?(Array) && (default_height? || max_height?)
|
753
1018
|
height[1].to_f
|
754
1019
|
end
|
755
1020
|
|
756
|
-
def
|
1021
|
+
def x_delta=(delta)
|
757
1022
|
return unless default_x?
|
758
|
-
|
1023
|
+
symbol = x.is_a?(Array) ? x.first : x
|
1024
|
+
self.x = [symbol, delta]
|
759
1025
|
end
|
760
1026
|
|
761
|
-
def
|
1027
|
+
def y_delta=(delta)
|
762
1028
|
return unless default_y?
|
763
|
-
|
1029
|
+
symbol = y.is_a?(Array) ? y.first : y
|
1030
|
+
self.y = [symbol, delta]
|
764
1031
|
end
|
765
1032
|
|
766
|
-
def
|
1033
|
+
def width_delta=(delta)
|
767
1034
|
return unless default_width?
|
768
|
-
|
1035
|
+
symbol = width.is_a?(Array) ? width.first : width
|
1036
|
+
self.width = [symbol, delta]
|
769
1037
|
end
|
770
1038
|
|
771
|
-
def
|
1039
|
+
def height_delta=(delta)
|
772
1040
|
return unless default_height?
|
773
|
-
|
1041
|
+
symbol = height.is_a?(Array) ? height.first : height
|
1042
|
+
self.height = [symbol, delta]
|
774
1043
|
end
|
775
1044
|
|
776
1045
|
def calculated_x
|
777
|
-
|
778
|
-
|
779
|
-
|
1046
|
+
calculated_x_dependencies = [default_x? && default_x, !default_x? && self.x, self.x_delta]
|
1047
|
+
if calculated_x_dependencies != @calculated_x_dependencies
|
1048
|
+
default_x, x, x_delta = @calculated_x_dependencies = calculated_x_dependencies
|
1049
|
+
result = default_x? ? default_x : x
|
1050
|
+
result += x_delta
|
1051
|
+
@calculated_x = result
|
1052
|
+
end
|
1053
|
+
@calculated_x
|
780
1054
|
end
|
781
1055
|
|
782
1056
|
def calculated_y
|
783
|
-
|
784
|
-
|
785
|
-
|
1057
|
+
calculated_y_dependencies = [default_y? && default_y, !default_y? && self.y, self.y_delta]
|
1058
|
+
if calculated_y_dependencies != @calculated_y_dependencies
|
1059
|
+
default_y, y, y_delta = @calculated_y_dependencies = calculated_y_dependencies
|
1060
|
+
result = default_y? ? default_y : y
|
1061
|
+
result += y_delta
|
1062
|
+
@calculated_y = result
|
1063
|
+
end
|
1064
|
+
@calculated_y
|
786
1065
|
end
|
787
1066
|
|
788
1067
|
def absolute_x
|
789
|
-
|
790
|
-
if
|
791
|
-
|
792
|
-
|
793
|
-
x
|
1068
|
+
absolute_x_dependencies = [calculated_x, parent.is_a?(Shape) && parent.absolute_x]
|
1069
|
+
if absolute_x_dependencies != @absolute_x_dependencies
|
1070
|
+
# do not repeat calculations
|
1071
|
+
calculated_x, parent_absolute_x = @absolute_x_dependencies = absolute_x_dependencies
|
1072
|
+
x = calculated_x
|
1073
|
+
@absolute_x = if parent.is_a?(Shape)
|
1074
|
+
parent_absolute_x + x
|
1075
|
+
else
|
1076
|
+
x
|
1077
|
+
end
|
794
1078
|
end
|
1079
|
+
@absolute_x
|
795
1080
|
end
|
796
1081
|
|
797
1082
|
def absolute_y
|
798
|
-
|
799
|
-
if
|
800
|
-
|
801
|
-
|
802
|
-
|
1083
|
+
absolute_y_dependencies = [calculated_y, parent.is_a?(Shape) && parent.absolute_y]
|
1084
|
+
if absolute_y_dependencies != @absolute_y_dependencies
|
1085
|
+
calculated_y, parent_absolute_y = @absolute_y_dependencies = absolute_y_dependencies
|
1086
|
+
y = calculated_y
|
1087
|
+
@absolute_y = if parent.is_a?(Shape)
|
1088
|
+
parent_absolute_y + y
|
1089
|
+
else
|
1090
|
+
y
|
1091
|
+
end
|
803
1092
|
end
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
1093
|
+
@absolute_y
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
# Overriding inspect to avoid printing very long nested shape hierarchies (recurses onces only)
|
1097
|
+
def inspect(recursive: 1, calculated: false, args: true, properties: true, calculated_args: false)
|
1098
|
+
recurse = recursive == true || recursive.is_a?(Integer) && recursive.to_i > 0
|
1099
|
+
recursive = [recursive -= 1, 0].max if recursive.is_a?(Integer)
|
1100
|
+
args_string = " args=#{@args.inspect}" if args
|
1101
|
+
properties_string = " properties=#{@properties.inspect}}" if properties
|
1102
|
+
calculated_args_string = " calculated_args=#{@calculated_args.inspect}" if calculated_args
|
1103
|
+
calculated_string = " absolute_x=#{absolute_x} absolute_y=#{absolute_y} calculated_width=#{calculated_width} calculated_height=#{calculated_height}" if calculated
|
1104
|
+
recursive_string = " shapes=#{@shapes.map {|s| s.inspect(recursive: recursive, calculated: calculated, args: args, properties: properties)}}" if recurse
|
1105
|
+
"#<#{self.class.name}:0x#{self.hash.to_s(16)}#{args_string}#{properties_string}#{calculated_args_string}#{calculated_string}#{recursive_string}>"
|
809
1106
|
rescue => e
|
1107
|
+
Glimmer::Config.logger.error { e.full_message }
|
810
1108
|
"#<#{self.class.name}:0x#{self.hash.to_s(16)}"
|
811
1109
|
end
|
812
1110
|
|
@@ -827,19 +1125,14 @@ module Glimmer
|
|
827
1125
|
end
|
828
1126
|
end
|
829
1127
|
else
|
1128
|
+
@properties = all_parent_properties.merge(@properties)
|
830
1129
|
@properties['background'] = [@drawable.background] if fill? && !has_some_background?
|
831
1130
|
@properties['foreground'] = [@drawable.foreground] if @drawable.respond_to?(:foreground) && draw? && !has_some_foreground?
|
832
1131
|
# TODO regarding alpha, make sure to reset it to parent stored alpha once we allow setting shape properties on parents directly without shapes
|
833
|
-
@properties['
|
834
|
-
@properties['font'] = [@drawable.font] if @drawable.respond_to?(:font) && draw? && !@properties.keys.map(&:to_s).include?('font')
|
1132
|
+
@properties['font'] = [@drawable.font] if @drawable.respond_to?(:font) && @name == 'text' && draw? && !@properties.keys.map(&:to_s).include?('font')
|
835
1133
|
# TODO regarding transform, make sure to reset it to parent stored transform once we allow setting shape properties on parents directly without shapes
|
836
1134
|
# Also do that with all future-added properties
|
837
|
-
|
838
|
-
@properties.each do |property, args|
|
839
|
-
method_name = attribute_setter(property)
|
840
|
-
converted_args = apply_property_arg_conversions(method_name, property, args)
|
841
|
-
@properties[property] = converted_args
|
842
|
-
end
|
1135
|
+
convert_properties!
|
843
1136
|
apply_shape_arg_conversions!
|
844
1137
|
apply_shape_arg_defaults!
|
845
1138
|
tolerate_shape_extra_args!
|