wxruby3-shapes 0.9.0.pre.beta.3 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/INSTALL.md +5 -7
  3. data/README.md +38 -6
  4. data/assets/logo.svg +339 -0
  5. data/assets/logo.xpm +60 -0
  6. data/assets/screenshot.png +0 -0
  7. data/assets/social.png +0 -0
  8. data/bin/wx-shapes +1 -1
  9. data/lib/wx/shapes/arrow_base.rb +4 -11
  10. data/lib/wx/shapes/arrows/circle_arrow.rb +22 -11
  11. data/lib/wx/shapes/arrows/circle_prong_arrow.rb +48 -0
  12. data/lib/wx/shapes/arrows/cross_bar_arrow.rb +57 -0
  13. data/lib/wx/shapes/arrows/cross_bar_circle_arrow.rb +56 -0
  14. data/lib/wx/shapes/arrows/cross_bar_prong_arrow.rb +49 -0
  15. data/lib/wx/shapes/arrows/crossed_circle.rb +46 -0
  16. data/lib/wx/shapes/arrows/cup_arrow.rb +65 -0
  17. data/lib/wx/shapes/arrows/diamond_arrow.rb +8 -13
  18. data/lib/wx/shapes/arrows/double_cross_bar_arrow.rb +27 -0
  19. data/lib/wx/shapes/arrows/filled_arrow.rb +60 -0
  20. data/lib/wx/shapes/arrows/line_arrow.rb +67 -0
  21. data/lib/wx/shapes/arrows/open_arrow.rb +22 -23
  22. data/lib/wx/shapes/arrows/prong_arrow.rb +42 -0
  23. data/lib/wx/shapes/arrows/solid_arrow.rb +21 -35
  24. data/lib/wx/shapes/arrows/square_arrow.rb +37 -0
  25. data/lib/wx/shapes/auto_layout.rb +2 -2
  26. data/lib/wx/shapes/base.rb +1 -1
  27. data/lib/wx/shapes/canvas_history.rb +20 -0
  28. data/lib/wx/shapes/connection_point.rb +10 -6
  29. data/lib/wx/shapes/diagram.rb +98 -78
  30. data/lib/wx/shapes/events.rb +8 -8
  31. data/lib/wx/shapes/printout.rb +3 -16
  32. data/lib/wx/shapes/serializable.rb +2 -436
  33. data/lib/wx/shapes/serialize/wx.rb +30 -18
  34. data/lib/wx/shapes/shape.rb +211 -168
  35. data/lib/wx/shapes/shape_canvas.rb +728 -267
  36. data/lib/wx/shapes/shape_data_object.rb +99 -18
  37. data/lib/wx/shapes/shape_handle.rb +18 -11
  38. data/lib/wx/shapes/shape_list.rb +34 -67
  39. data/lib/wx/shapes/shapes/bitmap_shape.rb +23 -24
  40. data/lib/wx/shapes/shapes/box_shape.rb +389 -0
  41. data/lib/wx/shapes/shapes/circle_shape.rb +19 -22
  42. data/lib/wx/shapes/shapes/control_shape.rb +77 -41
  43. data/lib/wx/shapes/shapes/curve_shape.rb +38 -31
  44. data/lib/wx/shapes/shapes/diamond_shape.rb +7 -17
  45. data/lib/wx/shapes/shapes/edit_text_shape.rb +6 -9
  46. data/lib/wx/shapes/shapes/ellipse_shape.rb +12 -15
  47. data/lib/wx/shapes/shapes/flex_grid_shape.rb +58 -33
  48. data/lib/wx/shapes/shapes/grid_shape.rb +259 -161
  49. data/lib/wx/shapes/shapes/line_shape.rb +155 -161
  50. data/lib/wx/shapes/shapes/manager_shape.rb +77 -0
  51. data/lib/wx/shapes/shapes/multi_sel_rect.rb +8 -8
  52. data/lib/wx/shapes/shapes/ortho_shape.rb +31 -36
  53. data/lib/wx/shapes/shapes/polygon_shape.rb +23 -29
  54. data/lib/wx/shapes/shapes/rect_shape.rb +95 -53
  55. data/lib/wx/shapes/shapes/round_ortho_shape.rb +6 -8
  56. data/lib/wx/shapes/shapes/round_rect_shape.rb +20 -24
  57. data/lib/wx/shapes/shapes/square_shape.rb +14 -17
  58. data/lib/wx/shapes/shapes/text_shape.rb +95 -53
  59. data/lib/wx/shapes/version.rb +1 -1
  60. data/lib/wx/shapes/wx.rb +16 -7
  61. data/lib/wx/wx-shapes/cmd/test.rb +1 -1
  62. data/samples/demo/arrows.json +1 -0
  63. data/samples/demo/arrows.yaml +793 -0
  64. data/samples/demo/art/HBox.xpm +22 -0
  65. data/samples/demo/art/VBox.xpm +22 -0
  66. data/samples/demo/art/logo.xpm +60 -0
  67. data/samples/demo/class.json +1 -0
  68. data/samples/demo/class.yaml +5631 -0
  69. data/samples/demo/demo.rb +301 -91
  70. data/samples/demo/dialogs.rb +1405 -0
  71. data/samples/demo/erd.json +1 -0
  72. data/samples/demo/erd.yaml +4072 -0
  73. data/samples/demo/frame_canvas.rb +409 -33
  74. data/samples/sample1/art/logo.xpm +60 -0
  75. data/samples/sample1/sample.rb +11 -11
  76. data/samples/sample2/art/logo.xpm +60 -0
  77. data/samples/sample2/sample.rb +2 -2
  78. data/samples/sample2/sample_shape.rb +15 -15
  79. data/samples/sample3/art/logo.xpm +60 -0
  80. data/samples/sample3/sample.rb +3 -3
  81. data/samples/sample4/art/logo.xpm +60 -0
  82. data/samples/sample4/sample.rb +2 -2
  83. data/tests/lib/wxapp_runner.rb +4 -0
  84. data/tests/serializer_tests.rb +8 -441
  85. data/tests/test_grid_shapes.rb +2 -2
  86. data/tests/test_serialize_xml.rb +17 -0
  87. data/tests/test_serialize_yaml.rb +2 -2
  88. metadata +78 -28
  89. data/lib/wx/shapes/serialize/core.rb +0 -40
  90. data/lib/wx/shapes/serialize/id.rb +0 -82
  91. data/lib/wx/shapes/serializer/json.rb +0 -258
  92. data/lib/wx/shapes/serializer/yaml.rb +0 -125
  93. data/samples/demo/art/sample.xpm +0 -251
  94. data/samples/sample1/art/sample.xpm +0 -251
  95. data/samples/sample2/art/sample.xpm +0 -251
  96. data/samples/sample3/art/sample.xpm +0 -251
  97. data/samples/sample4/art/sample.xpm +0 -251
