Class: Wx::SF::OrthoLineShape

Inherits:
LineShape show all
Defined in:
lib/wx/shapes/shapes/ortho_shape.rb

Overview

Orthogonal line shape. The class extends LineShape class and allows user to create connection line orthogonal to base axis.

Direct Known Subclasses

RoundOrthoLineShape

Defined Under Namespace

Classes: SEGMENTCPS

Instance Method Summary collapse

Methods inherited from LineShape

#contains?, #create_handles, #draw_highlighted, #draw_hover, #draw_normal, #get_absolute_position, #get_border_point, #get_bounding_box, #get_control_points, #get_direct_line, #get_dock_point, #get_dock_point_position, #get_line_mode, #get_line_pen, #get_line_segment, #get_line_segment_count, #get_mod_src_point, #get_mod_trg_point, #get_src_arrow, #get_src_point, #get_src_shape, #get_stand_alone, #get_trg_arrow, #get_trg_point, #get_trg_shape, #move_by, #move_to, #on_begin_drag, #on_end_handle, #on_handle, #on_left_double_click, #scale, #set_dock_point, #set_ending_connection_point, #set_line_mode, #set_line_pen, #set_src_arrow, #set_src_point, #set_src_shape, #set_stand_alone, #set_starting_connection_point, #set_trg_arrow, #set_trg_point, #set_trg_shape, #set_unfinished_point

Methods inherited from Shape

#accept_child, #accept_connection, #accept_currently_dragged_shapes, #accept_src_neighbour, #accept_trg_neighbour, #activate, #active?, #add_child_shape, #add_connection_point, #add_handle, #add_style, #ancestor?, #clear_accepted_childs, #clear_accepted_connections, #clear_accepted_src_neighbours, #clear_accepted_trg_neighbours, component, component_shapes, #contains?, #contains_style, #create_handles, #descendant?, #do_alignment, #does_not_accept_children?, #draw, #draw_highlighted, #draw_hover, #draw_normal, #draw_selected, #draw_shadow, #fit_to_children, #get_absolute_position, #get_accepted_children, #get_accepted_connections, #get_accepted_src_neighbours, #get_accepted_trg_neighbours, #get_assigned_connections, #get_border_point, #get_bounding_box, #get_center, #get_child_shapes, #get_children, #get_children_recursively, #get_complete_bounding_box, #get_connection_point, #get_connection_points, #get_custom_dock_point, #get_diagram, #get_grand_parent_shape, #get_h_align, #get_h_border, #get_handle, #get_handles, #get_hover_colour, #get_nearest_connection_point, #get_neighbours, #get_parent_absolute_position, #get_parent_canvas, #get_parent_shape, #get_relative_position, #get_shape_canvas, #get_style, #get_user_data, #get_v_align, #get_v_border, #has_children, #has_selected_parent?, #include_child_shape?, #inside?, #inspect, #intersects?, #is_child_accepted, #is_connection_accepted, #is_managed, #is_manager, #is_src_neighbour_accepted, #is_trg_neighbour_accepted, lines_intersection, #lines_intersection, #move_by, #move_to, #on_begin_drag, #on_begin_handle, #on_child_dropped, #on_dragging, #on_end_drag, #on_end_handle, #on_handle, #on_import, #on_key, #on_left_click, #on_left_double_click, #on_mouse_enter, #on_mouse_leave, #on_mouse_over, #on_right_click, #on_right_double_click, #refresh, #refresh_rect, #remove_connection_point, #remove_handle, #remove_style, #scale, #scale_children, #select, #selected?, #set_custom_dock_point, #set_diagram, #set_h_align, #set_h_border, #set_hover_colour, #set_parent_shape, #set_relative_position, #set_style, #set_user_data, #set_v_align, #set_v_border, #show, #show_handles, #to_s, #update, #visible?

Constructor Details

#initialize(src = nil, trg = nil, path: nil, diagram: nil) ⇒ OrthoLineShape

Constructor

Parameters:

  • src (Shape) (defaults to: nil)

    source shape

  • trg (Shape) (defaults to: nil)

    target shape

  • path (Array<Wx::RealPoint>) (defaults to: nil)

    List of the line control points (can be empty)

  • diagram (Diagram) (defaults to: nil)

    containing diagram



19
20
21
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 19

def initialize(src = nil, trg = nil, path: nil, diagram: nil)
  super
end

