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

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 (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,37 @@
1
+ # Wx::SF::SquareArrow - square arrow class
2
+ # Copyright (c) M.J.N. Corino, The Netherlands
3
+
4
+ require 'wx/shapes/arrows/solid_arrow'
5
+
6
+ module Wx::SF
7
+
8
+ # Class extends the Wx::SolidArrow class and encapsulates
9
+ # square arrow shapes.
10
+ class SquareArrow < SolidArrow
11
+
12
+ # Default square size
13
+ SIZE = 11
14
+
15
+ class << self
16
+
17
+ def arrow(size)
18
+ y = size / 2.0
19
+ [Wx::RealPoint.new(0, y), Wx::RealPoint.new(size, y), Wx::RealPoint.new(size, -y), Wx::RealPoint.new(0 ,-y), Wx::RealPoint.new(size, 0)]
20
+ end
21
+
22
+ end
23
+
24
+ # Get the circle radius
25
+ def get_size
26
+ (SIZE * @ratio).to_i
27
+ end
28
+ alias :size :get_size
29
+
30
+ def vertices
31
+ @vertices ||= SquareArrow.arrow(get_size)
32
+ end
33
+ protected :vertices
34
+
35
+ end
36
+
37
+ end
@@ -145,7 +145,7 @@ module Wx::SF
145
145
  rct_bb = node.get_bounding_box
146
146
  curr_max_width = rct_bb.width if rct_bb.width > curr_max_width
147
147
 
148
- lst_neighbours = node.get_neighbours(Shape, Shape::CONNECTMODE::STARTING)
148
+ lst_neighbours = node.get_neighbours(LineShape, Shape::CONNECTMODE::STARTING)
149
149
 
150
150
  if lst_neighbours.empty?
151
151
  min_x += curr_max_width + @h_space
@@ -204,7 +204,7 @@ module Wx::SF
204
204
  rct_bb = node.get_bounding_box
205
205
  curr_max_height = rct_bb.height if rct_bb.height > curr_max_height
206
206
 
207
- lst_neighbours = node.get_neighbours(Shape, Shape::CONNECTMODE::STARTING)
207
+ lst_neighbours = node.get_neighbours(LineShape, Shape::CONNECTMODE::STARTING)
208
208
 
209
209
  if lst_neighbours.empty?
210
210
  min_y += curr_max_height + @v_space
@@ -13,7 +13,7 @@ module Wx::SF
13
13
  WITHOUTCHILDREN = false
14
14
  ANY = nil
15
15
  DELAYED = true
16
- ACCEPT_ALL = :*
16
+ ACCEPT_ALL = ::NilClass
17
17
 
18
18
  INCLUDE_PARENTS = true
19
19
  WITHOUT_PARENTS = false
@@ -18,6 +18,19 @@ module Wx::SF
18
18
  end
19
19
 
20
20
  attr_accessor :max_states
21
+ attr_reader :current_state
22
+
23
+ # Returns true if no state has been saved yet.
24
+ # @return [Boolean]
25
+ def empty?
26
+ @current_state.nil?
27
+ end
28
+
29
+ # Returns true if the current state is the newest state saved.
30
+ # @return [Boolean]
31
+ def at_latest?
32
+ @current_state && @current_state_index == (@canvas_states.size-1)
33
+ end
21
34
 
22
35
  # Save current canvas state.
23
36
  # @param [String] state serialized diagram state
@@ -58,6 +71,13 @@ module Wx::SF
58
71
  @current_state = @canvas_states[@current_state_index]
59
72
  end
60
73
 
74
+ def clear_current_state
75
+ restore_older_state
76
+ if @current_state
77
+ @canvas_states.slice!(@current_state_index+1, @canvas_states.size)
78
+ end
79
+ end
80
+
61
81
  # Clear all canvas history.
62
82
  def clear
63
83
  @canvas_states.clear
@@ -7,7 +7,7 @@ module Wx::SF
7
7
 
8
8
  class ConnectionPoint
9
9
 
10
- include Wx::SF::Serializable
10
+ include FIRM::Serializable
11
11
 
12
12
  property :type
13
13
  property :ortho_direction
@@ -73,6 +73,8 @@ module Wx::SF
73
73
  end
74
74
  end
75
75
 
76
+ attr_accessor :id
77
+
76
78
  # Get connection point type.
77
79
  # @return [CPTYPE] Connection point type
78
80
  def get_type
@@ -80,6 +82,13 @@ module Wx::SF
80
82
  end
81
83
  alias :type :get_type
82
84
 
85
+ # Set connection point type.
86
+ # @param [CPTYPE] type
87
+ def set_type(type)
88
+ @type = type
89
+ end
90
+ alias :type= :set_type
91
+
83
92
  # Set direction of orthogonal line's connection.
84
93
  # @param [CPORTHODIR] dir Required direction
85
94
  # @see CPORTHODIR
@@ -212,11 +221,6 @@ module Wx::SF
212
221
 
213
222
  private
214
223
 
215
- # For deserialization
216
- def set_type(type)
217
- @type = type
218
- end
219
-
220
224
  # Event handler called when the mouse pointer is moving above shape canvas.
221
225
  # @param [Wx::Point] pos Current mouse position
222
226
  def _on_mouse_move(pos)
@@ -11,7 +11,7 @@ module Wx::SF
11
11
 
12
12
  class Diagram
13
13
 
14
- include Serializable
14
+ include FIRM::Serializable
15
15
 
16
16
  property shapes: :serialize_shapes
17
17
  property :accepted_shapes, :accepted_top_shapes
@@ -28,7 +28,7 @@ module Wx::SF
28
28
  end
29
29
 
30
30
  # Returns the shape canvas.
31
- # @return [Wx::SF::ShapeCanvas]
31
+ # @return [Wx::SF::ShapeCanvas, nil]
32
32
  def get_shape_canvas
33
33
  @shape_canvas
34
34
  end
@@ -63,25 +63,25 @@ module Wx::SF
63
63
  # This function creates new simple connection line (without arrows) between given
64
64
  # shapes.
65
65
  # @overload create_connection(src_id, trg_id, save_state = true)
66
- # @param [Wx::Serializable::ID] src_id id of a source shape
67
- # @param [Wx::Serializable::ID] trg_id id of target shape
66
+ # @param [Shape] src source shape
67
+ # @param [Shape] trg target shape
68
68
  # @param [Boolean] save_state set the parameter true if you wish to save canvas state after the operation
69
69
  # @return [Array(Wx::SF::ERRCODE, Wx::SF::Shape)] operation result and new connection object. the object is added to the shape canvas automatically.
70
70
  # @overload create_connection(src_id, trg_id, line_info, save_state = true)
71
- # @param [Wx::Serializable::ID] src_id id of a source shape
72
- # @param [Wx::Serializable::ID] trg_id id of target shape
71
+ # @param [Shape] src source shape
72
+ # @param [Shape] trg target shape
73
73
  # @param [Class] line_info Connection type (any class inherited from Wx::SF::LineShape)
74
74
  # @param [Boolean] save_state set the parameter true if you wish to save canvas state after the operation
75
75
  # @return [Array(Wx::SF::ERRCODE, Wx::SF::Shape)] operation result and new connection object. the object is added to the shape canvas automatically.
76
76
  # @overload create_connection(src_id, trg_id, line, save_state = true)
77
- # @param [Wx::Serializable::ID] src_id id of a source shape
78
- # @param [Wx::Serializable::ID] trg_id id of target shape
77
+ # @param [Shape] src source shape
78
+ # @param [Shape] trg target shape
79
79
  # @param [Wx::SF::LineShape] line the line shape
80
80
  # @param [Boolean] save_state set the parameter true if you wish to save canvas state after the operation
81
81
  # @return [Array(Wx::SF::ERRCODE, Wx::SF::Shape)] operation result and new connection object. the object is added to the shape canvas automatically.
82
82
  # @see start_interactive_connection
83
- def create_connection(src_id, trg_id, *rest)
84
- err = shape = nil
83
+ def create_connection(src, trg, *rest)
84
+ shape = nil
85
85
  if rest.first.is_a?(LineShape)
86
86
  line = rest.shift
87
87
  save_state = rest.empty? ? true : rest.shift
@@ -93,8 +93,8 @@ module Wx::SF
93
93
  err, shape = create_shape(line_type, DONT_SAVE_STATE)
94
94
  end
95
95
  if shape
96
- shape.set_src_shape_id(src_id)
97
- shape.set_trg_shape_id(trg_id)
96
+ shape.set_src_shape(src)
97
+ shape.set_trg_shape(trg)
98
98
 
99
99
  if @shape_canvas
100
100
  @shape_canvas.save_canvas_state if save_state
@@ -115,6 +115,24 @@ module Wx::SF
115
115
  # @param [Boolean] save_state Set the parameter true if you wish to save canvas state after the operation
116
116
  # @return [Array(Wx::SF::ERRCODE, Wx::SF::Shape)] operation result and new shape. the object is added to the shape canvas automatically.
117
117
  def create_shape(shape_info, *rest)
118
+ if shape_info && is_shape_accepted(shape_info)
119
+ insert_shape(shape_info.new, *rest)
120
+ else
121
+ [ERRCODE::NOT_ACCEPTED, nil]
122
+ end
123
+ end
124
+
125
+ # Insert new shape to the shape canvas.
126
+ # @overload insert_shape(shape, save_state = true)
127
+ # @param [Wx::SF::Shape] shape new shape
128
+ # @param [Boolean] save_state Set the parameter true if you wish to save canvas state after the operation
129
+ # @return [Array(Wx::SF::ERRCODE, Wx::SF::Shape)] operation result and new shape. the object is added to the shape canvas automatically.
130
+ # @overload insert_shape(shape, pos, save_state = true)
131
+ # @param [Wx::SF::Shape] shape new shape
132
+ # @param [Wx::Point] pos shape position (device coordinates)
133
+ # @param [Boolean] save_state Set the parameter true if you wish to save canvas state after the operation
134
+ # @return [Array(Wx::SF::ERRCODE, Wx::SF::Shape)] operation result and new shape. the object is added to the shape canvas automatically.
135
+ def insert_shape(shape, *rest)
118
136
  pos = if rest.first.respond_to?(:to_point)
119
137
  rest.shift.to_point
120
138
  elsif @shape_canvas
@@ -125,20 +143,26 @@ module Wx::SF
125
143
  Wx::Point.new
126
144
  end
127
145
  save_state = rest.empty? ? true : rest.shift
128
- if shape_info && is_shape_accepted(shape_info)
129
- # create shape object from class info
130
- shape = shape_info.new
131
-
146
+ if shape && is_shape_accepted(shape.class)
132
147
  parent_shape = nil
133
148
  # update given position
134
- lpos = pos;
135
- lpos = @shape_canvas.fit_position_to_grid(@shape_canvas.dp2lp(pos)) if @shape_canvas
149
+ lpos = @shape_canvas ? @shape_canvas.dp2lp(pos) : pos
136
150
  # line shapes can be assigned to root only
137
151
  parent_shape = get_shape_at_position(lpos) unless shape.is_a?(LineShape)
138
-
139
- if parent_shape && parent_shape.is_child_accepted(shape_info)
152
+ # In case the matching shape does not accept ANY children see if this shape has a
153
+ # parent that does also match the position and DOES accept children.
154
+ # This allows dropping shapes onto child shapes inside a (container) shapes like
155
+ # grids and/or boxes.
156
+ while parent_shape&.does_not_accept_children? && parent_shape.parent_shape
157
+ parent_shape = parent_shape.parent_shape
158
+ parent_shape = nil unless parent_shape.get_bounding_box.contains?(lpos)
159
+ end
160
+ # see if the located parent (if any) accepts this particular type of child
161
+ if parent_shape && parent_shape.is_child_accepted(shape.class)
162
+ # add shape as child of located parent
140
163
  err = add_shape(shape, parent_shape, pos - parent_shape.get_absolute_position.to_point, INITIALIZE, save_state)
141
164
  else
165
+ # add shape as new toplevel shape (if acceptable)
142
166
  err = add_shape(shape, nil, pos, INITIALIZE, save_state)
143
167
  end
144
168
 
@@ -153,7 +177,7 @@ module Wx::SF
153
177
  # Add an existing shape to the canvas.
154
178
  # @param [Wx::SF::Shape] shape new shape
155
179
  # @param [Wx::SF::Shape] parent the parent shape
156
- # @param [Wx::Point] pos shape position
180
+ # @param [Wx::Point] pos shape position (device coordinates)
157
181
  # @param [Boolean] initialize true if the shape should be reinitialized, otherwise false
158
182
  # @param [Boolean] save_state true if the canvas state should be saved
159
183
  # @return [Wx::SF::ERRCODE] operation result
@@ -192,11 +216,13 @@ module Wx::SF
192
216
  # initialize shape's children
193
217
  lst_children.each do |child|
194
218
  child.create_handles
195
- child.update
219
+ child.update(false)
196
220
 
197
221
  child.set_hover_colour(@shape_canvas.get_hover_colour) if @shape_canvas
198
222
  end
199
223
  end
224
+
225
+ shape.update
200
226
  end
201
227
 
202
228
  # reset scale of assigned shape canvas (if exists and it is necessary...)
@@ -246,9 +272,7 @@ module Wx::SF
246
272
  end
247
273
 
248
274
  # remove the shape and it's children from canvas cache and shape index list
249
- lst_children.each do |child|
250
- @shape_canvas.send(:remove_from_temporaries, shape) if @shape_canvas
251
- end
275
+ @shape_canvas.send(:remove_from_temporaries, shape) if @shape_canvas
252
276
 
253
277
  # remove the shape
254
278
  shape.set_parent_shape(nil) # also removes shape from parent if it had a parent
@@ -288,7 +312,7 @@ module Wx::SF
288
312
  # @param [Wx::SF::Shape] shape
289
313
  # @return [Boolean]
290
314
  def contains_shape(shape)
291
- @shapes.include?(shape.id,true)
315
+ @shapes.include?(shape,true)
292
316
  end
293
317
  alias :contains_shape? :contains_shape
294
318
  alias :contains? :contains_shape
@@ -315,7 +339,7 @@ module Wx::SF
315
339
  min_x = min_y = 0.0
316
340
 
317
341
  # find the maximal negative position value
318
- shapes = get_shapes
342
+ shapes = get_all_shapes
319
343
 
320
344
  shapes.each_with_index do |shape, ix|
321
345
  shape_pos = shape.get_absolute_position
@@ -341,7 +365,7 @@ module Wx::SF
341
365
 
342
366
  # Update all shapes in the diagram manager
343
367
  def update_all
344
- get_shapes.each { |shape| shape.update unless shape.has_children? }
368
+ get_all_shapes.each { |shape| shape.update unless shape.has_children? }
345
369
  end
346
370
 
347
371
  # Add given shape type to an acceptance list. The acceptance list contains class
@@ -350,7 +374,7 @@ module Wx::SF
350
374
  # @param [Class] type Class of accepted shape object
351
375
  # @see is_shape_accepted
352
376
  def accept_shape(type)
353
- ::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class) || type == ACCEPT_ALL
377
+ ::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
354
378
  @accepted_shapes << type