@@ -0,0 +1,77 @@
1
+ # Wx::SF::ContainerShape - container shape mixin
2
+ # Copyright (c) M.J.N. Corino, The Netherlands
3
+
4
+ module Wx::SF
5
+
6
+ # Mixin for container shape classes that control there child shape size/position/alignment.
7
+ module ManagerShape
8
+
9
+ # Returns true if the shape manages (size/position/alignment) of it's child shapes.
10
+ # @return [Boolean] true
11
+ def is_manager
12
+ true
13
+ end
14
+ alias :manager? :is_manager
15
+
16
+ # Update the shape's position in order to its alignment
17
+ def do_alignment
18
+ super
19
+
20
+ # do alignment of shape's children
21
+ do_children_layout
22
+ end
23
+
24
+ protected
25
+
26
+ def do_children_layout
27
+ raise NotImplementedError, 'Manager shapes need override'
28
+ end
29
+
30
+ # Move and resize given shape so it will fit the given bounding rectangle.
31
+ #
32
+ # The shape is aligned inside the given bounding rectangle in accordance to the shape's
33
+ # valign and halign flags.
34
+ # @param [Shape] shape modified shape
35
+ # @param [Wx::Rect] rct Bounding rectangle
36
+ # @see Shape#set_v_align
37
+ # @see Shape#set_h_align
38
+ def fit_shape_to_rect(shape, rct)
39
+ shape_bb = shape.get_bounding_box
40
+ prev_pos = shape.get_relative_position
41
+
42
+ # do vertical alignment
43
+ case shape.get_v_align
44
+ when Shape::VALIGN::TOP
45
+ shape.set_relative_position(prev_pos.x, rct.top + shape.get_v_border)
46
+ when Shape::VALIGN::MIDDLE
47
+ shape.set_relative_position(prev_pos.x, rct.top + (rct.height/2 - shape_bb.height/2))
48
+ when Shape::VALIGN::BOTTOM
49
+ shape.set_relative_position(prev_pos.x, rct.bottom - shape_bb.height - shape.get_v_border)
50
+ when Shape::VALIGN::EXPAND
51
+ shape.set_relative_position(prev_pos.x, rct.top + shape.get_v_border)
52
+ shape.scale(1.0, (rct.height - 2*shape.get_v_border).to_f/shape_bb.height)
53
+ else
54
+ shape.set_relative_position(prev_pos.x, rct.top)
55
+ end
56
+
57
+ prev_pos = shape.get_relative_position
58
+
59
+ # do horizontal alignment
60
+ case shape.get_h_align
61
+ when Shape::HALIGN::LEFT
62
+ shape.set_relative_position(rct.left + shape.get_h_border, prev_pos.y)
63
+ when Shape::HALIGN::CENTER
64
+ shape.set_relative_position(rct.left + (rct.width/2 - shape_bb.width/2), prev_pos.y)
65
+ when Shape::HALIGN::RIGHT
66
+ shape.set_relative_position(rct.right - shape_bb.width - shape.get_h_border, prev_pos.y)
67
+ when Shape::HALIGN::EXPAND
68
+ shape.set_relative_position(rct.left + shape.get_h_border, prev_pos.y)
69
+ shape.scale((rct.width - 2*shape.get_h_border).to_f/shape_bb.width, 1.0)
70
+ else
71
+ shape.set_relative_position(rct.left, prev_pos.y)
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -60,7 +60,7 @@ module Wx::SF
60
60
  lst_selection.each do |shape|
