ea 0.6.43 → 0.6.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00712a8a81ec1a2db75cb8d603ecea20b4f5499b59c4b32b269f5ae6630a8fc8
4
- data.tar.gz: 98957abd4b964ca2c27bc2f5637497ed08762f163fe042ee6091a4228a3c52ac
3
+ metadata.gz: 70775a4db6ad6a0d240e3eb3de0e60aa31db24561ad167898a9613df3f431810
4
+ data.tar.gz: b15a7d2bcce540619ed08e2fb32d6fe427850a6381e6db15dd72a25b6bc6739f
5
5
  SHA512:
6
- metadata.gz: 4224e7c3dac17d7d6174aed6cbca23530a91d28fc6270bca00c8a09a682e611bba397294ae9ba3e33081f627f38b18c5ea6820448ab0d317fdca512b83ec1ff5
7
- data.tar.gz: 5b377f89f6c20bdf4dfcc56fe02e503320404f6cfacfe9483ba4c7efd4bda8631ea64b30acb3d04f3f909590108e393a49263956eb0c3d8572caa984b42251fc
6
+ metadata.gz: 1d3e2a0d75fc280ab1eea83db6376dd9d6e045569ca99ef5ba5fa7bbc7a39d8c3b5eff7af59fa12bd7ad5b63f2518b16dbc20694b605c80574c5415617635036
7
+ data.tar.gz: 49baf9df9e8d0327b9d81bc5549edbf3a8d71e4401adbbe5cf895a17bcae8e283daf178e4e87ef5a509b9d7e0a94a2630899e22adebddebcdd9a40f5c1e2042a
@@ -39,6 +39,46 @@ module Ea
39
39
  edge_point(target_bounds, source_bounds)]
40
40
  end
41
41
 
42
+ # EA never docks a horizontal connector line at the header
43
+ # divider: endpoints landing on (box side edge, divider_y)
44
+ # move down one row slot to divider_y + 13 - the first
45
+ # attribute-row slot (E0C65C12/TK_PositionType: EA docks at
46
+ # (451,90) where the stored route says (451,77) = our
47
+ # divider; the (0,-13) endpoint-delta family, 57 lines).
48
+ ROW_SLOT_PITCH = 13
49
+
50
+ def row_slot_adjust(pairs, connector, diagram, model_index,
51
+ bounds_map, divider_y_by_ref)
52
+ return nil unless bounds_map && divider_y_by_ref
53
+ return nil unless pairs.size == 2
54
+
55
+ rel = relationship_for(connector, model_index)
56
+ return nil unless rel
57
+
58
+ source_ref, target_ref = end_refs(rel)
59
+ return nil unless source_ref && target_ref
60
+
61
+ bounds = [bounds_map[source_ref], bounds_map[target_ref]]
62
+ dividers = [divider_y_by_ref[source_ref],
63
+ divider_y_by_ref[target_ref]]
64
+ return nil unless bounds.all? && dividers.all?
65
+
66
+ changed = false
67
+ adjusted = pairs.each_with_index.map do |(x, y), i|
68
+ box = bounds[i]
69
+ divider = dividers[i]
70
+ at_edge = (x - box.x).abs <= 1 || (x - (box.x + box.width)).abs <= 1
71
+ at_divider = (y - divider.to_f).abs <= 1
72
+ if at_edge && at_divider
73
+ changed = true
74
+ [x, y + ROW_SLOT_PITCH]
75
+ else
76
+ [x, y]
77
+ end
78
+ end
79
+ changed ? adjusted : nil
80
+ end
81
+
42
82
  def direct?(connector)
43
83
  style = connector.style || {}
44
84
  %i[direct regenerated].any? { |k| style.key?(k) } ||
@@ -17,16 +17,18 @@ module Ea
17
17
  LINE_STYLE_KEY = :connector_line
18
18
 
19
19
  attr_reader :diagram, :canvas, :grouped, :stroke_width, :drawn_bounds,
20
- :model_index
20
+ :model_index, :divider_y_by_ref
21
21
 