355
379
  end
356
380
 
@@ -386,7 +410,7 @@ module Wx::SF
386
410
  # @param [Class] type Class of accepted shape object
387
411
  # @see is_top_shape_accepted
388
412
  def accept_top_shape(type)
389
- ::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class) || type == ACCEPT_ALL
413
+ ::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
390
414
  @accepted_top_shapes << type
391
415
  end
392
416
 
@@ -415,13 +439,6 @@ module Wx::SF
415
439
  end
416
440
  alias :accepted_top_shapes :get_accepted_top_shapes
417
441
 
418
- # Find shape with given ID.
419
- # @param [Wx::SF::Serializable::ID] id Shape's ID
420
- # @return [Wx::SF::Shape] shape if exists, otherwise nil
421
- def find_shape(id)
422
- @shapes.get(id, true)
423
- end
424
-
425
442
  # Get list of connections assigned to given parent shape.
426
443
  # @param [Wx::SF::Shape] parent parent shape
427
444
  # @param [Class] shape_info Line object type
@@ -430,19 +447,19 @@ module Wx::SF
430
447
  # @return [Array<Wx::SF::Shape>] shape list
431
448
  # @see Wx::SF::Shape::CONNECTMODE
432
449
  def get_assigned_connections(parent, shape_info, mode, lines = [])
