glimmer-dsl-swt 4.18.5.2 → 4.18.6.1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -0
  3. data/README.md +8 -10
  4. data/VERSION +1 -1
  5. data/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md +93 -16
  6. data/docs/reference/GLIMMER_SAMPLES.md +32 -0
  7. data/glimmer-dsl-swt.gemspec +9 -3
  8. data/lib/glimmer/swt/custom/drawable.rb +8 -7
  9. data/lib/glimmer/swt/custom/shape.rb +416 -37
  10. data/lib/glimmer/swt/custom/shape/arc.rb +22 -4
  11. data/lib/glimmer/swt/custom/shape/cubic.rb +117 -0
  12. data/lib/glimmer/swt/custom/shape/image.rb +19 -6
  13. data/lib/glimmer/swt/custom/shape/line.rb +119 -1
  14. data/lib/glimmer/swt/custom/shape/oval.rb +3 -3
  15. data/lib/glimmer/swt/custom/shape/path.rb +211 -0
  16. data/lib/glimmer/swt/custom/shape/path_segment.rb +111 -0
  17. data/lib/glimmer/swt/custom/shape/point.rb +40 -4
  18. data/lib/glimmer/swt/custom/shape/polygon.rb +93 -3
  19. data/lib/glimmer/swt/custom/shape/polyline.rb +76 -4
  20. data/lib/glimmer/swt/custom/shape/quad.rb +113 -0
  21. data/lib/glimmer/swt/custom/shape/rectangle.rb +7 -2
  22. data/lib/glimmer/swt/custom/shape/text.rb +2 -4
  23. data/lib/glimmer/swt/dialog_proxy.rb +4 -0
  24. data/lib/glimmer/swt/proxy_properties.rb +1 -1
  25. data/lib/glimmer/swt/widget_proxy.rb +16 -0
  26. data/samples/elaborate/contact_manager.rb +2 -0
  27. data/samples/elaborate/login.rb +2 -0
  28. data/samples/elaborate/mandelbrot_fractal.rb +2 -1
  29. data/samples/elaborate/meta_sample.rb +1 -0
  30. data/samples/elaborate/stock_ticker.rb +229 -0
  31. data/samples/elaborate/tetris.rb +2 -1
  32. data/samples/elaborate/tic_tac_toe.rb +2 -0
  33. data/samples/elaborate/user_profile.rb +10 -8
  34. data/samples/hello/hello_browser.rb +2 -0
  35. data/samples/hello/hello_button.rb +2 -0
  36. data/samples/hello/hello_canvas.rb +40 -21
  37. data/samples/hello/hello_canvas_animation.rb +2 -0
  38. data/samples/hello/hello_canvas_path.rb +66 -0
  39. data/samples/hello/hello_canvas_transform.rb +2 -0
  40. data/samples/hello/hello_checkbox.rb +2 -0
  41. data/samples/hello/hello_checkbox_group.rb +2 -0
  42. data/samples/hello/hello_code_text.rb +2 -0
  43. data/samples/hello/hello_color_dialog.rb +2 -0
  44. data/samples/hello/hello_combo.rb +2 -0
  45. data/samples/hello/hello_computed.rb +2 -0
  46. data/samples/hello/hello_cursor.rb +2 -0
  47. data/samples/hello/hello_custom_shell.rb +1 -0
  48. data/samples/hello/hello_custom_widget.rb +2 -0
  49. data/samples/hello/hello_date_time.rb +2 -0
  50. data/samples/hello/hello_dialog.rb +2 -0
  51. data/samples/hello/hello_directory_dialog.rb +2 -0
  52. data/samples/hello/hello_drag_and_drop.rb +5 -3
  53. data/samples/hello/hello_expand_bar.rb +2 -0
  54. data/samples/hello/hello_file_dialog.rb +2 -0
  55. data/samples/hello/hello_font_dialog.rb +2 -0
  56. data/samples/hello/hello_group.rb +2 -0
  57. data/samples/hello/hello_link.rb +2 -0
  58. data/samples/hello/hello_list_multi_selection.rb +2 -0
  59. data/samples/hello/hello_list_single_selection.rb +2 -0
  60. data/samples/hello/hello_menu_bar.rb +2 -0
  61. data/samples/hello/hello_message_box.rb +2 -0
  62. data/samples/hello/hello_pop_up_context_menu.rb +2 -0
  63. data/samples/hello/hello_progress_bar.rb +2 -0
  64. data/samples/hello/hello_radio.rb +2 -0
  65. data/samples/hello/hello_radio_group.rb +2 -0
  66. data/samples/hello/hello_sash_form.rb +2 -0
  67. data/samples/hello/hello_spinner.rb +2 -0
  68. data/samples/hello/hello_styled_text.rb +19 -17
  69. data/samples/hello/hello_tab.rb +2 -0
  70. data/samples/hello/hello_table.rb +2 -0
  71. data/samples/hello/hello_world.rb +2 -0
  72. metadata +8 -2