61
61
  # scale main parent shape
62
62
  if !shape.is_a?(LineShape)
63
- shape.scale(sx, 1, WITHCHILDREN) if shape.has_style?(STYLE::SIZE_CHANGE)
63
+ shape.scale(sx, 1, children: WITHCHILDREN) if shape.has_style?(STYLE::SIZE_CHANGE)
64
64
  if shape.has_style?(STYLE::POSITION_CHANGE)
65
65
  dx = (shape.get_absolute_position.x - (get_absolute_position.x + DEFAULT_ME_OFFSET))/(get_rect_size.x - 2*DEFAULT_ME_OFFSET)*handle.get_delta.x
66
66
  shape.move_by(dx, 0)
@@ -90,7 +90,7 @@ module Wx::SF
90
90
 
91
91
  lst_selection.each do |shape|
92
92
  if !shape.is_a?(LineShape)
93
- if shape.has_style?(STYLE:POSITION_CHANGE)
93
+ if shape.has_style?(STYLE::POSITION_CHANGE)
94
94
  if shape.get_parent_shape
95
95
  shape.set_relative_position(shape.get_relative_position.x*sx, shape.get_relative_position.y)
96
96
  else
@@ -98,7 +98,7 @@ module Wx::SF
98
98
  shape.move_by(dx, 0)
99
99
  end
100
100
  end
101
- shape.scale(sx, 1, WITHCHILDREN) if shape.has_style?(STYLE::SIZE_CHANGE)
101
+ shape.scale(sx, 1, children: WITHCHILDREN) if shape.has_style?(STYLE::SIZE_CHANGE)
102
102
  shape.fit_to_children unless shape.has_style?(STYLE::NO_FIT_TO_CHILDREN)
103
103
  else
104
104
  if shape.has_style?(STYLE::POSITION_CHANGE)
@@ -132,7 +132,7 @@ module Wx::SF
132
132
  shape.move_by(0, dy)
133
133
  end
134
134
  end
135
- shape.scale(1, sy, WITHCHILDREN) if shape.has_style?(STYLE::SIZE_CHANGE)
135
+ shape.scale(1, sy, children: WITHCHILDREN) if shape.has_style?(STYLE::SIZE_CHANGE)
136
136
  shape.fit_to_children unless shape.has_style?(STYLE::NO_FIT_TO_CHILDREN)
137
137
  else
138
138
  if shape.has_style?(STYLE::POSITION_CHANGE)
@@ -153,12 +153,12 @@ module Wx::SF
153
153
  def on_bottom_handle(handle)
154
154
  if get_parent_canvas && !any_height_exceeded(handle.get_delta)
155
155
  sy = (get_rect_size.y - 2*DEFAULT_ME_OFFSET + handle.get_delta.y).to_f/(get_rect_size.y - 2*DEFAULT_ME_OFFSET)
156
-
156
+
157
157
  lst_selection = get_parent_canvas.get_selected_shapes
158
158
 
159
159
  lst_selection.each do |shape|
160
160
  if !shape.is_a?(LineShape)
161
- shape.scale(1, sy, WITHCHILDREN) if shape.has_style?(STYLE::SIZE_CHANGE)
161
+ shape.scale(1, sy, children: WITHCHILDREN) if shape.has_style?(STYLE::SIZE_CHANGE)
162
162
  if shape.has_style?(STYLE::POSITION_CHANGE)
163
163
  dy = (shape.get_absolute_position.y - (get_absolute_position.y + DEFAULT_ME_OFFSET))/(get_rect_size.y - 2*DEFAULT_ME_OFFSET)*handle.get_delta.y
164
164
  shape.move_by(0, dy)
@@ -187,7 +187,7 @@ module Wx::SF
187
187
  lst_selection = get_parent_canvas.get_selected_shapes
188
188
  # determine whether any shape in the selection exceeds its bounds
189
189
  lst_selection.each do |shape|
190
- return true if !shape.is_a?(LineShape) && (shape.get_bounding_box.width + delta.x) <= 1
190
+ return true if !shape.is_a?(LineShape) && (shape.get_bounding_box.width + delta.x) < 1
191
191
  end
192
192
  return false
193
193
  end
@@ -202,7 +202,7 @@ module Wx::SF
202
202
  lst_selection = get_parent_canvas.get_selected_shapes
