Line data Source code
1 : /* File: pencil_relationship_1d_layouter.c; Copyright and License: see below */
2 :
3 : #include "pencil_relationship_1d_layouter.h"
4 : #include "u8/u8_trace.h"
5 : #include <pango/pangocairo.h>
6 : #include <stdio.h>
7 : #include <stdlib.h>
8 : #include <math.h>
9 : #include <stdint.h>
10 :
11 0 : void pencil_relationship_1d_layouter_init( pencil_relationship_1d_layouter_t *this_,
12 : layout_visible_set_t *layout_data,
13 : const data_profile_part_t *profile,
14 : const pencil_size_t *pencil_size )
15 : {
16 0 : U8_TRACE_BEGIN();
17 0 : assert( NULL != layout_data );
18 0 : assert( NULL != profile );
19 0 : assert( NULL != pencil_size );
20 :
21 0 : (*this_).layout_data = layout_data;
22 0 : (*this_).profile = profile;
23 0 : (*this_).pencil_size = pencil_size;
24 :
25 0 : pencil_relationship_painter_init( &((*this_).relationship_painter) );
26 :
27 0 : U8_TRACE_END();
28 0 : }
29 :
30 0 : void pencil_relationship_1d_layouter_destroy( pencil_relationship_1d_layouter_t *this_ )
31 : {
32 0 : U8_TRACE_BEGIN();
33 :
34 0 : pencil_relationship_painter_destroy( &((*this_).relationship_painter) );
35 :
36 0 : U8_TRACE_END();
37 0 : }
38 :
39 0 : void pencil_relationship_1d_layouter_private_make_all_visible ( pencil_relationship_1d_layouter_t *this_ )
40 : {
41 0 : U8_TRACE_BEGIN();
42 :
43 : /* determine visibility */
44 0 : const uint32_t count_relations = layout_visible_set_get_relationship_count ( (*this_).layout_data );
45 0 : for ( uint32_t index = 0; index < count_relations; index ++ )
46 : {
47 0 : layout_relationship_t *const the_relation = layout_visible_set_get_relationship_ptr ( (*this_).layout_data, index );
48 0 : const layout_visible_classifier_t *const from_layout = layout_relationship_get_from_classifier_ptr ( the_relation );
49 0 : const layout_visible_classifier_t *const to_layout = layout_relationship_get_to_classifier_ptr ( the_relation );
50 0 : assert( from_layout != NULL );
51 0 : assert( to_layout != NULL );
52 0 : const data_visible_classifier_t *const from_data = layout_visible_classifier_get_data_const( from_layout );
53 0 : const data_visible_classifier_t *const to_data = layout_visible_classifier_get_data_const( to_layout );
54 0 : const data_diagramelement_t *const from_diagele = data_visible_classifier_get_diagramelement_const( from_data );
55 0 : const data_diagramelement_t *const to_diagele = data_visible_classifier_get_diagramelement_const( to_data );
56 0 : const data_diagramelement_flag_t from_flags = data_diagramelement_get_display_flags ( from_diagele );
57 0 : const data_diagramelement_flag_t to_flags = data_diagramelement_get_display_flags ( to_diagele );
58 0 : if (( 0 != ( DATA_DIAGRAMELEMENT_FLAG_GRAY_OUT & from_flags ))
59 0 : || ( 0 != ( DATA_DIAGRAMELEMENT_FLAG_GRAY_OUT & to_flags )))
60 : {
61 0 : layout_relationship_set_visibility ( the_relation, PENCIL_VISIBILITY_GRAY_OUT );
62 : }
63 : else
64 : {
65 0 : layout_relationship_set_visibility ( the_relation, PENCIL_VISIBILITY_SHOW );
66 : }
67 : }
68 :
69 0 : U8_TRACE_END();
70 0 : }
71 :
72 0 : void pencil_relationship_1d_layouter_layout_for_sequence( pencil_relationship_1d_layouter_t *this_ )
73 : {
74 0 : U8_TRACE_BEGIN();
75 :
76 0 : pencil_relationship_1d_layouter_private_make_all_visible( this_ );
77 :
78 : /* get draw area */
79 : const layout_diagram_t *const diagram_layout
80 0 : = layout_visible_set_get_diagram_const( (*this_).layout_data );
81 : const geometry_rectangle_t *const diagram_draw_area
82 0 : = layout_diagram_get_draw_area_const( diagram_layout );
83 :
84 : /* layout the relationships */
85 : const uint32_t count_relations
86 0 : = layout_visible_set_get_relationship_count( (*this_).layout_data );
87 0 : U8_TRACE_INFO_INT( "count_relations:", count_relations );
88 0 : for ( uint32_t index = 0; index < count_relations; index ++ )
89 : {
90 : /* get the relationship to layout */
91 : layout_relationship_t *const the_relationship
92 0 : = layout_visible_set_get_relationship_ptr( (*this_).layout_data, index );
93 :
94 : /* adjust visibility */
95 0 : if ( ( NULL == layout_relationship_get_from_feature_ptr( the_relationship ) )
96 0 : && ( NULL == layout_relationship_get_to_feature_ptr( the_relationship ) ) )
97 : {
98 : /* this is a globally visible relation, not local/scenario-based */
99 0 : layout_visible_set_set_relationship_visibility( (*this_).layout_data, index, PENCIL_VISIBILITY_IMPLICIT );
100 : }
101 :
102 : /* calculate layout */
103 : {
104 : /* determine y-coordinate */
105 : const data_relationship_t *const the_relationdata
106 0 : = layout_relationship_get_data_const( the_relationship );
107 0 : int32_t list_order = data_relationship_get_list_order( the_relationdata );
108 0 : const double y_value_rel = (list_order/((double)UINT32_MAX))+0.5;
109 0 : const double draw_top = geometry_rectangle_get_top(diagram_draw_area);
110 0 : const double draw_bottom = geometry_rectangle_get_bottom(diagram_draw_area);
111 0 : const double y_value = ( (draw_bottom - draw_top) * y_value_rel ) + draw_top;
112 :
113 : /* get source and destination rectangles */
114 : const geometry_rectangle_t *const source_rect
115 0 : = layout_relationship_get_from_box_const ( the_relationship );
116 : const geometry_rectangle_t *const dest_rect
117 0 : = layout_relationship_get_to_box_const ( the_relationship );
118 :
119 : /* calculate coordinates */
120 0 : const double src_left = geometry_rectangle_get_left(source_rect);
121 0 : const double src_center_x = geometry_rectangle_get_center_x(source_rect);
122 0 : const double src_right = geometry_rectangle_get_right(source_rect);
123 0 : const double src_top = geometry_rectangle_get_top(source_rect);
124 : /*const double src_center_y = geometry_rectangle_get_center_y(source_rect);*/
125 0 : const double src_bottom = geometry_rectangle_get_bottom(source_rect);
126 :
127 0 : const double dst_left = geometry_rectangle_get_left(dest_rect);
128 0 : const double dst_center_x = geometry_rectangle_get_center_x(dest_rect);
129 0 : const double dst_right = geometry_rectangle_get_right(dest_rect);
130 0 : const double dst_top = geometry_rectangle_get_top(dest_rect);
131 : /*const double dst_center_y = geometry_rectangle_get_center_y(dest_rect);*/
132 0 : const double dst_bottom = geometry_rectangle_get_bottom(dest_rect);
133 :
134 : /* is interaction relation */
135 : /*
136 : const data_relationship_type_t rel_type
137 : = data_relationship_get_main_type( the_relationdata );
138 : const bool is_interaction
139 : = ( rel_type == DATA_RELATIONSHIP_TYPE_UML_ASYNC_CALL )
140 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_SYNC_CALL )
141 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_RETURN_CALL )
142 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_CONTROL_FLOW )
143 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_OBJECT_FLOW )
144 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_ASYNC_CALL );
145 : */
146 :
147 0 : const double src_from_y
148 0 : = ( y_value < src_top ) ? src_top : ( y_value > src_bottom ) ? src_bottom : y_value;
149 0 : const double dst_to_y
150 0 : = ( y_value < dst_top ) ? dst_top : ( y_value > dst_bottom ) ? dst_bottom : y_value;
151 0 : const double src_from_x
152 0 : = (( y_value < src_top )||( y_value > src_bottom ) /*|| is_interaction*/ )
153 : ? src_center_x /* activity bars are assumed to have depth 1 */
154 0 : : ( src_center_x < dst_center_x )
155 : ? src_right
156 0 : : src_left;
157 0 : const double dst_to_x
158 0 : = (( y_value < dst_top )||( y_value > dst_bottom ) /*|| is_interaction*/ )
159 : ? dst_center_x /* activity bars are assumed to have depth 1 */
160 0 : : ( src_center_x < dst_center_x )
161 : ? dst_left
162 0 : : dst_right;
163 :
164 : /* determine minimum arrow size for message/call to self */
165 0 : const double good_dist = pencil_size_get_preferred_object_distance( (*this_).pencil_size );
166 :
167 : /* define relation */
168 : geometry_connector_t relationship_shape;
169 0 : if ( fabs( src_center_x - dst_center_x ) < 0.0001 )
170 : {
171 : /* message/call to self */
172 0 : geometry_connector_init_vertical ( &relationship_shape,
173 : src_center_x,
174 0 : src_from_y - (good_dist/2.0),
175 : dst_center_x,
176 0 : dst_to_y + (good_dist/2.0),
177 : src_center_x + good_dist /* the main connector shall be right to the start/end points */
178 : );
179 : }
180 : else
181 : {
182 : /* normal message/call */
183 0 : geometry_connector_init_horizontal ( &relationship_shape,
184 : src_from_x,
185 : src_from_y,
186 : dst_to_x,
187 : dst_to_y,
188 : y_value
189 : );
190 : }
191 0 : layout_relationship_set_shape( the_relationship, &relationship_shape );
192 0 : geometry_connector_destroy( &relationship_shape );
193 :
194 : /* initialize also the label (to empty), this is updated later */
195 : {
196 : geometry_rectangle_t void_rect;
197 0 : geometry_rectangle_init_empty( &void_rect );
198 0 : layout_relationship_set_label_box( the_relationship, &void_rect );
199 0 : geometry_rectangle_destroy( &void_rect );
200 : }
201 : }
202 : }
203 :
204 0 : U8_TRACE_END();
205 0 : }
206 :
207 0 : void pencil_relationship_1d_layouter_layout_for_timing( pencil_relationship_1d_layouter_t *this_ )
208 : {
209 0 : U8_TRACE_BEGIN();
210 :
211 0 : pencil_relationship_1d_layouter_private_make_all_visible( this_ );
212 :
213 : /* get draw area */
214 : const layout_diagram_t *const diagram_layout
215 0 : = layout_visible_set_get_diagram_ptr( (*this_).layout_data );
216 : const geometry_rectangle_t *const diagram_draw_area
217 0 : = layout_diagram_get_draw_area_const( diagram_layout );
218 :
219 : /* layout the relationships */
220 : const uint32_t count_relations
221 0 : = layout_visible_set_get_relationship_count( (*this_).layout_data );
222 0 : U8_TRACE_INFO_INT( "count_relations:", count_relations );
223 0 : for ( uint32_t index = 0; index < count_relations; index ++ )
224 : {
225 : /* get the relationship to layout */
226 : layout_relationship_t *const the_relationship
227 0 : = layout_visible_set_get_relationship_ptr( (*this_).layout_data, index );
228 :
229 : /* adjust visibility */
230 0 : if ( ( NULL == layout_relationship_get_from_feature_ptr( the_relationship ) )
231 0 : && ( NULL == layout_relationship_get_to_feature_ptr( the_relationship ) ) )
232 : {
233 : /* this is a globally visible relation, not local/scenario-based */
234 0 : layout_visible_set_set_relationship_visibility( (*this_).layout_data, index, PENCIL_VISIBILITY_IMPLICIT );
235 : }
236 :
237 : /* calculate layout */
238 : {
239 : /* determine x-coordinate */
240 : const data_relationship_t *const the_relationdata
241 0 : = layout_relationship_get_data_const( the_relationship );
242 0 : const int32_t list_order = data_relationship_get_list_order ( the_relationdata );
243 0 : const double x_value_rel = (list_order/((double)UINT32_MAX))+0.5;
244 0 : const double draw_left = geometry_rectangle_get_left(diagram_draw_area);
245 0 : const double draw_right = geometry_rectangle_get_right(diagram_draw_area);
246 0 : const double x_value = ( (draw_right - draw_left) * x_value_rel ) + draw_left;
247 :
248 : /* get source and destination rectangles */
249 : const geometry_rectangle_t *const source_rect
250 0 : = layout_relationship_get_from_box_const( the_relationship );
251 : const geometry_rectangle_t *const dest_rect
252 0 : = layout_relationship_get_to_box_const( the_relationship );
253 :
254 : /* calculate coordinates */
255 0 : const double src_left = geometry_rectangle_get_left(source_rect);
256 : /*const double src_center_x = geometry_rectangle_get_center_x(source_rect);*/
257 0 : const double src_right = geometry_rectangle_get_right(source_rect);
258 0 : const double src_top = geometry_rectangle_get_top(source_rect);
259 0 : const double src_center_y = geometry_rectangle_get_center_y(source_rect);
260 0 : const double src_bottom = geometry_rectangle_get_bottom(source_rect);
261 :
262 0 : const double dst_left = geometry_rectangle_get_left(dest_rect);
263 : /*const double dst_center_x = geometry_rectangle_get_center_x(dest_rect);*/
264 0 : const double dst_right = geometry_rectangle_get_right(dest_rect);
265 0 : const double dst_top = geometry_rectangle_get_top(dest_rect);
266 0 : const double dst_center_y = geometry_rectangle_get_center_y(dest_rect);
267 0 : const double dst_bottom = geometry_rectangle_get_bottom(dest_rect);
268 :
269 : /* is interaction relation */
270 : const data_relationship_type_t rel_type
271 0 : = data_relationship_get_main_type( the_relationdata );
272 0 : const bool is_interaction
273 : = ( rel_type == DATA_RELATIONSHIP_TYPE_UML_ASYNC_CALL )
274 0 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_SYNC_CALL )
275 0 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_RETURN_CALL )
276 0 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_CONTROL_FLOW )
277 0 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_OBJECT_FLOW )
278 0 : || ( rel_type == DATA_RELATIONSHIP_TYPE_UML_ASYNC_CALL );
279 :
280 0 : const double src_from_x
281 0 : = ( x_value < src_left ) ? src_left : ( x_value > src_right ) ? src_right : x_value;
282 0 : const double dst_to_x
283 0 : = ( x_value < dst_left ) ? dst_left : ( x_value > dst_right ) ? dst_right : x_value;
284 0 : const double src_from_y
285 0 : = (( x_value < src_left )||( x_value > src_right )|| is_interaction )
286 : ? src_center_y
287 0 : : ( src_center_y < dst_center_y )
288 : ? src_bottom
289 0 : : src_top;
290 0 : const double dst_to_y
291 0 : = (( x_value < dst_left )||( x_value > dst_right )|| is_interaction )
292 : ? dst_center_y
293 0 : : ( src_center_y < dst_center_y )
294 : ? dst_top
295 0 : : dst_bottom;
296 :
297 : /* determine minimum arrow size for self transition */
298 0 : const double good_dist = pencil_size_get_preferred_object_distance( (*this_).pencil_size );
299 :
300 : /* define relation */
301 : geometry_connector_t relationship_shape;
302 0 : if ( fabs( src_center_y - dst_center_y ) < 0.0001 )
303 : {
304 : /* transition to self */
305 0 : geometry_connector_init_horizontal ( &relationship_shape,
306 0 : src_from_x - (good_dist/2.0),
307 : src_center_y,
308 0 : dst_to_x + (good_dist/2.0),
309 : dst_center_y,
310 : src_center_y - good_dist /* the main connector shall be above the start/end points */
311 : );
312 : }
313 : else
314 : {
315 : /* normal transition */
316 0 : geometry_connector_init_vertical ( &relationship_shape,
317 : src_from_x,
318 : src_from_y,
319 : dst_to_x,
320 : dst_to_y,
321 : x_value
322 : );
323 : }
324 0 : layout_relationship_set_shape( the_relationship, &relationship_shape );
325 0 : geometry_connector_destroy( &relationship_shape );
326 :
327 : /* initialize also the label (to empty), this is updated later */
328 : {
329 : geometry_rectangle_t void_rect;
330 0 : geometry_rectangle_init_empty( &void_rect );
331 0 : layout_relationship_set_label_box( the_relationship, &void_rect );
332 0 : geometry_rectangle_destroy( &void_rect );
333 : }
334 : }
335 : }
336 :
337 0 : U8_TRACE_END();
338 0 : }
339 :
340 :
341 : /*
342 : Copyright 2017-2026 Andreas Warnke
343 :
344 : Licensed under the Apache License, Version 2.0 (the "License");
345 : you may not use this file except in compliance with the License.
346 : You may obtain a copy of the License at
347 :
348 : http://www.apache.org/licenses/LICENSE-2.0
349 :
350 : Unless required by applicable law or agreed to in writing, software
351 : distributed under the License is distributed on an "AS IS" BASIS,
352 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
353 : See the License for the specific language governing permissions and
354 : limitations under the License.
355 : */
|