wxruby3-shapes 0.9.0.pre.beta.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +12 -0
- data/CREDITS.md +18 -0
- data/INSTALL.md +39 -0
- data/LICENSE +21 -0
- data/README.md +118 -0
- data/assets/screenshot.png +0 -0
- data/bin/wx-shapes +9 -0
- data/lib/wx/shapes/arrow_base.rb +86 -0
- data/lib/wx/shapes/arrows/circle_arrow.rb +39 -0
- data/lib/wx/shapes/arrows/diamond_arrow.rb +33 -0
- data/lib/wx/shapes/arrows/open_arrow.rb +56 -0
- data/lib/wx/shapes/arrows/solid_arrow.rb +69 -0
- data/lib/wx/shapes/art/shape_canvas/page.xpm +73 -0
- data/lib/wx/shapes/auto_layout.rb +358 -0
- data/lib/wx/shapes/base.rb +33 -0
- data/lib/wx/shapes/canvas_history.rb +84 -0
- data/lib/wx/shapes/connection_point.rb +238 -0
- data/lib/wx/shapes/core.rb +19 -0
- data/lib/wx/shapes/diagram.rb +659 -0
- data/lib/wx/shapes/events.rb +389 -0
- data/lib/wx/shapes/printout.rb +136 -0
- data/lib/wx/shapes/serializable.rb +440 -0
- data/lib/wx/shapes/serialize/core.rb +40 -0
- data/lib/wx/shapes/serialize/id.rb +82 -0
- data/lib/wx/shapes/serialize/wx.rb +104 -0
- data/lib/wx/shapes/serializer/json.rb +258 -0
- data/lib/wx/shapes/serializer/yaml.rb +125 -0
- data/lib/wx/shapes/shape.rb +2129 -0
- data/lib/wx/shapes/shape_canvas.rb +3285 -0
- data/lib/wx/shapes/shape_data_object.rb +43 -0
- data/lib/wx/shapes/shape_handle.rb +287 -0
- data/lib/wx/shapes/shape_list.rb +161 -0
- data/lib/wx/shapes/shapes/bitmap_shape.rb +257 -0
- data/lib/wx/shapes/shapes/circle_shape.rb +136 -0
- data/lib/wx/shapes/shapes/control_shape.rb +483 -0
- data/lib/wx/shapes/shapes/curve_shape.rb +231 -0
- data/lib/wx/shapes/shapes/diamond_shape.rb +62 -0
- data/lib/wx/shapes/shapes/edit_text_shape.rb +317 -0
- data/lib/wx/shapes/shapes/ellipse_shape.rb +106 -0
- data/lib/wx/shapes/shapes/flex_grid_shape.rb +78 -0
- data/lib/wx/shapes/shapes/grid_shape.rb +404 -0
- data/lib/wx/shapes/shapes/line_shape.rb +907 -0
- data/lib/wx/shapes/shapes/multi_sel_rect.rb +214 -0
- data/lib/wx/shapes/shapes/ortho_shape.rb +357 -0
- data/lib/wx/shapes/shapes/polygon_shape.rb +294 -0
- data/lib/wx/shapes/shapes/rect_shape.rb +378 -0
- data/lib/wx/shapes/shapes/round_ortho_shape.rb +131 -0
- data/lib/wx/shapes/shapes/round_rect_shape.rb +142 -0
- data/lib/wx/shapes/shapes/square_shape.rb +119 -0
- data/lib/wx/shapes/shapes/text_shape.rb +324 -0
- data/lib/wx/shapes/thumbnail.rb +234 -0
- data/lib/wx/shapes/version.rb +12 -0
- data/lib/wx/shapes/wx.rb +29 -0
- data/lib/wx/shapes.rb +18 -0
- data/lib/wx/wx-shapes/base.rb +87 -0
- data/lib/wx/wx-shapes/cmd/sampler.rb +58 -0
- data/lib/wx/wx-shapes/cmd/test.rb +27 -0
- data/rakelib/yard/templates/default/fulldoc/html/css/wxruby3.css +7 -0
- data/rakelib/yard/templates/default/layout/html/setup.rb +5 -0
- data/rakelib/yard/yard/relative_markdown_links/version.rb +8 -0
- data/rakelib/yard/yard/relative_markdown_links.rb +39 -0
- data/rakelib/yard/yard-custom-templates.rb +2 -0
- data/rakelib/yard/yard-relative_markdown_links.rb +4 -0
- data/samples/demo/art/AlignBottom.xpm +35 -0
- data/samples/demo/art/AlignCenter.xpm +35 -0
- data/samples/demo/art/AlignLeft.xpm +35 -0
- data/samples/demo/art/AlignMiddle.xpm +35 -0
- data/samples/demo/art/AlignRight.xpm +35 -0
- data/samples/demo/art/AlignTop.xpm +35 -0
- data/samples/demo/art/Bitmap.xpm +25 -0
- data/samples/demo/art/Circle.xpm +22 -0
- data/samples/demo/art/Curve.xpm +21 -0
- data/samples/demo/art/Diamond.xpm +22 -0
- data/samples/demo/art/EditText.xpm +21 -0
- data/samples/demo/art/Ellipse.xpm +22 -0
- data/samples/demo/art/FixedRect.xpm +22 -0
- data/samples/demo/art/FlexGrid.xpm +22 -0
- data/samples/demo/art/GC.xpm +23 -0
- data/samples/demo/art/Grid.xpm +22 -0
- data/samples/demo/art/Line.xpm +21 -0
- data/samples/demo/art/NoSource.xpm +69 -0
- data/samples/demo/art/OrthoLine.xpm +21 -0
- data/samples/demo/art/Rect.xpm +22 -0
- data/samples/demo/art/RoundOrthoLine.xpm +21 -0
- data/samples/demo/art/RoundRect.xpm +22 -0
- data/samples/demo/art/Shadow.xpm +23 -0
- data/samples/demo/art/StandAloneLine.xpm +22 -0
- data/samples/demo/art/Text.xpm +21 -0
- data/samples/demo/art/Tool.xpm +23 -0
- data/samples/demo/art/sample.xpm +251 -0
- data/samples/demo/demo.rb +658 -0
- data/samples/demo/frame_canvas.rb +422 -0
- data/samples/demo/images/motyl.bmp +0 -0
- data/samples/demo/images/motyl2.bmp +0 -0
- data/samples/sample1/art/sample.xpm +251 -0
- data/samples/sample1/sample.rb +263 -0
- data/samples/sample2/art/sample.xpm +251 -0
- data/samples/sample2/sample.rb +133 -0
- data/samples/sample2/sample_canvas.rb +35 -0
- data/samples/sample2/sample_shape.rb +108 -0
- data/samples/sample3/art/sample.xpm +251 -0
- data/samples/sample3/sample.rb +281 -0
- data/samples/sample4/art/sample.xpm +251 -0
- data/samples/sample4/sample.rb +180 -0
- data/tests/art/motyl.bmp +0 -0
- data/tests/lib/wxapp_runner.rb +64 -0
- data/tests/serializer_tests.rb +521 -0
- data/tests/test_grid_shapes.rb +42 -0
- data/tests/test_serialize.rb +7 -0
- data/tests/test_serialize_yaml.rb +17 -0
- metadata +242 -0
@@ -0,0 +1,907 @@
|
|
1
|
+
# Wx::SF::LineShape - line shape class
|
2
|
+
# Copyright (c) M.J.N. Corino, The Netherlands
|
3
|
+
|
4
|
+
require 'wx/shapes/arrow_base'
|
5
|
+
|
6
|
+
module Wx::SF
|
7
|
+
|
8
|
+
class LineShape < Shape
|
9
|
+
|
10
|
+
# Default values
|
11
|
+
module DEFAULT
|
12
|
+
# Default value of undefined ID.
|
13
|
+
UNKNOWNID = nil
|
14
|
+
# Default value of LineShape @pen data member.
|
15
|
+
PEN = Wx::Pen.new(Wx::BLACK) if Wx::App.is_main_loop_running
|
16
|
+
Wx.add_delayed_constant(self, :PEN) { Wx::Pen.new(Wx::BLACK) }
|
17
|
+
# Default value of LineShape @dock_point data member.
|
18
|
+
DOCKPOINT = 0
|
19
|
+
# Default value of LineShape @dock_point data member (start line point).
|
20
|
+
DOCKPOINT_START = -1
|
21
|
+
# Default value of LineShape @dock_point data member (end line point).
|
22
|
+
DOCKPOINT_END = -2
|
23
|
+
# Default value of LineShape @dock_point data member (middle dock point).
|
24
|
+
DOCKPOINT_CENTER = 2**64
|
25
|
+
# Default value of LineShape @src_offset and LineShape @trg_offset data members.
|
26
|
+
OFFSET = Wx::RealPoint.new(-1, -1)
|
27
|
+
# Default value of LineShape @src_point and LineShape @trg_point data members.
|
28
|
+
POINT = Wx::RealPoint.new(0, 0)
|
29
|
+
# Default value of LineShape @stand_alone data member.
|
30
|
+
STANDALONE = false
|
31
|
+
end
|
32
|
+
|
33
|
+
# The modes in which the line shape can stay.
|
34
|
+
class LINEMODE < Wx::Enum
|
35
|
+
READY = self.new(0)
|
36
|
+
UNDERCONSTRUCTION = self.new(1)
|
37
|
+
SRCCHANGE = self.new(2)
|
38
|
+
TRGCHANGE = self.new(3)
|
39
|
+
end
|
40
|
+
|
41
|
+
property :src_shape_id, :trg_shape_id
|
42
|
+
property src_point: :serialize_src_point, trg_point: :serialize_trg_point
|
43
|
+
property :stand_alone, :src_arrow, :trg_arrow, :src_offset, :trg_offset,
|
44
|
+
:dock_point, :line_pen, :control_points
|
45
|
+
|
46
|
+
# @overload initialize()
|
47
|
+
# default constructor
|
48
|
+
# @overload initialize(src, trg, path, manager)
|
49
|
+
# @param [Wx::SF::Serializable::ID] src ID of the source shape
|
50
|
+
# @param [Wx::SF::Serializable::ID] trg ID of the target shape
|
51
|
+
# @param [Array<Wx::RealPoint>] path List of the line control points (can be empty)
|
52
|
+
# @param [Diagram] diagram containing diagram
|
53
|
+
# @overload initialize(src, trg, path, manager)
|
54
|
+
# @param [Wx::RealPoint] src starting line point
|
55
|
+
# @param [Wx::RealPoint] trg end line point
|
56
|
+
# @param [Array<Wx::RealPoint>,nil] path List of the line control points (can be empty or nil)
|
57
|
+
# @param [Diagram] diagram containing diagram
|
58
|
+
def initialize(*args)
|
59
|
+
if args.empty?
|
60
|
+
super()
|
61
|
+
@src_shape_id = @trg_shape_id = DEFAULT::UNKNOWNID
|
62
|
+
@src_point = DEFAULT::POINT.dup
|
63
|
+
@trg_point = DEFAULT::POINT.dup
|
64
|
+
@stand_alone = DEFAULT::STANDALONE
|
65
|
+
@lst_points = []
|
66
|
+
else
|
67
|
+
src, trg, path, diagram = args
|
68
|
+
super(Shape::DEFAULT::POSITION.dup, diagram)
|
69
|
+
if src.respond_to?(:to_real_point) && trg.respond_to?(:to_real_point)
|
70
|
+
@src_point = src.to_real_point
|
71
|
+
@trg_point = trg.to_real_point
|
72
|
+
@src_shape_id = @trg_shape_id = DEFAULT::UNKNOWNID
|
73
|
+
@stand_alone = true
|
74
|
+
elsif src.is_a?(Wx::SF::Serializable::ID) && trg.is_a?(Wx::SF::Serializable::ID)
|
75
|
+
@src_point = DEFAULT::POINT.dup
|
76
|
+
@trg_point = DEFAULT::POINT.dup
|
77
|
+
@src_shape_id = src
|
78
|
+
@trg_shape_id = trg
|
79
|
+
@stand_alone = false
|
80
|
+
else
|
81
|
+
::Kernel.raise ArgumentError, "Invalid arguments #{args}"
|
82
|
+
end
|
83
|
+
path ||= []
|
84
|
+
@lst_points = path.select { |pt| pt.respond_to?(:to_real_point) }.collect { |pt| pt.to_real_point }
|
85
|
+
::Kernel.raise ArgumentError, "Invalid arguments #{args}" unless path.size == @lst_points.size
|
86
|
+
end
|
87
|
+
|
88
|
+
@src_arrow = nil
|
89
|
+
@trg_arrow = nil
|
90
|
+
|
91
|
+
@dock_point = DEFAULT::DOCKPOINT
|
92
|
+
@pen = DEFAULT::PEN
|
93
|
+
|
94
|
+
@src_offset = DEFAULT::OFFSET.dup
|
95
|
+
@trg_offset = DEFAULT::OFFSET.dup
|
96
|
+
|
97
|
+
@mode = LINEMODE::READY
|
98
|
+
@prev_position = Wx::RealPoint.new
|
99
|
+
@unfinished_point = Wx::Point.new
|
100
|
+
end
|
101
|
+
|
102
|
+
# Get source shape id.
|
103
|
+
# @return [Wx::SF::Serializable::ID]
|
104
|
+
def get_src_shape_id
|
105
|
+
@src_shape_id
|
106
|
+
end
|
107
|
+
alias :src_shape_id :get_src_shape_id
|
108
|
+
|
109
|
+
# Set source shape id.
|
110
|
+
# @param [Wx::SF::Serializable::ID] id
|
111
|
+
def set_src_shape_id(id)
|
112
|
+
@src_shape_id = id
|
113
|
+
end
|
114
|
+
alias :src_shape_id= :set_src_shape_id
|
115
|
+
|
116
|
+
# Get target shape id.
|
117
|
+
# @return [Wx::SF::Serializable::ID]
|
118
|
+
def get_trg_shape_id
|
119
|
+
@trg_shape_id
|
120
|
+
end
|
121
|
+
alias :trg_shape_id :get_trg_shape_id
|
122
|
+
|
123
|
+
# Set target shape id.
|
124
|
+
# @param [Wx::SF::Serializable::ID] id
|
125
|
+
def set_trg_shape_id(id)
|
126
|
+
@trg_shape_id = id
|
127
|
+
end
|
128
|
+
alias :trg_shape_id= :set_trg_shape_id
|
129
|
+
|
130
|
+
# Get source point.
|
131
|
+
# @return [Wx::RealPoint]
|
132
|
+
def get_src_point
|
133
|
+
unless @stand_alone
|
134
|
+
src_shape = @diagram.find_shape(@src_shape_id)
|
135
|
+
|
136
|
+
if src_shape && !@lst_points.empty?
|
137
|
+
if src_shape.get_connection_points.empty?
|
138
|
+
return src_shape.get_border_point(get_mod_src_point, @lst_points.first)
|
139
|
+
else
|
140
|
+
return get_mod_src_point
|
141
|
+
end
|
142
|
+
else
|
143
|
+
if @mode != LINEMODE::UNDERCONSTRUCTION
|
144
|
+
pt1, _ = get_direct_line
|
145
|
+
else
|
146
|
+
pt1 = get_mod_src_point
|
147
|
+
end
|
148
|
+
return pt1
|
149
|
+
end
|
150
|
+
|
151
|
+
return Wx::RealPoint.new
|
152
|
+
end
|
153
|
+
@src_point
|
154
|
+
end
|
155
|
+
alias :src_point :get_src_point
|
156
|
+
|
157
|
+
# Set source point.
|
158
|
+
# @param [Wx::RealPoint] pt
|
159
|
+
def set_src_point(pt)
|
160
|
+
@src_point = pt.to_real_point
|
161
|
+
end
|
162
|
+
|
163
|
+
# Get target point.
|
164
|
+
# @return [Wx::RealPoint]
|
165
|
+
def get_trg_point
|
166
|
+
unless @stand_alone
|
167
|
+
trg_shape = @diagram.find_shape(@trg_shape_id)
|
168
|
+
|
169
|
+
if trg_shape && !@lst_points.empty?
|
170
|
+
if trg_shape.get_connection_points.empty?
|
171
|
+
return trg_shape.get_border_point(get_mod_trg_point, @lst_points.last)
|
172
|
+
else
|
173
|
+
return get_mod_trg_point
|
174
|
+
end
|
175
|
+
else
|
176
|
+
if @mode != LINEMODE::UNDERCONSTRUCTION
|
177
|
+
_, pt2 = get_direct_line
|
178
|
+
else
|
179
|
+
pt2 = @unfinished_point.to_real
|
180
|
+
end
|
181
|
+
return pt2
|
182
|
+
end
|
183
|
+
|
184
|
+
return Wx::RealPoint.new
|
185
|
+
end
|
186
|
+
@trg_point
|
187
|
+
end
|
188
|
+
alias :trg_point :get_trg_point
|
189
|
+
|
190
|
+
# Set target point.
|
191
|
+
# @param [Wx::RealPoint] pt
|
192
|
+
def set_trg_point(pt)
|
193
|
+
@trg_point = pt.to_real_point
|
194
|
+
end
|
195
|
+
|
196
|
+
# Get source arrow.
|
197
|
+
# @return [Wx::SF::ArrowBase]
|
198
|
+
def get_src_arrow
|
199
|
+
@src_arrow
|
200
|
+
end
|
201
|
+
alias :src_arrow :get_src_arrow
|
202
|
+
|
203
|
+
# Set source arrow
|
204
|
+
# @overload set_src_arrow(arrow)
|
205
|
+
# @param [Wx::SF::ArrowBase] arrow
|
206
|
+
# @return [Wx::SF::ArrowBase,nil] the new source arrow object if invalid
|
207
|
+
# @overload set_src_arrow(arrow_klass)
|
208
|
+
# @param [Class] arrow_klass
|
209
|
+
# @return [Wx::SF::ArrowBase,nil] the new source arrow object if invalid
|
210
|
+
def set_src_arrow(arg)
|
211
|
+
if (arg.is_a?(::Class) && arg < ArrowBase) || arg.is_a?(ArrowBase)
|
212
|
+
@src_arrow = arg.is_a?(ArrowBase) ? arg : arg.new
|
213
|
+
@src_arrow.set_parent_shape(self)
|
214
|
+
end
|
215
|
+
nil
|
216
|
+
end
|
217
|
+
alias :src_arrow= :set_src_arrow
|
218
|
+
|
219
|
+
# Get target arrow.
|
220
|
+
# @return [Wx::SF::ArrowBase]
|
221
|
+
def get_trg_arrow
|
222
|
+
@trg_arrow
|
223
|
+
end
|
224
|
+
alias :trg_arrow :get_trg_arrow
|
225
|
+
|
226
|
+
# Set target arrow
|
227
|
+
# @overload set_trg_arrow(arrow)
|
228
|
+
# @param [Wx::SF::ArrowBase] arrow
|
229
|
+
# @return [Wx::SF::ArrowBase,nil] the new source arrow object if invalid
|
230
|
+
# @overload set_trg_arrow(arrow_klass)
|
231
|
+
# @param [Class] arrow_klass
|
232
|
+
# @return [Wx::SF::ArrowBase,nil] the new source arrow object if invalid
|
233
|
+
def set_trg_arrow(arg)
|
234
|
+
if (arg.is_a?(::Class) && arg < ArrowBase) || arg.is_a?(ArrowBase)
|
235
|
+
@trg_arrow = arg.is_a?(ArrowBase) ? arg : arg.new
|
236
|
+
@trg_arrow.set_parent_shape(self)
|
237
|
+
end
|
238
|
+
nil
|
239
|
+
end
|
240
|
+
alias :trg_arrow= :set_trg_arrow
|
241
|
+
|
242
|
+
# Get line type
|
243
|
+
# @return [Wx::Pen]
|
244
|
+
def get_line_pen
|
245
|
+
@pen
|
246
|
+
end
|
247
|
+
alias :line_pen :get_line_pen
|
248
|
+
|
249
|
+
# Set line type
|
250
|
+
# @param [Wx::Pen] pen line type
|
251
|
+
def set_line_pen(pen)
|
252
|
+
@pen = pen
|
253
|
+
end
|
254
|
+
alias :line_pen= :set_line_pen
|
255
|
+
|
256
|
+
# Set the line dock point. It is a zero based index of the line
|
257
|
+
# control point which will act as the shape position (value returned by Shape#get_relative_position function).
|
258
|
+
# @param [Integer] index Zero based index of the line control point
|
259
|
+
def set_dock_point(index)
|
260
|
+
@dock_point = index
|
261
|
+
end
|
262
|
+
alias :dock_point= :set_dock_point
|
263
|
+
|
264
|
+
# Get the line dock point. It is a zero based index of the line
|
265
|
+
# control point which will act as the shape position (value returned by Shape#get_relative_position function).
|
266
|
+
# @return [Integer] Zero based index of the line control point (-1 means UNDEFINED)
|
267
|
+
def get_dock_point
|
268
|
+
@dock_point
|
269
|
+
end
|
270
|
+
|
271
|
+
# Returns true if stand alone line
|
272
|
+
# @return [Boolean]
|
273
|
+
def get_stand_alone
|
274
|
+
@stand_alone
|
275
|
+
end
|
276
|
+
alias :stand_alone? :get_stand_alone
|
277
|
+
|
278
|
+
# Set stand alone line mode
|
279
|
+
# @param [Boolean] f flag
|
280
|
+
def set_stand_alone(f = true)
|
281
|
+
@stand_alone = !!f
|
282
|
+
end
|
283
|
+
alias :stand_alone= :set_stand_alone
|
284
|
+
|
285
|
+
# Get starting and ending line points.
|
286
|
+
# @return [Array(Wx::RealPoint, Wx::RealPoint)] starting line point and ending line point
|
287
|
+
def get_direct_line
|
288
|
+
if @stand_alone
|
289
|
+
return [@src_point, @trg_point]
|
290
|
+
else
|
291
|
+
src_shape = get_diagram.find_shape(@src_shape_id)
|
292
|
+
trg_shape = get_diagram.find_shape(@trg_shape_id)
|
293
|
+
|
294
|
+
if src_shape && trg_shape
|
295
|
+
trg_center = get_mod_trg_point
|
296
|
+
src_center = get_mod_src_point
|
297
|
+
|
298
|
+
if src_shape.get_parent_shape == trg_shape || trg_shape.get_parent_shape == src_shape
|
299
|
+
trg_bb = trg_shape.get_bounding_box
|
300
|
+
src_bb = src_shape.get_bounding_box
|
301
|
+
|
302
|
+
if trg_bb.contains?(src_center.x.to_i, src_center.y.to_i)
|
303
|
+
if src_center.y > trg_center.y
|
304
|
+
src = Wx::RealPoint.new(src_center.x, src_bb.bottom.to_f)
|
305
|
+
trg = Wx::RealPoint.new(src_center.x, trg_bb.bottom.to_f)
|
306
|
+
else
|
307
|
+
src = Wx::RealPoint.new(src_center.x, src_bb.top.to_f)
|
308
|
+
trg = Wx::RealPoint.new(src_center.x, trg_bb.top.to_f)
|
309
|
+
end
|
310
|
+
return [src, trg]
|
311
|
+
elsif src_bb.contains?(trg_center.x.to_i, trg_center.y.to_i)
|
312
|
+
if trg_center.y > src_center.y
|
313
|
+
src = Wx::RealPoint.new(trg_center.x, src_bb.bottom.to_f)
|
314
|
+
trg = Wx::RealPoint.new(trg_center.x, trg_bb.bottom.to_f)
|
315
|
+
else
|
316
|
+
src = Wx::RealPoint.new(trg_center.x, src_bb.top.to_f)
|
317
|
+
trg = Wx::RealPoint.new(trg_center.x, trg_bb.top.to_f)
|
318
|
+
end
|
319
|
+
return [src, trg]
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
if src_shape.get_connection_points.empty?
|
324
|
+
src = src_shape.get_border_point(src_center, trg_center)
|
325
|
+
else
|
326
|
+
src = src_center
|
327
|
+
end
|
328
|
+
|
329
|
+
if trg_shape.get_connection_points.empty?
|
330
|
+
trg = trg_shape.get_border_point(trg_center, src_center)
|
331
|
+
else
|
332
|
+
trg = trg_center
|
333
|
+
end
|
334
|
+
return [src, trg]
|
335
|
+
end
|
336
|
+
end
|
337
|
+
nil # should not happen
|
338
|
+
end
|
339
|
+
|
340
|
+
# Get a list of the line's control points (their positions).
|
341
|
+
# @return [Array<Wx::RealPoint>] List of control points' positions
|
342
|
+
def get_control_points
|
343
|
+
@lst_points
|
344
|
+
end
|
345
|
+
|
346
|
+
# Get a position of given line dock point.
|
347
|
+
# @param [Integer] dp Dock point
|
348
|
+
# @return [Wx::RealPoint] The dock point's position if exists, otherwise the line center
|
349
|
+
def get_dock_point_position(dp)
|
350
|
+
pts_cnt = @lst_points.size
|
351
|
+
|
352
|
+
if dp >= 0
|
353
|
+
if pts_cnt > dp
|
354
|
+
return @lst_points[dp]
|
355
|
+
elsif pts_cnt > 0
|
356
|
+
return @lst_points[pts_cnt/2]
|
357
|
+
end
|
358
|
+
elsif dp == -1 # start line point
|
359
|
+
return get_src_point
|
360
|
+
elsif dp == -2 # end line point
|
361
|
+
return get_trg_point
|
362
|
+
end
|
363
|
+
|
364
|
+
get_center
|
365
|
+
end
|
366
|
+
|
367
|
+
# Initialize line's starting point with existing fixed connection point.
|
368
|
+
# @param [Wx::SF::ConnectionPoint] cp Pointer to connection point
|
369
|
+
def set_starting_connection_point(cp)
|
370
|
+
if cp && cp.get_parent_shape
|
371
|
+
pos_cp = cp.get_connection_point
|
372
|
+
rct_bb = cp.get_parent_shape.get_bounding_box
|
373
|
+
|
374
|
+
@src_offset.x = (pos_cp.x - rct_bb.left).to_f / rct_bb.width
|
375
|
+
@src_offset.y = (pos_cp.y - rct_bb.top).to_f / rct_bb.height
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
# Initialize line's ending point with existing fixed connection point.
|
380
|
+
# @param [Wx::SF::ConnectionPoint] cp Pointer to connection point
|
381
|
+
def set_ending_connection_point(cp)
|
382
|
+
if cp && cp.get_parent_shape
|
383
|
+
pos_cp = cp.get_connection_point
|
384
|
+
rct_bb = cp.get_parent_shape.get_bounding_box
|
385
|
+
|
386
|
+
@trg_offset.x = (pos_cp.x - rct_bb.left).to_f / rct_bb.width
|
387
|
+
@trg_offset.y = (pos_cp.y - rct_bb.top).to_f / rct_bb.height
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
# Get number of line segments for this shape.
|
392
|
+
# @return [Integer] number of line segments
|
393
|
+
def get_line_segment_count
|
394
|
+
@lst_points.size+1
|
395
|
+
end
|
396
|
+
alias :line_segment_count :get_line_segment_count
|
397
|
+
alias :segment_count :get_line_segment_count
|
398
|
+
|
399
|
+
# Get starting and ending point of line segment defined by its index.
|
400
|
+
# @param [Integer] index Index of desired line segment
|
401
|
+
# @return [Array(Wx::RealPoint,Wx::RealPoint)] starting and ending point of line segment
|
402
|
+
def get_line_segment(index)
|
403
|
+
if @lst_points.empty?
|
404
|
+
return get_direct_line if index == 0
|
405
|
+
else
|
406
|
+
if index == 0
|
407
|
+
return [get_src_point, @lst_points.first.dup]
|
408
|
+
elsif index == @lst_points.size
|
409
|
+
return [@lst_points.last.dup, get_trg_point]
|
410
|
+
elsif index > 0 && index < @lst_points.size
|
411
|
+
return @lst_points[index-1, 2].collect {|p| p.dup}
|
412
|
+
end
|
413
|
+
end
|
414
|
+
[Wx::RealPoint.new, Wx::RealPoint.new]
|
415
|
+
end
|
416
|
+
|
417
|
+
# Get line's bounding box. The function can be overridden if necessary.
|
418
|
+
# @return [Wx::Rect] Bounding rectangle
|
419
|
+
def get_bounding_box
|
420
|
+
line_rct = nil
|
421
|
+
|
422
|
+
# calculate control points area if they exist
|
423
|
+
if !@lst_points.empty?
|
424
|
+
prev_pt = get_src_point
|
425
|
+
|
426
|
+
@lst_points.each do |pt|
|
427
|
+
if line_rct.nil?
|
428
|
+
line_rct = Wx::Rect.new(prev_pt.to_point, pt.to_point)
|
429
|
+
else
|
430
|
+
line_rct.union!(Wx::Rect.new(prev_pt.to_point, pt.to_point))
|
431
|
+
end
|
432
|
+
prev_pt = pt
|
433
|
+
end
|
434
|
+
|
435
|
+
line_rct.union!(Wx::Rect.new(prev_pt.to_point, get_trg_point.to_point))
|
436
|
+
else
|
437
|
+
# include starting point
|
438
|
+
pt = get_src_point
|
439
|
+
line_rct = Wx::Rect.new(pt.x.to_i, pt.y.to_i, 1, 1)
|
440
|
+
|
441
|
+
# include ending point
|
442
|
+
pt = get_trg_point
|
443
|
+
line_rct.union!(Wx::Rect.new(pt.x.to_i, pt.y.to_i, 1, 1))
|
444
|
+
end
|
445
|
+
|
446
|
+
# include unfinished point if the line is under construction
|
447
|
+
if @mode == LINEMODE::UNDERCONSTRUCTION || @mode == LINEMODE::SRCCHANGE || @mode == LINEMODE::TRGCHANGE
|
448
|
+
if line_rct.nil?
|
449
|
+
line_rct = Wx::Rect.new(@unfinished_point.x, @unfinished_point.y, 1, 1)
|
450
|
+
else
|
451
|
+
line_rct.union!(Wx::Rect.new(@unfinished_point.x, @unfinished_point.y, 1, 1))
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
line_rct ? line_rct : Wx::Rect.new
|
456
|
+
end
|
457
|
+
|
458
|
+
# Get the shape's absolute position in the canvas.
|
459
|
+
# @return [Wx::RealPoint] Shape's position
|
460
|
+
def get_absolute_position
|
461
|
+
get_dock_point_position(@dock_point)
|
462
|
+
end
|
463
|
+
|
464
|
+
# Get intersection point of the shape border and a line leading from
|
465
|
+
# 'start_pt' point to 'end_pt' point. The function can be overridden if necessary.
|
466
|
+
# @param [Wx::RealPoint] _start_pt Starting point of the virtual intersection line
|
467
|
+
# @param [Wx::RealPoint] _end_pt Ending point of the virtual intersection line
|
468
|
+
# @return [Wx::RealPoint] Intersection point
|
469
|
+
def get_border_point(_start_pt, _end_pt)
|
470
|
+
get_absolute_position
|
471
|
+
end
|
472
|
+
|
473
|
+
# Test whether the given point is inside the shape. The function
|
474
|
+
# can be overridden if necessary.
|
475
|
+
# @param pos Examined point
|
476
|
+
# @return TRUE if the point is inside the shape area, otherwise FALSE
|
477
|
+
def contains?(pos)
|
478
|
+
return true if @mode != LINEMODE::UNDERCONSTRUCTION && get_hit_linesegment(pos) >= 0
|
479
|
+
false
|
480
|
+
end
|
481
|
+
|
482
|
+
# Move the shape to the given absolute position. The function
|
483
|
+
# can be overridden if necessary.
|
484
|
+
# @param [Float] x X coordinate
|
485
|
+
# @param [Float] y Y coordinate
|
486
|
+
def move_to(x, y)
|
487
|
+
move_by(x - @prev_position.x, y - @prev_position.y)
|
488
|
+
@prev_position.x = x
|
489
|
+
@prev_position.y = y
|
490
|
+
end
|
491
|
+
|
492
|
+
# Move the shape by the given offset. The function
|
493
|
+
# can be overridden if necessary.
|
494
|
+
# @param [Float] x X offset
|
495
|
+
# @param [Float] y Y offset
|
496
|
+
def move_by(x, y)
|
497
|
+
@lst_points.each do |pt|
|
498
|
+
pt.x += x
|
499
|
+
pt.y += y
|
500
|
+
end
|
501
|
+
|
502
|
+
if @stand_alone
|
503
|
+
@src_point += [x, y]
|
504
|
+
@trg_point += [x, y]
|
505
|
+
end
|
506
|
+
|
507
|
+
update unless @child_shapes.empty?
|
508
|
+
|
509
|
+
get_diagram.set_modified if get_diagram
|
510
|
+
end
|
511
|
+
|
512
|
+
# Function called by the framework responsible for creation of shape handles
|
513
|
+
# at the creation time. The function can be overridden if necessary.
|
514
|
+
def create_handles
|
515
|
+
# first clear all previously used handles and then create new ones
|
516
|
+
@handles.clear
|
517
|
+
|
518
|
+
# create control points handles
|
519
|
+
@lst_points.size.times { |i| add_handle(Shape::Handle::TYPE::LINECTRL, i) }
|
520
|
+
|
521
|
+
# create border handles
|
522
|
+
add_handle(Shape::Handle::TYPE::LINESTART)
|
523
|
+
add_handle(Shape::Handle::TYPE::LINEEND)
|
524
|
+
end
|
525
|
+
|
526
|
+
# Event handler called during dragging of the shape handle.
|
527
|
+
# The function can be overridden if necessary.
|
528
|
+
#
|
529
|
+
# The function is called by the framework (by the shape canvas).
|
530
|
+
# @param [Wx::SF::Shape::Handle] handle Reference to dragged handle
|
531
|
+
def on_handle(handle)
|
532
|
+
case handle.type
|
533
|
+
when Shape::Handle::TYPE::LINECTRL
|
534
|
+
pt = @lst_points[handle.id]
|
535
|
+
if pt
|
536
|
+
pt.x = handle.get_position.x
|
537
|
+
pt.y = handle.get_position.y
|
538
|
+
end
|
539
|
+
|
540
|
+
when Shape::Handle::TYPE::LINEEND
|
541
|
+
@unfinished_point = handle.get_position
|
542
|
+
@trg_point = handle.get_position.to_real if @stand_alone
|
543
|
+
|
544
|
+
when Shape::Handle::TYPE::LINESTART
|
545
|
+
@unfinished_point = handle.get_position
|
546
|
+
@src_point = handle.get_position.to_real if @stand_alone
|
547
|
+
end
|
548
|
+
|
549
|
+
super
|
550
|
+
end
|
551
|
+
|
552
|
+
# Event handler called when the user finished dragging of the shape handle.
|
553
|
+
# The function can be overridden if necessary.
|
554
|
+
#
|
555
|
+
# The function is called by the framework (by the shape canvas).
|
556
|
+
# Default implementation does nothing.
|
557
|
+
# @param [Wx::SF::Shape::Handle] handle Reference to dragged handle
|
558
|
+
def on_end_handle(handle)
|
559
|
+
# update percentual offset of the line's ending points
|
560
|
+
parent = get_parent_canvas.get_shape_under_cursor
|
561
|
+
|
562
|
+
if parent && !@stand_alone
|
563
|
+
bb_rect = parent.get_bounding_box
|
564
|
+
|
565
|
+
case handle.type
|
566
|
+
when Shape::Handle::TYPE::LINESTART
|
567
|
+
if parent.id == @src_shape_id
|
568
|
+
@src_offset.x = (handle.get_position.x - bb_rect.left).to_f / bb_rect.width
|
569
|
+
@src_offset.y = (handle.get_position.y - bb_rect.top).to_f / bb_rect.height
|
570
|
+
end
|
571
|
+
|
572
|
+
when Shape::Handle::TYPE::LINEEND
|
573
|
+
if parent.id == @trg_shape_id
|
574
|
+
@trg_offset.x = (handle.get_position.x - bb_rect.left).to_f / bb_rect.width
|
575
|
+
@trg_offset.y = (handle.get_position.y - bb_rect.top).to_f / bb_rect.height
|
576
|
+
end
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
super
|
581
|
+
end
|
582
|
+
|
583
|
+
# Event handler called at the beginning of the shape dragging process.
|
584
|
+
# The function can be overridden if necessary.
|
585
|
+
#
|
586
|
+
# The function is called by the framework (by the shape canvas).
|
587
|
+
# @param [Wx::Point] pos Current mouse position
|
588
|
+
# @see Wx::SF::ShapeCanvas
|
589
|
+
def on_begin_drag(pos)
|
590
|
+
@prev_position = get_absolute_position
|
591
|
+
|
592
|
+
super
|
593
|
+
end
|
594
|
+
|
595
|
+
# Event handler called when the shape is double-clicked by
|
596
|
+
# the left mouse button. The function can be overridden if necessary.
|
597
|
+
#
|
598
|
+
# The function is called by the framework (by the shape canvas).
|
599
|
+
# @param [Wx::Point] pos Current mouse position
|
600
|
+
# @see Wx::SF::ShapeCanvas
|
601
|
+
def on_left_double_click(pos)
|
602
|
+
# HINT: override it for custom actions
|
603
|
+
|
604
|
+
if get_parent_canvas
|
605
|
+
# remove existing handle if exist otherwise create a new one at the
|
606
|
+
# given position
|
607
|
+
handle = get_parent_canvas.get_topmost_handle_at_position(pos)
|
608
|
+
if handle && handle.get_parent_shape == self
|
609
|
+
if handle.type == Shape::Handle::TYPE::LINECTRL
|
610
|
+
if has_style?(STYLE::EMIT_EVENTS)
|
611
|
+
evt = Wx::SF::ShapeHandleEvent.new(EVT_SF_LINE_HANDLE_REMOVE, id)
|
612
|
+
evt.set_shape(self)
|
613
|
+
evt.set_handle(handle)
|
614
|
+
get_parent_canvas.get_event_handler.process_event(evt)
|
615
|
+
end
|
616
|
+
|
617
|
+
@lst_points.delete_at(handle.id)
|
618
|
+
|
619
|
+
create_handles
|
620
|
+
show_handles(true)
|
621
|
+
end
|
622
|
+
else
|
623
|
+
index = get_hit_linesegment(pos)
|
624
|
+
if index > -1
|
625
|
+
@lst_points.insert(index, Wx::RealPoint.new(pos.x, pos.y))
|
626
|
+
|
627
|
+
create_handles
|
628
|
+
show_handles(true)
|
629
|
+
|
630
|
+
if has_style?(STYLE::EMIT_EVENTS)
|
631
|
+
handle = get_parent_canvas.get_topmost_handle_at_position(pos)
|
632
|
+
if handle
|
633
|
+
evt = ShapeHandleEvent.new(EVT_SF_LINE_HANDLE_ADD, id)
|
634
|
+
evt.set_shape(this)
|
635
|
+
evt.set_handle(handle)
|
636
|
+
get_parent_canvas.get_event_handler.process_event(evt)
|
637
|
+
end
|
638
|
+
end
|
639
|
+
end
|
640
|
+
end
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
# Scale the shape size by in both directions. The function can be overridden if necessary
|
645
|
+
# (new implementation should call default one or scale shape's children manually if necessary).
|
646
|
+
# @param [Float] x Horizontal scale factor
|
647
|
+
# @param [Float] y Vertical scale factor
|
648
|
+
# @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.
|
649
|
+
def scale(x, y, children = WITHCHILDREN)
|
650
|
+
@lst_points.each do |pt|
|
651
|
+
pt.x *= x
|
652
|
+
pt.y *= y
|
653
|
+
end
|
654
|
+
|
655
|
+
# call default function implementation (needed for scaling of shape's children)
|
656
|
+
super
|
657
|
+
end
|
658
|
+
|
659
|
+
# Get current working mode.
|
660
|
+
# @return [LINEMODE] Current working mode
|
661
|
+
# @see LINEMODE
|
662
|
+
def get_line_mode
|
663
|
+
@mode
|
664
|
+
end
|
665
|
+
|
666
|
+
protected
|
667
|
+
|
668
|
+
# Draw the shape in the normal way. The function can be overridden if necessary.
|
669
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
670
|
+
def draw_normal(dc)
|
671
|
+
dc.with_pen(@pen) do
|
672
|
+
draw_complete_line(dc)
|
673
|
+
end
|
674
|
+
end
|
675
|
+
|
676
|
+
# Draw the shape in the hower mode (the mouse cursor is above the shape).
|
677
|
+
# The function can be overridden if necessary.
|
678
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
679
|
+
def draw_hover(dc)
|
680
|
+
dc.with_pen(Wx::Pen.new(@hover_color, 1)) do
|
681
|
+
draw_complete_line(dc)
|
682
|
+
end
|
683
|
+
end
|
684
|
+
|
685
|
+
# Draw the shape in the highlighted mode (another shape is dragged over this
|
686
|
+
# shape and this shape will accept the dragged one if it will be dropped on it).
|
687
|
+
# The function can be overridden if necessary.
|
688
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
689
|
+
def draw_highlighted(dc)
|
690
|
+
dc.with_pen(Wx::Pen.new(@hover_color, 2)) do
|
691
|
+
draw_complete_line(dc)
|
692
|
+
end
|
693
|
+
end
|
694
|
+
|
695
|
+
# Draw completed line.
|
696
|
+
# @param [Wx::DC] dc Reference to device context where the shape will be drawn to
|
697
|
+
def draw_complete_line(dc)
|
698
|
+
return unless diagram
|
699
|
+
|
700
|
+
case @mode
|
701
|
+
when LINEMODE::READY
|
702
|
+
# draw basic line parts
|
703
|
+
src = trg = nil
|
704
|
+
line_segment_count.times do |i|
|
705
|
+
src, trg = get_line_segment(i)
|
706
|
+
dc.draw_line(src.to_point, trg.to_point)
|
707
|
+
end
|
708
|
+
# draw target arrow
|
709
|
+
@trg_arrow.draw(src, trg, dc) if @trg_arrow
|
710
|
+
# draw source arrow
|
711
|
+
if @src_arrow
|
712
|
+
src, trg = get_line_segment(0)
|
713
|
+
@src_arrow.draw(trg, src, dc)
|
714
|
+
end
|
715
|
+
|
716
|
+
when LINEMODE::UNDERCONSTRUCTION
|
717
|
+
# draw basic line parts
|
718
|
+
src = trg = nil
|
719
|
+
@lst_points.size.times do |i|
|
720
|
+
src, trg = get_line_segment(i)
|
721
|
+
dc.draw_line(src.to_point, trg.to_point)
|
722
|
+
end
|
723
|
+
# draw unfinished line segment if any (for interactive line creation)
|
724
|
+
dc.with_pen(Wx::Pen.new(Wx::BLACK, 1, Wx::PENSTYLE_DOT)) do
|
725
|
+
if @lst_points.size > 0
|
726
|
+
dc.draw_line(trg, @unfinished_point)
|
727
|
+
else
|
728
|
+
src_shape = diagram.find_shape(@src_shape_id)
|
729
|
+
if src_shape
|
730
|
+
if src_shape.get_connection_points.empty?
|
731
|
+
dc.draw_line((src_shape.get_border_point(src_shape.get_center, @unfinished_point.to_real)).to_point,
|
732
|
+
@unfinished_point)
|
733
|
+
else
|
734
|
+
dc.draw_line(get_mod_src_point.to_point, @unfinished_point)
|
735
|
+
end
|
736
|
+
end
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
740
|
+
when LINEMODE::SRCCHANGE
|
741
|
+
# draw basic line parts
|
742
|
+
src = trg = nil
|
743
|
+
@lst_points.size.times do |i|
|
744
|
+
src, trg = get_line_segment(i+1)
|
745
|
+
dc.draw_line(src.to_point, trg.to_point)
|
746
|
+
end
|
747
|
+
|
748
|
+
# draw linesegment being updated
|
749
|
+
src, trg = get_line_segment(0)
|
750
|
+
|
751
|
+
dc.set_pen(Wx::Pen.new(Wx::BLACK, 1, Wx::PENSTYLE_DOT)) unless @stand_alone
|
752
|
+
dc.draw_line(@unfinished_point, trg.to_point)
|
753
|
+
dc.set_pen(Wx::NULL_PEN) unless @stand_alone
|
754
|
+
|
755
|
+
when LINEMODE::TRGCHANGE
|
756
|
+
# draw basic line parts
|
757
|
+
src = trg = nil
|
758
|
+
if @lst_points.empty?
|
759
|
+
trg = get_src_point
|
760
|
+
else
|
761
|
+
@lst_points.size.times do |i|
|
762
|
+
src, trg = get_line_segment(i)
|
763
|
+
dc.draw_line(src.to_point, trg.to_point)
|
764
|
+
end
|
765
|
+
end
|
766
|
+
# draw linesegment being updated
|
767
|
+
dc.set_pen(Wx::Pen.new(Wx::BLACK, 1, Wx::PENSTYLE_DOT)) unless @stand_alone
|
768
|
+
dc.draw_line(trg.to_point, @unfinished_point)
|
769
|
+
dc.set_pen(Wx::NULL_PEN) unless @stand_alone
|
770
|
+
end
|
771
|
+
end
|
772
|
+
|
773
|
+
# Get index of the line segment intersecting the given point.
|
774
|
+
# @param [Wx::Point] pos Examined point
|
775
|
+
# @return [Integer] Zero-based index of line segment located under the given point
|
776
|
+
def get_hit_linesegment(pos)
|
777
|
+
return -1 unless get_bounding_box.contains?(pos)
|
778
|
+
|
779
|
+
pos = pos.to_point
|
780
|
+
# Get all polyline segments
|
781
|
+
line_segment_count.times do |i|
|
782
|
+
src, trg = get_line_segment(i)
|
783
|
+
|
784
|
+
# calculate line segment bounding box
|
785
|
+
ls_bb = Wx::Rect.new(src.to_point, trg.to_point)
|
786
|
+
ls_bb.inflate!(2)
|
787
|
+
|
788
|
+
# convert line segment to its parametric form
|
789
|
+
a = trg.y - src.y
|
790
|
+
b = src.x - trg.x
|
791
|
+
c = -a*src.x - b*src.y
|
792
|
+
|
793
|
+
# calculate distance of the line and give point
|
794
|
+
d = (a*pos.x + b*pos.y + c)/::Math.sqrt(a*a + b*b)
|
795
|
+
# NaN will be the result if src and trg are equal
|
796
|
+
# (which can happen for lines between parent and child shapes)
|
797
|
+
return i if (d.nan? || d.to_i.abs <= 5) && ls_bb.contains?(pos)
|
798
|
+
end
|
799
|
+
|
800
|
+
-1
|
801
|
+
end
|
802
|
+
|
803
|
+
# Set line shape's working mode.
|
804
|
+
# @param [LINEMODE] mode Working mode
|
805
|
+
# @see LINEMODE
|
806
|
+
def set_line_mode(mode)
|
807
|
+
@mode = mode
|
808
|
+
end
|
809
|
+
|
810
|
+
# Set next potential control point position (useful in LINEMODE::UNDERCONSTRUCTION working mode).
|
811
|
+
# @param [Wx::Point] pos New potential control point position
|
812
|
+
# @see LINEMODE
|
813
|
+
def set_unfinished_point(pos)
|
814
|
+
@unfinished_point = pos.to_point
|
815
|
+
end
|
816
|
+
|
817
|
+
# Get modified starting line point .
|
818
|
+
# @return [Wx::RealPoint] Modified starting line point
|
819
|
+
def get_mod_src_point
|
820
|
+
src_shape = diagram.find_shape(@src_shape_id)
|
821
|
+
return Wx::RealPoint.new unless src_shape
|
822
|
+
|
823
|
+
if @src_offset != DEFAULT::OFFSET
|
824
|
+
bb_rct = src_shape.get_bounding_box
|
825
|
+
mod_point = src_shape.get_absolute_position
|
826
|
+
|
827
|
+
mod_point.x += bb_rct.width.to_f * @src_offset.x
|
828
|
+
mod_point.y += bb_rct.height.to_f * @src_offset.y
|
829
|
+
else
|
830
|
+
mod_point = src_shape.get_center
|
831
|
+
end
|
832
|
+
|
833
|
+
conn_pt = src_shape.get_nearest_connection_point(mod_point)
|
834
|
+
mod_point = conn_pt.get_connection_point if conn_pt
|
835
|
+
|
836
|
+
mod_point
|
837
|
+
end
|
838
|
+
|
839
|
+
# Get modified ending line point .
|
840
|
+
# @return [Wx::RealPoint] Modified ending line point
|
841
|
+
def get_mod_trg_point
|
842
|
+
trg_shape = diagram.find_shape(@trg_shape_id)
|
843
|
+
return Wx::RealPoint.new unless trg_shape
|
844
|
+
|
845
|
+
if @trg_offset != DEFAULT::OFFSET
|
846
|
+
bb_rct = trg_shape.get_bounding_box
|
847
|
+
mod_point = trg_shape.get_absolute_position
|
848
|
+
|
849
|
+
mod_point.x += bb_rct.width.to_f * @trg_offset.x
|
850
|
+
mod_point.y += bb_rct.height.to_f * @trg_offset.y
|
851
|
+
else
|
852
|
+
mod_point = trg_shape.get_center
|
853
|
+
end
|
854
|
+
|
855
|
+
conn_pt = trg_shape.get_nearest_connection_point(mod_point)
|
856
|
+
mod_point = conn_pt.get_connection_point if conn_pt
|
857
|
+
|
858
|
+
mod_point
|
859
|
+
end
|
860
|
+
|
861
|
+
private
|
862
|
+
|
863
|
+
# Set control points. Deserialization only.
|
864
|
+
# @param [Array<Wx::RealPoint>] pts
|
865
|
+
def set_control_points(pts)
|
866
|
+
@lst_points.replace(pts)
|
867
|
+
end
|
868
|
+
|
869
|
+
# Serialization only
|
870
|
+
# @return [Wx::RealPoint]
|
871
|
+
def get_src_offset
|
872
|
+
@src_offset
|
873
|
+
end
|
874
|
+
|
875
|
+
# Deserialization only
|
876
|
+
# @param [Wx::RealPoint] offs
|
877
|
+
def set_src_offset(offs)
|
878
|
+
@src_offset = offs.to_real_point
|
879
|
+
end
|
880
|
+
|
881
|
+
# Serialization only
|
882
|
+
# @return [Wx::RealPoint]
|
883
|
+
def get_trg_offset
|
884
|
+
@trg_offset
|
885
|
+
end
|
886
|
+
|
887
|
+
# Deserialization only
|
888
|
+
# @param [Wx::RealPoint] offs
|
889
|
+
def set_trg_offset(offs)
|
890
|
+
@trg_offset = offs.to_real_point
|
891
|
+
end
|
892
|
+
|
893
|
+
# (De-)Serialization only
|
894
|
+
def serialize_src_point(*arg)
|
895
|
+
@src_point = arg.shift unless arg.empty?
|
896
|
+
@src_point
|
897
|
+
end
|
898
|
+
|
899
|
+
# (De-)Serialization only
|
900
|
+
def serialize_trg_point(*arg)
|
901
|
+
@trg_point = arg.shift unless arg.empty?
|
902
|
+
@trg_point
|
903
|
+
end
|
904
|
+
|
905
|
+
end
|
906
|
+
|
907
|
+
end
|