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