433
- return lines unless parent && parent.get_id
450
+ return lines unless parent
434
451
 
435
452
  # lines are all toplevel so we do not have to search recursively...
436
- lst_lines = @shapes.select { |shape| shape.is_a?(shape_info) }
453
+ lst_lines = @shapes.select { |shape| shape.is_a?(shape_info) && !shape.stand_alone? }
437
454
 
438
455
  lst_lines.each do |line|
439
456
  case mode
440
457
  when Shape::CONNECTMODE::STARTING
441
- lines << line if line.get_src_shape_id == parent.get_id
458
+ lines << line if line.get_src_shape == parent
442
459
  when Shape::CONNECTMODE::ENDING
443
- lines << line if line.get_trg_shape_id == parent.get_id
460
+ lines << line if line.get_trg_shape == parent
444
461
  when Shape::CONNECTMODE::BOTH
445
- lines << line if line.get_src_shape_id == parent.get_id || line.get_trg_shape_id == parent.get_id
462
+ lines << line if line.get_src_shape == parent || line.get_trg_shape == parent
446
463
  end
447
464
  end
448
465
  lines
@@ -453,6 +470,9 @@ module Wx::SF
453
470
  @shapes
454
471
  end
455
472
 
473
+ # Get all shapes recursively.
474
+ # This is an optimized convenience method which returns all shapes the same as if #get_shapes() was called with
475
+ # default arguments.
456
476
  def get_all_shapes
