Line data Source code
1 : /* File: gui_sketch_background.c; Copyright and License: see below */
2 :
3 : #include "sketch/gui_sketch_background.h"
4 : #include "meta/meta_info.h"
5 : #include "u8/u8_trace.h"
6 : #include <stdint.h>
7 : #include "gui_gtk.h"
8 : #include <assert.h>
9 :
10 : #if 0
11 : /* to convert the source file from e.g. char to int, you may uncomment this here: */
12 : void gui_sketch_background_private_write_as_ints( gui_sketch_background_t *this_ )
13 : {
14 : fprintf(stdout,"%s","\n ");
15 : cairo_surface_t *bg_img = gui_resources_get_sketch_background( (*this_).resources );
16 : int icon_width = cairo_image_surface_get_width( bg_img );
17 : int icon_height = cairo_image_surface_get_height( bg_img );
18 : unsigned char *data = cairo_image_surface_get_data( bg_img );
19 : for ( int y = 0; y < icon_height; y++ )
20 : {
21 : for ( int x = 0; x < icon_width; x++ )
22 : {
23 : guchar b = data[(4*(x+(y*icon_width)))+0];
24 : guchar g = data[(4*(x+(y*icon_width)))+1];
25 : guchar r = data[(4*(x+(y*icon_width)))+2];
26 : guchar a = data[(4*(x+(y*icon_width)))+3];
27 : fprintf(stdout,"O3R(%3d,%3d,%3d,%3d), ", r, g, b, a);
28 : if ( (x & 7) == 7 )
29 : {
30 : fprintf(stdout,"%s","\n ");
31 : }
32 : }
33 : }
34 : }
35 : #endif
36 :
37 0 : void gui_sketch_background_init( gui_sketch_background_t *this_,
38 : const gui_resources_t *resources,
39 : gui_sketch_texture_t *texture_downloader )
40 : {
41 0 : U8_TRACE_BEGIN();
42 0 : assert( resources != NULL );
43 0 : assert( texture_downloader != NULL );
44 :
45 0 : shape_int_rectangle_init( &((*this_).card_bounds), 0, 0, 0, 0 );
46 0 : shape_int_rectangle_init( &((*this_).label_bounds), 0, 0, 0, 0 );
47 0 : (*this_).resources = resources;
48 0 : (*this_).texture_downloader = texture_downloader;
49 : #if 0
50 : gui_sketch_background_private_write_as_ints( this_ );
51 : #endif
52 :
53 0 : U8_TRACE_END();
54 0 : }
55 :
56 0 : void gui_sketch_background_destroy( gui_sketch_background_t *this_ )
57 : {
58 0 : U8_TRACE_BEGIN();
59 :
60 0 : shape_int_rectangle_destroy( &((*this_).card_bounds) );
61 0 : shape_int_rectangle_destroy( &((*this_).label_bounds) );
62 0 : (*this_).resources = NULL;
63 0 : (*this_).texture_downloader = NULL;
64 :
65 0 : U8_TRACE_END();
66 0 : }
67 :
68 : static const double BLACK_R = 0.0;
69 : static const double BLACK_G = 0.0;
70 : static const double BLACK_B = 0.0;
71 : static const double BLACK_A = 1.0;
72 : static const double DARK_R = 0.375;
73 : static const double DARK_G = 0.375;
74 : static const double DARK_B = 0.375;
75 : static const double DARK_A = 1.0;
76 : static const double GREY_R = 0.75;
77 : static const double GREY_G = 0.75;
78 : static const double GREY_B = 0.75;
79 : static const double GREY_A = 1.0;
80 : static const double ORANGE_R = 1.0;
81 : static const double ORANGE_G = 0.75;
82 : static const double ORANGE_B = 0.5;
83 : static const double ORANGE_A = 1.0;
84 : static const double LIGHT_R = 0.875;
85 : static const double LIGHT_G = 0.875;
86 : static const double LIGHT_B = 0.875;
87 : static const double LIGHT_A = 1.0;
88 : static const double BORDER = 8; /* border between text/icons and ground rectangle */
89 :
90 0 : void gui_sketch_background_draw_introduction( gui_sketch_background_t *this_,
91 : cairo_t *cr )
92 : {
93 0 : U8_TRACE_BEGIN();
94 0 : assert( NULL != cr );
95 :
96 0 : const int32_t left = shape_int_rectangle_get_left( &((*this_).card_bounds) );
97 0 : const int32_t top = shape_int_rectangle_get_top( &((*this_).card_bounds) );
98 0 : const uint32_t width = shape_int_rectangle_get_width( &((*this_).card_bounds) );
99 0 : const uint32_t height = shape_int_rectangle_get_height( &((*this_).card_bounds) );
100 :
101 : int32_t text_area_start;
102 :
103 : /* if there is enough space, draw a nice picture bar on the left side */
104 0 : if ( width > 192 )
105 : {
106 0 : cairo_surface_t *bg_img = gui_resources_get_sketch_background( (*this_).resources );
107 0 : int icon_width = cairo_image_surface_get_width( bg_img );
108 0 : int icon_height = cairo_image_surface_get_height( bg_img );
109 0 : const unsigned int tiles = (height+(icon_height-1))/icon_height;
110 0 : for ( unsigned int tile = 0; tile < tiles; tile ++ )
111 : {
112 0 : cairo_set_source_surface( cr, bg_img, left, top + ( tile * icon_height ) );
113 0 : cairo_rectangle ( cr, left, top + ( tile * icon_height ), icon_width, icon_height );
114 0 : cairo_fill (cr);
115 : }
116 0 : text_area_start = left+icon_width;
117 : }
118 : else
119 : {
120 0 : text_area_start = left;
121 : }
122 :
123 0 : cairo_set_source_rgba( cr, GREY_R, GREY_G, GREY_B, GREY_A );
124 0 : cairo_rectangle ( cr, text_area_start, top, width-text_area_start, height );
125 0 : cairo_fill (cr);
126 :
127 0 : const int TAB_ROW0_Y = 48;
128 0 : const int TAB_ROW1_Y = 96;
129 0 : const int TAB_ROW2_Y = 192;
130 0 : gui_sketch_background_private_draw_icon_and_message( this_,
131 : gui_resources_get_crystal_facet_uml( (*this_).resources ),
132 : "Welcome to",
133 : META_INFO_PROGRAM_NAME_STR,
134 0 : text_area_start+BORDER,
135 0 : top+BORDER+TAB_ROW0_Y,
136 : cr
137 : );
138 :
139 0 : gui_sketch_background_private_draw_icon_and_message( this_,
140 : gui_resources_get_file_new( (*this_).resources ),
141 : "To begin, please",
142 : "create a new database file first.",
143 0 : text_area_start+BORDER,
144 0 : top+BORDER+TAB_ROW1_Y,
145 : cr
146 : );
147 :
148 0 : gui_sketch_background_private_draw_icon_and_message( this_,
149 : gui_resources_get_message_user_doc( (*this_).resources ),
150 : "The user manual crystal-facet-uml_documentation.pdf is available",
151 : #ifdef __linux__
152 : "in the net and locally at /usr/share/doc/(packages/)crystal-facet-uml",
153 : #else
154 : "in the net",
155 : #endif
156 0 : text_area_start+BORDER,
157 0 : top+BORDER+TAB_ROW2_Y,
158 : cr
159 : );
160 :
161 0 : U8_TRACE_END();
162 0 : }
163 :
164 0 : void gui_sketch_background_draw_navigation( gui_sketch_background_t *this_,
165 : unsigned int tree_depth,
166 : unsigned int num_children,
167 : cairo_t *cr )
168 : {
169 0 : U8_TRACE_BEGIN();
170 0 : assert( NULL != cr );
171 :
172 : /* draw background of nav_tree list labels */
173 0 : const int32_t label_left = shape_int_rectangle_get_left( &((*this_).label_bounds) );
174 0 : const int32_t label_top = shape_int_rectangle_get_top( &((*this_).label_bounds) );
175 0 : const uint32_t label_width = shape_int_rectangle_get_width( &((*this_).label_bounds) );
176 0 : const uint32_t label_height = shape_int_rectangle_get_height( &((*this_).label_bounds) );
177 0 : cairo_set_source_rgba( cr, LIGHT_R, LIGHT_G, LIGHT_B, LIGHT_A );
178 0 : cairo_rectangle ( cr, label_left, label_top, label_width, label_height );
179 0 : cairo_fill (cr);
180 :
181 : /* draw background of cards area */
182 0 : const int32_t left = shape_int_rectangle_get_left( &((*this_).card_bounds) );
183 0 : const int32_t top = shape_int_rectangle_get_top( &((*this_).card_bounds) );
184 0 : const uint32_t width = shape_int_rectangle_get_width( &((*this_).card_bounds) );
185 0 : const uint32_t height = shape_int_rectangle_get_height( &((*this_).card_bounds) );
186 :
187 0 : if ( 0 == tree_depth )
188 : {
189 0 : cairo_set_source_rgba( cr, LIGHT_R, LIGHT_G, LIGHT_B, LIGHT_A );
190 : }
191 : else
192 : {
193 0 : cairo_set_source_rgba( cr, DARK_R, DARK_G, DARK_B, DARK_A );
194 : }
195 0 : cairo_rectangle ( cr, left, top, width, height );
196 0 : cairo_fill (cr);
197 :
198 0 : if ( ( 0 == tree_depth )&&( 0 == num_children ))
199 : {
200 : /* this is a new, empty database */
201 :
202 0 : gui_sketch_background_private_draw_quick_introduction( this_, cr );
203 : }
204 :
205 0 : U8_TRACE_END();
206 0 : }
207 :
208 0 : void gui_sketch_background_draw_search( gui_sketch_background_t *this_, cairo_t *cr )
209 : {
210 0 : U8_TRACE_BEGIN();
211 0 : assert( NULL != cr );
212 :
213 : /* draw background of search result list list labels */
214 0 : const int32_t label_left = shape_int_rectangle_get_left( &((*this_).label_bounds) );
215 0 : const int32_t label_top = shape_int_rectangle_get_top( &((*this_).label_bounds) );
216 0 : const uint32_t label_width = shape_int_rectangle_get_width( &((*this_).label_bounds) );
217 0 : const uint32_t label_height = shape_int_rectangle_get_height( &((*this_).label_bounds) );
218 0 : cairo_set_source_rgba( cr, LIGHT_R, LIGHT_G, LIGHT_B, LIGHT_A );
219 0 : cairo_rectangle ( cr, label_left, label_top, label_width, label_height );
220 0 : cairo_fill (cr);
221 :
222 : /* draw background of cards area */
223 0 : const int32_t left = shape_int_rectangle_get_left( &((*this_).card_bounds) );
224 0 : const int32_t top = shape_int_rectangle_get_top( &((*this_).card_bounds) );
225 0 : const uint32_t width = shape_int_rectangle_get_width( &((*this_).card_bounds) );
226 0 : const uint32_t height = shape_int_rectangle_get_height( &((*this_).card_bounds) );
227 :
228 0 : cairo_set_source_rgba( cr, DARK_R, DARK_G, DARK_B, DARK_A );
229 0 : cairo_rectangle ( cr, left, top, width, height );
230 0 : cairo_fill (cr);
231 :
232 0 : U8_TRACE_END();
233 0 : }
234 :
235 0 : void gui_sketch_background_draw_edit( gui_sketch_background_t *this_, cairo_t *cr )
236 : {
237 0 : U8_TRACE_BEGIN();
238 0 : assert( NULL != cr );
239 :
240 0 : const int32_t left = shape_int_rectangle_get_left( &((*this_).card_bounds) );
241 0 : const int32_t top = shape_int_rectangle_get_top( &((*this_).card_bounds) );
242 0 : const uint32_t width = shape_int_rectangle_get_width( &((*this_).card_bounds) );
243 0 : const uint32_t height = shape_int_rectangle_get_height( &((*this_).card_bounds) );
244 :
245 0 : cairo_set_source_rgba( cr, DARK_R, DARK_G, DARK_B, DARK_A );
246 0 : cairo_rectangle ( cr, left, top, width, height );
247 0 : cairo_fill (cr);
248 :
249 0 : U8_TRACE_END();
250 0 : }
251 :
252 0 : void gui_sketch_background_draw_create( gui_sketch_background_t *this_, cairo_t *cr )
253 : {
254 0 : U8_TRACE_BEGIN();
255 0 : assert( NULL != cr );
256 :
257 0 : const int32_t left = shape_int_rectangle_get_left( &((*this_).card_bounds) );
258 0 : const int32_t top = shape_int_rectangle_get_top( &((*this_).card_bounds) );
259 0 : const uint32_t width = shape_int_rectangle_get_width( &((*this_).card_bounds) );
260 0 : const uint32_t height = shape_int_rectangle_get_height( &((*this_).card_bounds) );
261 :
262 0 : cairo_set_source_rgba( cr, ORANGE_R, ORANGE_G, ORANGE_B, ORANGE_A );
263 0 : cairo_rectangle ( cr, left, top, width, height );
264 0 : cairo_fill (cr);
265 :
266 0 : U8_TRACE_END();
267 0 : }
268 :
269 0 : void gui_sketch_background_draw_appears_link( gui_sketch_background_t *this_,
270 : const shape_int_rectangle_t *label_box,
271 : const shape_int_rectangle_t *card_box,
272 : cairo_t *cr )
273 : {
274 0 : U8_TRACE_BEGIN();
275 0 : assert( NULL != label_box );
276 0 : assert( NULL != card_box );
277 0 : assert( NULL != cr );
278 :
279 0 : const int32_t label_top = shape_int_rectangle_get_top( label_box );
280 0 : const uint32_t label_right = shape_int_rectangle_get_right( label_box );
281 0 : const uint32_t label_bottom = shape_int_rectangle_get_bottom( label_box );
282 0 : const int32_t card_left = shape_int_rectangle_get_left( card_box );
283 0 : const int32_t card_top = shape_int_rectangle_get_top( card_box );
284 0 : const uint32_t card_right = shape_int_rectangle_get_right( card_box );
285 0 : const uint32_t card_bottom = shape_int_rectangle_get_bottom( card_box );
286 :
287 0 : cairo_set_source_rgba( cr, GREY_R, GREY_G, GREY_B, GREY_A );
288 0 : cairo_move_to( cr, label_right, label_top );
289 0 : if ( label_top > card_bottom )
290 : {
291 0 : const int_fast32_t big_delta_x = card_right - label_right;
292 0 : const int_fast32_t small_delta_x = card_left - label_right;
293 0 : const int_fast32_t big_delta_y = label_bottom - card_bottom;
294 0 : const int_fast32_t small_delta_y = label_top - card_bottom;
295 0 : const int_fast32_t big_mid_x = label_right + ( big_delta_x * 3 ) / 4;
296 0 : const int_fast32_t small_mid_x = label_right + ( small_delta_x * 3 ) / 4;
297 0 : const int_fast32_t big_mid_y = card_bottom + ( big_delta_y * 3 ) / 4;
298 0 : const int_fast32_t small_mid_y = card_bottom + ( small_delta_y * 3 ) / 4;
299 0 : cairo_curve_to( cr, small_mid_x, label_top, card_left, small_mid_y, card_left, card_bottom );
300 0 : cairo_line_to( cr, card_right, card_bottom );
301 0 : cairo_curve_to( cr, card_right, big_mid_y, big_mid_x, label_bottom, label_right, label_bottom );
302 : }
303 0 : else if ( label_bottom < card_top )
304 : {
305 0 : const int_fast32_t big_delta_x = card_right - label_right;
306 0 : const int_fast32_t small_delta_x = card_left - label_right;
307 0 : const int_fast32_t big_delta_y = card_top - label_top;
308 0 : const int_fast32_t small_delta_y = card_top - label_bottom;
309 0 : const int_fast32_t big_mid_x = label_right + ( big_delta_x * 3 ) / 4;
310 0 : const int_fast32_t small_mid_x = label_right + ( small_delta_x * 3 ) / 4;
311 0 : const int_fast32_t big_mid_y = card_top - ( big_delta_y * 3 ) / 4;
312 0 : const int_fast32_t small_mid_y = card_top - ( small_delta_y * 3 ) / 4;
313 0 : cairo_curve_to( cr, big_mid_x, label_top, card_right, big_mid_y, card_right, card_top );
314 0 : cairo_line_to( cr, card_left, card_top );
315 0 : cairo_curve_to( cr, card_left, small_mid_y, small_mid_x, label_bottom, label_right, label_bottom );
316 : }
317 : else
318 : {
319 0 : const int32_t mid_x = ( label_right + card_left ) / 2;
320 0 : cairo_curve_to( cr, mid_x, label_top, mid_x, card_top, card_left, card_top );
321 0 : cairo_line_to( cr, card_left, card_bottom );
322 0 : cairo_curve_to( cr, mid_x, card_bottom, mid_x, label_bottom, label_right, label_bottom );
323 : }
324 0 : cairo_fill( cr );
325 :
326 0 : U8_TRACE_END();
327 0 : }
328 :
329 0 : void gui_sketch_background_private_draw_quick_introduction( gui_sketch_background_t *this_, cairo_t *cr )
330 : {
331 0 : U8_TRACE_BEGIN();
332 0 : assert( NULL != cr );
333 :
334 0 : const int32_t left = shape_int_rectangle_get_left( &((*this_).card_bounds) );
335 : //const int32_t top = shape_int_rectangle_get_top( &((*this_).card_bounds) );
336 : //const uint32_t width = shape_int_rectangle_get_width( &((*this_).card_bounds) );
337 0 : const uint32_t height = shape_int_rectangle_get_height( &((*this_).card_bounds) );
338 :
339 0 : const int32_t TAB_HEIGHT = 144 + BORDER;
340 0 : const int32_t TAB_WIDTH = 640 + BORDER;
341 0 : const int32_t TAB_X = left + 16;
342 0 : const int32_t TAB_Y = height - TAB_HEIGHT - 16;
343 0 : const int32_t TAB_COL0_X = TAB_X + BORDER + 14;
344 0 : const int32_t TAB_COL1_X = TAB_X + BORDER + 112;
345 0 : const int32_t TAB_COL2_X = TAB_X + BORDER + 340;
346 0 : const int32_t TAB_ROW0_Y = TAB_Y + BORDER + 0;
347 0 : const int32_t TAB_ROW1_Y = TAB_Y + BORDER + 48;
348 0 : const int32_t TAB_ROW2_Y = TAB_Y + BORDER + 96;
349 :
350 0 : cairo_set_source_rgba( cr, GREY_R, GREY_G, GREY_B, GREY_A );
351 0 : cairo_rectangle ( cr, TAB_X, TAB_Y, TAB_WIDTH, TAB_HEIGHT );
352 0 : cairo_fill (cr);
353 :
354 0 : gui_sketch_background_private_draw_icon_and_message( this_,
355 : gui_resources_get_message_user_doc( (*this_).resources ),
356 : "Quick",
357 : "Intro:",
358 : TAB_COL0_X,
359 : TAB_ROW0_Y,
360 : cr
361 : );
362 0 : gui_sketch_background_private_draw_icon_and_message( this_,
363 : gui_resources_get_view_navigate( (*this_).resources ),
364 : "Click on a diagram to navigate,",
365 : "on '+' to create a new diagram.",
366 : TAB_COL1_X,
367 : TAB_ROW0_Y,
368 : cr
369 : );
370 0 : gui_sketch_background_private_draw_icon_and_message( this_,
371 : gui_resources_get_view_edit( (*this_).resources ),
372 : "Click on an element to edit",
373 : "name, type and description.",
374 : TAB_COL1_X,
375 : TAB_ROW1_Y,
376 : cr
377 : );
378 0 : gui_sketch_background_private_draw_icon_and_message( this_,
379 : gui_resources_get_view_edit( (*this_).resources ),
380 : "Drag an element to change",
381 : "its position.",
382 : TAB_COL2_X,
383 : TAB_ROW1_Y,
384 : cr
385 : );
386 0 : gui_sketch_background_private_draw_icon_and_message( this_,
387 : gui_resources_get_view_create( (*this_).resources ),
388 : "Click to create items.",
389 : "Drag to create arrows.",
390 : TAB_COL1_X,
391 : TAB_ROW2_Y,
392 : cr
393 : );
394 0 : gui_sketch_background_private_draw_icon_and_message( this_,
395 : gui_resources_get_file_export( (*this_).resources ),
396 : "Select the output folder",
397 : "to export all diagrams.",
398 : TAB_COL2_X,
399 : TAB_ROW2_Y,
400 : cr
401 : );
402 :
403 0 : U8_TRACE_END();
404 0 : }
405 :
406 0 : void gui_sketch_background_private_draw_icon_and_message( gui_sketch_background_t *this_,
407 : GdkTexture *icon_1,
408 : const char *text_1,
409 : const char *text_2,
410 : int x,
411 : int y,
412 : cairo_t *cr )
413 : {
414 0 : U8_TRACE_BEGIN();
415 0 : assert( NULL != cr );
416 0 : assert( NULL != icon_1 );
417 0 : assert( NULL != text_1 );
418 0 : assert( NULL != text_2 );
419 :
420 0 : const double icon_width = gdk_texture_get_width ( icon_1 );
421 0 : gui_sketch_texture_draw( (*this_).texture_downloader, icon_1, x, y, cr );
422 :
423 0 : cairo_set_source_rgba( cr, BLACK_R, BLACK_G, BLACK_B, BLACK_A );
424 0 : cairo_set_font_size ( cr, 12.0 );
425 0 : cairo_move_to ( cr, x+icon_width+BORDER, y + 14 );
426 0 : cairo_show_text ( cr, text_1 );
427 0 : cairo_move_to ( cr, x+icon_width+BORDER, y + 2*14 );
428 0 : cairo_show_text ( cr, text_2 );
429 :
430 0 : U8_TRACE_END();
431 0 : }
432 :
433 :
434 : /*
435 : Copyright 2017-2025 Andreas Warnke
436 :
437 : Licensed under the Apache License, Version 2.0 (the "License");
438 : you may not use this file except in compliance with the License.
439 : You may obtain a copy of the License at
440 :
441 : http://www.apache.org/licenses/LICENSE-2.0
442 :
443 : Unless required by applicable law or agreed to in writing, software
444 : distributed under the License is distributed on an "AS IS" BASIS,
445 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
446 : See the License for the specific language governing permissions and
447 : limitations under the License.
448 : */
|