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

Generated by: LCOV version 1.16