203
203
  # determine whether any shape in the selection exceeds its bounds
204
204
  lst_selection.each do |shape|
205
- return true if !shape.is_a?(LineShape) && (shape.get_bounding_box.height + delta.y) <= 1
205
+ return true if !shape.is_a?(LineShape) && (shape.get_bounding_box.height + delta.y) < 1
206
206
  end
207
207
  return false
208
208
  end
@@ -11,14 +11,12 @@ module Wx::SF
11
11
 
12
12
  SEGMENTCPS = ::Struct.new(:src, :trg)
13
13
 
14
- # @overload initialize()
15
- # default constructor
16
- # @overload initialize(src, trg, path, manager)
17
- # @param [Wx::SF::Serializable::ID] src ID of the source shape
18
- # @param [Wx::SF::Serializable::ID] trg ID of the target shape
19
- # @param [Array<Wx::RealPoint>] path List of the line control points (can be empty)
20
- # @param [Diagram] diagram containing diagram
21
- def initialize(*args)
14
+ # Constructor
15
+ # @param [Shape] src source shape
16
+ # @param [Shape] trg target shape
17
+ # @param [Array<Wx::RealPoint>] path List of the line control points (can be empty)
18
+ # @param [Diagram] diagram containing diagram
19
+ def initialize(src = nil, trg = nil, path: nil, diagram: nil)
22
20
  super
23
21
  end
24
22
 
@@ -31,33 +29,33 @@ module Wx::SF
31
29
 
32
30
  src = trg = cp_src = cp_trg = nil
33
31
 
34
- shape = @diagram.find_shape(@src_shape_id)
35
- if shape
36
- cp_src = shape.get_nearest_connection_point(get_mod_src_point)
32
+ if @src_shape
33
+ cp_src = @src_shape.get_nearest_connection_point(get_mod_src_point)
37
34
  end
38
- shape = @diagram.find_shape(@trg_shape_id)
39
- if shape
40
- cp_trg = shape.get_nearest_connection_point(get_mod_trg_point)
35
+ if @trg_shape
36
+ cp_trg = @trg_shape.get_nearest_connection_point(get_mod_trg_point)
41
37
  end
42
38
 
43
39
  case @mode
44
40
  when LINEMODE::READY
45
41
  # draw basic line parts
46
- line_segment_count.times do |i|
42
+ n = line_segment_count-1
43
+ (0..n).each do |i|
47
44
  src, trg = get_line_segment(i)
45
+ # at starting (src) segment draw src arrow and get updated arrow connection point
46
+ if i == 0 && @src_arrow
47
+ asrc, atrg = get_first_subsegment(src, trg, get_used_connection_points(cp_src, cp_trg, 0))
48
+ src = @src_arrow.draw(atrg, asrc, dc)
49
+ cp_src = nil
50
+ end
51
+ # at end (tgt) segment draw tgt arrow and get updated connection point
52
+ if i == n && @trg_arrow
53
+ asrc, atrg = get_last_subsegment(src, trg, get_used_connection_points(cp_src, cp_trg, @lst_points.size))
54
+ trg = @trg_arrow.draw(asrc, atrg, dc)
55
+ cp_trg = nil
56
+ end
48
57
  draw_line_segment(dc, src, trg, get_used_connection_points(cp_src, cp_trg, i))
49
58
  end
50
- # draw target arrow
51
- if @trg_arrow
52
- asrc, atrg = get_last_subsegment(src, trg, get_used_connection_points(cp_src, cp_trg, @lst_points.size))
53
- @trg_arrow.draw(asrc, atrg, dc)
54
- end
55
- # draw source arrow
56
- if @src_arrow
57
- src, trg = get_line_segment(0)
58
- asrc, atrg = get_first_subsegment(src, trg, get_used_connection_points(cp_src, cp_trg, 0))
59
- @src_arrow.draw(atrg, asrc, dc)
60
- end
61
59
 
62
60
  when LINEMODE::UNDERCONSTRUCTION
63
61
  # draw basic line parts
@@ -71,11 +69,10 @@ module Wx::SF
71
69
  if @lst_points.size>1
72
70
  draw_line_segment(dc, trg, @unfinished_point.to_real, get_used_connection_points(cp_src, cp_trg, @lst_points.size))
73
71
  else
74
- src_shape = @diagram.find_shape(@src_shape_id)
75
- if src_shape
76
- if src_shape.get_connection_points.empty?
72
+ if @src_shape
73
+ if @src_shape.get_connection_points.empty?
77
74
  draw_line_segment(dc,
78
- src_shape.get_border_point(src_shape.get_center, @unfinished_point.to_real),
75
+ @src_shape.get_border_point(@src_shape.get_center, @unfinished_point.to_real),
79
76
  @unfinished_point.to_real,
80
77
  get_used_connection_points(cp_src, cp_trg, 0))