457
477
  @shapes.all
458
478
  end
@@ -478,7 +498,7 @@ module Wx::SF
478
498
  # @param [Wx::Point] pos Logical position
479
499
  # @param [Integer] zorder Z-order of searched shape (useful if several shapes are located at the given position)
480
500
  # @param [SEARCHMODE] mode Search mode
481
- # @return [Wx::SF::Shape] shape if found, otherwise nil
501
+ # @return [Wx::SF::Shape, nil] shape if found, otherwise nil
482
502
  # @see SEARCHMODE
483
503
  # @see Wx::SF::ShapeCanvas::dp2lp
484
504
  # @see Wx::SF::ShapeCanvas#get_shape_under_cursor
@@ -487,7 +507,7 @@ module Wx::SF
487
507
  # and all non-line shapes get listed in reversed order as returned from get_shapes (for z order)
488
508
  ins_pos = 0
489
509
  pos = pos.to_point
490
- shapes = get_shapes.inject([]) do |list, shape|
510
+ shapes = get_all_shapes.inject([]) do |list, shape|
491
511
  if shape.is_a?(LineShape)
492
512
  list.prepend(shape)
493
513
  ins_pos += 1
@@ -528,7 +548,7 @@ module Wx::SF
528
548
  # @see Wx::SF::ShapeCanvas::dp2lp