22
22
  def initialize(diagram, canvas: nil, grouped: true, stroke_width: 2,
23
- drawn_bounds: nil, model_index: nil)
23
+ drawn_bounds: nil, model_index: nil,
24
+ divider_y_by_ref: nil)
24
25
  @diagram = diagram
25
26
  @canvas = canvas
26
27
  @grouped = grouped
27
28
  @stroke_width = stroke_width
28
29
  @drawn_bounds = drawn_bounds
29
30
  @model_index = model_index
31
+ @divider_y_by_ref = divider_y_by_ref
30
32
  end
31
33
 
32
34
  def layers
@@ -62,6 +64,9 @@ module Ea
62
64
  pts = ConnectorRedock.pairs_for(connector, diagram, model_index,
63
65
  drawn_bounds) ||
64
66
  waypoints_for(connector)
67
+ pts = ConnectorRedock.row_slot_adjust(pts, connector, diagram,
68
+ model_index, drawn_bounds,
69
+ divider_y_by_ref) || pts
65
70
  return nil if pts.size < 2
66
71
 
67
72
  # DIRECT (auto-routed straight) connectors: EA writes the
@@ -61,35 +61,31 @@ module Ea
61
61
  # Y of the divider line between header and the rest.
62
62
  # Returns nil when there's no header content to separate
63
63
  # from empty below-header content.
64
+ # {root}/{leaf} marker lines sit INSIDE the header region:
65
+ # each pushes the divider down one row slot (E0C65C12/
66
+ # TK_PositionType: name at 69, EA divider at 90 = our old
67
+ # 77 + 13, attrs follow at 104 on both sides).
64
68
  def divider_y
65
69
  return nil if header_lines_count.zero?
66
70
 
67
71
  header_first_y +
68
72
  ([header_lines_count, 1].max - 1) * (size + (header_line_offset || 6)) +
73
+ (marker_count.to_i * (size + 6)) +
69
74
  (divider_offset || 8)
70
75
  end
71
76
 
72
77
  def attr_first_y
73
- base = raw_attr_first_y
74
- return base unless marker_count.to_i.positive?
75
-
76
- # EA renders the {root}/{leaf} marker compartment BETWEEN
77
- # the header divider and the attributes: its rows occupy
78
- # (attr_base - 9) onward at the 13px pitch, and attributes
79
- # shift down one row per marker line. Real OCL constraints
80
- # do NOT shift attributes — they render trailing.
81
- # Corpus-verified (TK_PositionType: name +13 {root} +22
82
- # first-attr; MD_Identification keeps attrs at +22 despite
83
- # carrying OCL constraints).
84
- base + (size + 6) * marker_count
78
+ raw_attr_first_y
85
79
  end
86
80
 
87
- # First marker-line baseline: one row slot above where
88
- # attributes would start without markers.
81
+ # First marker-line baseline: its own row between the name
82
+ # and the divider it pushes down (E0C65C12: name 69, {root}
83
+ # 82, divider 90 = {root} + 8).
89
84
  def marker_first_y
90
85
  return nil unless marker_count.to_i.positive?
86
+ return nil unless divider_y
91
87
 
92
- raw_attr_first_y - 9
88
+ divider_y - 8
93
89
  end
94
90
 
95
91
  def raw_attr_first_y
@@ -32,6 +32,7 @@ module Ea
32
32
  # divider, attrs) in EA's per-entity layer order.
33
33
  def groups
34
34
  @drawn_bounds = {}
35
+ @divider_y = {}
35
36
  ordered_elements.flat_map { |e| groups_for(e) }
36
37
  end
37
38
 
@@ -42,6 +43,11 @@ module Ea
42
43
  # drawn outlines, never the stored rect.
43
44
  attr_reader :drawn_bounds
44
45
 
46
+ # Logical-space header divider y per model element ref, for
47
+ # connector row-slot docking (EA docks horizontal exits at
48
+ # divider_y + 13, the first attribute-row slot).
49
+ attr_reader :divider_y
50
+
45
51
  private
46
52
 
47
53
  def ordered_elements
@@ -91,6 +97,9 @@ module Ea
91
97
  width: width,
92
98
  height: context.bounds.height
93
99
  )
100
+ return unless context.geometry
101
+
102
+ @divider_y[element.model_element_ref] = context.geometry.divider_y
94
103
  end
