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