529
549
  def get_shapes_at_position(pos, shapes = [])
530
550
  pos = pos.to_point
531
- get_shapes.each do |shape|
551
+ get_all_shapes.each do |shape|
532
552
  shapes << shape if shape.visible? && shape.active? && shape.contains?(pos)
533
553
  end
534
554
  end
@@ -538,7 +558,7 @@ module Wx::SF
538
558
  # @param [Array<Wx::SF::Shape>] shapes shape list where all found shapes will be stored
539
559
  # @return [Array<Wx::SF::Shape>] shape list
540
560
  def get_shapes_inside(rct, shapes = [])
541
- get_shapes.each do |shape|
561
+ get_all_shapes.each do |shape|
542
562
  shapes << shape if shape.visible? && shape.active? && shape.intersects?(rct)
543
563
  end
544
564
  end
@@ -576,20 +596,20 @@ module Wx::SF
576
596
  shape.get_neighbours(shape_info, condir, direct, neighbours)
577
597
  end
578
598
  end
599
+ neighbours
579
600
  end
580
601
 
581
602
  private
582
603
 
583
- # Update connection shapes after importing/dropping of new shapes
584
- def check_new_shapes(new_shapes)
585
- # deserializing will create unique ids synchronized across all deserialized shapes
586
- # lines and both connected shapes should have matching ids
587
- # we will remove any lines for which one or both connected shapes are missing (not copied)
604
+ # Update shapes after importing/dropping of new shapes
605
+ def on_import(new_shapes)
606
+ # Deserializing will create unique new shapes from the serialized data where
607
+ # lines and both connected shapes should be present.
608
+ # We will remove any lines for which one or both connected shapes are missing (not copied).
588
609
  new_shapes.select! do |shape|
589
610
  if shape.is_a?(LineShape)