Instance Method Details

#draw_complete_line(dc) ⇒ Object (protected)

Internal function used for drawing of completed line shape.

Parameters:

  • dc (Wx::DC)

    Reference of the device context where the shape will be drawn to



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 27

def draw_complete_line(dc)
  return unless @diagram
  
  src = trg = cp_src = cp_trg = nil

  if @src_shape
    cp_src = @src_shape.get_nearest_connection_point(get_mod_src_point)
  end
  if @trg_shape
    cp_trg = @trg_shape.get_nearest_connection_point(get_mod_trg_point)
  end
  
  case @mode
  when LINEMODE::READY
    # draw basic line parts
    n = line_segment_count-1
    (0..n).each do |i|
      src, trg = get_line_segment(i)
      # at starting (src) segment draw src arrow and get updated arrow connection point
      if i == 0 && @src_arrow
        asrc, atrg = get_first_subsegment(src, trg, get_used_connection_points(cp_src, cp_trg, 0))
        src = @src_arrow.draw(atrg, asrc, dc)
        cp_src = nil
      end
      # at end (tgt) segment draw tgt arrow and get updated connection point
      if i == n && @trg_arrow
        asrc, atrg = get_last_subsegment(src, trg, get_used_connection_points(cp_src, cp_trg, @lst_points.size))
        trg = @trg_arrow.draw(asrc, atrg, dc)
        cp_trg = nil
      end
      draw_line_segment(dc, src, trg, get_used_connection_points(cp_src, cp_trg, i))
    end

  when LINEMODE::UNDERCONSTRUCTION
    # draw basic line parts
    @lst_points.size.times do |i|
      src, trg = get_line_segment(i)
      draw_line_segment(dc, src, trg, get_used_connection_points(cp_src, cp_trg, i))
    end
  
    # draw unfinished line segment if any (for interactive line creation)
    dc.with_pen(Wx::Pen.new(Wx::BLACK, 1, Wx::PenStyle::PENSTYLE_DOT)) do
      if @lst_points.size>1
        draw_line_segment(dc, trg, @unfinished_point.to_real, get_used_connection_points(cp_src, cp_trg, @lst_points.size))
      else
        if @src_shape
          if @src_shape.get_connection_points.empty?
            draw_line_segment(dc,
                              @src_shape.get_border_point(@src_shape.get_center, @unfinished_point.to_real),
                              @unfinished_point.to_real,
                              get_used_connection_points(cp_src, cp_trg, 0))
          else
            draw_line_segment(dc,
                              get_mod_src_point,
                              @unfinished_point.to_real,
                              get_used_connection_points(cp_src, cp_trg, 0))
          end
        end
      end
    end

  when LINEMODE::SRCCHANGE
    # draw basic line parts
    @lst_points.size.times do |i|
      src, trg = get_line_segment(i+1)
      draw_line_segment(dc, src, trg, get_used_connection_points(cp_src, cp_trg, i+1))
    end
    # draw linesegment being updated
    src, trg = get_line_segment(0)
    dc.with_pen(Wx::Pen.new(Wx::BLACK, 1, Wx::PenStyle::PENSTYLE_DOT)) do
      draw_line_segment(dc,
                        @unfinished_point.to_real,
                        trg,
                        get_used_connection_points(cp_src, cp_trg, 0))
    end

  when LINEMODE::TRGCHANGE
    # draw basic line parts
    if !@lst_points.empty?
      @lst_points.size.times do |i|
        src, trg = get_line_segment(i)
        draw_line_segment(dc, src, trg, get_used_connection_points(cp_src, cp_trg, i))
      end
    else
      trg = get_src_point
    end
    # draw linesegment being updated
    dc.with_pen(Wx::Pen.new(Wx::BLACK, 1, Wx::PenStyle::PENSTYLE_DOT)) do
      draw_line_segment(dc,
                        trg,
                        @unfinished_point.to_real,
                        get_used_connection_points(cp_src, cp_trg, @lst_points.size))
    end

  end
end

#draw_line_segment(dc, src, trg, cps) ⇒ Object (protected)

Draw one orthogonal line segment.

Parameters:

  • dc (Wx::DC)

    Device context

  • src (Wx::RealPoint)

    Starting point of the ortho line segment

  • trg (Wx::RealPoint)

    Ending point of the ortho line segment

  • cps (SEGMENTCPS)

    Connection points used by the line segment



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 174