81
78
  else
@@ -133,13 +130,11 @@ module Wx::SF
133
130
  cp_src = nil
134
131
  cp_trg = nil
135
132
 
136
- shape = @diagram.find_shape(@src_shape_id)
137
- if shape
138
- cp_src = shape.get_nearest_connection_point(get_mod_src_point)
133
+ if @src_shape
134
+ cp_src = @src_shape.get_nearest_connection_point(get_mod_src_point)
139
135
  end
140
- shape = @diagram.find_shape(@trg_shape_id)
141
- if shape
142
- cp_trg = shape.get_nearest_connection_point(get_mod_trg_point)
136
+ if @trg_shape
137
+ cp_trg = @trg_shape.get_nearest_connection_point(get_mod_trg_point)
143
138
  end
144
139
 
145
140
  # Get all polyline segments
@@ -19,23 +19,14 @@ module Wx::SF
19
19
 
20
20
  property :connect_to_vertex, :vertices
21
21
 
22
- # @overload initialize()
23
- # Default constructor.
24
- # @overload initialize(pos, size, diagram)
25
- # User constructor.
26
- # @param [Array<Wx::RealPoint>] pts Array of the polygon vertices
27
- # @param [Wx::RealPoint] pos Initial position
28
- # @param [Wx::SF::Diagram] diagram parent diagram
29
- def initialize(*args)
22
+ # Constructor.
23
+ # @param [Wx::RealPoint,Wx::Point] pos Initial position
24
+ # @param [Array<Wx::RealPoint>] vertices Array of the polygon vertices
25
+ # @param [Wx::SF::Diagram] diagram parent diagram
26
+ def initialize(pos = Shape::DEFAULT::POSITION, vertices: [], diagram: nil)
27
+ super(pos, Wx::RealPoint.new(1,1), diagram: diagram)
30
28
  @connect_to_vertex = DEFAULT::VERTEXCONNECTIONS
31
- @vertices = []
32
- if args.empty?
33
- super
34
- else
35
- pts, pos, diagram = args
36
- super(pos,Wx::RealPoint.new(1,1), diagram)
37
- set_vertices(pts)
38
- end
29
+ set_vertices(vertices)
39
30
  end
40
31
 
41
32
  # Set connecting mode.
@@ -104,8 +95,9 @@ module Wx::SF
104
95
  intersection
105
96
  else
106
97
  success = false
98
+ min_dist = 0.0
107
99
  pts.each_with_index do |pt, i|
108
- if tmp_intersection = Wx::SF::Shape.lines_intersection(pt, pts[(i+1) % pts.size], start, end_pt)
100
+ if (tmp_intersection = Wx::SF::Shape.lines_intersection(pt, pts[(i+1) % pts.size], start, end_pt))
109
101
  if !success
110
102
  min_dist = intersection.distance_to(end_pt)
111
103
  intersection = tmp_intersection
@@ -166,12 +158,14 @@ module Wx::SF
166
158
  def fit_vertices_to_bounding_box
167
159
  minx, miny, maxx, maxy = get_extents
168
160
 
169
- sx = rect_size.x/(maxx - minx)
170
- sy = rect_size.y/(maxy - miny)
161
+ width = (maxx - minx)
162
+ height = (maxy - miny)
163
+ sx = rect_size.x/width
164
+ sy = rect_size.y/height
171
165
 
172
166
  @vertices.each do |pt|
173
- pt.x *= sx
174
- pt.y *= sy
167
+ pt.x = (width != 0.0) ? pt.x*sx : minx
168
+ pt.y = (height != 0.0) ? pt.y*sy : miny
175
169
  end
176
170
  end
177
171
 
@@ -227,8 +221,8 @@ module Wx::SF
227
221
  def draw_normal(dc)
228
222
  # HINT: overload it for custom actions...
229
223
 
230
- dc.with_pen(@border) do
231
- dc.with_brush(@fill) do
224
+ dc.with_pen(border) do
225
+ dc.with_brush(fill) do
232
226
  draw_polygon_shape(dc)
233
227
  end
234
228
  end
@@ -241,7 +235,7 @@ module Wx::SF
241
235
  # HINT: overload it for custom actions...
242
236
 
243
237
  dc.with_pen(Wx::Pen.new(get_hover_colour, 1)) do
244
- dc.with_brush(@fill) do
238
+ dc.with_brush(fill) do
245
239
  draw_polygon_shape(dc)
246
240
  end
247
241
  end
@@ -255,7 +249,7 @@ module Wx::SF
255
249
  # HINT: overload it for custom actions...
256
250
 
257
251
  dc.with_pen(Wx::Pen.new(get_hover_colour, 2)) do
258
- dc.with_brush(@fill) do
252
+ dc.with_brush(fill) do
259
253
  draw_polygon_shape(dc)
260
254
  end
261
255
  end