@@ -37,10 +37,23 @@ module Glimmer
37
37
  [:x, :y, :width, :height, :start_angle, :arc_angle]
38
38
  end
39
39
 
40
+ def bounds
41
+ shape_bounds = geometry.getBounds2D
42
+ org.eclipse.swt.graphics.Rectangle.new(shape_bounds.x, shape_bounds.y, shape_bounds.width, shape_bounds.height)
43
+ end
44
+
45
+ def size
46
+ shape_bounds = geometry.getBounds2D
47
+ org.eclipse.swt.graphics.Point.new(shape_bounds.width, shape_bounds.height)
48
+ end
49
+
50
+ def geometry
51
+ java.awt.geom.Arc2D::Double.new(self.absolute_x, self.absolute_y, calculated_width, calculated_height, start_angle, arc_angle, java.awt.geom.Arc2D::PIE)
52
+ end
53
+
40
54
  # checks if shape contains the point denoted by x and y
41
55
  def contain?(x, y)
42
- shape_geometry = java.awt.geom.Arc2D::Double.new(self.x, self.y, width, height, start_angle, arc_angle, java.awt.geom.Arc2D::PIE)
43
- shape_geometry.contains(x, y)
56
+ geometry.contains(x, y)
44
57
  end
45
58
 
46
59
  def include?(x, y)
@@ -48,11 +61,16 @@ module Glimmer
48
61
  contain?(x, y)
49
62
  else
50
63
  # give it some fuzz to allow a larger region around the drawn oval to accept including a point (helps with mouse clickability on a shape)
51
- outer_shape_geometry = java.awt.geom.Arc2D::Double.new(self.x, self.y, width + 3, height + 3, start_angle, arc_angle, java.awt.geom.Arc2D::PIE)
52
- inner_shape_geometry = java.awt.geom.Arc2D::Double.new(self.x, self.y, width - 3, height - 3, start_angle, arc_angle, java.awt.geom.Arc2D::PIE)
64
+ outer_shape_geometry = java.awt.geom.Arc2D::Double.new(self.absolute_x, self.absolute_y, calculated_width + 3, calculated_height + 3, start_angle, arc_angle, java.awt.geom.Arc2D::PIE)
65
+ inner_shape_geometry = java.awt.geom.Arc2D::Double.new(self.absolute_x, self.absolute_y, calculated_width - 3, calculated_height - 3, start_angle, arc_angle, java.awt.geom.Arc2D::PIE)
53
66
  outer_shape_geometry.contains(x, y) && !inner_shape_geometry.contains(x, y)
54
67
  end
55
68
  end
69
+
70
+ def irregular?
71
+ true
72
+ end
73
+
56
74
  end
57
75
  end
58
76
  end