95
104
 
96
105
 
@@ -62,11 +62,11 @@ module Ea
62
62
  text_pos, mult_pos)
63
63
  elsif mult_box && stored_offsets_zero?(mult_box)
64
64
  # A stored mult box with OX=0:OY=0 means "EA default":
65
- # the multiplicity sits 15px BELOW the endpoint anchor,
66
- # regardless of line direction (87-sample corpus fit:
67
- # dy = +15 constant; the dx residual follows the
68
- # dock-slot family).
69
- mult_pos = [anchor[0], anchor[1] + 15]
65
+ # the multiplicity sits 12px right of and 15px below the
66
+ # endpoint anchor, regardless of line direction
67
+ # (87-sample corpus fit: dy = +15 constant, dx = +12
68
+ # dominant with a +3 minority).
69
+ mult_pos = [anchor[0] + 12, anchor[1] + 15]
70
70
  end
71
71
  show_property = property_label?(connector, end_kind)
72
72
 
@@ -49,6 +49,10 @@ module Ea
49
49
  @elements&.drawn_bounds
50
50
  end
51
51
 
52
+ def divider_y_by_ref
53
+ @elements&.divider_y
54
+ end
55
+
52
56
  private
53
57
 
54
58
  def frame_layers
@@ -67,11 +71,13 @@ module Ea
67
71
  grouped: true,
68
72
  stroke_width: DEFAULT_STROKE_WIDTH,
69
73
  drawn_bounds: drawn_bounds,
74
+ divider_y_by_ref: divider_y_by_ref,
70
75
  model_index: model_index).layers
71
76
  marker_layers_raw = Markers.new(diagram, model_index: model_index,
72
77
  canvas: canvas, grouped: true,
73
78
  stroke_width: DEFAULT_STROKE_WIDTH,
74
- drawn_bounds: drawn_bounds).layers
79
+ drawn_bounds: drawn_bounds,
80
+ divider_y_by_ref: divider_y_by_ref).layers
75
81
  merge_layers_by_style(connector_layers_raw + marker_layers_raw).map(&:to_svg)
76
82
  end
77
83
 
@@ -32,16 +32,18 @@ module Ea
32
32
  DEP_ARROW_HEIGHT = 15
33
33
 
34
34
  attr_reader :diagram, :model_index, :canvas, :grouped, :stroke_width,
35
- :drawn_bounds
35
+ :drawn_bounds, :divider_y_by_ref
36
36
 
37
37
  def initialize(diagram, model_index:, canvas: nil, grouped: true,
38
- stroke_width: 2, drawn_bounds: nil)
38
+ stroke_width: 2, drawn_bounds: nil,
39
+ divider_y_by_ref: nil)
39
40
  @diagram = diagram
40
41
  @model_index = model_index
41
42
  @canvas = canvas
42
43
  @grouped = grouped
43
44
  @stroke_width = stroke_width
44
45
  @drawn_bounds = drawn_bounds
46
+ @divider_y_by_ref = divider_y_by_ref
45
47
  end
46
48
 
47
49
  def layers
@@ -459,7 +461,12 @@ module Ea
459
461
  def waypoint_pairs(connector)
460
462
  redocked = ConnectorRedock.pairs_for(connector, diagram,
461
463
  model_index, drawn_bounds)
462
- return redocked if redocked
464
+ if redocked
465
+ return ConnectorRedock.row_slot_adjust(redocked, connector,
466
+ diagram, model_index,
467
+ drawn_bounds,
468
+ divider_y_by_ref) || redocked
469
+ end
463
470
 
464
471
  (connector.waypoints || []).filter_map do |w|
465
472
  next unless w.position
data/lib/ea/version.rb CHANGED
@@ -4,5 +4,5 @@ module Ea
4
4
  # Gem release version. Extracted to its own file so the
5
5
  # `gem-release` tool's `gem bump` can find and update it via the
6
6
  # standard `lib/<gem>/version.rb` convention.
7
- VERSION = "0.6.43"
7
+ VERSION = "0.6.45"
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ea
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.43
4
+ version: 0.6.45
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.