590
- # so that lines with both connected shapes will have matching ids
591
- # we will remove any lines for which one or both connected shapes are missing (not copied)
592
- if @shapes.include?(shape.get_src_shape_id) && @shapes.include?(shape.get_trg_shape_id)
611
+ # remove any lines for which one or both connected shapes are missing (not copied)
612
+ if @shapes.include?(shape.get_src_shape, true) && @shapes.include?(shape.get_trg_shape, true)
593
613
  shape.create_handles
594
614
  true # keep
595
615
  else
@@ -601,39 +621,39 @@ module Wx::SF
601
621
  true # keep
602
622
  end
603
623
  end
604
- # deserializing will create unique ids synchronized across all deserialized shapes
605
- # so that grids and shapes linked to it's cells should have matching ids
606
- # we will clear any cells for which shapes are missing (not copied)
607
- update_grids(new_shapes) unless new_shapes.empty?
608
- end
609
-
610
- # Update grid shapes after importing/dropping of new shapes
611
- def update_grids(new_shapes)
612
- # deserializing will create unique ids synchronized across all deserialized shapes
613
- # so that grids and shapes linked to it's cells will have matching ids
614
- # we will clear any cells for which shapes are missing (not copied)
624
+ # deserializing will create unique ids which should have synchronized across
625
+ # all deserialized shapes and their internal links
626
+ # existing links to shapes that have not been copied/imported may be dangling
627
+ # and should be cleared
628
+ # iterate all accepted imported shapes and signal them to check links (if any)
615
629
  new_shapes.each do |shape|
616
- if shape.is_a?(GridShape)
617
- grid.each_cell do |row, col, id|
618
- grid.clear_cell(row, col) unless id.nil? || @shapes.include?(id)
619
- end
620
- elsif shape.has_children?
630
+ shape.__send__(:on_import)
631
+ if shape.has_children?
621
632
  shape.get_children_recursively(nil, Shape::SEARCHMODE::DFS).each do |child|
622
- if shape.is_a?(GridShape)
623
- grid.each_cell do |row, col, id|
624
- grid.clear_cell(row, col) unless id.nil? || @shapes.include?(id)
625
- end
626
- end
633
+ child.__send__(:on_import)
627
634
  end
628
635
  end
629
636
  end
630
637
  end
631
638
 
632
- # Shape lis (de-)serialization
639
+ # Shape list (de-)serialization
633
640
  def serialize_shapes(*arg)
634
641
  unless arg.empty?
635
- @shapes = arg.shift
636
- @shapes.each { |shape| shape.set_diagram(self); shape.create_handles }
642
+ @shapes = arg.shift # get deserialized shapes
643
+ # initialize deserialized shapes
644
+ @shapes.each do |shape|
645
+ # set diagram for shape (incl. children)
646
+ shape.set_diagram(self)
647
+ shape.create_handles
648
+ if has_children(shape)
649
+ # get shape's children (if exist)
650
+ lst_children = shape.get_child_shapes(ANY, RECURSIVE)
651
+ # initialize shape's children
652
+ lst_children.each do |child|
653
+ child.create_handles
654
+ end
655
+ end
656
+ end
637
657
  end
638
658
  @shapes
639
659
  end
@@ -7,7 +7,7 @@ module Wx::SF
7
7
  class ShapeEvent < Wx::Event
8
8
  # Constructor
9
9
  # @param [Integer] evt_type
10
- # @param [Wx::SF::Serializable::ID, Integer] id
10
+ # @param [Integer] id
11
11
  def initialize(evt_type = Wx::EVT_NULL, id = 0)
12
12
  super(evt_type, id.to_i)
13
13
  @shape = nil
@@ -45,7 +45,7 @@ module Wx::SF
45
45
  class ShapeKeyEvent < Wx::Event
46
46
  # Constructor
47
47
  # @param [Integer] evt_type
48
- # @param [Wx::SF::Serializable::ID, Integer] id
48
+ # @param [Integer] id
49
49
  def initialize(evt_type = Wx::EVT_NULL, id = 0)
50
50
  super(evt_type, id.to_i)
51
51
  @shape = nil
@@ -85,7 +85,7 @@ module Wx::SF
85
85
  class ShapeMouseEvent < Wx::Event
86
86
  # Constructor
87
87
  # @param [Integer] evt_type