@@ -0,0 +1,117 @@
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/swt/custom/shape'
23
+ require 'glimmer/swt/custom/shape/path_segment'
24
+ require 'glimmer/swt/swt_proxy'
25
+ require 'glimmer/swt/display_proxy'
26
+ require 'glimmer/swt/color_proxy'
27
+ require 'glimmer/swt/font_proxy'
28
+ require 'glimmer/swt/transform_proxy'
29
+
30
+ module Glimmer
31
+ module SWT
32
+ module Custom
33
+ # Represents a shape (graphics) to be drawn on a control/widget/canvas/display
34
+ # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
35
+ class Shape
36
+ class Cubic < Path
37
+ def parameter_names
38
+ [:point_array]
39
+ end
40
+
41
+ def geometry
42
+ the_point_array = point_array
43
+ if the_point_array != @geometry_point_array
44
+ @geometry_point_array = the_point_array
45
+ @geometry = Java::JavaAwtGeom::Path2D::Double.new
46
+ add_to_geometry(@geometry)
47
+ end
48
+ @geometry
49
+ end
50
+
51
+ def contain?(x, y)
52
+ include?(x, y, filled: true)
53
+ end
54
+
55
+ # checks if drawn or filled rectangle includes the point denoted by x and y (if drawn, it only returns true if point lies on the edge)
56
+ def include?(x, y, filled: nil)
57
+ filled = filled? if filled.nil?
58
+ makeshift_gc = org.eclipse.swt.graphics.GC.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
59
+ swt_path = org.eclipse.swt.graphics.Path.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
60
+ the_path_segment_args = path_segment_args.dup
61
+ if previous_point_connected?
62
+ the_previous_path_segment = previous_path_segment
63
+ swt_path.moveTo(the_previous_path_segment.x, the_previous_path_segment.y)
64
+ else
65
+ swt_path.moveTo(the_path_segment_args.shift, the_path_segment_args.shift)
66
+ end
67
+ swt_path.curveTo(*the_path_segment_args)
68
+ swt_path.contains(x.to_f, y.to_f, makeshift_gc, !filled)
69
+ ensure
70
+ swt_path.dispose
71
+ end
72
+
73
+ def move_by(x_delta, y_delta)
74
+ the_point_array = @args.compact
75
+ the_point_array = the_point_array.first if the_point_array.first.is_a?(Array)
76
+ self.point_array = the_point_array.each_with_index.map {|coordinate, i| i.even? ? coordinate + x_delta : coordinate + y_delta}
77
+ end
78
+
79
+ def path_segment_method_name
80
+ 'cubicTo'
81
+ end
82
+
83
+ def path_segment_args
84
+ # TODO make args auto-infer control points if previous_point_connected is true or if there is only a point_array with 1 point
85
+ @args.to_a
86
+ end
87
+
88
+ def default_path_segment_arg_count
89
+ 8
90
+ end
91
+
92
+ def default_connected_path_segment_arg_count
93
+ 6
94
+ end
95
+
96
+ def path_segment_geometry_method_name
97
+ 'curveTo'
98
+ end
99
+
100
+ def previous_point_connected?
101
+ @args.compact.count == 6 && !first_path_segment?
102
+ end
103
+
104
+ def eql?(other)
105
+ point_array == (other && other.respond_to?(:point_array) && other.point_array)
106
+ end
107
+ alias == eql?
108
+
109
+ def hash
110
+ point_array.hash
111
+ end
112
+
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -78,17 +78,30 @@ module Glimmer
78
78
  dest_height || image.bounds.height
79
79
  end
80
80
 
81
- def include?(x, y)
82
- x.between?(self.x, self.x + width) && y.between?(self.y, self.y + height)
81
+ def default_x?
82
+ super ||
83
+ current_parameter_name?(:dest_x) && (dest_x.nil? || dest_x.to_s == 'default')
83
84
  end
84
- alias contain? include?
85
-
85
+
86
+ def default_y?
87
+ super ||
88
+ current_parameter_name?(:dest_y) && (dest_y.nil? || dest_y.to_s == 'default')
89
+ end
90
+
86
91
  def move_by(x_delta, y_delta)
87
- if dest_x
92
+ if default_x?
93
+ self.default_x_delta += x_delta
94
+ elsif dest_x
88
95
  self.dest_x += x_delta
89
- self.dest_y += y_delta
90
96
  else
91
97
  self.x += x_delta
98
+ end
99
+
100
+ if default_y?
101
+ self.default_y_delta += y_delta
102
+ elsif dest_y
103
+ self.dest_y += y_delta
104
+ else
92
105
  self.y += y_delta
93
106
  end
94
107
  end
@@ -20,6 +20,7 @@
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
22
  require 'glimmer/swt/custom/shape'
