163 GtkWidget *shadow1 = gtk_label_new(text);
164 GtkWidget *shadow2 = gtk_label_new(text);
167 if(shadow_name) gtk_widget_set_name(shadow1, shadow_name);
168 if(shadow_name) gtk_widget_set_name(shadow2, shadow_name);
169 if(
name) gtk_widget_set_name(label,
name);
171 PangoAttrList *shadow_attrs = pango_attr_list_new();
172 PangoAttribute *fg = pango_attr_foreground_new(0, 0, 0);
173 PangoAttribute *alpha = pango_attr_foreground_alpha_new((guint16)(0.75 * 65535));
174 pango_attr_list_insert(shadow_attrs, fg);
175 pango_attr_list_insert(shadow_attrs, alpha);
176 gtk_label_set_attributes(GTK_LABEL(shadow1), shadow_attrs);
177 gtk_label_set_attributes(GTK_LABEL(shadow2), shadow_attrs);
178 pango_attr_list_unref(shadow_attrs);
180 PangoAttrList *main_attrs = pango_attr_list_new();
181 PangoAttribute *main_fg = pango_attr_foreground_new(65535, 65535, 65535);
182 PangoAttribute *main_alpha = pango_attr_foreground_alpha_new(65535);
183 pango_attr_list_insert(main_attrs, main_fg);
184 pango_attr_list_insert(main_attrs, main_alpha);
185 gtk_label_set_attributes(GTK_LABEL(label), main_attrs);
186 pango_attr_list_unref(main_attrs);
188 gtk_fixed_put(GTK_FIXED(fixed), shadow1, 1, 1);
189 gtk_fixed_put(GTK_FIXED(fixed), shadow2, 2, 2);
190 gtk_fixed_put(GTK_FIXED(fixed), label, 0, 0);
192 GList *shadows = NULL;
193 shadows = g_list_append(shadows, shadow1);
194 shadows = g_list_append(shadows, shadow2);
195 g_object_set_data_full(G_OBJECT(label),
"splash-shadow-labels", shadows, (GDestroyNotify)g_list_free);
197 if(out_main) *out_main = label;
233 gtk_widget_get_allocation(widget, &alloc);
234 const int width = alloc.width;
235 const int height = alloc.height;
240 int scale_factor = gtk_widget_get_scale_factor(widget);
241 if(scale_factor < 1) scale_factor = 1;
242 const int dev_width =
width * scale_factor;
243 const int dev_height =
height * scale_factor;
256 GError *
error = NULL;
257 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(slide->
path, &
error);
264 const int img_w = gdk_pixbuf_get_width(pixbuf);
265 const int img_h = gdk_pixbuf_get_height(pixbuf);
266 const double scale = fmax((
double)dev_width / img_w, (
double)dev_height / img_h);
267 const int scaled_w = (int)ceil(img_w * scale);
268 const int scaled_h = (int)ceil(img_h * scale);
270 splash->
slide_pixbuf = gdk_pixbuf_scale_simple(pixbuf, scaled_w, scaled_h, GDK_INTERP_HYPER);
271 g_object_unref(pixbuf);
280 const int offset_x = (dev_width - scaled_w) / 2;
281 const int offset_y = (dev_height - scaled_h) / 2;
284 cairo_scale(cr, 1.0 / scale_factor, 1.0 / scale_factor);
285 cairo_rectangle(cr, 0, 0, dev_width, dev_height);
295 gchar *label = g_strdup_printf(_(
"© %s"), slide->
author);
296 PangoLayout *layout = gtk_widget_create_pango_layout(widget, label);
297 PangoFontDescription *desc = pango_font_description_from_string(
"14px Roboto");
298 pango_layout_set_font_description(layout, desc);
299 pango_font_description_free(desc);
300 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
301 pango_layout_set_width(layout, (
width - 32) * PANGO_SCALE);
303 int text_w = 0, text_h = 0;
304 pango_layout_get_pixel_size(layout, &text_w, &text_h);
307 const int margin = 0;
308 int box_w = text_w + pad * 2;
309 int box_h = text_h + pad * 2;
310 int x =
width - box_w - margin;
314 cairo_rectangle(cr,
x, y, box_w, box_h);
315 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.55);
318 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.85);
319 cairo_move_to(cr,
x + pad, y + pad);
320 pango_cairo_show_layout(cr, layout);
323 g_object_unref(layout);
344 gchar *path = g_build_filename(datadir,
"AUTHORS", NULL);
345 gchar *content = NULL;
348 if(g_file_get_contents(path, &content, &len, NULL) && content)
350 gchar **lines = g_strsplit(content,
"\n", -1);
351 for(gint
i = 0; lines[
i];
i++)
353 gchar *trim = g_strstrip(lines[
i]);
354 if(trim[0] ==
'\0')
continue;
355 if(trim[0] ==
'*')
continue;
358 if(g_ptr_array_find_with_equal_func(
splash->
authors, trim, g_str_equal, NULL))
continue;
368 g_ptr_array_add(
splash->
authors, g_strdup(_(
"Darktable & Ansel contributors")));
374 const gchar *default_author = _(
"Boilerplate image");
376 gchar *content = NULL;
378 if(g_file_get_contents(list_path, &content, &len, NULL) && content)
380 gchar **lines = g_strsplit(content,
"\n", -1);
381 for(gint
i = 0; lines[
i];
i++)
383 gchar *line = g_strstrip(lines[
i]);
384 if(line[0] ==
'\0' || line[0] ==
'#')
continue;
386 gchar **parts = g_strsplit(line,
"|", 2);
387 const gchar *
name = parts[0] ? g_strstrip(parts[0]) : NULL;
388 const gchar *author = (parts[1] && parts[1][0]) ? g_strstrip(parts[1]) : default_author;
392 if(g_path_is_absolute(
name))
393 path = g_strdup(
name);
397 if(g_file_test(path, G_FILE_TEST_EXISTS))
431 if(scale_factor < 1) scale_factor = 1;
433 const int target_px = target_size * scale_factor;
434 GError *
error = NULL;
435 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale(path, target_px, target_px,
TRUE, &
error);
442 cairo_surface_t *surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, scale_factor, NULL);
443 g_object_unref(pixbuf);
446 gtk_image_set_from_surface(GTK_IMAGE(logo), surface);
447 cairo_surface_destroy(surface);
460 GPtrArray *paths = g_ptr_array_new_with_free_func(g_free);
461 g_ptr_array_add(paths, g_build_filename(datadir,
"pixmaps",
"scalable",
"ansel.svg", NULL));
462 g_ptr_array_add(paths, g_build_filename(sharedir,
"icons",
"hicolor",
"scalable",
"apps",
"ansel.svg", NULL));
463 const char *sizes[] = {
"256x256",
"128x128",
"64x64", NULL };
464 for(guint
i = 0; sizes[
i];
i++)
466 g_ptr_array_add(paths, g_build_filename(datadir,
"pixmaps", sizes[
i],
"ansel.png", NULL));
467 g_ptr_array_add(paths, g_build_filename(sharedir,
"icons",
"hicolor", sizes[
i],
"apps",
"ansel.png", NULL));
470 gboolean loaded =
FALSE;
471 for(guint
i = 0;
i < paths->len && !loaded;
i++)
473 const gchar *path = (
const gchar *)paths->pdata[
i];
474 if(path && g_file_test(path, G_FILE_TEST_EXISTS))
478 if(out_path) *out_path = g_strdup(path);
486 gtk_image_set_from_icon_name(GTK_IMAGE(image),
"ansel", GTK_ICON_SIZE_DIALOG);
487 gtk_image_set_pixel_size(GTK_IMAGE(image), target_size);
490 g_ptr_array_free(paths,
TRUE);
533 gtk_window_set_position(GTK_WINDOW(
splash->
window), GTK_WIN_POS_CENTER);
534 gtk_window_set_type_hint(GTK_WINDOW(
splash->
window), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
536 gtk_window_set_default_size(GTK_WINDOW(
splash->
window), 960, 600);
539 g_signal_connect(G_OBJECT(
splash->
window),
"notify::scale-factor",
543 gtk_container_add(GTK_CONTAINER(
splash->
window), overlay);
553 gtk_widget_set_name(info_box,
"splash-info");
554 gtk_widget_set_halign(info_box, GTK_ALIGN_START);
555 gtk_widget_set_valign(info_box, GTK_ALIGN_END);
556 gtk_overlay_add_overlay(GTK_OVERLAY(overlay), info_box);
559 gtk_widget_set_name(header,
"splash-header");
560 gtk_box_pack_start(GTK_BOX(info_box), header,
FALSE,
FALSE, 0);
567 gtk_widget_set_name(
splash->
logo,
"splash-logo");
568 gtk_widget_set_size_request(
splash->
logo, 128, 128);
569 gtk_widget_set_halign(
splash->
logo, GTK_ALIGN_START);
570 gtk_widget_set_valign(
splash->
logo, GTK_ALIGN_START);
575 gtk_widget_set_name(title_box,
"splash-title-box");
576 gtk_box_pack_start(GTK_BOX(header), title_box,
FALSE,
FALSE, 0);
581 gtk_box_pack_start(GTK_BOX(title_box), title_fixed,
FALSE,
FALSE, 0);
584 "splash-version-shadow", NULL);
585 gtk_box_pack_start(GTK_BOX(title_box), version_fixed,
FALSE,
FALSE, 0);
590 gtk_box_pack_start(GTK_BOX(title_box), authors_fixed,
FALSE,
FALSE, 0);
593 gtk_widget_set_name(ticker_box,
"splash-ticker");
594 gtk_widget_set_halign(ticker_box, GTK_ALIGN_FILL);
595 gtk_widget_set_valign(ticker_box, GTK_ALIGN_END);
596 gtk_widget_set_hexpand(ticker_box,
TRUE);
597 gtk_widget_set_size_request(ticker_box, -1, 28);
598 gtk_overlay_add_overlay(GTK_OVERLAY(overlay), ticker_box);
601 "splash-message-shadow",
603 gtk_box_pack_start(GTK_BOX(ticker_box), message_fixed,
FALSE,
FALSE, 0);
608 " background-color: #777777;"
611 " background-color: transparent;"
612 " background-image: none;"
616 " -GtkBox-spacing: 12px;"
619 " -GtkBox-spacing: 12px;"
623 "#splash-title-box {"
624 " -GtkBox-spacing: 12px;"
625 " padding-top: 18px;"
633 " font: 700 40px \"Roboto\";"
635 "#splash-title-shadow {"
636 " color: rgba(0,0,0,0.75);"
637 " font: 700 40px \"Roboto\";"
640 " color: rgb(255,255,255);"
641 " font: 16px \"Roboto\";"
643 "#splash-version-shadow {"
644 " color: rgba(0,0,0,0.75);"
645 " font: 16px \"Roboto\";"
648 " color: rgba(255,255,255,0.9);"
649 " font: 16px \"Roboto\";"
651 "#splash-message-shadow {"
652 " color: rgba(0,0,0,0.75);"
653 " font: 16px \"Roboto\";"
656 " background: transparent;"
658 " background-image: none;"
663 " color: rgba(255,255,255,0.92);"
664 " font: 16px \"Roboto\";"
667 "#splash-authors-shadow {"
668 " color: rgba(0,0,0,0.75);"
669 " font: 16px \"Roboto\";"
674 GdkScreen *screen = gdk_screen_get_default();
676 gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(
splash->
css),
677 GTK_STYLE_PROVIDER_PRIORITY_USER + 2);