LCOV - code coverage report
Current view: top level - gui/source/sketch - gui_sketch_card_layouter.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.65.6_covts Lines: 0 125 0.0 %
Date: 2025-09-25 21:07:53 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* File: gui_sketch_card_layouter.c; Copyright and License: see below */
       2             : 
       3             : #include "gui_sketch_card_layouter.h"
       4             : #include "sketch/gui_sketch_area.h"
       5             : #include "u8/u8_trace.h"
       6             : #include "u8/u8_log.h"
       7             : 
       8           0 : void gui_sketch_card_layouter_init( gui_sketch_card_layouter_t *this_, shape_int_rectangle_t *bounds )
       9             : {
      10           0 :     U8_TRACE_BEGIN();
      11           0 :     assert( NULL != bounds );
      12             : 
      13           0 :     (*this_).bounds = *bounds;
      14             : 
      15           0 :     U8_TRACE_END();
      16           0 : }
      17             : 
      18           0 : void gui_sketch_card_layouter_destroy( gui_sketch_card_layouter_t *this_ )
      19             : {
      20           0 :     U8_TRACE_BEGIN();
      21             : 
      22           0 :     U8_TRACE_END();
      23           0 : }
      24             : 
      25             : static const uint_fast32_t RATIO_WIDTH = 36;
      26             : static const uint_fast32_t RATIO_HEIGHT = 24;
      27             : static const uint_fast32_t BORDER = 8;
      28             : 
      29           0 : void gui_sketch_card_layouter_layout ( gui_sketch_card_layouter_t *this_,
      30             :                                        gui_tool_t selected_tool,
      31             :                                        gui_sketch_card_t io_cards[],
      32             :                                        uint32_t cards_num,
      33             :                                        const data_small_set_t *card_draw_list,
      34             :                                        cairo_t *cr )
      35             : {
      36           0 :     U8_TRACE_BEGIN();
      37           0 :     assert( NULL != cr );
      38           0 :     assert( NULL != io_cards );
      39           0 :     assert( cards_num <= GUI_SKETCH_AREA_CONST_MAX_CARDS );
      40             : 
      41             :     /* fetch area bounds */
      42           0 :     const uint_fast32_t width = shape_int_rectangle_get_width( &((*this_).bounds) );
      43           0 :     const uint_fast32_t height = shape_int_rectangle_get_height( &((*this_).bounds) );
      44           0 :     const int_fast32_t left = shape_int_rectangle_get_left( &((*this_).bounds) );
      45           0 :     const int_fast32_t top = shape_int_rectangle_get_top( &((*this_).bounds) );
      46           0 :     U8_TRACE_INFO_INT_INT( "width, height", width, height );
      47             : 
      48             :     /* calculate card sizes */
      49             :     uint_fast32_t focus_card_height;
      50             :     uint_fast32_t focus_card_width;
      51             :     {
      52           0 :         const uint_fast32_t focus_card_w_space = (width * 7) / 10;
      53           0 :         const uint_fast32_t focus_card_h_space = (height * 4) / 10;
      54           0 :         if ( (focus_card_w_space * RATIO_HEIGHT) > (focus_card_h_space * RATIO_WIDTH) )
      55             :         {
      56           0 :             focus_card_height = focus_card_h_space;
      57           0 :             focus_card_width = (focus_card_height * RATIO_WIDTH) / RATIO_HEIGHT;
      58             :         }
      59             :         else
      60             :         {
      61           0 :             focus_card_width = focus_card_w_space;
      62           0 :             focus_card_height = (focus_card_width * RATIO_HEIGHT) / RATIO_WIDTH;
      63             :         }
      64             :     }
      65           0 :     const uint_fast32_t parent_card_height = (focus_card_height * 6) / 10;
      66           0 :     const uint_fast32_t parent_card_width = (focus_card_width * 6) / 10;
      67             : 
      68             :     /* layout cards */
      69           0 :     switch( selected_tool )
      70             :     {
      71           0 :         case GUI_TOOL_SEARCH:
      72             :         {
      73             :             shape_int_rectangle_t card_bounds;
      74             : 
      75             :             /* search results */
      76             :             {
      77           0 :                 shape_int_rectangle_init( &card_bounds, left, top, width, height );
      78           0 :                 gui_sketch_card_layouter_private_layout_to_grid( this_,
      79             :                                                                  &card_bounds,
      80             :                                                                  focus_card_height,
      81             :                                                                  io_cards,
      82             :                                                                  cards_num,
      83             :                                                                  cr
      84             :                                                                );
      85             : 
      86             :                 /* hide cards that are not on current visible page */
      87           0 :                 for ( uint_fast32_t idx = 0; idx < cards_num; idx ++ )
      88             :                 {
      89           0 :                     gui_sketch_card_t* current_card = &(io_cards[idx]);
      90           0 :                     const data_id_t diag_id = gui_sketch_card_get_diagram_id( current_card );
      91           0 :                     const bool draw = data_small_set_contains( card_draw_list, diag_id );
      92           0 :                     gui_sketch_card_set_visible( current_card, draw );
      93             :                 }
      94             :             }
      95             :         }
      96           0 :         break;
      97             : 
      98           0 :         case GUI_TOOL_NAVIGATE:
      99             :         {
     100             :             shape_int_rectangle_t card_bounds;
     101             : 
     102             :             /* self */
     103           0 :             assert(cards_num > GUI_SKETCH_AREA_CONST_FOCUSED_CARD);
     104             :             {
     105           0 :                 const int_fast32_t self_left = (left + width) - focus_card_width - BORDER;
     106           0 :                 const int_fast32_t self_top = top + BORDER + (parent_card_height/2);
     107           0 :                 shape_int_rectangle_init( &card_bounds, self_left, self_top, focus_card_width, focus_card_height );
     108           0 :                 shape_int_rectangle_trace( &card_bounds );
     109           0 :                 gui_sketch_card_set_bounds( &(io_cards[GUI_SKETCH_AREA_CONST_FOCUSED_CARD]), card_bounds );
     110           0 :                 const bool valid_card = gui_sketch_card_is_valid( &(io_cards[GUI_SKETCH_AREA_CONST_FOCUSED_CARD]) );
     111           0 :                 gui_sketch_card_do_layout( &(io_cards[GUI_SKETCH_AREA_CONST_FOCUSED_CARD]), cr );
     112           0 :                 gui_sketch_card_set_visible( &(io_cards[GUI_SKETCH_AREA_CONST_FOCUSED_CARD]), valid_card );
     113             :             }
     114             : 
     115             :             /* parent */
     116           0 :             assert(cards_num > GUI_SKETCH_AREA_CONST_PARENT_CARD);
     117             :             {
     118           0 :                 const int_fast32_t parent_left = left + BORDER;
     119           0 :                 const int_fast32_t parent_top = top + BORDER;
     120           0 :                 shape_int_rectangle_init( &card_bounds, parent_left, parent_top, parent_card_width, parent_card_height );
     121           0 :                 shape_int_rectangle_trace( &card_bounds );
     122           0 :                 gui_sketch_card_set_bounds( &(io_cards[GUI_SKETCH_AREA_CONST_PARENT_CARD]), card_bounds );
     123           0 :                 const bool valid_parent = gui_sketch_card_is_valid( &(io_cards[GUI_SKETCH_AREA_CONST_PARENT_CARD]) );
     124           0 :                 gui_sketch_card_do_layout( &(io_cards[GUI_SKETCH_AREA_CONST_PARENT_CARD]), cr );
     125           0 :                 gui_sketch_card_set_visible( &(io_cards[GUI_SKETCH_AREA_CONST_PARENT_CARD]), valid_parent );
     126             :             }
     127             : 
     128             :             /* children */
     129           0 :             assert(cards_num >= GUI_SKETCH_AREA_CONST_FIRST_CHILD_CARD);
     130             :             {
     131           0 :                 const int_fast32_t children_top = top + focus_card_height + (parent_card_height/2) + 2*BORDER;
     132           0 :                 const uint_fast32_t children_height = (height > (children_top-top)) ? (height - (children_top-top)) : 0;
     133           0 :                 shape_int_rectangle_init( &card_bounds, left, children_top, width, children_height );
     134           0 :                 gui_sketch_card_layouter_private_layout_to_grid( this_,
     135             :                                                                  &card_bounds,
     136             :                                                                  parent_card_height,
     137             :                                                                  &(io_cards[GUI_SKETCH_AREA_CONST_FIRST_CHILD_CARD]),
     138           0 :                                                                  cards_num-GUI_SKETCH_AREA_CONST_FIRST_CHILD_CARD,
     139             :                                                                  cr
     140             :                                                                );
     141             :             }
     142             :         }
     143           0 :         break;
     144             : 
     145           0 :         case GUI_TOOL_EDIT:  /* or */
     146             :         case GUI_TOOL_CREATE:
     147             :         {
     148             :             shape_int_rectangle_t card_bounds;
     149             : 
     150           0 :             assert(cards_num == GUI_SKETCH_AREA_CONST_FOCUSED_CARD+1);
     151             :             {
     152           0 :                 card_bounds = (*this_).bounds;
     153           0 :                 shape_int_rectangle_shrink_by_border( &card_bounds, BORDER );
     154           0 :                 shape_int_rectangle_shrink_to_ratio( &card_bounds, RATIO_WIDTH, RATIO_HEIGHT, SHAPE_H_ALIGN_CENTER, SHAPE_V_ALIGN_CENTER );
     155           0 :                 shape_int_rectangle_trace( &card_bounds );
     156           0 :                 gui_sketch_card_set_bounds( &(io_cards[GUI_SKETCH_AREA_CONST_FOCUSED_CARD]), card_bounds );
     157           0 :                 const bool valid_card = gui_sketch_card_is_valid( &(io_cards[GUI_SKETCH_AREA_CONST_FOCUSED_CARD]) );
     158           0 :                 gui_sketch_card_do_layout( &(io_cards[GUI_SKETCH_AREA_CONST_FOCUSED_CARD]), cr );
     159           0 :                 gui_sketch_card_set_visible( &(io_cards[GUI_SKETCH_AREA_CONST_FOCUSED_CARD]), valid_card );
     160             :             }
     161             :         }
     162           0 :         break;
     163             : 
     164           0 :         default:
     165             :         {
     166           0 :             assert(false);
     167             :         }
     168             :         break;
     169             :     }
     170             : 
     171           0 :     U8_TRACE_END();
     172           0 : }
     173             : 
     174           0 : void gui_sketch_card_layouter_private_layout_to_grid ( gui_sketch_card_layouter_t *this_,
     175             :                                                        shape_int_rectangle_t *bounds,
     176             :                                                        uint_fast32_t max_card_height,
     177             :                                                        gui_sketch_card_t io_cards[],
     178             :                                                        uint_fast32_t cards_num,
     179             :                                                        cairo_t *cr )
     180             : {
     181           0 :     U8_TRACE_BEGIN();
     182           0 :     assert( NULL != cr );
     183           0 :     assert( NULL != bounds );
     184           0 :     assert( NULL != io_cards );
     185           0 :     assert( cards_num <= GUI_SKETCH_AREA_CONST_MAX_CARDS );
     186             : 
     187             :     /* fetch outer bounds */
     188           0 :     const uint_fast32_t width = shape_int_rectangle_get_width( bounds );
     189           0 :     const uint_fast32_t height = shape_int_rectangle_get_height( bounds );
     190           0 :     const int_fast32_t left = shape_int_rectangle_get_left( bounds );
     191           0 :     const int_fast32_t top = shape_int_rectangle_get_top( bounds );
     192             : 
     193             :     /* determine number of columns and rows for layout */
     194           0 :     uint_fast32_t cols = 0;  /* initial value, overwritten if a card exists */
     195           0 :     uint_fast32_t rows = 0;  /* initial value, overwritten if a card exists */
     196           0 :     uint_fast32_t card_width = 0;  /* initial value, overwritten if a card exists */
     197           0 :     uint_fast32_t card_height = 0;  /* initial value, overwritten if a card exists */
     198             :     {
     199           0 :         for ( uint_fast32_t probe_rows = 1; probe_rows <= cards_num; probe_rows ++ )
     200             :         {
     201           0 :             assert( probe_rows > 0 );
     202           0 :             uint_fast32_t probe_cols = (cards_num + probe_rows - 1) / probe_rows;
     203             :             shape_int_rectangle_t probe_bounds;
     204           0 :             shape_int_rectangle_init( &probe_bounds, 0, 0, ((width*2)/((probe_cols*2)+1)), height/probe_rows );
     205           0 :             shape_int_rectangle_shrink_by_border( &probe_bounds, BORDER );
     206           0 :             shape_int_rectangle_shrink_to_ratio( &probe_bounds, RATIO_WIDTH, RATIO_HEIGHT, SHAPE_H_ALIGN_LEFT, SHAPE_V_ALIGN_TOP );
     207           0 :             if ( card_height <= shape_int_rectangle_get_height( &probe_bounds ) )
     208             :             {
     209           0 :                 cols = probe_cols;
     210           0 :                 rows = probe_rows;
     211           0 :                 card_width = shape_int_rectangle_get_width( &probe_bounds );
     212           0 :                 card_height = shape_int_rectangle_get_height( &probe_bounds );
     213             :             }
     214             :         }
     215             :     }
     216             : 
     217             :     /* children shall not be bigger than the parent */
     218           0 :     if ( card_height > max_card_height )
     219             :     {
     220           0 :         assert( card_height > 0 );
     221           0 :         card_width = ( card_width * max_card_height ) / card_height;
     222           0 :         card_height = max_card_height;
     223             :     }
     224             : 
     225             :     /* layout cards to grid */
     226           0 :     for ( uint_fast32_t y = 0; y < rows; y ++ )
     227             :     {
     228           0 :         for ( uint_fast32_t x = 0; x < cols; x ++ )
     229             :         {
     230           0 :             uint_fast32_t card_idx = (y * cols) + x;
     231           0 :             if ( card_idx < cards_num )
     232             :             {
     233           0 :                 assert( rows > 0 );
     234           0 :                 const uint_fast32_t left_grid_gap = (cols==1) ? 0 : ((card_width*y)/(2*rows));  /* this gap is beautification only */
     235           0 :                 const int_fast32_t rel_left = left_grid_gap + BORDER + (x * ( card_width + BORDER + BORDER ));
     236           0 :                 const int_fast32_t rel_top = BORDER + (y * ( card_height + BORDER + BORDER ));
     237             :                 shape_int_rectangle_t card_bounds;
     238           0 :                 shape_int_rectangle_init( &card_bounds, left+rel_left, top+rel_top, card_width, card_height );
     239           0 :                 shape_int_rectangle_trace( &card_bounds );
     240           0 :                 gui_sketch_card_set_bounds( &(io_cards[card_idx]), card_bounds );
     241           0 :                 const bool valid_card = gui_sketch_card_is_valid( &(io_cards[card_idx]) );
     242           0 :                 gui_sketch_card_do_layout( &(io_cards[card_idx]), cr );
     243           0 :                 gui_sketch_card_set_visible( &(io_cards[card_idx]), valid_card );
     244             :             }
     245             :         }
     246             :     }
     247             : 
     248           0 :     U8_TRACE_END();
     249           0 : }
     250             : 
     251             : 
     252             : /*
     253             : Copyright 2019-2025 Andreas Warnke
     254             : 
     255             : Licensed under the Apache License, Version 2.0 (the "License");
     256             : you may not use this file except in compliance with the License.
     257             : You may obtain a copy of the License at
     258             : 
     259             :     http://www.apache.org/licenses/LICENSE-2.0
     260             : 
     261             : Unless required by applicable law or agreed to in writing, software
     262             : distributed under the License is distributed on an "AS IS" BASIS,
     263             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     264             : See the License for the specific language governing permissions and
     265             : limitations under the License.
     266             : */
     267             : 

Generated by: LCOV version 1.16