23
+ require 'glimmer/swt/custom/shape/path_segment'
23
24
  require 'glimmer/swt/swt_proxy'
24
25
  require 'glimmer/swt/display_proxy'
25
26
  require 'glimmer/swt/color_proxy'
@@ -33,6 +34,8 @@ module Glimmer
33
34
  # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
34
35
  class Shape
35
36
  class Line < Shape
37
+ include PathSegment
38
+
36
39
  class << self
37
40
  def include?(x1, y1, x2, y2, x, y)
38
41
  distance1 = Math.sqrt((x - x1)**2 + (y - y1)**2)
@@ -46,9 +49,81 @@ module Glimmer
46
49
  [:x1, :y1, :x2, :y2]
47
50
  end
48
51
 
52
+ def location_parameter_names
53
+ parameter_names
54
+ end
55
+
56
+ def bounds
57
+ shape_bounds = geometry.getBounds2D
58
+ org.eclipse.swt.graphics.Rectangle.new(shape_bounds.x, shape_bounds.y, shape_bounds.width, shape_bounds.height)
59
+ end
60
+
61
+ def size
62
+ shape_bounds = geometry.getBounds2D
63
+ org.eclipse.swt.graphics.Point.new(shape_bounds.width, shape_bounds.height)
64
+ end
65
+
66
+ def geometry
67
+ java.awt.geom.Line2D::Double.new(absolute_x1, absolute_y1, absolute_x2, absolute_y2)
68
+ end
69
+
70
+ # Logical x coordinate relative to parent
71
+ def x
72
+ x_value = bounds.x
73
+ x_value -= parent.absolute_x if parent.is_a?(Shape)
74
+ x_value
75
+ end
76
+
77
+ # Logical y coordinate relative to parent
78
+ def y
79
+ y_value = bounds.y
80
+ y_value -= parent.absolute_y if parent.is_a?(Shape)
81
+ y_value
82
+ end
83
+
84
+ def width
85
+ size.x
86
+ end
87
+
88
+ def height
89
+ size.y
90
+ end
91
+
92
+ def absolute_x1
93
+ if parent.is_a?(Shape)
94
+ parent.absolute_x + x1
95
+ else
96
+ x1
97
+ end
98
+ end
99
+
100
+ def absolute_y1
101
+ if parent.is_a?(Shape)
102
+ parent.absolute_y + y1
103
+ else
104
+ y1
105
+ end
106
+ end
107
+
108
+ def absolute_x2
109
+ if parent.is_a?(Shape)
110
+ parent.absolute_x + x2.to_f
111
+ else
112
+ x2
113
+ end
114
+ end
115
+
116
+ def absolute_y2
117
+ if parent.is_a?(Shape)
118
+ parent.absolute_y + y2.to_f
119
+ else
120
+ y2
121
+ end
122
+ end
123
+
49
124
  def include?(x, y)
50
125
  # TODO must account for line width
51
- Line.include?(x1, y1, x2, y2, x, y)
126
+ Line.include?(absolute_x1, absolute_y1, absolute_x2, absolute_y2, x, y)
52
127
  end
53
128
  alias contain? include?
54
129
 
@@ -58,6 +133,49 @@ module Glimmer
58
133
  self.x2 += x_delta
59
134
  self.y2 += y_delta
60
135
  end
136
+
137
+ def irregular?
138
+ true
139
+ end
140
+
141
+ def path_segment_method_name
142
+ 'lineTo'
143
+ end
144
+
145
+ def path_segment_args
146
+ # TODO make args auto-infer first point if previous_point_connected is true or if there is only x1,y1 or x2,y2 (but not both), or if there is an x, y, or if there is a point_array with 1 point
147
+ @args
148
+ end
149
+
150
+ def default_path_segment_arg_count
151
+ 4
152
+ end
153
+
154
+ def default_connected_path_segment_arg_count
155
+ 2
156
+ end
157
+
158
+ def path_segment_geometry_args
159
+ # TODO make args auto-infer first point if previous_point_connected is true or if there is only x1,y1 or x2,y2 (but not both), or if there is an x, y, or if there is a point_array with 1 point
160
+ @args[0..1]
161
+ end
162
+
163
+ def previous_point_connected?
164
+ @args.compact.count == 2 && !first_path_segment?
165
+ end
166
+
167
+ def eql?(other)
168
+ x1 == (other && other.respond_to?(:x1) && other.x1) &&
169
+ y1 == (other && other.respond_to?(:y1) && other.y1) &&
170
+ x2 == (other && other.respond_to?(:x2) && other.x2) &&
171
+ y2 == (other && other.respond_to?(:y2) && other.y2)
172
+ end
173
+ alias == eql?
174
+
175
+ def hash
176
+ [x1, y1, x2, y2].hash
177
+ end
178
+
61
179
  end
