Line data Source code
1 : /* File: pencil_diagram_maker.c; Copyright and License: see below */
2 :
3 : #include "pencil_diagram_maker.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 :
10 0 : void pencil_diagram_maker_draw ( pencil_diagram_maker_t *this_,
11 : data_id_t mark_focused,
12 : data_id_t mark_highlighted,
13 : const data_small_set_t *mark_selected,
14 : cairo_t *cr )
15 : {
16 0 : U8_TRACE_BEGIN();
17 0 : assert( NULL != mark_selected );
18 0 : assert( NULL != cr );
19 :
20 : PangoLayout *layout;
21 0 : layout = pango_cairo_create_layout (cr);
22 :
23 : /* get layout data object */
24 0 : const layout_visible_set_t *const layout_data = pencil_layouter_get_layout_data_const ( &((*this_).layouter) );
25 :
26 : /* get diagram bounds */
27 0 : const layout_diagram_t *const diagram_layout = layout_visible_set_get_diagram_const( layout_data );
28 0 : const geometry_rectangle_t *const diagram_bounds = layout_diagram_get_bounds_const ( diagram_layout );
29 0 : double width = geometry_rectangle_get_width ( diagram_bounds );
30 0 : double height = geometry_rectangle_get_height ( diagram_bounds );
31 :
32 0 : const pencil_size_t *const pencil_size = pencil_layouter_get_pencil_size_const( &((*this_).layouter) );
33 :
34 : /* draw diagram */
35 0 : const data_diagram_t *diag = data_visible_set_get_diagram_const( (*this_).input_data );
36 0 : pencil_diagram_painter_draw ( &((*this_).diagram_painter),
37 : diagram_layout,
38 : data_id_equals_id( &mark_focused, DATA_TABLE_DIAGRAM, data_diagram_get_row_id(diag) ),
39 : data_id_equals_id( &mark_highlighted, DATA_TABLE_DIAGRAM, data_diagram_get_row_id(diag) ),
40 : data_small_set_contains_row_id( mark_selected, DATA_TABLE_DIAGRAM, data_diagram_get_row_id(diag) ),
41 : (*this_).profile,
42 : pencil_size,
43 : layout,
44 : cr
45 : );
46 :
47 0 : if (( width > 20.0 ) && ( height > 20.0 ))
48 : {
49 : /* draw all contained classifiers */
50 0 : pencil_diagram_maker_private_draw_classifiers ( this_,
51 : mark_focused,
52 : mark_highlighted,
53 : mark_selected,
54 : layout,
55 : cr
56 : );
57 :
58 : /* draw all contained features */
59 0 : pencil_diagram_maker_private_draw_features ( this_,
60 : mark_focused,
61 : mark_highlighted,
62 : mark_selected,
63 : layout,
64 : cr
65 : );
66 :
67 : /* draw all contained relationships */
68 0 : pencil_diagram_maker_private_draw_relationships ( this_,
69 : mark_focused,
70 : mark_highlighted,
71 : mark_selected,
72 : layout,
73 : cr
74 : );
75 : }
76 :
77 0 : g_object_unref (layout);
78 :
79 0 : U8_TRACE_END();
80 0 : }
81 :
82 0 : void pencil_diagram_maker_private_draw_classifiers ( pencil_diagram_maker_t *this_,
83 : data_id_t mark_focused,
84 : data_id_t mark_highlighted,
85 : const data_small_set_t *mark_selected,
86 : PangoLayout *layout,
87 : cairo_t *cr )
88 : {
89 0 : U8_TRACE_BEGIN();
90 0 : assert( NULL != mark_selected );
91 0 : assert( NULL != cr );
92 :
93 0 : const layout_visible_set_t *const layout_data = pencil_layouter_get_layout_data_const ( &((*this_).layouter) );
94 :
95 : /* iterate over all classifiers */
96 0 : const uint32_t count = layout_visible_set_get_visible_classifier_count ( layout_data );
97 0 : for ( uint32_t index = 0; index < count; index ++ )
98 : {
99 0 : const layout_visible_classifier_t *const classifier_layout = layout_visible_set_get_visible_classifier_const( layout_data, index );
100 :
101 0 : const pencil_size_t *const pencil_size = pencil_layouter_get_pencil_size_const( &((*this_).layouter) );
102 :
103 0 : pencil_classifier_composer_draw( &((*this_).classifier_painter),
104 : classifier_layout,
105 : mark_focused,
106 : mark_highlighted,
107 : mark_selected,
108 : layout_data,
109 : (*this_).profile,
110 : pencil_size,
111 : layout,
112 : cr
113 : );
114 : }
115 :
116 0 : U8_TRACE_END();
117 0 : }
118 :
119 0 : void pencil_diagram_maker_private_draw_features ( pencil_diagram_maker_t *this_,
120 : data_id_t mark_focused,
121 : data_id_t mark_highlighted,
122 : const data_small_set_t *mark_selected,
123 : PangoLayout *layout,
124 : cairo_t *cr )
125 : {
126 0 : U8_TRACE_BEGIN();
127 0 : assert( NULL != mark_selected );
128 0 : assert( NULL != cr );
129 :
130 0 : const layout_visible_set_t *const layout_data = pencil_layouter_get_layout_data_const ( &((*this_).layouter) );
131 :
132 : /* iterate over all features */
133 0 : const uint32_t count = layout_visible_set_get_feature_count ( layout_data );
134 0 : for ( uint32_t f_idx = 0; f_idx < count; f_idx ++ )
135 : {
136 : /* get feature */
137 0 : const layout_feature_t *const the_feature = layout_visible_set_get_feature_const( layout_data, f_idx );
138 :
139 : /* determine display flags of diagramelement */
140 0 : const layout_visible_classifier_t *const classifier_layout = layout_feature_get_classifier_const ( the_feature );
141 0 : const data_diagramelement_t *const diagramelement = layout_visible_classifier_get_diagramelement_const( classifier_layout );
142 0 : const data_diagramelement_flag_t display_flags = data_diagramelement_get_display_flags( diagramelement );
143 :
144 : /* draw features */
145 0 : pencil_feature_painter_draw ( &((*this_).feature_painter),
146 : the_feature,
147 : data_id_equals_id( &mark_focused, DATA_TABLE_FEATURE, layout_feature_get_feature_id(the_feature) ),
148 : data_id_equals_id( &mark_highlighted, DATA_TABLE_FEATURE, layout_feature_get_feature_id( the_feature ) ),
149 : data_small_set_contains_row_id( mark_selected, DATA_TABLE_FEATURE, layout_feature_get_feature_id(the_feature) ),
150 0 : (0 != ( display_flags & DATA_DIAGRAMELEMENT_FLAG_GRAY_OUT )),
151 : (*this_).profile,
152 : pencil_layouter_get_pencil_size_const( &((*this_).layouter) ),
153 : layout,
154 : cr
155 : );
156 : }
157 :
158 0 : U8_TRACE_END();
159 0 : }
160 :
161 0 : void pencil_diagram_maker_private_draw_relationships ( pencil_diagram_maker_t *this_,
162 : data_id_t mark_focused,
163 : data_id_t mark_highlighted,
164 : const data_small_set_t *mark_selected,
165 : PangoLayout *layout,
166 : cairo_t *cr )
167 : {
168 0 : U8_TRACE_BEGIN();
169 0 : assert( NULL != mark_selected );
170 0 : assert( NULL != cr );
171 :
172 0 : const layout_visible_set_t *const layout_data = pencil_layouter_get_layout_data_const ( &((*this_).layouter) );
173 :
174 0 : const uint32_t rel_count = layout_visible_set_get_relationship_count ( layout_data );
175 0 : for ( uint32_t index = 0; index < rel_count; index ++ )
176 : {
177 : pencil_visibility_t show_relation;
178 0 : const layout_relationship_t *const relationship_layout = layout_visible_set_get_relationship_const ( layout_data, index );
179 0 : const data_relationship_t *const the_relationship = layout_relationship_get_data_const ( relationship_layout );
180 0 : show_relation = layout_relationship_get_visibility ( relationship_layout );
181 0 : if ( PENCIL_VISIBILITY_IMPLICIT == show_relation )
182 : {
183 0 : if ( data_id_equals_id( &mark_focused, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) )
184 0 : || data_id_equals_id( &mark_highlighted, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) )
185 0 : || data_small_set_contains_row_id( mark_selected, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) ) )
186 : {
187 : /* the implicit relationship is focused or marked or highlighted */
188 0 : show_relation = PENCIL_VISIBILITY_SHOW;
189 : }
190 : else
191 : {
192 0 : if ( DATA_TABLE_DIAGRAMELEMENT == data_id_get_table( &mark_highlighted ) )
193 : {
194 0 : const data_row_id_t diagramelement_id = data_id_get_row_id( &mark_highlighted );
195 0 : const data_visible_classifier_t *visible_clsfy = data_visible_set_get_visible_classifier_by_id_const ( (*this_).input_data, diagramelement_id );
196 0 : if ( visible_clsfy != NULL )
197 : {
198 0 : if ( data_visible_classifier_is_valid( visible_clsfy ) )
199 : {
200 0 : const data_classifier_t *classifier = data_visible_classifier_get_classifier_const( visible_clsfy );
201 0 : if (( data_classifier_get_row_id( classifier ) == data_relationship_get_from_classifier_row_id( the_relationship ) )
202 0 : ||( data_classifier_get_row_id( classifier ) == data_relationship_get_to_classifier_row_id( the_relationship ) ))
203 : {
204 : /* the implicit relationship has highlighted from or to classifier */
205 0 : show_relation = PENCIL_VISIBILITY_SHOW;
206 : }
207 : }
208 : }
209 :
210 : }
211 : }
212 : }
213 0 : if (( PENCIL_VISIBILITY_SHOW == show_relation )||( PENCIL_VISIBILITY_GRAY_OUT == show_relation ))
214 : {
215 0 : const pencil_size_t *const pencil_size = pencil_layouter_get_pencil_size_const( &((*this_).layouter) );
216 0 : pencil_relationship_painter_draw ( &((*this_).relationship_painter),
217 : relationship_layout,
218 : data_id_equals_id( &mark_focused, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) ),
219 : data_id_equals_id( &mark_highlighted, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id( the_relationship ) ),
220 : data_small_set_contains_row_id( mark_selected, DATA_TABLE_RELATIONSHIP, data_relationship_get_row_id(the_relationship) ),
221 : (*this_).profile,
222 : pencil_size,
223 : layout,
224 : cr
225 : );
226 : }
227 : }
228 :
229 0 : U8_TRACE_END();
230 0 : }
231 :
232 0 : pencil_error_t pencil_diagram_maker_get_order_at_pos ( const pencil_diagram_maker_t *this_,
233 : data_id_t obj_id,
234 : double x,
235 : double y,
236 : double snap_to_grid_distance,
237 : layout_order_t* out_layout_order )
238 : {
239 0 : U8_TRACE_BEGIN();
240 0 : assert( NULL != out_layout_order );
241 :
242 0 : pencil_error_t result = PENCIL_ERROR_NONE;
243 :
244 0 : const data_table_t table = data_id_get_table ( &obj_id );
245 0 : switch ( table )
246 : {
247 0 : case DATA_TABLE_CLASSIFIER:
248 : {
249 0 : const data_row_id_t classifier_id = data_id_get_row_id ( &obj_id );
250 : const data_classifier_t *const the_classifier
251 0 : = data_visible_set_get_classifier_by_id_const ( (*this_).input_data, classifier_id );
252 0 : const data_classifier_type_t c_type
253 : = (NULL == the_classifier)
254 : ? DATA_CLASSIFIER_TYPE_CLASS /* for new or unknown objects, assume class */
255 0 : : data_classifier_get_main_type( the_classifier );
256 0 : result = pencil_layouter_get_classifier_order_at_pos ( &((*this_).layouter),
257 : c_type,
258 : x,
259 : y,
260 : snap_to_grid_distance,
261 : out_layout_order
262 : );
263 : }
264 0 : break;
265 :
266 0 : case DATA_TABLE_FEATURE:
267 : {
268 0 : const data_row_id_t feature_id = data_id_get_row_id ( &obj_id );
269 : const data_feature_t *const the_feature
270 0 : = data_visible_set_get_feature_by_id_const ( (*this_).input_data, feature_id );
271 0 : if( NULL != the_feature )
272 : {
273 0 : result = pencil_layouter_get_feature_order_at_pos ( &((*this_).layouter),
274 : the_feature,
275 : x,
276 : y,
277 : out_layout_order
278 : );
279 : }
280 : else
281 : {
282 0 : U8_LOG_ANOMALY( "feature to move does not exist in input_data." );
283 0 : layout_order_init_empty( out_layout_order );
284 0 : result = PENCIL_ERROR_UNKNOWN_OBJECT;
285 : }
286 : }
287 0 : break;
288 :
289 0 : case DATA_TABLE_RELATIONSHIP:
290 : {
291 0 : result = pencil_layouter_get_relationship_order_at_pos ( &((*this_).layouter),
292 : x,
293 : y,
294 : out_layout_order
295 : );
296 : }
297 0 : break;
298 :
299 0 : case DATA_TABLE_DIAGRAMELEMENT:
300 : {
301 0 : U8_LOG_WARNING( "not implemented to move diagramelements. use the classifier instead." );
302 0 : layout_order_init_empty( out_layout_order );
303 0 : result = PENCIL_ERROR_UNKNOWN_OBJECT;
304 : }
305 0 : break;
306 :
307 0 : case DATA_TABLE_DIAGRAM:
308 : {
309 : /* pencil cannot move diagrams */
310 0 : U8_LOG_WARNING( "object to be re-positioned has unexpected type: diagram" );
311 0 : layout_order_init_empty( out_layout_order );
312 0 : result = PENCIL_ERROR_UNKNOWN_OBJECT;
313 : }
314 0 : break;
315 :
316 0 : default:
317 : {
318 0 : U8_LOG_WARNING( "object to be re-positioned has illegal type" );
319 0 : layout_order_init_empty( out_layout_order );
320 0 : result = PENCIL_ERROR_UNKNOWN_OBJECT;
321 : }
322 0 : break;
323 : }
324 :
325 0 : U8_TRACE_END_ERR(result);
326 0 : return result;
327 : }
328 :
329 0 : pencil_error_t pencil_diagram_maker_get_feature_order_at_pos ( const pencil_diagram_maker_t *this_,
330 : const data_feature_t *feature_ptr,
331 : double x,
332 : double y,
333 : layout_order_t* out_layout_order )
334 : {
335 0 : U8_TRACE_BEGIN();
336 0 : assert( NULL != feature_ptr );
337 0 : assert( NULL != out_layout_order );
338 :
339 : const pencil_error_t result
340 0 : = pencil_layouter_get_feature_order_at_pos ( &((*this_).layouter),
341 : feature_ptr,
342 : x,
343 : y,
344 : out_layout_order
345 : );
346 :
347 0 : U8_TRACE_END_ERR(result);
348 0 : return result;
349 : }
350 :
351 :
352 : /*
353 : Copyright 2016-2024 Andreas Warnke
354 :
355 : Licensed under the Apache License, Version 2.0 (the "License");
356 : you may not use this file except in compliance with the License.
357 : You may obtain a copy of the License at
358 :
359 : http://www.apache.org/licenses/LICENSE-2.0
360 :
361 : Unless required by applicable law or agreed to in writing, software
362 : distributed under the License is distributed on an "AS IS" BASIS,
363 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
364 : See the License for the specific language governing permissions and
365 : limitations under the License.
366 : */
|