LCOV - code coverage report
Current view: top level - gui/source/sketch - gui_sketch_result_list.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.57.0_covts Lines: 0 147 0.0 %
Date: 2024-04-07 11:14:42 Functions: 0 6 0.0 %

          Line data    Source code
       1             : /* File: gui_sketch_result_list.c; Copyright and License: see below */
       2             : 
       3             : #include "sketch/gui_sketch_result_list.h"
       4             : #include "geometry/geometry_rectangle.h"
       5             : #include "utf8stringbuf/utf8stringbuf.h"
       6             : #include "gui_sketch_int_compare.h"
       7             : #include "u8/u8_trace.h"
       8             : #include "u8/u8_log.h"
       9             : #include <gdk/gdk.h>
      10             : 
      11             : static const int GUI_SKETCH_RESULT_LIST_PANGO_AUTO_DETECT_LENGTH = -1;  /*!< pango automatically determines the string length */
      12             : static const int GUI_SKETCH_RESULT_LIST_PANGO_UNLIMITED_WIDTH = -1;
      13             : static const int OBJ_GAP = 4;
      14             : 
      15           0 : void gui_sketch_result_list_init( gui_sketch_result_list_t *this_,
      16             :                                   gui_resources_t *resources,
      17             :                                   gui_sketch_texture_t *texture_downloader )
      18             : {
      19           0 :     U8_TRACE_BEGIN();
      20           0 :     assert( resources != NULL );
      21           0 :     assert( texture_downloader != NULL );
      22             : 
      23           0 :     DATA_SEARCH_RESULT_LIST_INIT( &((*this_).result_list), (*this_).result_list_buf );
      24             : 
      25           0 :     (*this_).visible = false;
      26           0 :     shape_int_rectangle_init( &((*this_).bounds), 0, 0, 0, 0 );
      27             : 
      28           0 :     (*this_).element_count = 0;
      29             : 
      30           0 :     gui_sketch_style_init( &((*this_).sketch_style) );
      31           0 :     gui_sketch_marker_init( &((*this_).sketch_marker), true );
      32           0 :     (*this_).resources = resources;
      33           0 :     gui_type_resource_list_init( &((*this_).selector), resources );
      34           0 :     (*this_).texture_downloader = texture_downloader;
      35             : 
      36           0 :     U8_TRACE_END();
      37           0 : }
      38             : 
      39           0 : void gui_sketch_result_list_destroy( gui_sketch_result_list_t *this_ )
      40             : {
      41           0 :     U8_TRACE_BEGIN();
      42             : 
      43           0 :     (*this_).texture_downloader = NULL;
      44           0 :     gui_type_resource_list_destroy( &((*this_).selector) );
      45           0 :     (*this_).resources = NULL;
      46           0 :     gui_sketch_marker_destroy( &((*this_).sketch_marker) );
      47           0 :     gui_sketch_style_destroy( &((*this_).sketch_style) );
      48             : 
      49           0 :     gui_sketch_result_list_invalidate_data( this_ );
      50             : 
      51           0 :     shape_int_rectangle_destroy( &((*this_).bounds) );
      52             : 
      53           0 :     U8_TRACE_END();
      54           0 : }
      55             : 
      56           0 : void gui_sketch_result_list_do_layout( gui_sketch_result_list_t *this_, cairo_t *cr )
      57             : {
      58           0 :     U8_TRACE_BEGIN();
      59             : 
      60             :     /* create the font_layout */
      61             :     PangoLayout *font_layout;
      62             :     {
      63           0 :         font_layout = pango_cairo_create_layout (cr);
      64             :         const PangoFontDescription *const std_font
      65           0 :             = gui_sketch_style_get_standard_font_description( &((*this_).sketch_style ) );
      66           0 :         pango_layout_set_font_description( font_layout, std_font );
      67             :     }
      68             : 
      69           0 :     int32_t y_pos = shape_int_rectangle_get_top( &((*this_).bounds) );
      70             : 
      71           0 :     const unsigned int count = data_search_result_list_get_length( &((*this_).result_list) );
      72           0 :     assert( count <= GUI_SKETCH_RESULT_LIST_MAX_ELEMENTS );
      73           0 :     (*this_).element_count = count;
      74           0 :     for ( unsigned int idx = 0; idx < count; idx ++ )
      75             :     {
      76           0 :         const data_search_result_t *result = data_search_result_list_get_const( &((*this_).result_list), idx );
      77           0 :         pos_search_result_init( &((*this_).element_pos[idx]), result );
      78           0 :         gui_sketch_result_list_private_layout_element( this_, &((*this_).element_pos[idx]), &y_pos, font_layout );
      79             :     }
      80             : 
      81             :     /* release the font_layout */
      82           0 :     g_object_unref(font_layout);
      83             : 
      84           0 :     U8_TRACE_END();
      85           0 : }
      86             : 
      87           0 : void gui_sketch_result_list_private_layout_element ( gui_sketch_result_list_t *this_,
      88             :                                                      pos_search_result_t *element,
      89             :                                                      int32_t *io_y_pos,
      90             :                                                      PangoLayout *font_layout )
      91             : {
      92           0 :     U8_TRACE_BEGIN();
      93           0 :     assert( NULL != element );
      94           0 :     assert( NULL != io_y_pos );
      95           0 :     assert( NULL != font_layout );
      96             : 
      97           0 :     int_fast32_t left = shape_int_rectangle_get_left( &((*this_).bounds) );
      98           0 :     uint_fast32_t width = shape_int_rectangle_get_width( &((*this_).bounds) );
      99           0 :     const data_search_result_t *result = pos_search_result_get_data_const( element );
     100             : 
     101             :     /* determine icon dimensions */
     102             :     {
     103           0 :         const data_table_t result_table = data_search_result_get_match_table( result );
     104           0 :         const int result_type = data_search_result_get_match_type( result );
     105             :         gui_type_resource_t *const type_data
     106           0 :             = gui_type_resource_list_get_type ( &((*this_).selector), result_table, result_type );
     107           0 :         GdkTexture *const icon = gui_type_resource_get_icon( type_data );
     108           0 :         const double icon_width = gdk_texture_get_width( icon );
     109           0 :         const double icon_height = gdk_texture_get_height( icon );
     110             : 
     111           0 :         const shape_int_rectangle_t new_icon_box = (shape_int_rectangle_t) {
     112           0 :             .left=left+OBJ_GAP,
     113           0 :             .top=(*io_y_pos)+OBJ_GAP,
     114           0 :             .width=icon_width+0.999,
     115           0 :             .height=icon_height+0.999 };
     116           0 :         pos_search_result_set_icon_box( element, &new_icon_box );
     117             :     }
     118             : 
     119             :     /* determine label dimensions */
     120           0 :     const shape_int_rectangle_t *const icon_box = pos_search_result_get_icon_box_const( element );
     121             :     {
     122           0 :         int_fast32_t proposed_pango_width = width - shape_int_rectangle_get_width(icon_box) - (4*OBJ_GAP);
     123           0 :         pango_layout_set_text( font_layout,
     124             :                                 data_search_result_get_match_name_const( result ),
     125             :                                 GUI_SKETCH_RESULT_LIST_PANGO_AUTO_DETECT_LENGTH
     126             :                                 );
     127           0 :         pango_layout_set_width(font_layout, proposed_pango_width * PANGO_SCALE );
     128             :         int text_width;
     129             :         int text_height;
     130           0 :         pango_layout_get_pixel_size(font_layout, &text_width, &text_height);
     131             : 
     132           0 :         int_fast32_t x_pos = shape_int_rectangle_get_right(icon_box);
     133             : 
     134           0 :         const shape_int_rectangle_t new_label_box = (shape_int_rectangle_t) {
     135           0 :             .left=x_pos+OBJ_GAP,
     136           0 :             .top=(*io_y_pos)+OBJ_GAP,
     137             :             .width=text_width,
     138             :             .height=text_height };
     139           0 :         pos_search_result_set_label_box( element, &new_label_box );
     140             :     }
     141             : 
     142           0 :     const shape_int_rectangle_t *const label_box = pos_search_result_get_label_box_const( element );
     143             :     *io_y_pos
     144           0 :         = gui_sketch_int_compare_max_i32( shape_int_rectangle_get_bottom(icon_box), shape_int_rectangle_get_bottom(label_box) )
     145           0 :         + OBJ_GAP;
     146             : 
     147           0 :     U8_TRACE_END();
     148           0 : }
     149             : 
     150             : static const double GREY_R = 0.8;
     151             : static const double GREY_G = 0.8;
     152             : static const double GREY_B = 0.8;
     153             : static const double GREY_A = 1.0;
     154             : 
     155           0 : void gui_sketch_result_list_draw ( gui_sketch_result_list_t *this_, const gui_marked_set_t *marker, cairo_t *cr )
     156             : {
     157           0 :     U8_TRACE_BEGIN();
     158           0 :     assert( NULL != marker );
     159           0 :     assert( NULL != cr );
     160             : 
     161           0 :     if ( (*this_).visible )
     162             :     {
     163           0 :         PangoLayout *font_layout = pango_cairo_create_layout (cr);
     164             :         {
     165             :             const PangoFontDescription *const std_font
     166           0 :                 = gui_sketch_style_get_standard_font_description( &((*this_).sketch_style ) );
     167           0 :             pango_layout_set_font_description ( font_layout, std_font );
     168             :         }
     169             : 
     170             :         /* draw background */
     171             :         {
     172           0 :             const int_fast32_t left = shape_int_rectangle_get_left( &((*this_).bounds) );
     173           0 :             const int_fast32_t top = shape_int_rectangle_get_top( &((*this_).bounds) );
     174           0 :             const uint_fast32_t width = shape_int_rectangle_get_width( &((*this_).bounds) );
     175           0 :             const uint_fast32_t height = shape_int_rectangle_get_height( &((*this_).bounds) );
     176             : 
     177           0 :             cairo_set_source_rgba( cr, GREY_R, GREY_G, GREY_B, GREY_A );
     178           0 :             cairo_rectangle ( cr, left, top, width, height );
     179           0 :             cairo_fill (cr);
     180             :         }
     181             : 
     182             :         /* draw icons and text */
     183           0 :         const unsigned int count = (*this_).element_count;
     184           0 :         assert( count <= GUI_SKETCH_RESULT_LIST_MAX_ELEMENTS );
     185           0 :         if ( count == 0 )
     186             :         {
     187           0 :             const int_fast32_t left = shape_int_rectangle_get_left( &((*this_).bounds) );
     188           0 :             const int_fast32_t top = shape_int_rectangle_get_top( &((*this_).bounds) );
     189           0 :             GdkTexture *undef_icon = gui_resources_get_type_undef( (*this_).resources );
     190           0 :             double icon_width = gdk_texture_get_width ( undef_icon );
     191             : 
     192             :             /* draw text first, use the above set color and font */
     193           0 :             const GdkRGBA std_color = gui_sketch_style_get_standard_color( &((*this_).sketch_style) );
     194           0 :             cairo_set_source_rgba( cr, std_color.red, std_color.green, std_color.blue, std_color.alpha );
     195           0 :             cairo_move_to( cr, left+OBJ_GAP+icon_width, top+OBJ_GAP );
     196           0 :             pango_layout_set_text( font_layout, "no results", GUI_SKETCH_RESULT_LIST_PANGO_AUTO_DETECT_LENGTH );
     197           0 :             pango_layout_set_width(font_layout, GUI_SKETCH_RESULT_LIST_PANGO_UNLIMITED_WIDTH );
     198           0 :             pango_cairo_show_layout( cr, font_layout );
     199             : 
     200             :             /* draw the icon */
     201           0 :             const int x = left+OBJ_GAP;
     202           0 :             const int y = top+OBJ_GAP;
     203           0 :             gui_sketch_texture_draw( (*this_).texture_downloader, undef_icon, x, y, cr );
     204             :         }
     205             :         else
     206             :         {
     207           0 :             for ( unsigned int idx = 0; idx < count; idx ++ )
     208             :             {
     209           0 :                 const pos_search_result_t *const element = &((*this_).element_pos[idx]);
     210           0 :                 gui_sketch_result_list_private_draw_element( this_, element, marker, font_layout, cr );
     211             :             }
     212             :         }
     213             : 
     214           0 :         g_object_unref(font_layout);
     215             :     }
     216             : 
     217           0 :     U8_TRACE_END();
     218           0 : }
     219             : 
     220           0 : void gui_sketch_result_list_private_draw_element( gui_sketch_result_list_t *this_,
     221             :                                                   const pos_search_result_t *element,
     222             :                                                   const gui_marked_set_t *marker,
     223             :                                                   PangoLayout *font_layout,
     224             :                                                   cairo_t *cr )
     225             : {
     226           0 :     U8_TRACE_BEGIN();
     227           0 :     assert( NULL != cr );
     228           0 :     assert( NULL != element );
     229           0 :     assert( NULL != marker );
     230           0 :     assert( NULL != font_layout );
     231             : 
     232           0 :     const data_search_result_t *const result = pos_search_result_get_data_const( element );
     233             : 
     234             :     /* draw marker and set color */
     235             :     {
     236             :         shape_int_rectangle_t destination_rect;
     237           0 :         shape_int_rectangle_init_by_bounds( &destination_rect,
     238             :                                             pos_search_result_get_icon_box_const(element),
     239             :                                             pos_search_result_get_label_box_const(element)
     240             :                                           );
     241             : 
     242           0 :         const data_id_t highlighted = gui_marked_set_get_highlighted( marker );
     243           0 :         gui_sketch_marker_prepare_draw( &((*this_).sketch_marker),
     244             :                                         data_search_result_get_match_id( result ),
     245             :                                         marker,
     246             :                                         destination_rect,
     247             :                                         cr
     248             :                                       );
     249           0 :         if ( data_id_equals( &highlighted, data_search_result_get_diagram_id_const( result ) ) )
     250             :         {
     251           0 :             const GdkRGBA high_color = gui_sketch_style_get_highlight_color( &((*this_).sketch_style) );
     252           0 :             cairo_set_source_rgba( cr, high_color.red, high_color.green, high_color.blue, high_color.alpha );
     253             :         }
     254             : 
     255           0 :         shape_int_rectangle_destroy( &destination_rect );
     256             :     }
     257             : 
     258             :     /* draw text first, use the above set color and font */
     259             :     {
     260             :         /* what to draw */
     261           0 :         const char *const label = data_search_result_get_match_name_const( result );
     262             : 
     263             :         /* where to draw to */
     264             :         const shape_int_rectangle_t *const label_box
     265           0 :             = pos_search_result_get_label_box_const( element );
     266             : 
     267             :         /* do draw */
     268           0 :         cairo_move_to( cr, shape_int_rectangle_get_left(label_box), shape_int_rectangle_get_top(label_box) );
     269           0 :         pango_layout_set_text( font_layout, label, GUI_SKETCH_RESULT_LIST_PANGO_AUTO_DETECT_LENGTH );
     270           0 :         const unsigned int text_width
     271           0 :             = shape_int_rectangle_get_width(label_box)
     272           0 :             +(2.0*OBJ_GAP);  /* add gap to avoid line breaks by rounding errors and whitespace character widths */
     273           0 :         pango_layout_set_width(font_layout, text_width * PANGO_SCALE );
     274           0 :         pango_cairo_show_layout( cr, font_layout );
     275             :     }
     276             : 
     277             :     /* draw the icon */
     278             :     {
     279             :         /* what to draw */
     280           0 :         const data_table_t result_table = data_search_result_get_match_table( result );
     281           0 :         const int result_type = data_search_result_get_match_type( result );
     282             :         gui_type_resource_t *const type_data
     283           0 :             = gui_type_resource_list_get_type ( &((*this_).selector), result_table, result_type );
     284           0 :         GdkTexture *const icon = gui_type_resource_get_icon( type_data );
     285             : 
     286             :         /* where to draw to */
     287             :         const shape_int_rectangle_t *const icon_box
     288           0 :             = pos_search_result_get_icon_box_const( element );
     289           0 :         const int x = shape_int_rectangle_get_left(icon_box);
     290           0 :         const int y = shape_int_rectangle_get_top(icon_box);
     291             :         /* double icon_width = gdk_texture_get_width ( icon ); */
     292             :         /* double icon_height = gdk_texture_get_width ( icon ); */
     293             : 
     294             :         /* do draw */
     295           0 :         gui_sketch_texture_draw( (*this_).texture_downloader, icon, x, y, cr );
     296             :     }
     297             : 
     298           0 :     U8_TRACE_END();
     299           0 : }
     300             : 
     301             : 
     302             : /*
     303             : Copyright 2018-2024 Andreas Warnke
     304             : 
     305             : Licensed under the Apache License, Version 2.0 (the "License");
     306             : you may not use this file except in compliance with the License.
     307             : You may obtain a copy of the License at
     308             : 
     309             :     http://www.apache.org/licenses/LICENSE-2.0
     310             : 
     311             : Unless required by applicable law or agreed to in writing, software
     312             : distributed under the License is distributed on an "AS IS" BASIS,
     313             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     314             : See the License for the specific language governing permissions and
     315             : limitations under the License.
     316             : */

Generated by: LCOV version 1.16