88
- # @param [Wx::SF::Serializable::ID, Integer] id
88
+ # @param [Integer] id
89
89
  def initialize(evt_type = Wx::EVT_NULL, id = 0)
90
90
  super(evt_type, id.to_i)
91
91
  @shape = nil
@@ -125,7 +125,7 @@ module Wx::SF
125
125
  class ShapeTextEvent < Wx::Event
126
126
  # Constructor
127
127
  # @param [Integer] evt_type
128
- # @param [Wx::SF::Serializable::ID, Integer] id
128
+ # @param [Integer] id
129
129
  def initialize(evt_type = Wx::EVT_NULL, id = 0)
130
130
  super(evt_type, id.to_i)
131
131
  @shape = nil
@@ -165,7 +165,7 @@ module Wx::SF
165
165
  class ShapeHandleEvent < Wx::Event
166
166
  # Constructor
167
167
  # @param [Integer] evt_type
168
- # @param [Wx::SF::Serializable::ID, Integer] id
168
+ # @param [Integer] id
169
169
  def initialize(evt_type = Wx::EVT_NULL, id = 0)
170
170
  super(evt_type, id.to_i)
171
171
  @shape = nil
@@ -211,7 +211,7 @@ module Wx::SF
211
211
  # @param [Integer] y
212
212
  # @param [Wx::SF::ShapeCanvas] target
213
213
  # @param [Wx::DragResult] def_result
214
- # @param [Wx::SF::Serializable::ID, Integer] id
214
+ # @param [Integer] id
215
215
  def initialize(evt_type = Wx::EVT_NULL, x = 0, y = 0, target = nil, def_result = Wx::DragResult::DragNone, id = 0)
216
216
  super(evt_type, id.to_i)
217
217
  @dropped_shapes = []
@@ -284,7 +284,7 @@ module Wx::SF
284
284
  # Constructor
285
285
  # @param [Integer] evt_type
286
286
  # @param [Wx::SF::ShapeCanvas] target
287
- # @param [Wx::SF::Serializable::ID, Integer] id
287
+ # @param [Integer] id
288
288
  def initialize(evt_type = Wx::EVT_NULL, target = nil, id = 0)
289
289
  super(evt_type, id.to_i)
290
290
  @pasted_shapes = []
@@ -324,7 +324,7 @@ module Wx::SF
324
324
  class ShapeChildDropEvent < Wx::Event
325
325
  # Constructor
326
326
  # @param [Integer] evt_type
327
- # @param [Wx::SF::Serializable::ID, Integer] id
327
+ # @param [Integer] id
328
328
  def initialize(evt_type = Wx::EVT_NULL, id = 0)
329
329
  super(evt_type, id.to_i)
330
330
  @shape = nil
@@ -100,27 +100,14 @@ module Wx::SF
100
100
 
101
101
  # store current canvas properties
102
102
  prev_scale = @canvas.get_scale
103
- prev_style = @canvas.get_style
104
- prev_colour = @canvas.get_canvas_colour
105
-
106
- # disable canvas background drawing if required
107
- unless @canvas.has_style?(ShapeCanvas::STYLE::PRINT_BACKGROUND)
108
- @canvas.remove_style(ShapeCanvas::STYLE::GRADIENT_BACKGROUND)
109
- @canvas.remove_style(ShapeCanvas::STYLE::GRID_SHOW)
110
- @canvas.set_canvas_colour(Wx::WHITE)
111
- end
112
-
103
+
113
104
  # draw the canvas content without any scale (dc is scaled by the printing framework)
114
105
  @canvas.set_scale(1.0)
106
+ @canvas.draw_background(dc, NOT_FROM_PAINT) if @canvas.has_style?(ShapeCanvas::STYLE::PRINT_BACKGROUND)
115
107
  @canvas.draw_content(dc, NOT_FROM_PAINT)
108
+ @canvas.draw_foreground(dc, NOT_FROM_PAINT)
116
109
  @canvas.set_scale(prev_scale)
117
110
 
118
- # restore previous canvas properties if needed
119
- unless @canvas.has_style?(ShapeCanvas::STYLE::PRINT_BACKGROUND)
120
- @canvas.set_style(prev_style)
121
- @canvas.set_canvas_colour(prev_colour)
122
- end
123
-
124
111
  return true
125
112
  end
126
113
  false