62
180
  end
63
181
  end
@@ -39,7 +39,7 @@ module Glimmer
39
39
 
40
40
  # checks if shape contains the point denoted by x and y
41
41
  def contain?(x, y)
42
- shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.x, self.y, width, height)
42
+ shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.absolute_x, self.absolute_y, calculated_width, calculated_height)
43
43
  shape_geometry.contains(x, y)
44
44
  end
45
45
 
@@ -49,8 +49,8 @@ module Glimmer
49
49
  contain?(x, y)
50
50
  else
51
51
  # give it some fuzz to allow a larger region around the drawn oval to accept including a point (helps with mouse clickability on a shape)
52
- outer_shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.x - 3, self.y - 3, width + 6, height + 6)
53
- inner_shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.x + 3, self.y + 3, width - 6, height - 6)
52
+ outer_shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.absolute_x - 3, self.absolute_y - 3, calculated_width + 6, calculated_height + 6)
53
+ inner_shape_geometry = java.awt.geom.Ellipse2D::Double.new(self.absolute_x + 3, self.absolute_y + 3, calculated_width - 6, calculated_height - 6)
54
54
  outer_shape_geometry.contains(x, y) && !inner_shape_geometry.contains(x, y)
55
55
  end
56
56
  end
@@ -0,0 +1,211 @@
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/swt/custom/shape'
23
+ require 'glimmer/swt/custom/shape/path_segment'
24
+ require 'glimmer/swt/swt_proxy'
25
+ require 'glimmer/swt/display_proxy'
26
+ require 'glimmer/swt/color_proxy'
27
+ require 'glimmer/swt/font_proxy'
28
+ require 'glimmer/swt/display_proxy'
29
+
30
+ module Glimmer
31
+ module SWT
32
+ module Custom
33
+ # Represents a path to be drawn on a control/widget/canvas/display
34
+ # That is because Shape is drawn on a parent as graphics and doesn't have an SWT widget for itself
35
+ class Shape
36
+ class Path < Shape
37
+ include PathSegment # a path may behave as a path segment in another path
38
+
39
+ attr_accessor :flatness, :closed
40
+ attr_reader :swt_path, :path_segments
41
+
42
+ def initialize(parent, keyword, *args, &property_block)
43
+ super
44
+ @path_segments = []
45
+ @uncalculated_path_segments = []
46
+ end
47
+
48
+ def parameter_names
49
+ [:swt_path]
50
+ end
51
+
52
+ def add_shape(shape)
53
+ if shape.is_a?(PathSegment)
54
+ @path_segments << shape
55
+ @uncalculated_path_segments << shape
56
+ else
57
+ super
58
+ end
59
+ end
60
+
61
+ def contain?(x, y)
62
+ makeshift_gc = org.eclipse.swt.graphics.GC.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
63
+ @swt_path.contains(x.to_f, y.to_f, makeshift_gc, false)
64
+ end
65
+
66
+ def contain?(x, y)
67
+ include?(x, y, filled: true)
68
+ end
69
+
70
+ # checks if drawn or filled rectangle includes the point denoted by x and y (if drawn, it only returns true if point lies on the edge)
71
+ def include?(x, y, filled: nil)
72
+ filled = filled? if filled.nil?
73
+ makeshift_gc = org.eclipse.swt.graphics.GC.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
74
+ @swt_path.contains(x.to_f, y.to_f, makeshift_gc, !filled)
75
+ end
76
+
77
+ def irregular?
78
+ true
79
+ end
80
+
81
+ def post_dispose_content(path_segment)
82
+ @path_segments.delete(path_segment)
83
+ @uncalculated_path_segments = @path_segments.dup
84
+ dispose
85
+ end
86
+
87
+ def dispose
88
+ @swt_path&.dispose
89
+ @swt_path = nil
90
+ @args = []
91
+ calculated_args_changed!(children: false)
92
+ super
93
+ end
94
+
95
+ def calculated_args_changed!(children: true)
96
+ super
97
+ end
98
+
99
+ def calculated_args
100
+ new_swt_path = @swt_path.nil?
101
+ @swt_path ||= org.eclipse.swt.graphics.Path.new(Glimmer::SWT::DisplayProxy.instance.swt_display)
102
+ # TODO recreate @swt_path only if one of the children get disposed (must notify parent on dispose)
103
+ @args = [@swt_path]
104
+ @uncalculated_path_segments.each do |path_segment|
105
+ path_segment.add_to_swt_path(@swt_path)
106
+ @uncalculated_path_segments.delete(path_segment)
107
+ end
108
+ if new_swt_path
109
+ @path_calculated_args = super
110
+ else
111
+ @path_calculated_args
112
+ end
113
+ rescue => e
114
+ Glimmer::Config.logger.error {e.full_message}
115
+ @args
116
+ end
117
+
118
+ def move_by(x_delta, y_delta)
119
+ @path_segments.each {|path_segment| path_segment.move_by(x_delta, y_delta)}
120
+ end
121
+
122
+ def bounds
123
+ if @path_segments != @bounds_path_segments
124
+ @bounds_path_segments = @path_segments
125
+ shape_bounds = geometry.getBounds2D
126
+ @bounds = org.eclipse.swt.graphics.Rectangle.new(shape_bounds.x, shape_bounds.y, shape_bounds.width, shape_bounds.height)
127
+ end
128
+ @bounds
129
+ end
130
+
131
+ def size
132
+ if @path_segments != @size_path_segments
133
+ @size_path_segments = @path_segments
134
+ shape_bounds = geometry.getBounds2D
135
+ @size = org.eclipse.swt.graphics.Point.new(shape_bounds.width, shape_bounds.height)
136
+ end
137
+ @size
138
+ end
139
+
140
+ # Logical x coordinate relative to parent
141
+ def x
142
+ x_value = bounds.x
143
+ x_value -= parent.absolute_x if parent.is_a?(Shape)
144
+ x_value
145
+ end
146
+
147
+ # Logical y coordinate relative to parent
148
+ def y
149
+ y_value = bounds.y
150
+ y_value -= parent.absolute_y if parent.is_a?(Shape)
151
+ y_value
152
+ end
153
+
154
+ def width
155
+ size.x
156
+ end
157
+
158
+ def height
159
+ size.y
160
+ end
161
+
162
+ def geometry
163
+ if @path_segments != @geometry_path_segments
164
+ @geometry_path_segments = @path_segments
165
+ @geometry = Java::JavaAwtGeom::Path2D::Double.new
166
+ @path_segments.each do |path_segment|
167
+ path_segment.add_to_geometry(@geometry)
168
+ end
169
+ end
170
+ @geometry
171
+ end
172
+
173
+ def path_segment_method_name
174
+ 'addPath'
175
+ end
176
+
177
+ def path_segment_args
178
+ @args
179
+ end
180
+
181
+ def path_segment_geometry_method_name
182
+ if self.class == Path
183
+ 'append'
184
+ else
185
+ super
186
+ end
187
+ end
188
+
189
+ def path_segment_geometry_args
190
+ if self.class == Path
191
+ # TODO consider supporting connected true instead of false (2nd arg)
192
+ [geometry, false]
193
+ else
194
+ super
195
+ end
196
+ end
197
+
198
+ def eql?(other)
199
+ geometry.equals(other && other.respond_to?(:geometry) && other.geometry)
200
+ end
201
+ alias == eql?
202
+
203
+ def hash
204
+ geometry.hashCode
205
+ end
206
+
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end