@@ -266,7 +260,7 @@ module Wx::SF
266
260
  def draw_shadow(dc)
267
261
  # HINT: overload it for custom actions...
268
262
 
269
- if @fill.get_style != Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT
263
+ if fill.get_style != Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT
270
264
  dc.with_pen(Wx::TRANSPARENT_PEN) do
271
265
  dc.with_brush(get_parent_canvas.get_shadow_fill) do
272
266
  offset = get_parent_canvas.get_shadow_offset
@@ -280,15 +274,15 @@ module Wx::SF
280
274
  end
281
275
 
282
276
  # Deserialize attributes and recalculate rectangle size afterwards.
283
- # @param [Hash] data
284
277
  # @return [self]
285
- def from_serialized(data)
286
- super
278
+ def deserialize_finalize
287
279
  normalize_vertices
288
280
  fit_vertices_to_bounding_box
289
281
  self
290
282
  end
291
283
 
284
+ define_deserialize_finalizer :deserialize_finalize
285
+
292
286
  end
293
287
 
294
288
  end
@@ -7,64 +7,76 @@ module Wx::SF
7
7
 
8
8
  # default values
9
9
  module DEFAULT
10
+ class << self
11
+ # Default value of RectShape fill data member.
12
+ def fill; fill ||= Wx::WHITE_BRUSH.dup; end
13
+ # Default value of RectShape @border data member.
14
+ def border; @border ||= Wx::BLACK_PEN.dup; end
15
+ end
10
16
  # Default value of RectShape @rect_size data member.
11
17
  SIZE = Wx::RealPoint.new(100, 50)
12
- # Default value of RectShape @fill data member.
13
- FILL = Wx::Brush.new(Wx::WHITE) if Wx::App.is_main_loop_running
14
- Wx.add_delayed_constant(self, :FILL) { Wx::Brush.new(Wx::WHITE) }
15
- # Default value of RectShape @border data member.
16
- BORDER = Wx::Pen.new(Wx::BLACK) if Wx::App.is_main_loop_running
17
- Wx.add_delayed_constant(self, :BORDER) { Wx::Pen.new(Wx::BLACK) }
18
18
  end
19
19
 
20
- property :rect_size, :fill, :border
21
-
22
- # @overload initialize()
23
- # Default constructor.
24
- # @overload initialize(pos, size, diagram)
25
- # User constructor.
26
- # @param [Wx::RealPoint] pos Initial position
27
- # @param [Wx::RealPoint] size Initial size
28
- # @param [Wx::SF::Diagram] diagram parent diagram
29
- def initialize(*args)
30
- size = nil
31
- if args.empty?
32
- super
33
- else
34
- pos, size, diagram = args
35
- super(pos, diagram)
36
- end
37
- @rect_size = size ? size.to_real_point : DEFAULT::SIZE.dup
38
- @fill = DEFAULT::FILL
39
- @border = DEFAULT::BORDER
40
- @prev_size = @prev_position = Wx::RealPoint
20
+ property rect_size: :serialize_rect_size
21
+ property({ fill: :serialize_rect_fill,
22
+ border: :serialize_rect_border },
23
+ optional: true)
24
+
25
+ # Constructor.
26
+ # @param [Wx::RealPoint,Wx::Point] pos Initial position
27
+ # @param [Wx::RealPoint,Wx::Size,Wx::Point,Array(Float,Float)] size Initial size
28
+ # @param [Wx::SF::Diagram] diagram parent diagram
29
+ def initialize(pos = Shape::DEFAULT::POSITION, size = DEFAULT::SIZE, diagram: nil)
30
+ super(pos, diagram: diagram)
31
+ set_rect_size(size.to_real_point)
32
+ @fill = nil
33
+ @border = nil
41
34
  end
42
35
 
43
36
  # Set rectangle's fill style.
44
- # @param [Wx::Brush] brush Reference to a brush object
45
- def set_fill(brush)
46
- @fill = brush
37
+ # @overload set_fill(brush)
38
+ # @param [Wx::Brush] brush
39
+ # @overload set_fill(color, style=Wx::BrushStyle::BRUSHSTYLE_SOLID)
40
+ # @param [Wx::Colour,Symbol,String] color brush color
41
+ # @param [Wx::BrushStyle] style
42
+ # @overload set_fill(stipple_bitmap)
43
+ # @param [Wx::Bitmap] stipple_bitmap
44
+ def set_fill(*args)
45
+ @fill = if args.size == 1 && Wx::Brush === args.first
46
+ args.first
47
+ else
48
+ Wx::Brush.new(*args)
49
+ end
47
50
  end
48
51
  alias :fill= :set_fill
49
52
 
50
53
  # Get current fill style.
51
54
  # @return [Wx::Brush] Current brush
52
55
  def get_fill
53
- @fill
56
+ @fill || (@diagram&.shape_canvas ? @diagram.shape_canvas.fill_brush : DEFAULT.fill)
54
57
  end
