@@ -80,57 +80,16 @@ def to_s
8080 # @rbs return: Choice
8181 def format ( x , y , width )
8282 left_gap , right_gap = determine_gaps ( width , @width )
83-
84- # Hook up the two sides if self is narrower than its stated width.
8583 Path . new ( x , y ) . h ( left_gap ) . add ( self )
8684 Path . new ( x + left_gap + @width , y + @height ) . h ( right_gap ) . add ( self )
8785 x += left_gap
8886
8987 inner_width = @width - ( AR * 4 )
9088 default = @items [ @default ]
9189
92- # Do the elements that curve above
93- distance_from_y = 0
94- ( @default - 1 ) . downto ( 0 ) do |i |
95- item = @items [ i ]
96- lower_item = @items [ i + 1 ]
97- distance_from_y += lower_item . up + @separators [ i ] + item . down + item . height
98- Path . new ( x , y )
99- . arc ( 'se' )
100- . up ( distance_from_y - ( AR * 2 ) )
101- . arc ( 'wn' )
102- . add ( self )
103- item . format ( x + ( AR * 2 ) , y - distance_from_y , inner_width ) . add ( self )
104- Path . new ( x + ( AR * 2 ) + inner_width , y - distance_from_y + item . height )
105- . arc ( 'ne' )
106- . down ( distance_from_y - item . height + default . height - ( AR * 2 ) )
107- . arc ( 'ws' )
108- . add ( self )
109- end
110-
111- # Do the straight-line path.
112- Path . new ( x , y ) . right ( AR * 2 ) . add ( self )
113- @items [ @default ] . format ( x + ( AR * 2 ) , y , inner_width ) . add ( self )
114- Path . new ( x + ( AR * 2 ) + inner_width , y + @height ) . right ( AR * 2 ) . add ( self )
115-
116- # Do the elements that curve below
117- distance_from_y = 0
118- ( @default + 1 ...@items . size ) . each do |i |
119- item = @items [ i ]
120- upper_item = @items [ i - 1 ]
121- distance_from_y += upper_item . height + upper_item . down + @separators [ i - 1 ] + item . up
122- Path . new ( x , y )
123- . arc ( 'ne' )
124- . down ( distance_from_y - ( AR * 2 ) )
125- . arc ( 'ws' )
126- . add ( self )
127- item . format ( x + ( AR * 2 ) , y + distance_from_y , inner_width ) . add ( self )
128- Path . new ( x + ( AR * 2 ) + inner_width , y + distance_from_y + item . height )
129- . arc ( 'se' )
130- . up ( distance_from_y - ( AR * 2 ) + item . height - default . height )
131- . arc ( 'wn' )
132- . add ( self )
133- end
90+ format_items_above_default ( x , y , inner_width , default )
91+ format_default_item ( x , y , inner_width )
92+ format_items_below_default ( x , y , inner_width , default )
13493
13594 self
13695 end
@@ -144,11 +103,9 @@ def text_diagram
144103 ]
145104 )
146105
147- # Format all the child items, so we can know the maximum width.
148106 item_tds = @items . map { |item | item . text_diagram . expand ( 1 , 1 , 0 , 0 ) }
149107 max_item_width = item_tds . map ( &:width ) . max
150108 diagram_td = TextDiagram . new ( 0 , 0 , [ ] )
151- # Format the choice collection.
152109 item_tds . each_with_index do |item_td , i |
153110 left_pad , right_pad = TextDiagram . gaps ( max_item_width , item_td . width )
154111 item_td = item_td . expand ( left_pad , right_pad , 0 , 0 )
@@ -158,46 +115,37 @@ def text_diagram
158115 move_entry = false
159116 move_exit = false
160117 if i <= @default
161- # Item below the line: round off the entry/exit lines downwards.
162118 left_lines [ item_td . entry ] = roundcorner_top_left
163119 right_lines [ item_td . exit ] = roundcorner_top_right
164120 if i . zero?
165- # First item and above the line: also remove ascenders above the item's entry and exit, suppress the separator above it.
166121 has_separator = false
167122 ( 0 ...item_td . entry ) . each { |j | left_lines [ j ] = ' ' }
168123 ( 0 ...item_td . exit ) . each { |j | right_lines [ j ] = ' ' }
169124 end
170125 end
171126 if i >= @default
172- # Item below the line: round off the entry/exit lines downwards.
173127 left_lines [ item_td . entry ] = roundcorner_bot_left
174128 right_lines [ item_td . exit ] = roundcorner_bot_right
175129 if i . zero?
176- # First item and below the line: also suppress the separator above it.
177130 has_separator = false
178131 end
179132 if i == @items . size - 1
180- # Last item and below the line: also remove descenders below the item's entry and exit
181133 ( item_td . entry + 1 ...item_td . height ) . each { |j | left_lines [ j ] = ' ' }
182134 ( item_td . exit + 1 ...item_td . height ) . each { |j | right_lines [ j ] = ' ' }
183135 end
184136 end
185137 if i == @default
186- # Item on the line: entry/exit are horizontal, and sets the outer entry/exit.
187138 left_lines [ item_td . entry ] = cross
188139 right_lines [ item_td . exit ] = cross
189140 move_entry = true
190141 move_exit = true
191142 if i . zero? && i == @items . size - 1
192- # Only item and on the line: set entry/exit for straight through.
193143 left_lines [ item_td . entry ] = line
194144 right_lines [ item_td . exit ] = line
195145 elsif i . zero?
196- # First item and on the line: set entry/exit for no ascenders.
197146 left_lines [ item_td . entry ] = roundcorner_top_right
198147 right_lines [ item_td . exit ] = roundcorner_top_left
199148 elsif i == @items . size - 1
200- # Last item and on the line: set entry/exit for no descenders.
201149 left_lines [ item_td . entry ] = roundcorner_bot_right
202150 right_lines [ item_td . exit ] = roundcorner_bot_left
203151 end
@@ -218,5 +166,105 @@ def text_diagram
218166 end
219167 diagram_td
220168 end
169+
170+ private
171+
172+ # @rbs x: Numeric
173+ # @rbs y: Numeric
174+ # @rbs inner_width: Numeric
175+ # @rbs default: DiagramItem
176+ # @rbs return: void
177+ def format_items_above_default ( x , y , inner_width , default )
178+ distance_from_y = 0
179+ ( @default - 1 ) . downto ( 0 ) do |i |
180+ item = @items [ i ]
181+ lower_item = @items [ i + 1 ]
182+ distance_from_y += lower_item . up + @separators [ i ] + item . down + item . height
183+
184+ add_upward_path ( x , y , distance_from_y )
185+ item . format ( x + ( AR * 2 ) , y - distance_from_y , inner_width ) . add ( self )
186+ add_downward_return_path ( x + ( AR * 2 ) + inner_width , y , distance_from_y , item , default )
187+ end
188+ end
189+
190+ # @rbs x: Numeric
191+ # @rbs y: Numeric
192+ # @rbs inner_width: Numeric
193+ # @rbs return: void
194+ def format_default_item ( x , y , inner_width )
195+ Path . new ( x , y ) . right ( AR * 2 ) . add ( self )
196+ @items [ @default ] . format ( x + ( AR * 2 ) , y , inner_width ) . add ( self )
197+ Path . new ( x + ( AR * 2 ) + inner_width , y + @height ) . right ( AR * 2 ) . add ( self )
198+ end
199+
200+ # @rbs x: Numeric
201+ # @rbs y: Numeric
202+ # @rbs inner_width: Numeric
203+ # @rbs default: DiagramItem
204+ # @rbs return: void
205+ def format_items_below_default ( x , y , inner_width , default )
206+ distance_from_y = 0
207+ ( @default + 1 ...@items . size ) . each do |i |
208+ item = @items [ i ]
209+ upper_item = @items [ i - 1 ]
210+ distance_from_y += upper_item . height + upper_item . down + @separators [ i - 1 ] + item . up
211+
212+ add_downward_path ( x , y , distance_from_y )
213+ item . format ( x + ( AR * 2 ) , y + distance_from_y , inner_width ) . add ( self )
214+ add_upward_return_path ( x + ( AR * 2 ) + inner_width , y , distance_from_y , item , default )
215+ end
216+ end
217+
218+ # @rbs x: Numeric
219+ # @rbs y: Numeric
220+ # @rbs distance: Numeric
221+ # @rbs return: void
222+ def add_upward_path ( x , y , distance )
223+ Path . new ( x , y )
224+ . arc ( 'se' )
225+ . up ( distance - ( AR * 2 ) )
226+ . arc ( 'wn' )
227+ . add ( self )
228+ end
229+
230+ # @rbs x: Numeric
231+ # @rbs y: Numeric
232+ # @rbs distance: Numeric
233+ # @rbs item: DiagramItem
234+ # @rbs default: DiagramItem
235+ # @rbs return: void
236+ def add_downward_return_path ( x , y , distance , item , default )
237+ Path . new ( x , y - distance + item . height )
238+ . arc ( 'ne' )
239+ . down ( distance - item . height + default . height - ( AR * 2 ) )
240+ . arc ( 'ws' )
241+ . add ( self )
242+ end
243+
244+ # @rbs x: Numeric
245+ # @rbs y: Numeric
246+ # @rbs distance: Numeric
247+ # @rbs return: void
248+ def add_downward_path ( x , y , distance )
249+ Path . new ( x , y )
250+ . arc ( 'ne' )
251+ . down ( distance - ( AR * 2 ) )
252+ . arc ( 'ws' )
253+ . add ( self )
254+ end
255+
256+ # @rbs x: Numeric
257+ # @rbs y: Numeric
258+ # @rbs distance: Numeric
259+ # @rbs item: DiagramItem
260+ # @rbs default: DiagramItem
261+ # @rbs return: void
262+ def add_upward_return_path ( x , y , distance , item , default )
263+ Path . new ( x , y + distance + item . height )
264+ . arc ( 'se' )
265+ . up ( distance - ( AR * 2 ) + item . height - default . height )
266+ . arc ( 'wn' )
267+ . add ( self )
268+ end
221269 end
222270end
0 commit comments