LCOV - code coverage report
Current view: top level - gui/source/sketch - gui_sketch_card_painter.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 0.0 % 480 0
Test Date: 2025-05-01 10:10:14 Functions: 0.0 % 13 0

            Line data    Source code
       1              : /* File: gui_sketch_card_painter.c; Copyright and License: see below */
       2              : 
       3              : #include "sketch/gui_sketch_card_painter.h"
       4              : #include "u8/u8_trace.h"
       5              : #include "gui_gtk.h"
       6              : #include <assert.h>
       7              : 
       8            0 : void gui_sketch_card_painter_init( gui_sketch_card_painter_t *this_ )
       9              : {
      10            0 :     U8_TRACE_BEGIN();
      11              : 
      12            0 :     gui_sketch_style_init( &((*this_).sketch_style) );
      13              : 
      14            0 :     U8_TRACE_END();
      15            0 : }
      16              : 
      17            0 : void gui_sketch_card_painter_destroy( gui_sketch_card_painter_t *this_ )
      18              : {
      19            0 :     U8_TRACE_BEGIN();
      20              : 
      21            0 :     gui_sketch_style_destroy( &((*this_).sketch_style) );
      22              : 
      23            0 :     U8_TRACE_END();
      24            0 : }
      25              : 
      26            0 : void gui_sketch_card_painter_draw_overlay( gui_sketch_card_painter_t *this_,
      27              :                                            gui_tool_t selected_tool,
      28              :                                            const gui_sketch_drag_state_t *drag_state,
      29              :                                            const gui_sketch_card_t *card_under_mouse,
      30              :                                            gui_marked_set_t *marked_objects,
      31              :                                            cairo_t *cr )
      32              : {
      33            0 :     U8_TRACE_BEGIN();
      34            0 :     assert( NULL != drag_state );
      35            0 :     assert( NULL != cr );
      36              : 
      37            0 :     switch ( selected_tool )
      38              :     {
      39            0 :         case GUI_TOOL_NAVIGATE:
      40              :         {
      41              :         }
      42            0 :         break;
      43              : 
      44            0 :         case GUI_TOOL_EDIT:
      45              :         {
      46            0 :             gui_sketch_card_painter_private_draw_edit_mode( this_, drag_state, card_under_mouse, cr );
      47              :         }
      48            0 :         break;
      49              : 
      50            0 :         case GUI_TOOL_CREATE:
      51              :         {
      52            0 :             const data_id_t highlighted = gui_marked_set_get_highlighted( marked_objects );
      53            0 :             const layout_subelement_kind_t highlighted_kind = gui_marked_set_get_highlighted_kind( marked_objects );
      54            0 :             gui_sketch_card_painter_private_draw_create_mode( this_,
      55              :                                                               drag_state,
      56              :                                                               card_under_mouse,
      57              :                                                               data_id_get_table(&highlighted),
      58              :                                                               highlighted_kind,
      59              :                                                               cr
      60              :                                                             );
      61              :         }
      62            0 :         break;
      63              : 
      64            0 :         case GUI_TOOL_SEARCH:
      65              :         {
      66              :         }
      67            0 :         break;
      68              : 
      69            0 :         default:
      70              :         {
      71            0 :             U8_LOG_ERROR("selected_tool is out of range");
      72              :         }
      73            0 :         break;
      74              :     }
      75              : 
      76            0 :     U8_TRACE_END();
      77            0 : }
      78              : 
      79              : 
      80            0 : void gui_sketch_card_painter_private_draw_edit_mode( gui_sketch_card_painter_t *this_,
      81              :                                                      const gui_sketch_drag_state_t *drag_state,
      82              :                                                      const gui_sketch_card_t *card_under_mouse,
      83              :                                                      cairo_t *cr )
      84              : {
      85            0 :     U8_TRACE_BEGIN();
      86            0 :     assert( NULL != drag_state );
      87            0 :     assert( NULL != cr );
      88              : 
      89            0 :     if ( gui_sketch_drag_state_is_dragging ( drag_state ) )
      90              :     {
      91              :         const data_full_id_t *const dragged_object
      92            0 :             = gui_sketch_drag_state_get_dragged_object_const( drag_state );
      93            0 :         const data_id_t *const dragged_primary = data_full_id_get_primary_id_const( dragged_object );
      94            0 :         const bool dragging_classifier = ( DATA_TABLE_DIAGRAMELEMENT == data_id_get_table( dragged_primary ) );
      95              : 
      96            0 :         if ( NULL != card_under_mouse )
      97              :         {
      98            0 :             const data_diagram_t *diag = gui_sketch_card_get_diagram_const ( card_under_mouse );
      99            0 :             const data_diagram_type_t diag_type = data_diagram_get_diagram_type( diag );
     100            0 :             const bool draw_2d_diagram
     101              :                 = (( diag_type != DATA_DIAGRAM_TYPE_UML_SEQUENCE_DIAGRAM )
     102            0 :                 && ( diag_type != DATA_DIAGRAM_TYPE_UML_TIMING_DIAGRAM )
     103            0 :                 && ( diag_type != DATA_DIAGRAM_TYPE_LIST ));
     104              : 
     105            0 :             if ( draw_2d_diagram && dragging_classifier )
     106              :             {
     107              :                 /* draw grid line crossings */
     108            0 :                 gui_sketch_card_painter_private_draw_grid( this_, card_under_mouse, cr );
     109              : 
     110              :                 /* draw new grid lines that visualize the order of classifiers */
     111            0 :                 const int32_t to_x = gui_sketch_drag_state_get_to_x ( drag_state );
     112            0 :                 const int32_t to_y = gui_sketch_drag_state_get_to_y ( drag_state );
     113            0 :                 gui_sketch_card_painter_private_visualize_order( this_, card_under_mouse, to_x, to_y, cr );
     114              :             }
     115              :         }
     116              :     }
     117              : 
     118            0 :     U8_TRACE_END();
     119            0 : }
     120              : 
     121            0 : void gui_sketch_card_painter_private_draw_create_mode( gui_sketch_card_painter_t *this_,
     122              :                                                        const gui_sketch_drag_state_t *drag_state,
     123              :                                                        const gui_sketch_card_t *card_under_mouse,
     124              :                                                        data_table_t highlighted_table,
     125              :                                                        layout_subelement_kind_t highlighted_kind,
     126              :                                                        cairo_t *cr )
     127              : {
     128            0 :     U8_TRACE_BEGIN();
     129            0 :     assert( NULL != drag_state );
     130            0 :     assert( NULL != cr );
     131              : 
     132            0 :     if ( gui_sketch_drag_state_is_dragging ( drag_state ) )
     133              :     {
     134              :         /* draw a line */
     135            0 :         const int32_t from_x = gui_sketch_drag_state_get_from_x ( drag_state );
     136            0 :         const int32_t from_y = gui_sketch_drag_state_get_from_y ( drag_state );
     137            0 :         const int32_t to_x = gui_sketch_drag_state_get_to_x ( drag_state );
     138            0 :         const int32_t to_y = gui_sketch_drag_state_get_to_y ( drag_state );
     139            0 :         gui_sketch_card_painter_private_draw_arrow( this_, from_x, from_y, to_x, to_y, cr );
     140              :     }
     141              :     else /* ! gui_sketch_drag_state_is_dragging() */
     142              :     {
     143            0 :         if ( NULL != card_under_mouse )
     144              :         {
     145            0 :             const bool draw_new_classifier
     146            0 :                 = (( highlighted_table == DATA_TABLE_CLASSIFIER )&&( highlighted_kind == LAYOUT_SUBELEMENT_KIND_SPACE ))
     147            0 :                 || (( highlighted_table == DATA_TABLE_DIAGRAMELEMENT )&&( highlighted_kind == LAYOUT_SUBELEMENT_KIND_SPACE ))
     148            0 :                 || (( highlighted_table == DATA_TABLE_DIAGRAM )&&( highlighted_kind == LAYOUT_SUBELEMENT_KIND_SPACE ));
     149            0 :             const bool draw_new_feature
     150            0 :                 = (( highlighted_table == DATA_TABLE_CLASSIFIER )&&( highlighted_kind == LAYOUT_SUBELEMENT_KIND_OUTLINE ))
     151            0 :                 || (( highlighted_table == DATA_TABLE_DIAGRAMELEMENT )&&( highlighted_kind == LAYOUT_SUBELEMENT_KIND_OUTLINE ));
     152            0 :             const bool draw_new_relationship
     153            0 :                 = (( highlighted_table == DATA_TABLE_CLASSIFIER )&&( highlighted_kind != LAYOUT_SUBELEMENT_KIND_SPACE ))
     154            0 :                 || (( highlighted_table == DATA_TABLE_DIAGRAMELEMENT )&&( highlighted_kind != LAYOUT_SUBELEMENT_KIND_SPACE ))
     155            0 :                 || ( highlighted_table == DATA_TABLE_FEATURE );
     156              : 
     157            0 :             const data_diagram_t *diag = gui_sketch_card_get_diagram_const ( card_under_mouse );
     158            0 :             const data_diagram_type_t diag_type = data_diagram_get_diagram_type( diag );
     159            0 :             const bool draw_2d_diagram
     160              :                 = (( diag_type != DATA_DIAGRAM_TYPE_UML_SEQUENCE_DIAGRAM )
     161            0 :                 && ( diag_type != DATA_DIAGRAM_TYPE_UML_TIMING_DIAGRAM )
     162            0 :                 && ( diag_type != DATA_DIAGRAM_TYPE_LIST ));
     163              : 
     164              :             /* get coordinates */
     165            0 :             const int32_t to_x = gui_sketch_drag_state_get_to_x ( drag_state );
     166            0 :             const int32_t to_y = gui_sketch_drag_state_get_to_y ( drag_state );
     167              : 
     168              :             /* draw grid */
     169            0 :             if (( draw_new_classifier )&&( draw_2d_diagram ))
     170              :             {
     171              :                 /* draw grid line crossings */
     172            0 :                 gui_sketch_card_painter_private_draw_grid( this_, card_under_mouse, cr );
     173              : 
     174              :                 /* draw new grid lines that visualize the order of classifiers */
     175            0 :                 gui_sketch_card_painter_private_visualize_order( this_, card_under_mouse, to_x, to_y, cr );
     176              :             }
     177              : 
     178              :             /* draw boxes and arrow icons */
     179            0 :             if ( draw_new_classifier )
     180              :             {
     181            0 :                 gui_sketch_card_painter_private_draw_new_classifier( this_, to_x, to_y, cr );
     182              :             }
     183            0 :             if ( draw_new_feature )
     184              :             {
     185            0 :                 gui_sketch_card_painter_private_draw_new_feature( this_, to_x, to_y, cr );
     186              :             }
     187            0 :             if ( draw_new_relationship )
     188              :             {
     189            0 :                 gui_sketch_card_painter_private_draw_new_relationship( this_, to_x, to_y, cr );
     190              :             }
     191              :         }
     192              :     }
     193              : 
     194            0 :     U8_TRACE_END();
     195            0 : }
     196              : 
     197            0 : void gui_sketch_card_painter_private_draw_arrow( gui_sketch_card_painter_t *this_,
     198              :                                                  int32_t from_x,
     199              :                                                  int32_t from_y,
     200              :                                                  int32_t to_x,
     201              :                                                  int32_t to_y,
     202              :                                                  cairo_t *cr )
     203              : {
     204            0 :     U8_TRACE_BEGIN();
     205            0 :     assert( NULL != cr );
     206              : 
     207            0 :     const GdkRGBA high_color = gui_sketch_style_get_highlight_color( &((*this_).sketch_style) );
     208            0 :     cairo_set_source_rgba( cr, high_color.red, high_color.green, high_color.blue, high_color.alpha );
     209            0 :     cairo_move_to ( cr, from_x, from_y );
     210            0 :     cairo_line_to ( cr, to_x, to_y );
     211            0 :     cairo_stroke (cr);
     212              : 
     213              :     /* draw the arrow tip */
     214              :     int clock_direction;  /* the gdk coordinate system if bottom up - and out clock is also mirrored! */
     215            0 :     const int32_t x_dist = to_x - from_x;
     216            0 :     const int32_t y_dist = to_y - from_y;
     217            0 :     if ( x_dist == 0 )
     218              :     {
     219            0 :         clock_direction = ( y_dist < 0 ) ? 6 : 0;
     220              :     }
     221              :     else
     222              :     {
     223            0 :         int32_t y_x_deci_ratio = ( y_dist * 10 ) / x_dist;
     224            0 :         if ( y_x_deci_ratio < 3 /* = 0.26 = tan(15 deg) */ )
     225              :         {
     226            0 :             if ( y_x_deci_ratio < -10 /* = -1.00 = tan(-45 deg) */ )
     227              :             {
     228            0 :                 if ( y_x_deci_ratio < -37 /* = -3.73 = tan(-75 deg) */ )
     229              :                 {
     230            0 :                     clock_direction = 6;
     231              :                 }
     232              :                 else
     233              :                 {
     234            0 :                     clock_direction = 5;
     235              :                 }
     236              :             }
     237              :             else
     238              :             {
     239            0 :                 if ( y_x_deci_ratio < -2 /* = -0.26 = tan(-15 deg) */ )
     240              :                 {
     241            0 :                     clock_direction = 4;
     242              :                 }
     243              :                 else
     244              :                 {
     245            0 :                     clock_direction = 3;
     246              :                 }
     247              :             }
     248              :         }
     249              :         else
     250              :         {
     251            0 :             if ( y_x_deci_ratio < 10 /* = 1.00 = tan(45 deg) */ )
     252              :             {
     253            0 :                 clock_direction = 2;
     254              :             }
     255              :             else
     256              :             {
     257            0 :                 if ( y_x_deci_ratio < 38 /* = 3.73 = tan(75 deg) */ )
     258              :                 {
     259            0 :                     clock_direction = 1;
     260              :                 }
     261              :                 else
     262              :                 {
     263            0 :                     clock_direction = 0;
     264              :                 }
     265              :             }
     266              :         }
     267            0 :         if ( x_dist < 0 )
     268              :         {
     269            0 :             clock_direction = (clock_direction+6)%12;
     270              :         }
     271              :     }
     272              :     const static int32_t DX[12][2]={{-6,+6},{-9,  0},{-11,-4},{-9,-9},{-4,-11},{  0,-9},{+6,-6},{+9,  0},{+11,+4},{+9,+9},{+4,+11},{  0,+9}};
     273              :     const static int32_t DY[12][2]={{-9,-9},{-4,-11},{  0,-9},{+6,-6},{+9,  0},{+11,+4},{+9,+9},{+4,+11},{  0,+9},{+6,-6},{-9,  0},{-11,-4}};
     274            0 :     cairo_move_to ( cr, to_x + DX[clock_direction][0], to_y + DY[clock_direction][0] );
     275            0 :     cairo_line_to ( cr, to_x, to_y );
     276            0 :     cairo_line_to ( cr, to_x + DX[clock_direction][1], to_y + DY[clock_direction][1] );
     277            0 :     cairo_stroke (cr);
     278              : 
     279            0 :     U8_TRACE_END();
     280            0 : }
     281              : 
     282            0 : void gui_sketch_card_painter_private_draw_new_classifier( gui_sketch_card_painter_t *this_,
     283              :                                                           int32_t x,
     284              :                                                          int32_t y,
     285              :                                                          cairo_t *cr )
     286              : {
     287            0 :     U8_TRACE_BEGIN();
     288            0 :     assert( NULL != cr );
     289              : 
     290            0 :     const GdkRGBA high_color = gui_sketch_style_get_highlight_color( &((*this_).sketch_style) );
     291            0 :     cairo_set_source_rgba( cr, high_color.red, high_color.green, high_color.blue, high_color.alpha );
     292              :     static const int32_t ICON_UNIT = 2;
     293              :     static const int32_t DIST = 12;
     294              : 
     295              :     /* star */
     296            0 :     const int32_t star_center_x = x+(1)*ICON_UNIT;
     297            0 :     const int32_t star_center_y = y-DIST-6*ICON_UNIT;
     298            0 :     cairo_move_to ( cr, star_center_x, star_center_y-2*ICON_UNIT );
     299            0 :     cairo_line_to ( cr, star_center_x, star_center_y+2*ICON_UNIT );
     300            0 :     cairo_move_to ( cr, star_center_x-2*ICON_UNIT, star_center_y-1*ICON_UNIT );
     301            0 :     cairo_line_to ( cr, star_center_x+2*ICON_UNIT, star_center_y+1*ICON_UNIT );
     302            0 :     cairo_move_to ( cr, star_center_x-2*ICON_UNIT, star_center_y+1*ICON_UNIT );
     303            0 :     cairo_line_to ( cr, star_center_x+2*ICON_UNIT, star_center_y-1*ICON_UNIT );
     304              : 
     305              :     /* big box */
     306            0 :     cairo_move_to ( cr, x-1*ICON_UNIT, y-DIST-6*ICON_UNIT );
     307            0 :     cairo_line_to ( cr, x-8*ICON_UNIT, y-DIST-6*ICON_UNIT );
     308            0 :     cairo_line_to ( cr, x-8*ICON_UNIT, y-DIST+3*ICON_UNIT );
     309            0 :     cairo_line_to ( cr, x+1*ICON_UNIT, y-DIST+3*ICON_UNIT );
     310            0 :     cairo_line_to ( cr, x+1*ICON_UNIT, y-DIST-2*ICON_UNIT );
     311              : 
     312            0 :     cairo_stroke (cr);
     313              : 
     314            0 :     U8_TRACE_END();
     315            0 : }
     316              : 
     317            0 : void gui_sketch_card_painter_private_draw_new_feature( gui_sketch_card_painter_t *this_,
     318              :                                                        int32_t x,
     319              :                                                        int32_t y,
     320              :                                                        cairo_t *cr )
     321              : {
     322            0 :     U8_TRACE_BEGIN();
     323            0 :     assert( NULL != cr );
     324              : 
     325            0 :     const GdkRGBA high_color = gui_sketch_style_get_highlight_color( &((*this_).sketch_style) );
     326            0 :     cairo_set_source_rgba( cr, high_color.red, high_color.green, high_color.blue, high_color.alpha );
     327              :     static const int32_t ICON_UNIT = 2;
     328              :     static const int32_t DIST = 12;
     329              : 
     330              :     /* star */
     331            0 :     const int32_t star_center_x = x+(-2)*ICON_UNIT;
     332            0 :     const int32_t star_center_y = y-DIST-6*ICON_UNIT;
     333            0 :     cairo_move_to ( cr, star_center_x, star_center_y-2*ICON_UNIT );
     334            0 :     cairo_line_to ( cr, star_center_x, star_center_y+2*ICON_UNIT );
     335            0 :     cairo_move_to ( cr, star_center_x-2*ICON_UNIT, star_center_y-1*ICON_UNIT );
     336            0 :     cairo_line_to ( cr, star_center_x+2*ICON_UNIT, star_center_y+1*ICON_UNIT );
     337            0 :     cairo_move_to ( cr, star_center_x-2*ICON_UNIT, star_center_y+1*ICON_UNIT );
     338            0 :     cairo_line_to ( cr, star_center_x+2*ICON_UNIT, star_center_y-1*ICON_UNIT );
     339              : 
     340              :     /* small box */
     341            0 :     cairo_move_to ( cr, x-4*ICON_UNIT, y-DIST-6*ICON_UNIT );
     342            0 :     cairo_line_to ( cr, x-8*ICON_UNIT, y-DIST-6*ICON_UNIT );
     343            0 :     cairo_line_to ( cr, x-8*ICON_UNIT, y-DIST-2*ICON_UNIT );
     344            0 :     cairo_line_to ( cr, x-2*ICON_UNIT, y-DIST-2*ICON_UNIT );
     345              : 
     346            0 :     cairo_stroke (cr);
     347              : 
     348            0 :     U8_TRACE_END();
     349            0 : }
     350              : 
     351            0 : void gui_sketch_card_painter_private_draw_new_relationship( gui_sketch_card_painter_t *this_,
     352              :                                                             int32_t x,
     353              :                                                             int32_t y,
     354              :                                                             cairo_t *cr )
     355              : {
     356            0 :     U8_TRACE_BEGIN();
     357            0 :     assert( NULL != cr );
     358              : 
     359            0 :     const GdkRGBA high_color = gui_sketch_style_get_highlight_color( &((*this_).sketch_style) );
     360            0 :     cairo_set_source_rgba( cr, high_color.red, high_color.green, high_color.blue, high_color.alpha );
     361              :     static const int32_t ICON_UNIT = 2;
     362              :     static const int32_t DIST = 12;
     363              : 
     364              :     /* arrow */
     365            0 :     cairo_move_to ( cr, x+2*ICON_UNIT, y-DIST-0*ICON_UNIT );
     366            0 :     cairo_line_to ( cr, x+8*ICON_UNIT, y-DIST-6*ICON_UNIT );
     367            0 :     cairo_line_to ( cr, x+5*ICON_UNIT, y-DIST-5*ICON_UNIT );
     368            0 :     cairo_move_to ( cr, x+8*ICON_UNIT, y-DIST-6*ICON_UNIT );
     369            0 :     cairo_line_to ( cr, x+7*ICON_UNIT, y-DIST-3*ICON_UNIT );
     370              : 
     371            0 :     cairo_stroke (cr);
     372              : 
     373            0 :     U8_TRACE_END();
     374            0 : }
     375              : 
     376            0 : void gui_sketch_card_painter_private_draw_grid( gui_sketch_card_painter_t *this_,
     377              :                                                 const gui_sketch_card_t *card_under_mouse,
     378              :                                                 cairo_t *cr )
     379              : {
     380            0 :     U8_TRACE_BEGIN();
     381            0 :     assert( NULL != card_under_mouse );
     382            0 :     assert( NULL != cr );
     383              : 
     384            0 :     const GdkRGBA high_color = gui_sketch_style_get_highlight_color( &((*this_).sketch_style) );
     385            0 :     cairo_set_source_rgba( cr, high_color.red, high_color.green, high_color.blue, high_color.alpha );
     386              : 
     387              :     /* draw grid */
     388              :     shape_int_rectangle_t bounds;
     389              :     uint32_t x_count;
     390              :     uint32_t y_count;
     391            0 :     gui_sketch_card_get_grid_area( card_under_mouse, &bounds, &x_count, &y_count );
     392            0 :     assert( x_count >= 2 );
     393            0 :     assert( y_count >= 2 );
     394            0 :     const int32_t left = shape_int_rectangle_get_left(&bounds);
     395            0 :     const int32_t top = shape_int_rectangle_get_top(&bounds);
     396            0 :     const int32_t width = shape_int_rectangle_get_width(&bounds);
     397            0 :     const int32_t height = shape_int_rectangle_get_height(&bounds);
     398            0 :     for ( uint32_t x_idx = 1; (x_idx+1) < x_count; x_idx ++ )
     399              :     {
     400            0 :         for ( uint32_t y_idx = 1; (y_idx+1) < y_count; y_idx ++ )
     401              :         {
     402            0 :             const int32_t x = left + (( width * x_idx )/( x_count-1 ));
     403            0 :             const int32_t y = top + (( height * y_idx )/( y_count-1 ));
     404              :             static const int32_t HALF_LINE = 16;
     405            0 :             cairo_rectangle ( cr, x, y-HALF_LINE, 1, 2*HALF_LINE );
     406            0 :             cairo_fill (cr);
     407            0 :             cairo_rectangle ( cr, x-HALF_LINE, y, 2*HALF_LINE, 1 );
     408            0 :             cairo_fill (cr);
     409              :         }
     410              :     }
     411              : 
     412            0 :     U8_TRACE_END();
     413            0 : }
     414              : 
     415            0 : void gui_sketch_card_painter_private_visualize_order( gui_sketch_card_painter_t *this_,
     416              :                                                       const gui_sketch_card_t *card_under_mouse,
     417              :                                                       int32_t x,
     418              :                                                       int32_t y,
     419              :                                                       cairo_t *cr )
     420              : {
     421            0 :     U8_TRACE_BEGIN();
     422            0 :     assert( NULL != card_under_mouse );
     423            0 :     assert( NULL != cr );
     424              : 
     425              :     /* fetch input data: subwidget */
     426            0 :     const shape_int_rectangle_t bounds = gui_sketch_card_get_bounds( card_under_mouse );
     427            0 :     const int32_t left = shape_int_rectangle_get_left(&bounds);
     428            0 :     const int32_t top = shape_int_rectangle_get_top(&bounds);
     429            0 :     const int32_t right = shape_int_rectangle_get_right(&bounds);
     430            0 :     const int32_t bottom = shape_int_rectangle_get_bottom(&bounds);
     431              : 
     432              :     /* fetch input data: grid */
     433            0 :     const geometry_grid_t *const grid = gui_sketch_card_get_grid_const( card_under_mouse);
     434            0 :     const geometry_grid_kind_t grid_kind = geometry_grid_get_kind( grid );
     435            0 :     const double snap_interval = gui_sketch_style_get_snap_to_grid( &((*this_).sketch_style) );
     436            0 :     const geometry_non_linear_scale_t *const x_scale = geometry_grid_get_x_scale_const( grid );
     437            0 :     const int32_t order_at_x = geometry_non_linear_scale_get_order( x_scale, (double) x, snap_interval );
     438            0 :     const geometry_non_linear_scale_t *const y_scale = geometry_grid_get_y_scale_const( grid );
     439            0 :     const int32_t order_at_y = geometry_non_linear_scale_get_order( y_scale, (double) y, snap_interval );
     440              : 
     441              :     /* define own distances */
     442            0 :     const double gap = 3.0;
     443            0 :     const double curve_space = 3.0 * gap;
     444              : 
     445              :     /* fetch input data: visible set */
     446            0 :     const layout_visible_set_t *const layout_data = gui_sketch_card_get_visible_set( card_under_mouse );
     447            0 :     const uint32_t classifiers = layout_visible_set_get_visible_classifier_count( layout_data );
     448              : 
     449              :     /* to draw x, follow y from top to bottom */
     450            0 :     if (( grid_kind == GEOMETRY_GRID_KIND_X )||( grid_kind == GEOMETRY_GRID_KIND_XY ))
     451              :     {
     452              :         /* order visible set by top y coordinates of classifiers */
     453              :         universal_array_index_sorter_t sorted;
     454            0 :         universal_array_index_sorter_init( &sorted );
     455            0 :         for ( uint32_t idx = 0; idx < classifiers; idx ++ )
     456              :         {
     457              :             const layout_visible_classifier_t *const classifier
     458            0 :                 = layout_visible_set_get_visible_classifier_const( layout_data, idx );
     459              : 
     460            0 :             const geometry_rectangle_t *const envelope = layout_visible_classifier_get_envelope_box_const( classifier );
     461            0 :             const int64_t weight = geometry_rectangle_get_top( envelope );
     462            0 :             const u8_error_t insert_error = universal_array_index_sorter_insert( &sorted, idx, weight );
     463            0 :             if ( U8_ERROR_NONE != insert_error )
     464              :             {
     465            0 :                 U8_LOG_WARNING( "not all rectangles are considered for the top-to-bottom line" );
     466              :             }
     467              :         }
     468              : 
     469              :         /* process rectangles top to bottom */
     470              :         /* local variables represent 3 points: */
     471              :         /* current_pos_x / current_pos_y : The position where the already drawn line ends */
     472              :         /* planned_pos_x / planned_pos_y : The position that would be the next unless the next loop finds an earlier position */
     473              :         /* draw_to_pos_x / draw_to_pos_y : While drawing, this is a temporary value storing the next current_pos position */
     474            0 :         double current_pos_x = x;
     475            0 :         double current_pos_y = top;
     476            0 :         double planned_pos_x = x;
     477            0 :         double planned_pos_y = top;  /* the planned next y - may be superseded by the next classifier */
     478            0 :         cairo_move_to( cr, x, top );
     479            0 :         const uint32_t count_sorted = universal_array_index_sorter_get_count( &sorted );
     480            0 :         for ( uint32_t idx_of_idx = 0; idx_of_idx < count_sorted; idx_of_idx ++ )
     481              :         {
     482            0 :             const uint32_t idx = universal_array_index_sorter_get_array_index( &sorted, idx_of_idx );
     483              :             const layout_visible_classifier_t *const classifier
     484            0 :                 = layout_visible_set_get_visible_classifier_const( layout_data, idx );
     485              : 
     486              :             /* skip classifiers which contain others, these are not positioned according to their order value */
     487            0 :             const uint32_t children = layout_visible_set_count_descendants( layout_data, classifier );
     488            0 :             if ( children == 0 )
     489              :             {
     490            0 :                 const data_visible_classifier_t *const vis_data = layout_visible_classifier_get_data_const( classifier );
     491            0 :                 const data_classifier_t *const c_data = data_visible_classifier_get_classifier_const( vis_data );
     492            0 :                 const int32_t c_x_order = data_classifier_get_x_order( c_data );
     493            0 :                 const geometry_rectangle_t *const envelope = layout_visible_classifier_get_envelope_box_const( classifier );
     494            0 :                 const double envelope_left = geometry_rectangle_get_left( envelope );
     495            0 :                 const double envelope_right = geometry_rectangle_get_right( envelope );
     496            0 :                 const double envelope_top = geometry_rectangle_get_top( envelope );
     497            0 :                 const double envelope_bottom = geometry_rectangle_get_bottom( envelope );
     498              :                 /* if line passes through the classifier, center on symbol, not on envelope */
     499            0 :                 const geometry_rectangle_t *const symbol = layout_visible_classifier_get_symbol_box_const( classifier );
     500            0 :                 const double symbol_center_x = geometry_rectangle_get_center_x( symbol );
     501              : 
     502            0 :                 const bool pass_through_center_x = ( c_x_order == order_at_x );
     503            0 :                 const bool pass_on_left = ( c_x_order > order_at_x ) && ( envelope_left < x );
     504            0 :                 const bool pass_on_right = ( c_x_order < order_at_x ) && ( envelope_right > x );
     505            0 :                 const bool ignored = !( pass_through_center_x || pass_on_left || pass_on_right );
     506            0 :                 const double draw_to_pos_y = envelope_top - gap;
     507            0 :                 double draw_to_pos_x = x;
     508            0 :                 if ( pass_through_center_x )
     509              :                 {
     510            0 :                     draw_to_pos_x = symbol_center_x;
     511              :                 }
     512            0 :                 if ( pass_on_left )
     513              :                 {
     514            0 :                     draw_to_pos_x = envelope_left - gap;
     515              :                 }
     516            0 :                 if ( pass_on_right )
     517              :                 {
     518            0 :                     draw_to_pos_x = envelope_right + gap;
     519              :                 }
     520            0 :                 if ( ! ignored )
     521              :                 {
     522              :                     /* if planned_pos_x not at x and enough space to draw */
     523              :                     /* 1) a return to x and 2) a comeback to new draw_to_pos_x */
     524            0 :                     if ( (( planned_pos_x < ( x - 0.001 ) )||( planned_pos_x > ( x + 0.001 ) ))
     525            0 :                          && ( planned_pos_y + ( 2 * curve_space ) < draw_to_pos_y ) )
     526              :                     {
     527            0 :                         cairo_line_to( cr, current_pos_x, planned_pos_y );
     528            0 :                         cairo_curve_to( cr,
     529              :                                         current_pos_x,
     530              :                                         planned_pos_y + curve_space,
     531              :                                         x,
     532              :                                         planned_pos_y,
     533              :                                         x,
     534              :                                         planned_pos_y + curve_space
     535              :                                       );
     536            0 :                         current_pos_x = x;
     537            0 :                         current_pos_y = planned_pos_y + curve_space;
     538              :                     }
     539              : 
     540              :                     /* if there is enough space to draw a line before drawing a curve to draw_to_pos_x */
     541            0 :                     if ( ( current_pos_y + curve_space ) < draw_to_pos_y )
     542              :                     {
     543            0 :                         cairo_line_to( cr, current_pos_x, draw_to_pos_y - curve_space );
     544            0 :                         current_pos_y = draw_to_pos_y - curve_space;
     545              :                     }
     546              : 
     547              :                     /* draw begin of current pass-by */
     548            0 :                     cairo_curve_to( cr,
     549              :                                     current_pos_x,
     550              :                                     draw_to_pos_y,
     551              :                                     draw_to_pos_x,
     552              :                                     current_pos_y,
     553              :                                     draw_to_pos_x,
     554              :                                     draw_to_pos_y
     555              :                                   );
     556              :                     /* update variables for next loop */
     557            0 :                     current_pos_x = draw_to_pos_x;
     558            0 :                     current_pos_y = draw_to_pos_y;
     559            0 :                     planned_pos_x = current_pos_x;
     560            0 :                     planned_pos_y = envelope_bottom + gap;
     561              :                 }
     562              :             }
     563              :         }
     564              :         /* draw end of last pass-by (if any) */
     565            0 :         if ( (( planned_pos_x < ( x - 0.001 ) )||( planned_pos_x > ( x + 0.001 ) ))
     566            0 :             && ( planned_pos_y + ( 1 * curve_space ) < bottom ) )
     567              :         {
     568            0 :             cairo_line_to( cr, current_pos_x, planned_pos_y );
     569            0 :             cairo_curve_to( cr,
     570              :                             current_pos_x,
     571              :                             planned_pos_y + curve_space,
     572              :                             x,
     573              :                             planned_pos_y,
     574              :                             x,
     575              :                             planned_pos_y + curve_space
     576              :                           );
     577            0 :             current_pos_x = x;
     578            0 :             current_pos_y = planned_pos_y + curve_space;
     579              :         }
     580              :         /* draw to end point and stroke the drawn path */
     581            0 :         cairo_line_to( cr, current_pos_x, bottom );
     582              :         {
     583              :             double dashes[2];
     584            0 :             dashes[0] = 2.0 * gap;  /* on segment */
     585            0 :             dashes[1] = 4.0 * gap;  /* off segment */
     586            0 :             cairo_set_dash ( cr, dashes, 2, 0.0 );
     587              :         }
     588            0 :         cairo_stroke( cr );
     589            0 :         cairo_set_dash( cr, NULL, 0, 0.0 );
     590              :     }
     591              : 
     592              :     /* to draw y, follow x from left to right */
     593            0 :     if (( grid_kind == GEOMETRY_GRID_KIND_Y )||( grid_kind == GEOMETRY_GRID_KIND_XY ))
     594              :     {
     595              :         /* order visible set by left x coordinates of classifiers */
     596              :         universal_array_index_sorter_t sorted;
     597            0 :         universal_array_index_sorter_init( &sorted );
     598            0 :         for ( uint32_t idx = 0; idx < classifiers; idx ++ )
     599              :         {
     600              :             const layout_visible_classifier_t *const classifier
     601            0 :                 = layout_visible_set_get_visible_classifier_const( layout_data, idx );
     602              : 
     603            0 :             const geometry_rectangle_t *const envelope = layout_visible_classifier_get_envelope_box_const( classifier );
     604            0 :             const int64_t weight = geometry_rectangle_get_left( envelope );
     605            0 :             const u8_error_t insert_error = universal_array_index_sorter_insert( &sorted, idx, weight );
     606            0 :             if ( U8_ERROR_NONE != insert_error )
     607              :             {
     608            0 :                 U8_LOG_WARNING( "not all rectangles are considered for the left-to-right line" );
     609              :             }
     610              :         }
     611              : 
     612              :         /* process rectangles left to right */
     613              :         /* local variables represent 3 points: */
     614              :         /* current_pos_x / current_pos_y : The position where the already drawn line ends */
     615              :         /* planned_pos_x / planned_pos_y : The position that would be the next unless the next loop finds an earlier position */
     616              :         /* draw_to_pos_x / draw_to_pos_y : While drawing, this is a temporary value storing the next current_pos position */
     617            0 :         double current_pos_x = left;
     618            0 :         double current_pos_y = y;
     619            0 :         double planned_pos_x = left;  /* the planned next x - may be superseded by the next classifier */
     620            0 :         double planned_pos_y = y;
     621            0 :         cairo_move_to( cr, left, y );
     622            0 :         const uint32_t count_sorted = universal_array_index_sorter_get_count( &sorted );
     623            0 :         for ( uint32_t idx_of_idx = 0; idx_of_idx < count_sorted; idx_of_idx ++ )
     624              :         {
     625            0 :             const uint32_t idx = universal_array_index_sorter_get_array_index( &sorted, idx_of_idx );
     626              :             const layout_visible_classifier_t *const classifier
     627            0 :                 = layout_visible_set_get_visible_classifier_const( layout_data, idx );
     628              : 
     629              :             /* skip classifiers which contain others, these are not positioned according to their order value */
     630            0 :             const uint32_t children = layout_visible_set_count_descendants( layout_data, classifier );
     631            0 :             if ( children == 0 )
     632              :             {
     633            0 :                 const data_visible_classifier_t *const vis_data = layout_visible_classifier_get_data_const( classifier );
     634            0 :                 const data_classifier_t *const c_data = data_visible_classifier_get_classifier_const( vis_data );
     635            0 :                 const int32_t c_y_order = data_classifier_get_y_order( c_data );
     636            0 :                 const geometry_rectangle_t *const envelope = layout_visible_classifier_get_envelope_box_const( classifier );
     637            0 :                 const double envelope_top = geometry_rectangle_get_top( envelope );
     638            0 :                 const double envelope_bottom = geometry_rectangle_get_bottom( envelope );
     639            0 :                 const double envelope_left = geometry_rectangle_get_left( envelope );
     640            0 :                 const double envelope_right = geometry_rectangle_get_right( envelope );
     641              :                 /* if line passes through the classifier, center on symbol, not on envelope */
     642            0 :                 const geometry_rectangle_t *const symbol = layout_visible_classifier_get_symbol_box_const( classifier );
     643            0 :                 const double symbol_center_y = geometry_rectangle_get_center_y( symbol );
     644              : 
     645            0 :                 const bool pass_through_center_y = ( c_y_order == order_at_y );
     646            0 :                 const bool pass_on_top = ( c_y_order > order_at_y ) && ( envelope_top < y );
     647            0 :                 const bool pass_on_bottom = ( c_y_order < order_at_y ) && ( envelope_bottom > y );
     648            0 :                 const bool ignored = !( pass_through_center_y || pass_on_top || pass_on_bottom );
     649            0 :                 const double draw_to_pos_x = envelope_left - gap;
     650            0 :                 double draw_to_pos_y = y;
     651            0 :                 if ( pass_through_center_y )
     652              :                 {
     653            0 :                     draw_to_pos_y = symbol_center_y;
     654              :                 }
     655            0 :                 if ( pass_on_top )
     656              :                 {
     657            0 :                     draw_to_pos_y = envelope_top - gap;
     658              :                 }
     659            0 :                 if ( pass_on_bottom )
     660              :                 {
     661            0 :                     draw_to_pos_y = envelope_bottom + gap;
     662              :                 }
     663            0 :                 if ( ! ignored )
     664              :                 {
     665              :                     /* if planned_pos_y not at y and enough space to draw */
     666              :                     /* 1) a return to y and 2) a comeback to new draw_to_pos_y */
     667            0 :                     if ( (( planned_pos_y < ( y - 0.001 ) )||( planned_pos_y > ( y + 0.001 ) ))
     668            0 :                          && ( planned_pos_x + ( 2 * curve_space ) < draw_to_pos_x ) )
     669              :                     {
     670            0 :                         cairo_line_to( cr, planned_pos_x, current_pos_y );
     671            0 :                         cairo_curve_to( cr,
     672              :                                         planned_pos_x + curve_space,
     673              :                                         current_pos_y,
     674              :                                         planned_pos_x,
     675              :                                         y,
     676              :                                         planned_pos_x + curve_space,
     677              :                                         y
     678              :                                       );
     679            0 :                         current_pos_x = planned_pos_x + curve_space;
     680            0 :                         current_pos_y = y;
     681              :                     }
     682              : 
     683              :                     /* if there is enough space to draw a line before drawing a curve to draw_to_pos_x */
     684            0 :                     if ( ( current_pos_x + curve_space ) < draw_to_pos_x )
     685              :                     {
     686            0 :                         cairo_line_to( cr, draw_to_pos_x - curve_space, current_pos_y );
     687            0 :                         current_pos_x = draw_to_pos_x - curve_space;
     688              :                     }
     689              : 
     690              :                     /* draw begin of current pass-by */
     691            0 :                     cairo_curve_to( cr,
     692              :                                     draw_to_pos_x,
     693              :                                     current_pos_y,
     694              :                                     current_pos_x,
     695              :                                     draw_to_pos_y,
     696              :                                     draw_to_pos_x,
     697              :                                     draw_to_pos_y
     698              :                                   );
     699              :                     /* update variables for next loop */
     700            0 :                     current_pos_x = draw_to_pos_x;
     701            0 :                     current_pos_y = draw_to_pos_y;
     702            0 :                     planned_pos_x = envelope_right + gap;
     703            0 :                     planned_pos_y = current_pos_y;
     704              :                 }
     705              :             }
     706              :         }
     707              :         /* draw end of last pass-by (if any) */
     708            0 :         if ( (( planned_pos_y < ( y - 0.001 ) )||( planned_pos_y > ( y + 0.001 ) ))
     709            0 :             && ( planned_pos_x + ( 1 * curve_space ) < right ) )
     710              :         {
     711            0 :             cairo_line_to( cr, planned_pos_x, current_pos_y );
     712            0 :             cairo_curve_to( cr,
     713              :                             planned_pos_x + curve_space,
     714              :                             current_pos_y,
     715              :                             planned_pos_x,
     716              :                             y,
     717              :                             planned_pos_x + curve_space,
     718              :                             y
     719              :                           );
     720            0 :             current_pos_x = planned_pos_x + curve_space;
     721            0 :             current_pos_y = y;
     722              :         }
     723              :         /* draw to end point and stroke the drawn path */
     724            0 :         cairo_line_to( cr, right, current_pos_y );
     725              :         {
     726              :             double dashes[2];
     727            0 :             dashes[0] = 2.0 * gap;  /* on segment */
     728            0 :             dashes[1] = 4.0 * gap;  /* off segment */
     729            0 :             cairo_set_dash ( cr, dashes, 2, 0.0 );
     730              :         }
     731            0 :         cairo_stroke( cr );
     732            0 :         cairo_set_dash( cr, NULL, 0, 0.0 );
     733              :     }
     734              : 
     735            0 :     U8_TRACE_END();
     736            0 : }
     737              : 
     738            0 : void gui_sketch_card_painter_private_draw_element_space( const gui_sketch_card_painter_t *this_,
     739              :                                                          const layout_subelement_id_t *subelement,
     740              :                                                          const layout_visible_set_t *layouted_set,
     741              :                                                          cairo_t *cr )
     742              : {
     743            0 :     assert( NULL != subelement );
     744            0 :     assert( NULL != layouted_set );
     745            0 :     assert( NULL != cr );
     746            0 :     const layout_diagram_t *const layout_diag = layout_visible_set_get_diagram_const( layouted_set );
     747            0 :     const double label_border = 2.0;  /* additional visible border that just draws a box nicely, without effect for selecting */
     748            0 :     const double connector_border = (double) gui_sketch_style_get_snap_to_relationship( &((*this_).sketch_style) );
     749              : 
     750              :     geometry_rectangle_t highlight;
     751            0 :     geometry_rectangle_init_empty( &highlight );
     752              :     data_id_t search_id;
     753            0 :     data_id_copy( &search_id, data_full_id_get_primary_id_const( layout_subelement_id_get_id_const( subelement ) ) );
     754            0 :     const layout_subelement_kind_t kind = layout_subelement_id_get_kind( subelement );
     755              : 
     756              :     /* check diagram */
     757            0 :     const data_diagram_t *const diag_data = layout_diagram_get_data_const( layout_diag );
     758            0 :     const data_id_t diag_id = data_diagram_get_data_id( diag_data );
     759            0 :     if ( data_id_equals( &search_id, &diag_id ) )
     760              :     {
     761            0 :         switch ( kind )
     762              :         {
     763            0 :             case LAYOUT_SUBELEMENT_KIND_LABEL:
     764              :             {
     765            0 :                 geometry_rectangle_replace( &highlight, layout_diagram_get_label_box_const( layout_diag ) );
     766            0 :                 geometry_rectangle_expand_4dir( &highlight, 4.0 /* delta_width */, 4.0 /* delta_height */ );
     767            0 :                 gui_sketch_card_painter_private_draw_rect( this_, &highlight, cr );
     768              :             }
     769            0 :             break;
     770              : 
     771            0 :             case LAYOUT_SUBELEMENT_KIND_OUTLINE:
     772              :             {
     773              :                 geometry_rectangle_t empty_space;
     774            0 :                 geometry_rectangle_replace( &highlight, layout_diagram_get_bounds_const( layout_diag ) );
     775            0 :                 geometry_rectangle_copy( &empty_space, layout_diagram_get_draw_area_const( layout_diag ) );  /* no highlight in space */
     776            0 :                 gui_sketch_card_painter_private_draw_border( this_, &highlight, &empty_space, cr );
     777              :             }
     778            0 :             break;
     779              : 
     780            0 :             default:
     781              :             case LAYOUT_SUBELEMENT_KIND_SPACE:
     782              :             {
     783            0 :                 geometry_rectangle_replace( &highlight, layout_diagram_get_draw_area_const( layout_diag ) );
     784            0 :                 gui_sketch_card_painter_private_draw_rect( this_, &highlight, cr );
     785              :             }
     786            0 :             break;
     787              :         }
     788              :     }
     789              : 
     790              :     /* iterate over all classifiers */
     791            0 :     const uint32_t c_count = layout_visible_set_get_visible_classifier_count( layouted_set );
     792            0 :     for ( uint32_t c_index = 0; c_index < c_count; c_index ++ )
     793              :     {
     794              :         const layout_visible_classifier_t *const visible_classifier
     795            0 :             = layout_visible_set_get_visible_classifier_const ( layouted_set, c_index );
     796            0 :         const data_diagramelement_t *diagele = layout_visible_classifier_get_diagramelement_const( visible_classifier );
     797            0 :         const data_id_t diagele_id = data_diagramelement_get_data_id( diagele );
     798            0 :         if ( data_id_equals( &search_id, &diagele_id ) )
     799              :         {
     800            0 :             switch ( kind )
     801              :             {
     802            0 :                 case LAYOUT_SUBELEMENT_KIND_LABEL:
     803              :                 {
     804            0 :                     geometry_rectangle_replace( &highlight, layout_visible_classifier_get_label_box_const( visible_classifier ) );
     805            0 :                     geometry_rectangle_expand_4dir( &highlight, 4.0 /* delta_width */, 4.0 /* delta_height */ );
     806            0 :                     gui_sketch_card_painter_private_draw_rect( this_, &highlight, cr );
     807              :                 }
     808            0 :                 break;
     809              : 
     810            0 :                 case LAYOUT_SUBELEMENT_KIND_OUTLINE:
     811              :                 {
     812              :                     geometry_rectangle_t empty_space;
     813            0 :                     geometry_rectangle_replace( &highlight, layout_visible_classifier_get_symbol_box_const( visible_classifier ) );
     814            0 :                     geometry_rectangle_copy( &empty_space, layout_visible_classifier_get_space_const( visible_classifier ) );  /* no highlight in space */
     815            0 :                     gui_sketch_card_painter_private_draw_border( this_, &highlight, &empty_space, cr );
     816              :                 }
     817            0 :                 break;
     818              : 
     819            0 :                 default:
     820              :                 case LAYOUT_SUBELEMENT_KIND_SPACE:
     821              :                 {
     822            0 :                     geometry_rectangle_replace( &highlight, layout_visible_classifier_get_space_const( visible_classifier ) );
     823            0 :                     gui_sketch_card_painter_private_draw_rect( this_, &highlight, cr );
     824              :                 }
     825            0 :                 break;
     826              :             }
     827              :         }
     828              :     }
     829              : 
     830              :     /* check all contained features */
     831            0 :     const uint32_t f_count = layout_visible_set_get_feature_count( layouted_set );
     832            0 :     for ( uint32_t f_index = 0; f_index < f_count; f_index ++ )
     833              :     {
     834              :         const layout_feature_t *const the_feature
     835            0 :             = layout_visible_set_get_feature_const ( layouted_set, f_index );
     836            0 :         const data_feature_t *feature = layout_feature_get_data_const( the_feature );
     837            0 :         const data_id_t feature_id = data_feature_get_data_id( feature );
     838            0 :         if ( data_id_equals( &search_id, &feature_id ) )
     839              :         {
     840            0 :             switch ( kind )
     841              :             {
     842            0 :                 case LAYOUT_SUBELEMENT_KIND_LABEL:
     843              :                 {
     844            0 :                     geometry_rectangle_replace( &highlight, layout_feature_get_label_box_const( the_feature ) );
     845            0 :                     geometry_rectangle_expand_4dir( &highlight, 2.0 * label_border, 2.0 * label_border );
     846            0 :                     gui_sketch_card_painter_private_draw_rect( this_, &highlight, cr );
     847              :                 }
     848            0 :                 break;
     849              : 
     850            0 :                 default:
     851              :                 case LAYOUT_SUBELEMENT_KIND_OUTLINE:
     852              :                 {
     853            0 :                     geometry_rectangle_replace( &highlight, layout_feature_get_symbol_box_const( the_feature ) );
     854            0 :                     geometry_rectangle_expand_4dir( &highlight, 2.0 * label_border, 2.0 * label_border );
     855            0 :                     gui_sketch_card_painter_private_draw_rect( this_, &highlight, cr );
     856              :                 }
     857            0 :                 break;
     858              :             }
     859              :         }
     860              :     }
     861              : 
     862            0 :     const uint32_t count_relations = layout_visible_set_get_relationship_count ( layouted_set );
     863            0 :     for ( uint32_t rel_index = 0; rel_index < count_relations; rel_index ++ )
     864              :     {
     865              :         const layout_relationship_t *const the_relationship
     866            0 :             = layout_visible_set_get_relationship_const( layouted_set, rel_index );
     867            0 :         const data_relationship_t *const relationship = layout_relationship_get_data_const( the_relationship );
     868            0 :         const data_id_t relationship_id = data_relationship_get_data_id( relationship );
     869            0 :         if ( data_id_equals( &search_id, &relationship_id ) )
     870              :         {
     871            0 :             switch ( kind )
     872              :             {
     873            0 :                 case LAYOUT_SUBELEMENT_KIND_LABEL:
     874              :                 {
     875            0 :                     geometry_rectangle_replace( &highlight, layout_relationship_get_label_box_const( the_relationship ) );
     876            0 :                     geometry_rectangle_expand_4dir( &highlight, 2.0 * label_border, 2.0 * label_border );
     877            0 :                     gui_sketch_card_painter_private_draw_rect( this_, &highlight, cr );
     878              :                 }
     879            0 :                 break;
     880              : 
     881            0 :                 default:
     882              :                 case LAYOUT_SUBELEMENT_KIND_OUTLINE:
     883              :                 {
     884              :                     const geometry_connector_t *const relationship_shape
     885            0 :                         = layout_relationship_get_shape_const( the_relationship );
     886              :                     {
     887              :                         geometry_rectangle_t segment_src;
     888            0 :                         segment_src = geometry_connector_get_segment_bounds( relationship_shape,
     889              :                                                                              GEOMETRY_CONNECTOR_SEGMENT_SOURCE
     890              :                                                                            );
     891            0 :                         geometry_rectangle_expand_4dir( &segment_src, 2.0 * connector_border, 2.0 * connector_border );
     892            0 :                         gui_sketch_card_painter_private_draw_rect( this_, &segment_src, cr );
     893              :                     }
     894              :                     {
     895              :                         geometry_rectangle_t segment_dst;
     896            0 :                         segment_dst = geometry_connector_get_segment_bounds( relationship_shape,
     897              :                                                                              GEOMETRY_CONNECTOR_SEGMENT_DESTINATION
     898              :                                                                            );
     899            0 :                         geometry_rectangle_expand_4dir( &segment_dst, 2.0 * connector_border, 2.0 * connector_border );
     900            0 :                         gui_sketch_card_painter_private_draw_rect( this_, &segment_dst, cr );
     901              :                     }
     902              :                     {
     903              :                         geometry_rectangle_t segment_main;
     904            0 :                         segment_main = geometry_connector_get_segment_bounds( relationship_shape,
     905              :                                                                               GEOMETRY_CONNECTOR_SEGMENT_MAIN
     906              :                                                                             );
     907            0 :                         geometry_rectangle_expand_4dir( &segment_main, 2.0 * connector_border, 2.0 * connector_border );
     908            0 :                         gui_sketch_card_painter_private_draw_rect( this_, &segment_main, cr );
     909              :                     }
     910              :                 }
     911            0 :                 break;
     912              :             }
     913              :         }
     914              :     }
     915            0 : }
     916              : 
     917            0 : void gui_sketch_card_painter_draw_paper( gui_sketch_card_painter_t *this_,
     918              :                                          gui_tool_t selected_tool,
     919              :                                          const gui_sketch_drag_state_t *drag_state,
     920              :                                          const gui_sketch_card_t *card,
     921              :                                          cairo_t *cr )
     922              : {
     923            0 :     U8_TRACE_BEGIN();
     924            0 :     assert( NULL != drag_state );
     925            0 :     assert( NULL != card );
     926            0 :     assert( NULL != cr );
     927              : 
     928            0 :     if ( gui_sketch_card_is_visible(card) )
     929              :     {
     930            0 :         const bool create_tool = ( selected_tool == GUI_TOOL_CREATE );
     931              : 
     932            0 :         shape_int_rectangle_t bounds = gui_sketch_card_get_bounds( card );
     933            0 :         const int32_t left = shape_int_rectangle_get_left( &bounds );
     934            0 :         const int32_t top = shape_int_rectangle_get_top( &bounds );
     935            0 :         const uint32_t width = shape_int_rectangle_get_width( &bounds );
     936            0 :         const uint32_t height = shape_int_rectangle_get_height( &bounds );
     937              : 
     938              :         /* draw paper */
     939            0 :         if ( create_tool )
     940              :         {
     941              :             static const double GRAY_R = 0.875;
     942              :             static const double GRAY_G = 0.875;
     943              :             static const double GRAY_B = 0.875;
     944              :             static const double GRAY_A = 1.0;
     945            0 :             cairo_set_source_rgba( cr, GRAY_R, GRAY_G, GRAY_B, GRAY_A );
     946              :         }
     947              :         else
     948              :         {
     949              :             static const double WHITE_R = 1.0;
     950              :             static const double WHITE_G = 1.0;
     951              :             static const double WHITE_B = 1.0;
     952              :             static const double WHITE_A = 1.0;
     953            0 :             cairo_set_source_rgba( cr, WHITE_R, WHITE_G, WHITE_B, WHITE_A );
     954              :         }
     955            0 :         cairo_rectangle ( cr, left, top, width, height );
     956            0 :         cairo_fill (cr);
     957              : 
     958            0 :         const layout_visible_set_t *const layout = gui_sketch_card_get_visible_set( card );
     959            0 :         if ( layout_visible_set_is_valid( layout ) && create_tool )
     960              :         {
     961            0 :             const int32_t mouse_x = gui_sketch_drag_state_get_to_x( drag_state );
     962            0 :             const int32_t mouse_y = gui_sketch_drag_state_get_to_y( drag_state );
     963              : 
     964              :             const layout_subelement_id_t subelement_to_highlight
     965            0 :                 = gui_sketch_card_get_element_at_pos( card, mouse_x, mouse_y, !create_tool /* filter_lifelines */ );
     966              : 
     967            0 :             gui_sketch_card_painter_private_draw_element_space( this_, &subelement_to_highlight, layout, cr );
     968              :         }
     969              :     }
     970              : 
     971            0 :     U8_TRACE_END();
     972            0 : }
     973              : 
     974              : 
     975              : /*
     976              : Copyright 2017-2025 Andreas Warnke
     977              : 
     978              : Licensed under the Apache License, Version 2.0 (the "License");
     979              : you may not use this file except in compliance with the License.
     980              : You may obtain a copy of the License at
     981              : 
     982              :     http://www.apache.org/licenses/LICENSE-2.0
     983              : 
     984              : Unless required by applicable law or agreed to in writing, software
     985              : distributed under the License is distributed on an "AS IS" BASIS,
     986              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     987              : See the License for the specific language governing permissions and
     988              : limitations under the License.
     989              : */
        

Generated by: LCOV version 2.0-1