55
58
  alias :fill :get_fill
56
59
 
57
60
  # Set rectangle's border style.
58
- # @param [Wx::Pen] pen Reference to a pen object
59
- def set_border(pen)
60
- @border = pen
61
+ # @overload set_border(pen)
62
+ # @param [Wx::Pen] pen
63
+ # @overload set_border(color, width=1, style=Wx::PenStyle::PENSTYLE_SOLID)
64
+ # @param [Wx::Colour,String,Symbol] color
65
+ # @param [Integer] width
66
+ # @param [Wx::PenStyle] style
67
+ def set_border(*args)
68
+ @border = if args.size == 1 && Wx::Pen === args.first
69
+ args.first
70
+ else
71
+ Wx::Pen.new(*args)
72
+ end
61
73
  end
62
74
  alias :border= :set_border
63
75
 
64
76
  # Get current border style.
65
77
  # @return [Wx::Pen] Current pen
66
78
  def get_border
67
- @border
79
+ @border || (@diagram&.shape_canvas ? @diagram.shape_canvas.border_pen : DEFAULT.border)
68
80
  end
69
81
  alias :border :get_border
70
82
 
@@ -73,9 +85,11 @@ module Wx::SF
73
85
  # @param [Float] x Horizontal size
74
86
  # @param [Float] y Vertical size
75
87
  # @overload set_rect_size(size)
76
- # @param [Wx::RealPoint] size New size
77
- def set_rect_size(arg1, arg2 = nil)
78
- @rect_size = arg2 ? Wx::RealPoint.new(arg1.to_f, arg2.to_f) : arg1.to_real_point
88
+ # @param [Wx::RealPoint,Array(Float, Float)] size New size
89
+ def set_rect_size(*args)
90
+ x, y = args.size == 1 ? args.first.to_real_point : args
91
+ # set new size while preventing 'invisible' shapes
92
+ @rect_size = Wx::RealPoint.new([1.0, x].max, [1.0, y].max)
79
93
  end
80
94
  alias :rect_size= :set_rect_size
81
95
 
@@ -163,7 +177,7 @@ module Wx::SF
163
177
  def fit_to_children
164
178
  # HINT: overload it for custom actions...
165
179
 
166
- # get bounding box of the shape and children set be inside it
180
+ # get bounding box of the shape and children set to be inside it
167
181
  ch_bb = get_bounding_box
168
182
  shp_bb = ch_bb.dup
169
183
 
@@ -183,7 +197,7 @@ module Wx::SF
183
197
  move_to(shp_bb.get_position.x, shp_bb.get_position.y)
184
198
  @rect_size = Wx::RealPoint.new(shp_bb.get_size.x.to_f, shp_bb.get_size.y.to_f)
185
199
  if has_style?(STYLE::EMIT_EVENTS)
186
- evt = ShapeEvent.new(EVT_SF_SHAPE_SIZE_CHANGED, id)
200
+ evt = ShapeEvent.new(EVT_SF_SHAPE_SIZE_CHANGED, self.object_id)
187
201
  evt.set_shape(self)
188
202
  get_parent_canvas.get_event_handler.process_event(evt)
189
203
  end
@@ -200,11 +214,11 @@ module Wx::SF
200
214
  end
201
215
 
202
216
  # Scale the shape size by in both directions. The function can be overridden if necessary
203
- # (new implementation should call default one ore scale shape's children manualy if neccesary).
217
+ # (new implementation should call default one ore scale shape's children manually if necessary).
204
218
  # @param [Float] x Horizontal scale factor
205
219
  # @param [Float] y Vertical scale factor
206
220
  # @param [Boolean] children true if the shape's children should be scaled as well, otherwise the shape will be updated after scaling via update() function.
207
- def scale(x, y, children = WITHCHILDREN)
221
+ def scale(x, y, children: WITHCHILDREN)
208
222
  # HINT: overload it for custom actions...
209
223
  if x > 0 && y > 0
210
224
  scale_rectangle(x, y)
@@ -218,8 +232,7 @@ module Wx::SF
218
232
 
219
233
  # Handle action at handle drag beginning
220
234
  def do_begin_handle
221
- @prev_position = @relative_position.dup
222
- @prev_size = @rect_size.dup
235
+ # noop
223
236
  end
224
237
 
225
238
  # Scale the rectangle size for this shape.
@@ -270,8 +283,8 @@ module Wx::SF
270
283
  def draw_normal(dc)
271
284
  # HINT: overload it for custom actions...
272
285
 
273
- dc.with_pen(@border) do
274
- dc.with_brush(@fill) do
286
+ dc.with_pen(border) do
287
+ dc.with_brush(fill) do
275
288
  dc.draw_rectangle(get_absolute_position.to_point, @rect_size.to_size)
276
289
  end
277
290
  end