def draw_line_segment(dc, src, trg, cps)
  direction = 0.0
  src_pt = src.to_point
  trg_pt = trg.to_point

  if (trg.x == src.x) || (trg.y == src.y)
    dc.draw_line(src_pt, trg_pt)
    return
  else
    direction = get_segment_direction(src, trg, cps)
  end
  
  if is_two_segment(cps)
    if direction < 1.0
      dc.draw_line(src_pt.x, src_pt.y, trg_pt.x, src_pt.y)
      dc.draw_line(trg_pt.x, src_pt.y, trg_pt.x, trg_pt.y)
    else
      dc.draw_line(src_pt.x, src_pt.y, src_pt.x, trg_pt.y)
      dc.draw_line(src_pt.x, trg_pt.y, trg_pt.x, trg_pt.y)
    end
  else
    pt_center = Wx::Point.new(((src.x + trg.x)/2).to_i, ((src.y + trg.y)/2).to_i)
    if direction < 1.0
      dc.draw_line(src_pt.x, src_pt.y, pt_center.x, src_pt.y)
      dc.draw_line(pt_center.x, src_pt.y, pt_center.x, trg_pt.y)
      dc.draw_line(pt_center.x, trg_pt.y, trg_pt.x, trg_pt.y)
    else
      dc.draw_line(src_pt.x, src_pt.y, src_pt.x, pt_center.y)
      dc.draw_line(src_pt.x, pt_center.y, trg_pt.x, pt_center.y)
      dc.draw_line(trg_pt.x, pt_center.y, trg_pt.x, trg_pt.y)
    end
  end
end

#get_first_subsegment(src, trg, cps) ⇒ Array(Wx::RealPoint, Wx::RealPoint) (protected)

Returns starting and ending point of the first part of ortho line segment.

Returns:



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 213

def get_first_subsegment(src, trg, cps)
  direction = get_segment_direction(src, trg, cps)
  
  if is_two_segment(cps)
    if direction < 1.0
      subsrc = src
      subtrg = Wx::RealPoint.new(trg.x, src.y)
    else
      subsrc = src
      subtrg = Wx::RealPoint.new(src.x, trg.y)
    end
  else
    pt_center = Wx::RealPoint.new((src.x + trg.x)/2, (src.y + trg.y)/2)
    if direction < 1.0
      subsrc = src
      subtrg = Wx::RealPoint.new(pt_center.x, src.y)
    else
      subsrc = src
      subtrg = Wx::RealPoint.new(src.x, pt_center.y)
    end
  end
  [subsrc, subtrg]
end

#get_hit_linesegment(pos) ⇒ Object (protected)

Returns Zero-based index of line segment located under the given point.

Parameters:

Returns:

  • Zero-based index of line segment located under the given point



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 127

def get_hit_linesegment(pos)
  return -1 unless get_bounding_box.inflate!(5, 5).contains?(pos)

  cp_src = nil
  cp_trg = nil

  if @src_shape
    cp_src = @src_shape.get_nearest_connection_point(get_mod_src_point)
  end
  if @trg_shape
    cp_trg = @trg_shape.get_nearest_connection_point(get_mod_trg_point)
  end

  # Get all polyline segments
  line_segment_count.times do |i|
    pt_src, pt_trg = get_line_segment(i)

    # test first subsegment
    pt_s_src, pt_s_trg = get_first_subsegment( pt_src, pt_trg, get_used_connection_points(cp_src, cp_trg, i))
    rct_bb = Wx::Rect.new(pt_s_src.to_point, pt_s_trg.to_point)
    rct_bb.inflate!(5)

    return i if rct_bb.contains?(pos)

    # test middle subsegment
    pt_s_src, pt_s_trg = get_middle_subsegment(pt_src, pt_trg, get_used_connection_points(cp_src, cp_trg, i))
    rct_bb = Wx::Rect.new(pt_s_src.to_point, pt_s_trg.to_point)
    rct_bb.inflate!(5)

    return i if rct_bb.contains?(pos)

    # test last subsegment
    pt_s_src, pt_s_trg = get_last_subsegment( pt_src, pt_trg, get_used_connection_points(cp_src, cp_trg, i))
    rct_bb = Wx::Rect.new(pt_s_src.to_point, pt_s_trg.to_point)
    rct_bb.inflate!(5)

    return i if rct_bb.contains?(pos)
  end

  -1
