Line data Source code
1 : /* File: gui_sketch_nav_tree.inl; Copyright and License: see below */ 2 : 3 : #include "u8/u8_log.h" 4 : 5 0 : static inline data_row_id_t gui_sketch_nav_tree_get_root_diagram_id ( const gui_sketch_nav_tree_t *this_ ) 6 : { 7 0 : assert( (*this_).ancestors_count <= GUI_SKETCH_NAV_TREE_CONST_MAX_ANCESTORS ); 8 : data_row_id_t result; 9 : 10 0 : if ( (*this_).ancestors_count == 0 ) 11 : { 12 0 : result = DATA_ROW_ID_VOID; 13 : } 14 : else 15 : { 16 0 : result = data_diagram_get_row_id ( &((*this_).ancestor_diagrams[(*this_).ancestors_count-1]) ); 17 : } 18 : 19 0 : return result; 20 : } 21 : 22 0 : static inline int32_t gui_sketch_nav_tree_get_siblings_highest_order ( const gui_sketch_nav_tree_t *this_ ) 23 : { 24 0 : assert( (*this_).siblings_count <= GUI_SKETCH_NAV_TREE_CONST_MAX_SIBLINGS ); 25 : int32_t result; 26 : 27 0 : if ( (*this_).siblings_count == 0 ) 28 : { 29 0 : result = 0; 30 : } 31 : else 32 : { 33 0 : result = data_diagram_get_list_order ( &((*this_).sibling_diagrams[(*this_).siblings_count-1]) ); 34 : } 35 : 36 0 : return result; 37 : } 38 : 39 0 : static inline int32_t gui_sketch_nav_tree_get_children_highest_order ( const gui_sketch_nav_tree_t *this_ ) 40 : { 41 0 : assert( (*this_).children_count <= GUI_SKETCH_NAV_TREE_CONST_MAX_CHILDREN ); 42 : 43 : int32_t result; 44 : 45 0 : if ( (*this_).children_count == 0 ) 46 : { 47 0 : result = 0; 48 : } 49 : else 50 : { 51 0 : result = data_diagram_get_list_order ( &((*this_).child_diagrams[(*this_).children_count-1]) ); 52 : } 53 : 54 0 : return result; 55 : } 56 : 57 0 : static inline gui_error_t gui_sketch_nav_tree_is_descendant ( const gui_sketch_nav_tree_t *this_, 58 : data_row_id_t probe_ancestor_id, 59 : data_row_id_t probe_descendant_id, 60 : bool *out_is_descendant ) 61 : { 62 0 : assert( (*this_).ancestors_count <= GUI_SKETCH_NAV_TREE_CONST_MAX_ANCESTORS ); 63 0 : assert( (*this_).siblings_count <= GUI_SKETCH_NAV_TREE_CONST_MAX_SIBLINGS ); 64 0 : assert( (*this_).children_count <= GUI_SKETCH_NAV_TREE_CONST_MAX_CHILDREN ); 65 : 66 : gui_error_t result; 67 : 68 : /* search the two ids in the diagram lists */ 69 0 : int_fast32_t probe_anc_in_anc_idx = -1; 70 0 : int_fast32_t probe_anc_in_sib_idx = -1; 71 0 : int_fast32_t probe_anc_in_child_idx = -1; 72 0 : int_fast32_t probe_desc_in_anc_idx = -1; 73 0 : int_fast32_t probe_desc_in_sib_idx = -1; 74 0 : int_fast32_t probe_desc_in_child_idx = -1; 75 : 76 0 : for ( uint_fast32_t anc_idx = 0; anc_idx < (*this_).ancestors_count; anc_idx ++ ) 77 : { 78 0 : if ( probe_ancestor_id == data_diagram_get_row_id ( &((*this_).ancestor_diagrams[anc_idx]) ) ) 79 : { 80 0 : probe_anc_in_anc_idx = anc_idx; 81 : } 82 0 : if ( probe_descendant_id == data_diagram_get_row_id ( &((*this_).ancestor_diagrams[anc_idx]) ) ) 83 : { 84 0 : probe_desc_in_anc_idx = anc_idx; 85 : } 86 : } 87 0 : for ( uint_fast32_t sib_idx = 0; sib_idx < (*this_).siblings_count; sib_idx ++ ) 88 : { 89 0 : if ( probe_ancestor_id == data_diagram_get_row_id ( &((*this_).sibling_diagrams[sib_idx]) ) ) 90 : { 91 0 : probe_anc_in_sib_idx = sib_idx; 92 : } 93 0 : if ( probe_descendant_id == data_diagram_get_row_id ( &((*this_).sibling_diagrams[sib_idx]) ) ) 94 : { 95 0 : probe_desc_in_sib_idx = sib_idx; 96 : } 97 : } 98 0 : for ( uint_fast32_t child_idx = 0; child_idx < (*this_).children_count; child_idx ++ ) 99 : { 100 0 : if ( probe_ancestor_id == data_diagram_get_row_id ( &((*this_).child_diagrams[child_idx]) ) ) 101 : { 102 0 : probe_anc_in_child_idx = child_idx; 103 : } 104 0 : if ( probe_descendant_id == data_diagram_get_row_id ( &((*this_).child_diagrams[child_idx]) ) ) 105 : { 106 0 : probe_desc_in_child_idx = child_idx; 107 : } 108 : } 109 : 110 : /* define the return value */ 111 0 : if (( probe_anc_in_anc_idx == -1 )&&( probe_anc_in_sib_idx == -1 )&&( probe_anc_in_child_idx == -1 )) 112 : { 113 : /* probe_ancestor_id not found */ 114 0 : result = GUI_ERROR_UNKNOWN_OBJECT; 115 0 : *out_is_descendant = false; /* avoid "uninitialzed" warnings */ 116 : } 117 0 : else if (( probe_desc_in_anc_idx == -1 )&&( probe_desc_in_sib_idx == -1 )&&( probe_desc_in_child_idx == -1 )) 118 : { 119 : /* probe_descendant_id not found */ 120 0 : result = GUI_ERROR_UNKNOWN_OBJECT; 121 0 : *out_is_descendant = false; /* avoid "uninitialzed" warnings */ 122 : } 123 : else 124 : { 125 0 : result = GUI_ERROR_NONE; 126 : 127 0 : if ( probe_anc_in_anc_idx != -1 ) 128 : { 129 0 : if ( probe_desc_in_anc_idx != -1 ) 130 : { 131 0 : *out_is_descendant = ( probe_anc_in_anc_idx > probe_desc_in_anc_idx ); /* root is last in list */ 132 : } 133 : else 134 : { 135 0 : assert( ( probe_desc_in_sib_idx != -1 )||( probe_desc_in_child_idx != -1 ) ); 136 0 : *out_is_descendant = true; 137 : } 138 : } 139 0 : else if ( probe_anc_in_sib_idx != -1 ) 140 : { 141 0 : if ( probe_desc_in_child_idx != -1 ) 142 : { 143 0 : *out_is_descendant = ( probe_anc_in_sib_idx == (*this_).siblings_self_index ); 144 : } 145 : else 146 : { 147 0 : assert( ( probe_desc_in_anc_idx != -1 )||( probe_desc_in_sib_idx != -1 ) ); 148 0 : *out_is_descendant = false; /* probe_descendant_id is ancestor or sibling to probe_ancestor_id, not descendant */ 149 : } 150 : } 151 : else 152 : { 153 0 : assert ( probe_anc_in_child_idx != -1 ); 154 0 : *out_is_descendant = false; /* probe_descendant_id is sibling or ancestor to probe_ancestor_id, not descendant */ 155 : } 156 : } 157 : 158 0 : return result; 159 : } 160 : 161 : static inline shape_int_rectangle_t gui_sketch_nav_tree_get_bounds( const gui_sketch_nav_tree_t *this_ ) 162 : { 163 : return (*this_).bounds; 164 : } 165 : 166 4 : static inline void gui_sketch_nav_tree_set_bounds( gui_sketch_nav_tree_t *this_, shape_int_rectangle_t bounds ) 167 : { 168 4 : (*this_).bounds = bounds; 169 4 : } 170 : 171 0 : static inline bool gui_sketch_nav_tree_is_visible( const gui_sketch_nav_tree_t *this_ ) 172 : { 173 0 : return (*this_).visible; 174 : } 175 : 176 0 : static inline void gui_sketch_nav_tree_set_visible( gui_sketch_nav_tree_t *this_, bool visible ) 177 : { 178 0 : (*this_).visible = visible; 179 0 : } 180 : 181 0 : static inline const data_diagram_t *gui_sketch_nav_tree_get_diagram_ptr ( const gui_sketch_nav_tree_t *this_ ) 182 : { 183 0 : return &((*this_).ancestor_diagrams[0]); 184 : } 185 : 186 17 : static inline void gui_sketch_nav_tree_get_button_at_pos ( const gui_sketch_nav_tree_t *this_, 187 : int32_t x, 188 : int32_t y, 189 : gui_sketch_action_t *out_action_id ) 190 : { 191 17 : assert ( NULL != out_action_id ); 192 : 193 : /* default in case no object found */ 194 : { 195 17 : *out_action_id = GUI_SKETCH_ACTION_NONE; 196 : } 197 : 198 : /* search object */ 199 17 : if ( shape_int_rectangle_contains( &((*this_).bounds), x, y ) ) 200 : { 201 16 : const unsigned int count = (*this_).node_count; 202 16 : assert( count <= GUI_SKETCH_NAV_TREE_CONST_MAX_NODES ); 203 96 : for ( unsigned int idx = 0; idx < count; idx ++ ) 204 : { 205 80 : const pos_nav_tree_node_t *const node = &((*this_).node_pos[idx]); 206 80 : const shape_int_rectangle_t *icon_box = pos_nav_tree_node_get_icon_box_const( node ); 207 80 : const shape_int_rectangle_t *label_box = pos_nav_tree_node_get_label_box_const( node ); 208 : 209 80 : if ( shape_int_rectangle_contains( icon_box, x, y ) || shape_int_rectangle_contains( label_box, x, y ) ) 210 : { 211 15 : const pos_nav_tree_node_type_t node_type = pos_nav_tree_node_get_type( node ); 212 15 : switch( node_type ) 213 : { 214 1 : case POS_NAV_TREE_NODE_TYPE_NEW_ROOT: 215 : { 216 1 : *out_action_id = GUI_SKETCH_ACTION_NEW_ROOT_DIAGRAM; 217 : } 218 1 : break; 219 : 220 2 : case POS_NAV_TREE_NODE_TYPE_NEW_SIBLING: 221 : { 222 2 : *out_action_id = GUI_SKETCH_ACTION_NEW_SIBLING_DIAGRAM; 223 : } 224 2 : break; 225 : 226 3 : case POS_NAV_TREE_NODE_TYPE_NEW_CHILD: 227 : { 228 3 : *out_action_id = GUI_SKETCH_ACTION_NEW_CHILD_DIAGRAM; 229 : } 230 3 : break; 231 : 232 80 : default: 233 : { 234 : } 235 : } 236 : } 237 : } 238 : } 239 17 : } 240 : 241 15 : static inline const pos_nav_tree_node_t *gui_sketch_nav_tree_get_node_pos_const ( const gui_sketch_nav_tree_t *this_, 242 : uint32_t index ) 243 : { 244 15 : assert( index < (*this_).node_count ); 245 15 : return &((*this_).node_pos[index]); 246 : } 247 : 248 19 : static inline uint32_t gui_sketch_nav_tree_get_node_count ( const gui_sketch_nav_tree_t *this_ ) 249 : { 250 19 : assert( (*this_).node_count <= GUI_SKETCH_NAV_TREE_CONST_MAX_NODES ); 251 19 : return (*this_).node_count; 252 : } 253 : 254 : static inline const pos_nav_tree_gap_t *gui_sketch_nav_tree_get_gap_pos_const ( const gui_sketch_nav_tree_t *this_, 255 : uint32_t index ) 256 : { 257 : assert( index < (*this_).gap_count ); 258 : return &((*this_).gap_pos[index]); 259 : } 260 : 261 : static inline uint32_t gui_sketch_nav_tree_get_gap_count ( const gui_sketch_nav_tree_t *this_ ) 262 : { 263 : assert( (*this_).gap_count <= GUI_SKETCH_NAV_TREE_CONST_MAX_GAPS ); 264 : return (*this_).gap_count; 265 : } 266 : 267 : 268 : /* 269 : Copyright 2018-2024 Andreas Warnke 270 : 271 : Licensed under the Apache License, Version 2.0 (the "License"); 272 : you may not use this file except in compliance with the License. 273 : You may obtain a copy of the License at 274 : 275 : http://www.apache.org/licenses/LICENSE-2.0 276 : 277 : Unless required by applicable law or agreed to in writing, software 278 : distributed under the License is distributed on an "AS IS" BASIS, 279 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 280 : See the License for the specific language governing permissions and 281 : limitations under the License. 282 : */