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.
- checksums.yaml +4 -4
- data/INSTALL.md +5 -7
- data/README.md +38 -6
- data/assets/logo.svg +339 -0
- data/assets/logo.xpm +60 -0
- data/assets/screenshot.png +0 -0
- data/assets/social.png +0 -0
- data/bin/wx-shapes +1 -1
- data/lib/wx/shapes/arrow_base.rb +4 -11
- data/lib/wx/shapes/arrows/circle_arrow.rb +22 -11
- data/lib/wx/shapes/arrows/circle_prong_arrow.rb +48 -0
- data/lib/wx/shapes/arrows/cross_bar_arrow.rb +57 -0
- data/lib/wx/shapes/arrows/cross_bar_circle_arrow.rb +56 -0
- data/lib/wx/shapes/arrows/cross_bar_prong_arrow.rb +49 -0
- data/lib/wx/shapes/arrows/crossed_circle.rb +46 -0
- data/lib/wx/shapes/arrows/cup_arrow.rb +65 -0
- data/lib/wx/shapes/arrows/diamond_arrow.rb +8 -13
- data/lib/wx/shapes/arrows/double_cross_bar_arrow.rb +27 -0
- data/lib/wx/shapes/arrows/filled_arrow.rb +60 -0
- data/lib/wx/shapes/arrows/line_arrow.rb +67 -0
- data/lib/wx/shapes/arrows/open_arrow.rb +22 -23
- data/lib/wx/shapes/arrows/prong_arrow.rb +42 -0
- data/lib/wx/shapes/arrows/solid_arrow.rb +21 -35
- data/lib/wx/shapes/arrows/square_arrow.rb +37 -0
- data/lib/wx/shapes/auto_layout.rb +2 -2
- data/lib/wx/shapes/base.rb +1 -1
- data/lib/wx/shapes/canvas_history.rb +20 -0
- data/lib/wx/shapes/connection_point.rb +10 -6
- data/lib/wx/shapes/diagram.rb +98 -78
- data/lib/wx/shapes/events.rb +8 -8
- data/lib/wx/shapes/printout.rb +3 -16
- data/lib/wx/shapes/serializable.rb +2 -436
- data/lib/wx/shapes/serialize/wx.rb +30 -18
- data/lib/wx/shapes/shape.rb +211 -168
- data/lib/wx/shapes/shape_canvas.rb +728 -267
- data/lib/wx/shapes/shape_data_object.rb +99 -18
- data/lib/wx/shapes/shape_handle.rb +18 -11
- data/lib/wx/shapes/shape_list.rb +34 -67
- data/lib/wx/shapes/shapes/bitmap_shape.rb +23 -24
- data/lib/wx/shapes/shapes/box_shape.rb +389 -0
- data/lib/wx/shapes/shapes/circle_shape.rb +19 -22
- data/lib/wx/shapes/shapes/control_shape.rb +77 -41
- data/lib/wx/shapes/shapes/curve_shape.rb +38 -31
- data/lib/wx/shapes/shapes/diamond_shape.rb +7 -17
- data/lib/wx/shapes/shapes/edit_text_shape.rb +6 -9
- data/lib/wx/shapes/shapes/ellipse_shape.rb +12 -15
- data/lib/wx/shapes/shapes/flex_grid_shape.rb +58 -33
- data/lib/wx/shapes/shapes/grid_shape.rb +259 -161
- data/lib/wx/shapes/shapes/line_shape.rb +155 -161
- data/lib/wx/shapes/shapes/manager_shape.rb +77 -0
- data/lib/wx/shapes/shapes/multi_sel_rect.rb +8 -8
- data/lib/wx/shapes/shapes/ortho_shape.rb +31 -36
- data/lib/wx/shapes/shapes/polygon_shape.rb +23 -29
- data/lib/wx/shapes/shapes/rect_shape.rb +95 -53
- data/lib/wx/shapes/shapes/round_ortho_shape.rb +6 -8
- data/lib/wx/shapes/shapes/round_rect_shape.rb +20 -24
- data/lib/wx/shapes/shapes/square_shape.rb +14 -17
- data/lib/wx/shapes/shapes/text_shape.rb +95 -53
- data/lib/wx/shapes/version.rb +1 -1
- data/lib/wx/shapes/wx.rb +16 -7
- data/lib/wx/wx-shapes/cmd/test.rb +1 -1
- data/samples/demo/arrows.json +1 -0
- data/samples/demo/arrows.yaml +793 -0
- data/samples/demo/art/HBox.xpm +22 -0
- data/samples/demo/art/VBox.xpm +22 -0
- data/samples/demo/art/logo.xpm +60 -0
- data/samples/demo/class.json +1 -0
- data/samples/demo/class.yaml +5631 -0
- data/samples/demo/demo.rb +301 -91
- data/samples/demo/dialogs.rb +1405 -0
- data/samples/demo/erd.json +1 -0
- data/samples/demo/erd.yaml +4072 -0
- data/samples/demo/frame_canvas.rb +409 -33
- data/samples/sample1/art/logo.xpm +60 -0
- data/samples/sample1/sample.rb +11 -11
- data/samples/sample2/art/logo.xpm +60 -0
- data/samples/sample2/sample.rb +2 -2
- data/samples/sample2/sample_shape.rb +15 -15
- data/samples/sample3/art/logo.xpm +60 -0
- data/samples/sample3/sample.rb +3 -3
- data/samples/sample4/art/logo.xpm +60 -0
- data/samples/sample4/sample.rb +2 -2
- data/tests/lib/wxapp_runner.rb +4 -0
- data/tests/serializer_tests.rb +8 -441
- data/tests/test_grid_shapes.rb +2 -2
- data/tests/test_serialize_xml.rb +17 -0
- data/tests/test_serialize_yaml.rb +2 -2
- metadata +78 -28
- data/lib/wx/shapes/serialize/core.rb +0 -40
- data/lib/wx/shapes/serialize/id.rb +0 -82
- data/lib/wx/shapes/serializer/json.rb +0 -258
- data/lib/wx/shapes/serializer/yaml.rb +0 -125
- data/samples/demo/art/sample.xpm +0 -251
- data/samples/sample1/art/sample.xpm +0 -251
- data/samples/sample2/art/sample.xpm +0 -251
- data/samples/sample3/art/sample.xpm +0 -251
- data/samples/sample4/art/sample.xpm +0 -251
data/lib/wx/shapes/shape.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# Copyright (c) M.J.N. Corino, The Netherlands
|
3
3
|
|
4
4
|
require 'wx/shapes/serializable'
|
5
|
+
require 'wx/shapes/shapes/manager_shape'
|
5
6
|
|
6
7
|
require 'set'
|
7
8
|
|
@@ -29,15 +30,16 @@ module Wx::SF
|
|
29
30
|
# mostly triggered by a parent shape canvas.
|
30
31
|
class Shape
|
31
32
|
|
32
|
-
include Serializable
|
33
|
+
include FIRM::Serializable
|
33
34
|
|
34
|
-
property :
|
35
|
+
property :active, :visibility, :style,
|
35
36
|
:accepted_children, :accepted_connections,
|
36
37
|
:accepted_src_neighbours, :accepted_trg_neighbours,
|
37
|
-
:
|
38
|
+
:relative_position,
|
38
39
|
:h_align, :v_align, :h_border, :v_border,
|
39
40
|
:custom_dock_point, :connection_points,
|
40
41
|
:user_data
|
42
|
+
property({ hover_colour: :serialize_hover_colour }, optional: true)
|
41
43
|
property child_shapes: :serialize_child_shapes
|
42
44
|
|
43
45
|
class SEARCHMODE < Wx::Enum
|
@@ -102,8 +104,10 @@ module Wx::SF
|
|
102
104
|
HIGHLIGHTING = self.new(16)
|
103
105
|
# Shape is always inside its parent
|
104
106
|
ALWAYS_INSIDE = self.new(32)
|
105
|
-
#
|
106
|
-
|
107
|
+
# Shape is not drawn. Does not apply to children.
|
108
|
+
# Should be combined with PROPAGATE_DRAGGING | PROPAGATE_SELECTION | PROPAGATE_INTERACTIVE_CONNECTION | PROPAGATE_HOVERING | PROPAGATE_HIGHLIGHTING | PROPAGATE_DROPPING
|
109
|
+
# in most cases.
|
110
|
+
NOT_DRAWN = self.new(64)
|
107
111
|
# The DEL key is processed by the shape (not by the shape canvas)
|
108
112
|
PROCESS_DEL = self.new(128)
|
109
113
|
# Show handles if the shape is selected
|
@@ -124,21 +128,26 @@ module Wx::SF
|
|
124
128
|
NO_FIT_TO_CHILDREN = self.new(32768)
|
125
129
|
# Propagate hovering to parent.
|
126
130
|
PROPAGATE_HOVERING = self.new(65536)
|
127
|
-
# Propagate
|
131
|
+
# Propagate highlighting to parent.
|
128
132
|
PROPAGATE_HIGHLIGHTING = self.new(131072)
|
133
|
+
# Propagate dropping to parent.
|
134
|
+
PROPAGATE_DROPPING = self.new(262144)
|
129
135
|
# Default shape style
|
130
|
-
DEFAULT_SHAPE_STYLE = PARENT_CHANGE | POSITION_CHANGE | SIZE_CHANGE | HOVERING | HIGHLIGHTING | SHOW_HANDLES | ALWAYS_INSIDE
|
136
|
+
DEFAULT_SHAPE_STYLE = PARENT_CHANGE | POSITION_CHANGE | SIZE_CHANGE | HOVERING | HIGHLIGHTING | SHOW_HANDLES | ALWAYS_INSIDE
|
137
|
+
# Shortcut for all propagation options
|
138
|
+
PROPAGATE_ALL = PROPAGATE_DRAGGING | PROPAGATE_SELECTION | PROPAGATE_INTERACTIVE_CONNECTION | PROPAGATE_HOVERING | PROPAGATE_HIGHLIGHTING | PROPAGATE_DROPPING
|
131
139
|
end
|
132
140
|
|
133
141
|
# Default values
|
134
142
|
module DEFAULT
|
143
|
+
class << self
|
144
|
+
# Default value of Wx::SF::Shape @hoverColor data member
|
145
|
+
def hover_colour; Wx::Colour.new(120, 120, 255); end
|
146
|
+
end
|
135
147
|
# Default value of Wx::SF::Shape @visible data member
|
136
148
|
VISIBILITY = true
|
137
149
|
# Default value of Wx::SF::Shape @active data member
|
138
150
|
ACTIVITY = true
|
139
|
-
# Default value of Wx::SF::Shape @hoverColor data member
|
140
|
-
HOVERCOLOUR = Wx::Colour.new(120, 120, 255) if Wx::App.is_main_loop_running
|
141
|
-
Wx.add_delayed_constant(self, :HOVERCOLOUR) { Wx::Colour.new(120, 120, 255) }
|
142
151
|
# Default value of Wx::SF::Shape @relativePosition data member
|
143
152
|
POSITION = Wx::RealPoint.new(0, 0)
|
144
153
|
# Default value of Wx::SF::Shape @vAlign data member
|
@@ -172,7 +181,7 @@ module Wx::SF
|
|
172
181
|
# @overload component(hash)
|
173
182
|
# Specifies one or more serialized component properties with associated setter/getter method ids/procs/lambda-s.
|
174
183
|
# @example
|
175
|
-
#
|
184
|
+
# component(
|
176
185
|
# prop_a: ->(obj, *val) {
|
177
186
|
# obj.my_prop_a_setter(val.first) unless val.empty?
|
178
187
|
# obj.my_prop_a_getter
|
@@ -227,35 +236,24 @@ module Wx::SF
|
|
227
236
|
protected :from_serialized
|
228
237
|
end
|
229
238
|
include ComponentSerializerMethods
|
230
|
-
|
239
|
+
__CODE
|
231
240
|
end
|
232
241
|
end
|
233
242
|
|
234
|
-
#
|
235
|
-
#
|
236
|
-
# @
|
237
|
-
|
238
|
-
# @param [Diagram] diagram containing diagram
|
239
|
-
def initialize(*args)
|
240
|
-
pos, diagram = args
|
243
|
+
# Constructor
|
244
|
+
# @param [Wx::RealPoint, Wx::Point] pos Initial relative position
|
245
|
+
# @param [Diagram] diagram containing diagram
|
246
|
+
def initialize(pos = DEFAULT::POSITION, diagram: nil)
|
241
247
|
::Kernel.raise ArgumentError, "Invalid arguments pos: #{pos}, diagram: #{diagram}" unless
|
242
|
-
|
248
|
+
Wx::RealPoint === pos && (diagram.nil? || Wx::SF::Diagram === diagram)
|
243
249
|
|
244
|
-
@id = Serializable::ID.new
|
245
250
|
@diagram = diagram
|
246
251
|
@parent_shape = nil
|
247
252
|
@child_shapes = ShapeList.new
|
248
253
|
@components = ::Set.new
|
249
254
|
|
250
|
-
|
251
|
-
|
252
|
-
@hover_color = @diagram.shape_canvas.hover_colour
|
253
|
-
else
|
254
|
-
@hover_color = DEFAULT::HOVERCOLOUR;
|
255
|
-
end
|
256
|
-
else
|
257
|
-
@hover_color = DEFAULT::HOVERCOLOUR;
|
258
|
-
end
|
255
|
+
# by default the common canvas hover colour will be used
|
256
|
+
@hover_color = nil
|
259
257
|
|
260
258
|
@selected = false
|
261
259
|
@mouse_over = false
|
@@ -273,11 +271,7 @@ module Wx::SF
|
|
273
271
|
@h_border = DEFAULT::HBORDER
|
274
272
|
@custom_dock_point = DEFAULT::DOCK_POINT
|
275
273
|
|
276
|
-
|
277
|
-
@relative_position = pos.to_real_point - get_parent_absolute_position
|
278
|
-
else
|
279
|
-
@relative_position = DEFAULT::POSITION.dup
|
280
|
-
end
|
274
|
+
@relative_position = Wx::RealPoint === pos ? pos.dup : pos.to_real_point
|
281
275
|
|
282
276
|
@handles = []
|
283
277
|
@connection_pts = []
|
@@ -288,20 +282,6 @@ module Wx::SF
|
|
288
282
|
@accepted_trg_neighbours = ::Set.new
|
289
283
|
end
|
290
284
|
|
291
|
-
# Get the shape's id
|
292
|
-
# @return [Wx::SF::Serializable::ID]
|
293
|
-
def get_id
|
294
|
-
@id
|
295
|
-
end
|
296
|
-
alias :id :get_id
|
297
|
-
|
298
|
-
# Set the shape's id. Deserialization only.
|
299
|
-
# @param [Wx::SF::Serializable::ID] id
|
300
|
-
def set_id(id)
|
301
|
-
@id = id
|
302
|
-
end
|
303
|
-
private :set_id
|
304
|
-
|
305
285
|
# Set managing diagram
|
306
286
|
# @param [Wx::SF::Diagram] diagram
|
307
287
|
def set_diagram(diagram)
|
@@ -343,9 +323,10 @@ module Wx::SF
|
|
343
323
|
# @param [Wx::SF::Shape] child child shape to add
|
344
324
|
# @return [Wx::SF::Shape,nil] added child shape or nil if not accepted
|
345
325
|
def add_child_shape(child)
|
326
|
+
raise SFException, 'Illegal attempt to add self as Shape child' if child == self
|
346
327
|
if is_child_accepted(child.class)
|
347
328
|
if child.get_diagram
|
348
|
-
child.get_diagram.reparent_shape(child,
|
329
|
+
child.get_diagram.reparent_shape(child, self)
|
349
330
|
else
|
350
331
|
child.set_parent_shape(self)
|
351
332
|
end
|
@@ -355,12 +336,24 @@ module Wx::SF
|
|
355
336
|
nil
|
356
337
|
end
|
357
338
|
|
339
|
+
|
340
|
+
# Returns true if the given shape is included in the child shapes list.
|
341
|
+
# Performs a recursive search in case :recursive is true.
|
342
|
+
# @param [shape] shape shape to match
|
343
|
+
# @param [Boolean] recursive pass true to search recursively, false for non-recursive
|
344
|
+
# @return [Boolean] true if included, otherwise false
|
345
|
+
def include_child_shape?(shape, recursive = false)
|
346
|
+
@child_shapes.include?(shape, recursive)
|
347
|
+
end
|
348
|
+
|
358
349
|
# Set parent shape object.
|
359
350
|
# @param [Wx::SF::Shape] parent
|
360
351
|
# @note Note that this does not check this shape against the acceptance list of the parent. Use #add_child_shape if that is required.
|
361
352
|
# @note Note that this does not add (if parent == nil) or remove (if parent != nil) the shape from the diagram's
|
362
353
|
# toplevel shapes. Use Diagram#reparent_shape when that is needed.
|
363
354
|
def set_parent_shape(parent)
|
355
|
+
raise SFException, 'Illegal to set Shape parent to self' if parent == self
|
356
|
+
raise SFException, 'Illegal to set Shape parent to (grand-)child of self' if parent && include_child_shape?(parent, true)
|
364
357
|
@parent_shape.send(:remove_child, self) if @parent_shape
|
365
358
|
parent.send(:add_child, self) if parent
|
366
359
|
set_diagram(parent.get_diagram) if parent
|
@@ -383,7 +376,7 @@ module Wx::SF
|
|
383
376
|
alias :grand_parent_shape :get_grand_parent_shape
|
384
377
|
|
385
378
|
# Refresh (redraw) the shape
|
386
|
-
# @param [Boolean] delayed If true then the shape canvas will be rather
|
379
|
+
# @param [Boolean] delayed If true then the shape canvas will be invalidated rather than refreshed.
|
387
380
|
# @see ShapeCanvas#invalidate_rect
|
388
381
|
# @see ShapeCanvas#refresh_invalidated_rect
|
389
382
|
def refresh(delayed = false)
|
@@ -400,25 +393,29 @@ module Wx::SF
|
|
400
393
|
return unless @diagram && @diagram.shape_canvas
|
401
394
|
return unless @visible
|
402
395
|
|
403
|
-
|
404
|
-
|
396
|
+
unless has_style?(STYLE::NOT_DRAWN)
|
397
|
+
|
398
|
+
# draw the shape shadow if required
|
399
|
+
draw_shadow(dc) if !@selected && has_style?(STYLE::SHOW_SHADOW)
|
405
400
|
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
401
|
+
# first, draw itself
|
402
|
+
if @mouse_over && (@highlight_parent || has_style?(STYLE::HOVERING))
|
403
|
+
if @highlight_parent
|
404
|
+
draw_highlighted(dc)
|
405
|
+
@highlight_parent = false
|
406
|
+
else
|
407
|
+
draw_hover(dc)
|
408
|
+
end
|
411
409
|
else
|
412
|
-
|
410
|
+
draw_normal(dc)
|
413
411
|
end
|
414
|
-
else
|
415
|
-
draw_normal(dc)
|
416
|
-
end
|
417
412
|
|
418
|
-
|
413
|
+
draw_selected(dc) if @selected
|
419
414
|
|
420
|
-
|
421
|
-
|
415
|
+
# ... then draw connection points ...
|
416
|
+
@connection_pts.each { |cpt| cpt.draw(dc) } unless has_style?(STYLE::PROPAGATE_INTERACTIVE_CONNECTION)
|
417
|
+
|
418
|
+
end
|
422
419
|
|
423
420
|
# ... then draw child shapes
|
424
421
|
if children
|
@@ -460,11 +457,10 @@ module Wx::SF
|
|
460
457
|
# @return [Wx::RealPoint] Shape's position
|
461
458
|
def get_absolute_position
|
462
459
|
# HINT: overload it for custom actions...
|
463
|
-
parent_shape
|
464
|
-
if parent_shape
|
460
|
+
if @parent_shape
|
465
461
|
@relative_position + get_parent_absolute_position
|
466
462
|
else
|
467
|
-
@relative_position
|
463
|
+
@relative_position
|
468
464
|
end
|
469
465
|
end
|
470
466
|
|
@@ -501,7 +497,7 @@ module Wx::SF
|
|
501
497
|
|
502
498
|
# Set shape's style.
|
503
499
|
#
|
504
|
-
# Default value is STYLE::PARENT_CHANGE | STYLE::POSITION_CHANGE | STYLE::SIZE_CHANGE | STYLE::HOVERING | STYLE::HIGHLIGHTING | STYLE::SHOW_HANDLES | STYLE::ALWAYS_INSIDE
|
500
|
+
# Default value is STYLE::PARENT_CHANGE | STYLE::POSITION_CHANGE | STYLE::SIZE_CHANGE | STYLE::HOVERING | STYLE::HIGHLIGHTING | STYLE::SHOW_HANDLES | STYLE::ALWAYS_INSIDE
|
505
501
|
# @param [Integer] style Combination of the shape's styles
|
506
502
|
# @see STYLE
|
507
503
|
def set_style(style)
|
@@ -523,7 +519,7 @@ module Wx::SF
|
|
523
519
|
@style &= ~style
|
524
520
|
end
|
525
521
|
def contains_style(style)
|
526
|
-
|
522
|
+
@style.allbits?(style)
|
527
523
|
end
|
528
524
|
alias :contains_style? :contains_style
|
529
525
|
alias :has_style? :contains_style
|
@@ -610,7 +606,7 @@ module Wx::SF
|
|
610
606
|
end
|
611
607
|
|
612
608
|
# Get shape's bounding box which includes also associated child shapes and connections.
|
613
|
-
# @param [Wx::Rect] rct bounding rectangle
|
609
|
+
# @param [Wx::Rect, nil] rct bounding rectangle
|
614
610
|
# @param [BBMODE] mask Bit mask of object types which should be included into calculation
|
615
611
|
# @return [Wx::Rect] returned bounding box
|
616
612
|
# @see BBMODE
|
@@ -689,17 +685,31 @@ module Wx::SF
|
|
689
685
|
@diagram.set_modified(true) if @diagram
|
690
686
|
end
|
691
687
|
|
692
|
-
#
|
693
|
-
|
694
|
-
|
688
|
+
# Returns true if this shape manages (size/position/alignment) of it's child shapes.
|
689
|
+
# Returns false by default.
|
690
|
+
# @return [Boolean]
|
691
|
+
def is_manager
|
692
|
+
false
|
693
|
+
end
|
694
|
+
alias :manager? :is_manager
|
695
|
+
|
696
|
+
# Returns true if this shape is managed (size/position/alignment) by it's parent shape.
|
697
|
+
# @return [Boolean]
|
698
|
+
def is_managed
|
699
|
+
!!@parent_shape&.is_manager
|
700
|
+
end
|
701
|
+
alias :managed? :is_managed
|
695
702
|
|
696
|
-
if parent && !parent.is_a?(Wx::SF::GridShape)
|
697
703
|
|
698
|
-
|
704
|
+
# Update the shape's position in order to its alignment
|
705
|
+
def do_alignment
|
706
|
+
# align to parent unless parent is manager
|
707
|
+
unless @parent_shape.nil? || managed?
|
708
|
+
if @parent_shape.is_a?(Wx::SF::LineShape)
|
699
709
|
line_pos = get_parent_absolute_position
|
700
710
|
parent_bb = Wx::Rect.new(line_pos.x.to_i, line_pos.y.to_i, 1, 1)
|
701
711
|
else
|
702
|
-
parent_bb =
|
712
|
+
parent_bb = @parent_shape.get_bounding_box
|
703
713
|
end
|
704
714
|
|
705
715
|
shape_bb = get_bounding_box
|
@@ -722,8 +732,8 @@ module Wx::SF
|
|
722
732
|
end
|
723
733
|
|
724
734
|
when VALIGN::LINE_START
|
725
|
-
if
|
726
|
-
line_start, line_end =
|
735
|
+
if @parent_shape.is_a?(Wx::SF::LineShape)
|
736
|
+
line_start, line_end = @parent_shape.get_line_segment(0)
|
727
737
|
|
728
738
|
if line_end.y >= line_start.y
|
729
739
|
@relative_position.y = line_start.y - line_pos.y + @v_border
|
@@ -733,8 +743,8 @@ module Wx::SF
|
|
733
743
|
end
|
734
744
|
|
735
745
|
when VALIGN::LINE_END
|
736
|
-
if
|
737
|
-
line_start, line_end =
|
746
|
+
if @parent_shape.is_a?(Wx::SF::LineShape)
|
747
|
+
line_start, line_end = @parent_shape.get_line_segment(parent.get_control_points.get_count)
|
738
748
|
|
739
749
|
if line_end.y >= line_start.y
|
740
750
|
@relative_position.y = line_end.y - line_pos.y - shape_bb.height - @v_border
|
@@ -762,8 +772,8 @@ module Wx::SF
|
|
762
772
|
end
|
763
773
|
|
764
774
|
when HALIGN::LINE_START
|
765
|
-
if
|
766
|
-
line_start, line_end =
|
775
|
+
if @parent_shape.is_a?(Wx::SF::LineShape)
|
776
|
+
line_start, line_end = @parent_shape.get_line_segment(0)
|
767
777
|
|
768
778
|
if line_end.x >= line_start.x
|
769
779
|
|
@@ -774,8 +784,8 @@ module Wx::SF
|
|
774
784
|
end
|
775
785
|
|
776
786
|
when HALIGN::LINE_END
|
777
|
-
if
|
778
|
-
line_start, line_end =
|
787
|
+
if @parent_shape.is_a?(Wx::SF::LineShape)
|
788
|
+
line_start, line_end = @parent_shape.get_line_segment(@parent_shape.get_control_points.get_count)
|
779
789
|
|
780
790
|
if line_end.x >= line_start.x
|
781
791
|
@relative_position.x = line_end.x - line_pos.x - shape_bb.width - @h_border
|
@@ -788,7 +798,7 @@ module Wx::SF
|
|
788
798
|
end
|
789
799
|
|
790
800
|
# Update shape (align all child shapes and resize it to fit them)
|
791
|
-
def update
|
801
|
+
def update(recurse = true)
|
792
802
|
# do self-alignment
|
793
803
|
do_alignment
|
794
804
|
|
@@ -799,8 +809,8 @@ module Wx::SF
|
|
799
809
|
fit_to_children unless has_style?(STYLE::NO_FIT_TO_CHILDREN)
|
800
810
|
|
801
811
|
# do it recursively on all parent shapes
|
802
|
-
if (parent = get_parent_shape)
|
803
|
-
parent.update
|
812
|
+
if recurse && (parent = get_parent_shape)
|
813
|
+
parent.update(recurse)
|
804
814
|
end
|
805
815
|
end
|
806
816
|
|
@@ -814,11 +824,17 @@ module Wx::SF
|
|
814
824
|
@selected
|
815
825
|
end
|
816
826
|
|
827
|
+
# Returns true if any (grand-)parent is selected?
|
828
|
+
def has_selected_parent?
|
829
|
+
@parent_shape&.selected? || @parent_shape&.has_selected_parent?
|
830
|
+
end
|
831
|
+
alias :selected_parent? :has_selected_parent?
|
832
|
+
|
817
833
|
# Set the shape as a selected/deselected one
|
818
834
|
# @param [Boolean] state Selection state (true is selected, false is deselected)
|
819
835
|
def select(state)
|
820
836
|
@selected = state
|
821
|
-
show_handles(state && (
|
837
|
+
show_handles(state && has_style?(STYLE::SHOW_HANDLES))
|
822
838
|
end
|
823
839
|
|
824
840
|
# Set shape's relative position. Absolute shape's position is then calculated
|
@@ -840,7 +856,7 @@ module Wx::SF
|
|
840
856
|
# @return [Wx::RealPoint] Current relative position
|
841
857
|
# @see #get_absolute_position
|
842
858
|
def get_relative_position
|
843
|
-
@relative_position
|
859
|
+
@relative_position
|
844
860
|
end
|
845
861
|
|
846
862
|
# Set vertical alignment of this shape inside its parent
|
@@ -942,7 +958,7 @@ module Wx::SF
|
|
942
958
|
# Associate user data with the shape.
|
943
959
|
# If the data object is properly set then its marked properties will be serialized
|
944
960
|
# together with the parent shape. This means the user data must either be a serializable
|
945
|
-
# core type or a
|
961
|
+
# core type or a FIRM::Serializable.
|
946
962
|
# @param [Object] data user data
|
947
963
|
def set_user_data(data)
|
948
964
|
@user_data = data
|
@@ -990,7 +1006,7 @@ module Wx::SF
|
|
990
1006
|
# Get shape's hover color
|
991
1007
|
# @return [Wx::Colour] Current hover color
|
992
1008
|
def get_hover_colour
|
993
|
-
@hover_color
|
1009
|
+
@hover_color || (@diagram&.shape_canvas ? @diagram.shape_canvas.hover_colour : DEFAULT.hover_colour)
|
994
1010
|
end
|
995
1011
|
alias :hover_colour :get_hover_colour
|
996
1012
|
|
@@ -1030,10 +1046,10 @@ module Wx::SF
|
|
1030
1046
|
def accept_currently_dragged_shapes
|
1031
1047
|
return false unless get_shape_canvas
|
1032
1048
|
|
1033
|
-
unless
|
1049
|
+
unless @accepted_children.include?(ACCEPT_ALL)
|
1034
1050
|
lst_selection = get_shape_canvas.get_selected_shapes
|
1035
1051
|
|
1036
|
-
return false if lst_selection.any? { |shape| !@accepted_children.include?(shape.class
|
1052
|
+
return false if lst_selection.any? { |shape| !@accepted_children.include?(shape.class) }
|
1037
1053
|
end
|
1038
1054
|
true
|
1039
1055
|
end
|
@@ -1044,7 +1060,7 @@ module Wx::SF
|
|
1044
1060
|
# @param [Class] type Class of accepted shape object
|
1045
1061
|
# @see #is_child_accepted
|
1046
1062
|
def accept_child(type)
|
1047
|
-
::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
|
1063
|
+
::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
|
1048
1064
|
@accepted_children << type
|
1049
1065
|
end
|
1050
1066
|
|
@@ -1056,6 +1072,14 @@ module Wx::SF
|
|
1056
1072
|
end
|
1057
1073
|
alias :accepted_children :get_accepted_children
|
1058
1074
|
|
1075
|
+
# Tells whether the shape does not accept ANY children
|
1076
|
+
# @return [Boolean] true if no children accepted, false otherwise
|
1077
|
+
def does_not_accept_children?
|
1078
|
+
@accepted_children.empty?
|
1079
|
+
end
|
1080
|
+
alias :no_children_accepted? :does_not_accept_children?
|
1081
|
+
alias :accepts_no_children? :does_not_accept_children?
|
1082
|
+
|
1059
1083
|
# Tells whether the given connection type is accepted by this shape (it means
|
1060
1084
|
# whether this shape can be connected to another one by a connection of given type).
|
1061
1085
|
#
|
@@ -1073,7 +1097,7 @@ module Wx::SF
|
|
1073
1097
|
# @param [Class] type Class of accepted connection object
|
1074
1098
|
# @see #is_connection_accepted
|
1075
1099
|
def accept_connection(type)
|
1076
|
-
::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
|
1100
|
+
::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
|
1077
1101
|
@accepted_connections << type
|
1078
1102
|
end
|
1079
1103
|
|
@@ -1102,7 +1126,7 @@ module Wx::SF
|
|
1102
1126
|
# @param [Class] type Class of accepted connection object
|
1103
1127
|
# @see #is_src_neighbour_accepted
|
1104
1128
|
def accept_src_neighbour(type)
|
1105
|
-
::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
|
1129
|
+
::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
|
1106
1130
|
@accepted_src_neighbours << type
|
1107
1131
|
end
|
1108
1132
|
|
@@ -1131,7 +1155,7 @@ module Wx::SF
|
|
1131
1155
|
# @param [Class] type Class of accepted connection object
|
1132
1156
|
# @see #is_trg_neighbour_accepted
|
1133
1157
|
def accept_trg_neighbour(type)
|
1134
|
-
::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
|
1158
|
+
::Kernel.raise ArgumentError, 'Class or ACCEPT_ALL expected' unless type.is_a?(::Class)
|
1135
1159
|
@accepted_trg_neighbours << type
|
1136
1160
|
end
|
1137
1161
|
|
@@ -1214,10 +1238,10 @@ module Wx::SF
|
|
1214
1238
|
|
1215
1239
|
# Get connection point of given type assigned to the shape.
|
1216
1240
|
# @param [Wx::SF::ConnectionPoint::CPTYPE] type Connection point type
|
1217
|
-
# @param [Integer] id Optional connection point ID
|
1241
|
+
# @param [Integer, nil] id Optional connection point ID
|
1218
1242
|
# @return [Wx::SF::ConnectionPoint,nil] connection point if exists, otherwise nil
|
1219
1243
|
# @see Wx::SF::ConnectionPoint::CPTYPE
|
1220
|
-
def get_connection_point(type, id =
|
1244
|
+
def get_connection_point(type, id = nil)
|
1221
1245
|
@connection_pts.find { |cp| cp.type == type && cp.id == id }
|
1222
1246
|
end
|
1223
1247
|
alias :connection_point :get_connection_point
|
@@ -1242,16 +1266,16 @@ module Wx::SF
|
|
1242
1266
|
# @overload add_connection_point(type, persistent: true)
|
1243
1267
|
# @param [Wx::SF::ConnectionPoint::CPTYPE] type Connection point type
|
1244
1268
|
# @param [Boolean] persistent true if the connection point should be serialized
|
1245
|
-
# @return [Wx::SF::ConnectionPoint] new connection point
|
1269
|
+
# @return [Wx::SF::ConnectionPoint, nil] new connection point if succeeded, otherwise nil
|
1246
1270
|
# @overload add_connection_point(relpos, id=-1, persistent: true)
|
1247
1271
|
# @param [Wx::RealPoint] relpos Relative position in percentages
|
1248
1272
|
# @param [Integer] id connection point ID
|
1249
1273
|
# @param [Boolean] persistent true if the connection point should be serialized
|
1250
|
-
# @return [Wx::SF::ConnectionPoint] new connection point
|
1274
|
+
# @return [Wx::SF::ConnectionPoint, nil] new connection point if succeeded, otherwise nil
|
1251
1275
|
# @overload add_connection_point(cp, persistent: true)
|
1252
1276
|
# @param [Wx::SF::ConnectionPoint] cp connection point (shape will take the ownership)
|
1253
1277
|
# @param [Boolean] persistent true if the connection point should be serialized
|
1254
|
-
# @return [Wx::SF::ConnectionPoint] added connection point
|
1278
|
+
# @return [Wx::SF::ConnectionPoint, nil] added connection point if succeeded, otherwise nil
|
1255
1279
|
# @see Wx::SF::ConnectionPoint::CPTYPE
|
1256
1280
|
def add_connection_point(arg, *rest, persistent: true)
|
1257
1281
|
cp = nil
|
@@ -1292,7 +1316,7 @@ module Wx::SF
|
|
1292
1316
|
# HINT: overload it for custom actions...
|
1293
1317
|
|
1294
1318
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1295
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_LEFT_DOWN, self.
|
1319
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_LEFT_DOWN, self.object_id)
|
1296
1320
|
evt.set_shape(self)
|
1297
1321
|
evt.set_mouse_position(pos)
|
1298
1322
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1310,7 +1334,7 @@ module Wx::SF
|
|
1310
1334
|
# HINT: overload it for custom actions...
|
1311
1335
|
|
1312
1336
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1313
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_RIGHT_DOWN, self.
|
1337
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_RIGHT_DOWN, self.object_id)
|
1314
1338
|
evt.set_shape(self)
|
1315
1339
|
evt.set_mouse_position(pos)
|
1316
1340
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1328,7 +1352,7 @@ module Wx::SF
|
|
1328
1352
|
# HINT: overload it for custom actions...
|
1329
1353
|
|
1330
1354
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1331
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_LEFT_DCLICK, self.
|
1355
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_LEFT_DCLICK, self.object_id)
|
1332
1356
|
evt.set_shape(self)
|
1333
1357
|
evt.set_mouse_position(pos)
|
1334
1358
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1346,7 +1370,7 @@ module Wx::SF
|
|
1346
1370
|
# HINT: overload it for custom actions...
|
1347
1371
|
|
1348
1372
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1349
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_RIGHT_DCLICK, self.
|
1373
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_RIGHT_DCLICK, self.object_id)
|
1350
1374
|
evt.set_shape(self)
|
1351
1375
|
evt.set_mouse_position(pos)
|
1352
1376
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1364,7 +1388,7 @@ module Wx::SF
|
|
1364
1388
|
# HINT: overload it for custom actions...
|
1365
1389
|
|
1366
1390
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1367
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_DRAG_BEGIN, self.
|
1391
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_DRAG_BEGIN, self.object_id)
|
1368
1392
|
evt.set_shape(self)
|
1369
1393
|
evt.set_mouse_position(pos)
|
1370
1394
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1382,7 +1406,7 @@ module Wx::SF
|
|
1382
1406
|
# HINT: overload it for custom actions...
|
1383
1407
|
|
1384
1408
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1385
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_DRAG, self.
|
1409
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_DRAG, self.object_id)
|
1386
1410
|
evt.set_shape(self)
|
1387
1411
|
evt.set_mouse_position(pos)
|
1388
1412
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1400,7 +1424,7 @@ module Wx::SF
|
|
1400
1424
|
# HINT: overload it for custom actions...
|
1401
1425
|
|
1402
1426
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1403
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_DRAG_END, self.
|
1427
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_DRAG_END, self.object_id)
|
1404
1428
|
evt.set_shape(self)
|
1405
1429
|
evt.set_mouse_position(pos)
|
1406
1430
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1417,7 +1441,7 @@ module Wx::SF
|
|
1417
1441
|
# HINT: overload it for custom actions...
|
1418
1442
|
|
1419
1443
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1420
|
-
evt = Wx::SF::ShapeHandleEvent.new(Wx::SF::EVT_SF_SHAPE_HANDLE_BEGIN, self.
|
1444
|
+
evt = Wx::SF::ShapeHandleEvent.new(Wx::SF::EVT_SF_SHAPE_HANDLE_BEGIN, self.object_id)
|
1421
1445
|
evt.set_shape(self)
|
1422
1446
|
evt.set_handle(handle)
|
1423
1447
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1434,7 +1458,7 @@ module Wx::SF
|
|
1434
1458
|
# HINT: overload it for custom actions...
|
1435
1459
|
|
1436
1460
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1437
|
-
evt = Wx::SF::ShapeHandleEvent.new(Wx::SF::EVT_SF_SHAPE_HANDLE, self.
|
1461
|
+
evt = Wx::SF::ShapeHandleEvent.new(Wx::SF::EVT_SF_SHAPE_HANDLE, self.object_id)
|
1438
1462
|
evt.set_shape(self)
|
1439
1463
|
evt.set_handle(handle)
|
1440
1464
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1451,7 +1475,7 @@ module Wx::SF
|
|
1451
1475
|
# HINT: overload it for custom actions...
|
1452
1476
|
|
1453
1477
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1454
|
-
evt = Wx::SF::ShapeHandleEvent.new(Wx::SF::EVT_SF_SHAPE_HANDLE_END, self.
|
1478
|
+
evt = Wx::SF::ShapeHandleEvent.new(Wx::SF::EVT_SF_SHAPE_HANDLE_END, self.object_id)
|
1455
1479
|
evt.set_shape(self)
|
1456
1480
|
evt.set_handle(handle)
|
1457
1481
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1468,7 +1492,7 @@ module Wx::SF
|
|
1468
1492
|
# HINT: overload it for custom actions...
|
1469
1493
|
|
1470
1494
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1471
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_MOUSE_ENTER, self.
|
1495
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_MOUSE_ENTER, self.object_id)
|
1472
1496
|
evt.set_shape(self)
|
1473
1497
|
evt.set_mouse_position(pos)
|
1474
1498
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1485,7 +1509,7 @@ module Wx::SF
|
|
1485
1509
|
# HINT: overload it for custom actions...
|
1486
1510
|
|
1487
1511
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1488
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_MOUSE_OVER, self.
|
1512
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_MOUSE_OVER, self.object_id)
|
1489
1513
|
evt.set_shape(self)
|
1490
1514
|
evt.set_mouse_position(pos)
|
1491
1515
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1502,7 +1526,7 @@ module Wx::SF
|
|
1502
1526
|
# HINT: overload it for custom actions...
|
1503
1527
|
|
1504
1528
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1505
|
-
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_MOUSE_LEAVE, self.
|
1529
|
+
evt = Wx::SF::ShapeMouseEvent.new(Wx::SF::EVT_SF_SHAPE_MOUSE_LEAVE, self.object_id)
|
1506
1530
|
evt.set_shape(self)
|
1507
1531
|
evt.set_mouse_position(pos)
|
1508
1532
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1522,7 +1546,7 @@ module Wx::SF
|
|
1522
1546
|
# HINT: overload it for custom actions...
|
1523
1547
|
|
1524
1548
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1525
|
-
evt = Wx::SF::ShapeKeyEvent.new(Wx::SF::EVT_SF_SHAPE_KEYDOWN, self.
|
1549
|
+
evt = Wx::SF::ShapeKeyEvent.new(Wx::SF::EVT_SF_SHAPE_KEYDOWN, self.object_id)
|
1526
1550
|
evt.set_shape(self)
|
1527
1551
|
evt.set_key_code(key)
|
1528
1552
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1542,7 +1566,7 @@ module Wx::SF
|
|
1542
1566
|
# HINT: overload it for custom actions...
|
1543
1567
|
|
1544
1568
|
if has_style?(STYLE::EMIT_EVENTS) && get_shape_canvas
|
1545
|
-
evt = Wx::SF::ShapeChildDropEvent.new(Wx::SF::EVT_SF_SHAPE_CHILD_DROP, self.
|
1569
|
+
evt = Wx::SF::ShapeChildDropEvent.new(Wx::SF::EVT_SF_SHAPE_CHILD_DROP, self.object_id)
|
1546
1570
|
evt.set_shape(self)
|
1547
1571
|
evt.set_child_shape(child)
|
1548
1572
|
get_shape_canvas.get_event_handler.process_event(evt)
|
@@ -1550,7 +1574,7 @@ module Wx::SF
|
|
1550
1574
|
end
|
1551
1575
|
|
1552
1576
|
def to_s
|
1553
|
-
"#<#{self.class}:#{
|
1577
|
+
"#<#{self.class}:#{self.object_id}#{@parent_shape ? " parent=#{@parent_shape.object_id}" : ''}>"
|
1554
1578
|
end
|
1555
1579
|
|
1556
1580
|
def inspect
|
@@ -1559,6 +1583,13 @@ module Wx::SF
|
|
1559
1583
|
|
1560
1584
|
protected
|
1561
1585
|
|
1586
|
+
# called after the shape has been newly imported/pasted/dropped
|
1587
|
+
# allows for checking stale links
|
1588
|
+
# by default does nothing
|
1589
|
+
def on_import
|
1590
|
+
# nothing
|
1591
|
+
end
|
1592
|
+
|
1562
1593
|
# Draw the shape in the normal way. The function can be overridden if necessary.
|
1563
1594
|
# @param [Wx::DC] _dc Reference to device context where the shape will be drawn to
|
1564
1595
|
def draw_normal(_dc)
|
@@ -1614,11 +1645,11 @@ module Wx::SF
|
|
1614
1645
|
# Get absolute position of the shape parent.
|
1615
1646
|
# @return [Wx::RealPoint] Absolute position of the shape parent if exists, otherwise 0,0
|
1616
1647
|
def get_parent_absolute_position
|
1617
|
-
if
|
1618
|
-
if
|
1619
|
-
return
|
1648
|
+
if @parent_shape
|
1649
|
+
if @parent_shape.is_a?(Wx::SF::LineShape) && @custom_dock_point != DEFAULT::DOCK_POINT
|
1650
|
+
return @parent_shape.get_dock_point_position(@custom_dock_point)
|
1620
1651
|
else
|
1621
|
-
return
|
1652
|
+
return @parent_shape.get_absolute_position
|
1622
1653
|
end
|
1623
1654
|
end
|
1624
1655
|
|
@@ -1628,7 +1659,7 @@ module Wx::SF
|
|
1628
1659
|
private
|
1629
1660
|
|
1630
1661
|
# Auxiliary function called by GetNeighbours function.
|
1631
|
-
# @param [Class,nil]
|
1662
|
+
# @param [Class,nil] shape_info Line object type
|
1632
1663
|
# @param [CONNECTMODE] condir Connection direction
|
1633
1664
|
# @param [Boolean] direct Set this flag to TRUE if only closest shapes should be found,
|
1634
1665
|
# otherwise also shapes connected by forked lines will be found (also
|
@@ -1649,16 +1680,16 @@ module Wx::SF
|
|
1649
1680
|
lst_connections.each do |line|
|
1650
1681
|
case condir
|
1651
1682
|
when CONNECTMODE::STARTING
|
1652
|
-
opposite =
|
1683
|
+
opposite = line.get_trg_shape
|
1653
1684
|
|
1654
1685
|
when CONNECTMODE::ENDING
|
1655
|
-
opposite =
|
1686
|
+
opposite = line.get_src_shape
|
1656
1687
|
|
1657
1688
|
when CONNECTMODE::BOTH
|
1658
|
-
if
|
1659
|
-
opposite =
|
1689
|
+
if self == line.get_src_shape
|
1690
|
+
opposite = line.get_trg_shape
|
1660
1691
|
else
|
1661
|
-
opposite =
|
1692
|
+
opposite = line.get_src_shape
|
1662
1693
|
end
|
1663
1694
|
end
|
1664
1695
|
|
@@ -1674,7 +1705,7 @@ module Wx::SF
|
|
1674
1705
|
if opposite.is_a?(Wx::SF::LineShape)
|
1675
1706
|
case condir
|
1676
1707
|
when CONNECTMODE::STARTING
|
1677
|
-
opposite =
|
1708
|
+
opposite = opposite.get_src_shape
|
1678
1709
|
|
1679
1710
|
if opposite.is_a?(Wx::SF::LineShape)
|
1680
1711
|
opposite.__send__(:_get_neighbours, shape_info, condir, direct, neighbours, processed)
|
@@ -1683,7 +1714,7 @@ module Wx::SF
|
|
1683
1714
|
end
|
1684
1715
|
|
1685
1716
|
when CONNECTMODE::ENDING
|
1686
|
-
opposite =
|
1717
|
+
opposite = opposite.get_trg_shape
|
1687
1718
|
|
1688
1719
|
if opposite.is_a?(Wx::SF::LineShape)
|
1689
1720
|
opposite.__send__(:_get_neighbours, shape_info, condir, direct, neighbours, processed)
|
@@ -1692,14 +1723,14 @@ module Wx::SF
|
|
1692
1723
|
end
|
1693
1724
|
|
1694
1725
|
when CONNECTMODE::BOTH
|
1695
|
-
opposite =
|
1726
|
+
opposite = opposite.get_src_shape
|
1696
1727
|
if opposite.is_a?(Wx::SF::LineShape)
|
1697
1728
|
opposite.__send__(:_get_neighbours, shape_info, condir, direct, neighbours, processed)
|
1698
1729
|
elsif !neighbours.include?(opposite)
|
1699
1730
|
neighbours << opposite
|
1700
1731
|
end
|
1701
1732
|
|
1702
|
-
opposite =
|
1733
|
+
opposite = opposite.get_trg_shape
|
1703
1734
|
if opposite.is_a?(Wx::SF::LineShape)
|
1704
1735
|
opposite.__send__(:_get_neighbours, shape_info, condir, direct, neighbours, processed)
|
1705
1736
|
elsif !neighbours.include?(opposite)
|
@@ -1715,7 +1746,7 @@ module Wx::SF
|
|
1715
1746
|
end
|
1716
1747
|
|
1717
1748
|
# Auxiliary function called by GetCompleteBoundingBox function.
|
1718
|
-
# @param [Wx::Rect] rct bounding rectangle to update
|
1749
|
+
# @param [Wx::Rect, nil] rct bounding rectangle to update
|
1719
1750
|
# @param [BBMODE] mask Bit mask of object types which should be included into calculation
|
1720
1751
|
# @param [Set<Wx::SF::Shape] processed set to keep track of processed shapes
|
1721
1752
|
# @return [Wx::Rect] bounding rectangle
|
@@ -1727,14 +1758,18 @@ module Wx::SF
|
|
1727
1758
|
processed << self
|
1728
1759
|
|
1729
1760
|
# first, get bounding box of the current shape
|
1730
|
-
if (
|
1731
|
-
if rct.
|
1732
|
-
rct
|
1761
|
+
if mask.allbits?(BBMODE::SELF)
|
1762
|
+
if rct.nil?
|
1763
|
+
rct = get_bounding_box.inflate!(@h_border.abs.to_i, @v_border.abs.to_i)
|
1733
1764
|
else
|
1734
|
-
rct.
|
1765
|
+
if rct.empty?
|
1766
|
+
rct += get_bounding_box.inflate!(@h_border.abs.to_i, @v_border.abs.to_i)
|
1767
|
+
else
|
1768
|
+
rct.union!(get_bounding_box.inflate!(@h_border.abs.to_i, @v_border.abs.to_i))
|
1769
|
+
end
|
1735
1770
|
|
1736
1771
|
# add also shadow offset if necessary
|
1737
|
-
if (
|
1772
|
+
if mask.allbits?(BBMODE::SHADOW) && has_style?(STYLE::SHOW_SHADOW) && !has_style(STYLE::NOT_DRAWN) && get_parent_canvas
|
1738
1773
|
n_offset = get_parent_canvas.get_shadow_offset
|
1739
1774
|
|
1740
1775
|
if n_offset.x < 0
|
@@ -1758,7 +1793,7 @@ module Wx::SF
|
|
1758
1793
|
|
1759
1794
|
# get list of all connection lines assigned to the shape and find their child shapes
|
1760
1795
|
lst_children = []
|
1761
|
-
if (
|
1796
|
+
if mask.allbits?(BBMODE::CONNECTIONS)
|
1762
1797
|
lst_lines = get_assigned_connections(Wx::SF::LineShape, CONNECTMODE::BOTH)
|
1763
1798
|
|
1764
1799
|
lst_lines.each do |line|
|
@@ -1771,15 +1806,15 @@ module Wx::SF
|
|
1771
1806
|
end
|
1772
1807
|
|
1773
1808
|
# get children of this shape
|
1774
|
-
if (
|
1809
|
+
if mask.allbits?(BBMODE::CHILDREN)
|
1775
1810
|
get_child_shapes(ANY, NORECURSIVE, SEARCHMODE::BFS, lst_children)
|
1776
1811
|
|
1777
1812
|
# now, call this function for all children recursively...
|
1778
1813
|
lst_children.each do |child|
|
1779
|
-
child.send(:_get_complete_bounding_box, rct, mask, processed)
|
1814
|
+
rct = child.send(:_get_complete_bounding_box, rct, mask, processed)
|
1780
1815
|
end
|
1781
1816
|
end
|
1782
|
-
rct
|
1817
|
+
rct || Wx::Rect.new
|
1783
1818
|
end
|
1784
1819
|
|
1785
1820
|
# Original protected event handler called when the mouse pointer is moving around the shape canvas.
|
@@ -1800,7 +1835,7 @@ module Wx::SF
|
|
1800
1835
|
@handles.each { |h| h.__send__(:_on_mouse_move, pos) }
|
1801
1836
|
|
1802
1837
|
# send the event to the connection points too...
|
1803
|
-
@connection_pts.each { |cp| cp.__send__(:_on_mouse_move, pos) }
|
1838
|
+
@connection_pts.each { |cp| cp.__send__(:_on_mouse_move, pos) } unless has_style?(STYLE::PROPAGATE_INTERACTIVE_CONNECTION)
|
1804
1839
|
|
1805
1840
|
# determine, whether the shape should be highlighted for any reason
|
1806
1841
|
if canvas
|
@@ -1872,8 +1907,8 @@ module Wx::SF
|
|
1872
1907
|
@first_move = true
|
1873
1908
|
on_begin_drag(pos)
|
1874
1909
|
|
1875
|
-
if
|
1876
|
-
|
1910
|
+
if @parent_shape && has_style?(STYLE::PROPAGATE_DRAGGING)
|
1911
|
+
@parent_shape.__send__(:_on_begin_drag, pos)
|
1877
1912
|
end
|
1878
1913
|
end
|
1879
1914
|
|
@@ -1891,7 +1926,7 @@ module Wx::SF
|
|
1891
1926
|
end
|
1892
1927
|
|
1893
1928
|
# get shape BB BEFORE movement and combine it with BB of assigned lines
|
1894
|
-
prev_bb = get_complete_bounding_box(
|
1929
|
+
prev_bb = get_complete_bounding_box(nil, BBMODE::SELF | BBMODE::CONNECTIONS | BBMODE::CHILDREN | BBMODE::SHADOW)
|
1895
1930
|
|
1896
1931
|
move_to(pos.x - @mouse_offset.x, pos.y - @mouse_offset.y)
|
1897
1932
|
on_dragging(pos)
|
@@ -1901,7 +1936,7 @@ module Wx::SF
|
|
1901
1936
|
lst_child_ctrls.each { |ctrl| ctrl.update_control }
|
1902
1937
|
|
1903
1938
|
# get shape BB AFTER movement and combine it with BB of assigned lines
|
1904
|
-
curr_bb = get_complete_bounding_box(
|
1939
|
+
curr_bb = get_complete_bounding_box(nil, BBMODE::SELF | BBMODE::CONNECTIONS | BBMODE::CHILDREN | BBMODE::SHADOW)
|
1905
1940
|
|
1906
1941
|
# update canvas
|
1907
1942
|
refresh_rect(prev_bb.union!(curr_bb), DELAYED)
|
@@ -1909,8 +1944,8 @@ module Wx::SF
|
|
1909
1944
|
@first_move = false
|
1910
1945
|
end
|
1911
1946
|
|
1912
|
-
if
|
1913
|
-
|
1947
|
+
if @parent_shape && has_style?(STYLE::PROPAGATE_DRAGGING)
|
1948
|
+
@parent_shape.__send__(:_on_dragging, pos)
|
1914
1949
|
end
|
1915
1950
|
end
|
1916
1951
|
|
@@ -1924,8 +1959,8 @@ module Wx::SF
|
|
1924
1959
|
|
1925
1960
|
on_end_drag(pos)
|
1926
1961
|
|
1927
|
-
if
|
1928
|
-
|
1962
|
+
if @parent_shape && has_style?(STYLE::PROPAGATE_DRAGGING)
|
1963
|
+
@parent_shape.__send__(:_on_end_drag, pos)
|
1929
1964
|
end
|
1930
1965
|
end
|
1931
1966
|
|
@@ -1946,8 +1981,8 @@ module Wx::SF
|
|
1946
1981
|
f_refresh_all = false
|
1947
1982
|
|
1948
1983
|
if canvas.has_style?(Wx::SF::ShapeCanvas::STYLE::GRID_USE)
|
1949
|
-
dx = canvas.get_grid_size
|
1950
|
-
dy = canvas.get_grid_size
|
1984
|
+
dx = canvas.get_grid_size
|
1985
|
+
dy = canvas.get_grid_size
|
1951
1986
|
end
|
1952
1987
|
|
1953
1988
|
lst_selection = canvas.get_selected_shapes
|
@@ -1955,8 +1990,8 @@ module Wx::SF
|
|
1955
1990
|
f_refresh_all = true
|
1956
1991
|
end
|
1957
1992
|
|
1958
|
-
prev_bb =
|
1959
|
-
|
1993
|
+
prev_bb = nil
|
1994
|
+
unless f_refresh_all
|
1960
1995
|
prev_bb = get_complete_bounding_box(prev_bb, BBMODE::SELF | BBMODE::CONNECTIONS | BBMODE::CHILDREN | BBMODE::SHADOW)
|
1961
1996
|
end
|
1962
1997
|
|
@@ -1977,10 +2012,9 @@ module Wx::SF
|
|
1977
2012
|
end
|
1978
2013
|
|
1979
2014
|
if !f_refresh_all
|
1980
|
-
curr_bb = get_complete_bounding_box(
|
2015
|
+
curr_bb = get_complete_bounding_box(prev_bb, BBMODE::SELF | BBMODE::CONNECTIONS | BBMODE::CHILDREN | BBMODE::SHADOW)
|
1981
2016
|
|
1982
|
-
|
1983
|
-
refresh_rect(prev_bb, DELAYED)
|
2017
|
+
refresh_rect(curr_bb, DELAYED)
|
1984
2018
|
else
|
1985
2019
|
canvas.refresh(false)
|
1986
2020
|
end
|
@@ -1995,9 +2029,9 @@ module Wx::SF
|
|
1995
2029
|
return unless @diagram
|
1996
2030
|
|
1997
2031
|
if @parent_shape
|
1998
|
-
prev_bb = get_grand_parent_shape.get_complete_bounding_box(
|
2032
|
+
prev_bb = get_grand_parent_shape.get_complete_bounding_box(nil)
|
1999
2033
|
else
|
2000
|
-
prev_bb = get_complete_bounding_box(
|
2034
|
+
prev_bb = get_complete_bounding_box(nil)
|
2001
2035
|
end
|
2002
2036
|
|
2003
2037
|
# call appropriate user-defined handler
|
@@ -2014,9 +2048,9 @@ module Wx::SF
|
|
2014
2048
|
update
|
2015
2049
|
|
2016
2050
|
if @parent_shape
|
2017
|
-
curr_bb = get_grand_parent_shape.get_complete_bounding_box(
|
2051
|
+
curr_bb = get_grand_parent_shape.get_complete_bounding_box(nil)
|
2018
2052
|
else
|
2019
|
-
curr_bb = get_complete_bounding_box(
|
2053
|
+
curr_bb = get_complete_bounding_box(nil)
|
2020
2054
|
end
|
2021
2055
|
|
2022
2056
|
# refresh shape
|
@@ -2062,7 +2096,6 @@ module Wx::SF
|
|
2062
2096
|
def update_child_parents
|
2063
2097
|
@child_shapes.each do |shape|
|
2064
2098
|
shape.instance_variable_set(:@parent_shape, self)
|
2065
|
-
shape.send(:update_child_parents)
|
2066
2099
|
end
|
2067
2100
|
end
|
2068
2101
|
|
@@ -2070,11 +2103,21 @@ module Wx::SF
|
|
2070
2103
|
def serialize_child_shapes(*val)
|
2071
2104
|
unless val.empty?
|
2072
2105
|
@child_shapes = val.first
|
2106
|
+
# @parent_shape is not serialized, instead we rely on child shapes being (de-)serialized
|
2107
|
+
# by their parent (child shapes restored before restoring parent child list) and let
|
2108
|
+
# the parent reset the @parent_shape attributes of their children.
|
2109
|
+
# That way the links never get out of sync.
|
2073
2110
|
update_child_parents
|
2074
2111
|
end
|
2075
2112
|
@child_shapes
|
2076
2113
|
end
|
2077
2114
|
|
2115
|
+
# (de-)serialize hover colour; allows for nil values
|
2116
|
+
def serialize_hover_colour(*val)
|
2117
|
+
@hover_colour = val.first unless val.empty?
|
2118
|
+
@hover_colour
|
2119
|
+
end
|
2120
|
+
|
2078
2121
|
public
|
2079
2122
|
|
2080
2123
|
# Returns intersection point of two lines (if any)
|
@@ -2103,10 +2146,10 @@ module Wx::SF
|
|
2103
2146
|
xi = (b1*c2 - c1*b2) / (a1*b2 - a2*b1)
|
2104
2147
|
yi = -(a1*c2 - a2*c1) / (a1*b2 - a2*b1)
|
2105
2148
|
|
2106
|
-
if
|
2107
|
-
((from2.x - xi)*(xi - to2.x) >= 0.0) &&
|
2108
|
-
((from1.y - yi)*(yi - to1.y) >= 0.0) &&
|
2109
|
-
((from2.y - yi)*(yi - to2.y) >= 0.0)
|
2149
|
+
if ((from1.x - xi) * (xi - to1.x) >= 0.0) &&
|
2150
|
+
((from2.x - xi) * (xi - to2.x) >= 0.0) &&
|
2151
|
+
((from1.y - yi) * (yi - to1.y) >= 0.0) &&
|
2152
|
+
((from2.y - yi) * (yi - to2.y) >= 0.0)
|
2110
2153
|
return Wx::RealPoint.new(xi, yi)
|
2111
2154
|
end
|
2112
2155
|
|