@@ -283,8 +296,8 @@ module Wx::SF
283
296
  def draw_hover(dc)
284
297
  # HINT: overload it for custom actions...
285
298
 
286
- dc.with_pen(Wx::Pen.new(@hover_color, 1)) do
287
- dc.with_brush(@fill) do
299
+ dc.with_pen(Wx::Pen.new(hover_colour, 1)) do
300
+ dc.with_brush(fill) do
288
301
  dc.draw_rectangle(get_absolute_position.to_point, @rect_size.to_size)
289
302
  end
290
303
  end
@@ -297,8 +310,8 @@ module Wx::SF
297
310
  def draw_highlighted(dc)
298
311
  # HINT: overload it for custom actions...
299
312
 
300
- dc.with_pen(Wx::Pen.new(@hover_color, 2)) do
301
- dc.with_brush(@fill) do
313
+ dc.with_pen(Wx::Pen.new(hover_colour, 2)) do
314
+ dc.with_brush(fill) do
302
315
  dc.draw_rectangle(get_absolute_position.to_point, @rect_size.to_size)
303
316
  end
304
317
  end
@@ -309,7 +322,7 @@ module Wx::SF
309
322
  def draw_shadow(dc)
310
323
  # HINT: overload it for custom actions...
311
324
 
312
- if @fill.style != Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT
325
+ if fill.style != Wx::BrushStyle::BRUSHSTYLE_TRANSPARENT
313
326
  dc.with_pen(Wx::TRANSPARENT_PEN) do
314
327
  dc.with_brush(get_parent_canvas.get_shadow_fill) do
315
328
  dc.draw_rectangle((get_absolute_position + get_parent_canvas.get_shadow_offset).to_point, @rect_size.to_size)
@@ -325,6 +338,7 @@ module Wx::SF
325
338
  # HINT: overload it for custom actions...
326
339
 
327
340
  @rect_size.x += handle.get_delta.x
341
+ @rect_size.x = 1.0 if @rect_size.x < 1.0
328
342
  end
329
343
 
330
344
  # Event handler called during dragging of the left shape handle.
@@ -334,7 +348,11 @@ module Wx::SF
334
348
  # HINT: overload it for custom actions...
335
349
 
336
350
  dx = handle.get_delta.x.to_f
337
-
351
+
352
+ if (@rect_size.x - dx) < 1.0
353
+ dx = @rect_size.x - 1.0
354
+ end
355
+
338
356
  # update position of children
339
357
  unless has_style?(STYLE::LOCK_CHILDREN)
340
358
  @child_shapes.each do |child|
@@ -353,7 +371,11 @@ module Wx::SF
353
371
  # HINT: overload it for custom actions...
354
372
 
355
373
  dy = handle.get_delta.y.to_f
356
-
374
+
375
+ if (@rect_size.y - dy) < 1.0
376
+ dy = @rect_size.y - 1.0
377
+ end
378
+
357
379
  # update position of children
358
380
  unless has_style?(STYLE::LOCK_CHILDREN)
359
381
  @child_shapes.each do |child|
@@ -372,7 +394,27 @@ module Wx::SF
372
394
  # HINT: overload it for custom actions...
373
395
 
374
396
  @rect_size.y += handle.get_delta.y
397
+ @rect_size.y = 1.0 if @rect_size.y < 1.0
398
+ end
399
+
400
+ def serialize_rect_size(*val)
401
+ @rect_size = val.first unless val.empty?
402
+ @rect_size
375
403
  end
404
+ private :serialize_rect_size
405
+
406
+ def serialize_rect_fill(*val)
407
+ @fill = val.first unless val.empty?
408
+ @fill
409
+ end
410
+ private :serialize_rect_fill
411
+
412
+ def serialize_rect_border(*val)
413
+ @border = val.first unless val.empty?
414
+ @border
415
+ end
416
+ private :serialize_rect_border
417
+
376
418
  end
377
419
 
378
420
  end
@@ -13,14 +13,12 @@ module Wx::SF
13
13
 
14
14
  property :max_radius
15
15
 
16
- # @overload initialize()
17
- # default constructor
18
- # @overload initialize(src, trg, path, manager)
19
- # @param [Wx::SF::Serializable::ID] src ID of the source shape
20
- # @param [Wx::SF::Serializable::ID] trg ID of the target shape
21
- # @param [Array<Wx::RealPoint>] path List of the line control points (can be empty)
22
- # @param [Diagram] diagram containing diagram
23
- def initialize(*args)
16
+ # Constructor
17
+ # @param [Shape] src source shape
18
+ # @param [Shape] trg target shape
19
+ # @param [Array<Wx::RealPoint>] path List of the line control points (can be empty)
20
+ # @param [Diagram] diagram containing diagram
21
+ def initialize(src = nil, trg = nil, path: nil, diagram: nil)
24
22
  super
25
23
  @max_radius = MAX_RADIUS
26
24
  end