end

#get_last_subsegment(src, trg, cps) ⇒ Array(Wx::RealPoint, Wx::RealPoint) (protected)

Returns starting and ending point of the third part of ortho line segment.

Parameters:

  • src (Wx::RealPoint)

    Starting point of the ortho line segment

  • trg (Wx::RealPoint)

    Ending point of the ortho line segment

  • cps (SEGMENTCPS)

    Connection points used by the line segment

Returns:



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 271

def get_last_subsegment(src, trg, cps)
  direction = get_segment_direction(src, trg, cps)

  if is_two_segment(cps)
    if direction < 1.0
      subsrc = Wx::RealPoint.new(trg.x, src.y)
    else
      subsrc = Wx::RealPoint.new(src.x, trg.y)
    end
  else
    pt_center = Wx::RealPoint.new((src.x + trg.x)/2, (src.y + trg.y)/2)
    if direction < 1.0
      subsrc = Wx::RealPoint.new(pt_center.x, trg.y)
    else
      subsrc = Wx::RealPoint.new(trg.x, pt_center.y)
    end
  end
  [subsrc, trg]
end

#get_middle_subsegment(src, trg, cps) ⇒ Array(Wx::RealPoint, Wx::RealPoint) (protected)

Returns starting and ending point of the second part of ortho line segment.

Parameters:

  • src (Wx::RealPoint)

    Starting point of the ortho line segment

  • trg (Wx::RealPoint)

    Ending point of the ortho line segment

  • cps (SEGMENTCPS)

    Connection points used by the line segment

Returns:



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 242

def get_middle_subsegment(src, trg, cps)
  direction = get_segment_direction(src, trg, cps)
  
  if is_two_segment(cps)
    if direction < 1.0
      subsrc = src
      subtrg = Wx::RealPoint.new(trg.x, src.y)
    else
      subsrc = src
      subtrg = Wx::RealPoint.new(src.x, trg.y)
    end
  else
    pt_center = Wx::RealPoint.new((src.x + trg.x)/2, (src.y + trg.y)/2)
    if direction < 1.0
      subsrc = Wx::RealPoint.new(pt_center.x, src.y)
      subtrg = Wx::RealPoint.new(pt_center.x, trg.y)
    else
      subsrc = Wx::RealPoint.new(src.x, pt_center.y)
      subtrg = Wx::RealPoint.new(trg.x, pt_center.y)
    end
  end
  [subsrc, subtrg]
end

#get_segment_direction(src, trg, cps) ⇒ Float (protected)

Returns Direction number.

Returns:

  • (Float)

    Direction number



296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 296

def get_segment_direction(src, trg, cps)
  direction = 0

  if trg.x == src.x
    direction = 1
  else
    direction =  (trg.y - src.y).abs / (trg.x - src.x).abs

    cp = nil
    if cps.src && !cps.trg
      cp = cps.src
    elsif !cps.src && cps.trg
      cp = cps.trg
    elsif cps.src && cps.trg
      cp = cps.src
    end

    if cp
      case cp.get_ortho_direction
      when ConnectionPoint::CPORTHODIR::VERTICAL
        direction = 1.0
      when ConnectionPoint::CPORTHODIR::HORIZONTAL
        direction = 0.0
      end
    end
  end

  direction
end

#get_used_connection_points(src, trg, i) ⇒ SEGMENTCPS (protected)

Determine which available connection points are used by given line segment.

Parameters:

Returns:

  • (SEGMENTCPS)

    Structure containing used connection points



331
332
333
334
335
336
337
338
339
340
341
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 331

def get_used_connection_points(src, trg, i)
  if @lst_points.empty?
    SEGMENTCPS.new(src, trg)
  elsif i == 0
    SEGMENTCPS.new(src, nil)
  elsif i == @lst_points.size
    SEGMENTCPS.new(nil, trg)
  else
    SEGMENTCPS.new(nil, nil)
  end
end

#is_two_segment(cps) ⇒ Boolean (protected)

Determine whether a line using give connection point should be drawn as two-segmented.

Parameters:

Returns:

  • (Boolean)

    true if the line should be just two-segmented



346
347
348
# File 'lib/wx/shapes/shapes/ortho_shape.rb', line 346

def is_two_segment(cps)
  cps.src && cps.trg && (cps.src.get_ortho_direction != cps.trg.get_ortho_direction)
end