162 GtkWidget *shadow1 = gtk_label_new(text);
163 GtkWidget *shadow2 = gtk_label_new(text);
166 if(shadow_name) gtk_widget_set_name(shadow1, shadow_name);
167 if(shadow_name) gtk_widget_set_name(shadow2, shadow_name);
168 if(
name) gtk_widget_set_name(label,
name);
170 PangoAttrList *shadow_attrs = pango_attr_list_new();
171 PangoAttribute *fg = pango_attr_foreground_new(0, 0, 0);
172 PangoAttribute *alpha = pango_attr_foreground_alpha_new((guint16)(0.75 * 65535));
173 pango_attr_list_insert(shadow_attrs, fg);
174 pango_attr_list_insert(shadow_attrs, alpha);
175 gtk_label_set_attributes(GTK_LABEL(shadow1), shadow_attrs);
176 gtk_label_set_attributes(GTK_LABEL(shadow2), shadow_attrs);
177 pango_attr_list_unref(shadow_attrs);
179 PangoAttrList *main_attrs = pango_attr_list_new();
180 PangoAttribute *main_fg = pango_attr_foreground_new(65535, 65535, 65535);
181 PangoAttribute *main_alpha = pango_attr_foreground_alpha_new(65535);
182 pango_attr_list_insert(main_attrs, main_fg);
183 pango_attr_list_insert(main_attrs, main_alpha);
184 gtk_label_set_attributes(GTK_LABEL(label), main_attrs);
185 pango_attr_list_unref(main_attrs);
187 gtk_fixed_put(GTK_FIXED(fixed), shadow1, 1, 1);
188 gtk_fixed_put(GTK_FIXED(fixed), shadow2, 2, 2);
189 gtk_fixed_put(GTK_FIXED(fixed), label, 0, 0);
191 GList *shadows = NULL;
192 shadows = g_list_append(shadows, shadow1);
193 shadows = g_list_append(shadows, shadow2);
194 g_object_set_data_full(G_OBJECT(label),
"splash-shadow-labels", shadows, (GDestroyNotify)g_list_free);
196 if(out_main) *out_main = label;
232 gtk_widget_get_allocation(widget, &alloc);
233 const int width = alloc.width;
234 const int height = alloc.height;
239 int scale_factor = gtk_widget_get_scale_factor(widget);
240 if(scale_factor < 1) scale_factor = 1;
241 const int dev_width =
width * scale_factor;
242 const int dev_height =
height * scale_factor;
255 GError *
error = NULL;
256 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(slide->
path, &
error);
263 const int img_w = gdk_pixbuf_get_width(pixbuf);
264 const int img_h = gdk_pixbuf_get_height(pixbuf);
265 const double scale = fmax((
double)dev_width / img_w, (
double)dev_height / img_h);
266 const int scaled_w = (int)ceil(img_w * scale);
267 const int scaled_h = (int)ceil(img_h * scale);
269 splash->
slide_pixbuf = gdk_pixbuf_scale_simple(pixbuf, scaled_w, scaled_h, GDK_INTERP_HYPER);
270 g_object_unref(pixbuf);
279 const int offset_x = (dev_width - scaled_w) / 2;
280 const int offset_y = (dev_height - scaled_h) / 2;
283 cairo_scale(cr, 1.0 / scale_factor, 1.0 / scale_factor);
284 cairo_rectangle(cr, 0, 0, dev_width, dev_height);
294 gchar *label = g_strdup_printf(_(
"© %s"), slide->
author);
295 PangoLayout *layout = gtk_widget_create_pango_layout(widget, label);
296 PangoFontDescription *desc = pango_font_description_from_string(
"14px Roboto");
297 pango_layout_set_font_description(layout, desc);
298 pango_font_description_free(desc);
299 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
300 pango_layout_set_width(layout, (
width - 32) * PANGO_SCALE);
302 int text_w = 0, text_h = 0;
303 pango_layout_get_pixel_size(layout, &text_w, &text_h);
306 const int margin = 0;
307 int box_w = text_w + pad * 2;
308 int box_h = text_h + pad * 2;
309 int x =
width - box_w - margin;
313 cairo_rectangle(cr,
x, y, box_w, box_h);
314 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.55);
317 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.85);
318 cairo_move_to(cr,
x + pad, y + pad);
319 pango_cairo_show_layout(cr, layout);
322 g_object_unref(layout);
370 const gchar *default_author = _(
"Boilerplate image");
372 gchar *content = NULL;
374 if(g_file_get_contents(list_path, &content, &len, NULL) && content)
376 gchar **lines = g_strsplit(content,
"\n", -1);
377 for(gint
i = 0; lines[
i];
i++)
379 gchar *line = g_strstrip(lines[
i]);
380 if(line[0] ==
'\0' || line[0] ==
'#')
continue;
382 gchar **parts = g_strsplit(line,
"|", 2);
383 const gchar *
name = parts[0] ? g_strstrip(parts[0]) : NULL;
384 const gchar *author = (parts[1] && parts[1][0]) ? g_strstrip(parts[1]) : default_author;
388 if(g_path_is_absolute(
name))
389 path = g_strdup(
name);
393 if(g_file_test(path, G_FILE_TEST_EXISTS))
427 if(scale_factor < 1) scale_factor = 1;
429 const int target_px = target_size * scale_factor;
430 GError *
error = NULL;
431 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale(path, target_px, target_px,
TRUE, &
error);
438 cairo_surface_t *surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, scale_factor, NULL);
439 g_object_unref(pixbuf);
442 gtk_image_set_from_surface(GTK_IMAGE(logo), surface);
443 cairo_surface_destroy(surface);
456 GPtrArray *paths = g_ptr_array_new_with_free_func(g_free);
457 g_ptr_array_add(paths, g_build_filename(datadir,
"pixmaps",
"scalable",
"ansel.svg", NULL));
458 g_ptr_array_add(paths, g_build_filename(sharedir,
"icons",
"hicolor",
"scalable",
"apps",
"ansel.svg", NULL));
459 const char *sizes[] = {
"256x256",
"128x128",
"64x64", NULL };
460 for(guint
i = 0; sizes[
i];
i++)
462 g_ptr_array_add(paths, g_build_filename(datadir,
"pixmaps", sizes[
i],
"ansel.png", NULL));
463 g_ptr_array_add(paths, g_build_filename(sharedir,
"icons",
"hicolor", sizes[
i],
"apps",
"ansel.png", NULL));
466 gboolean loaded =
FALSE;
467 for(guint
i = 0;
i < paths->len && !loaded;
i++)
469 const gchar *path = (
const gchar *)paths->pdata[
i];
470 if(path && g_file_test(path, G_FILE_TEST_EXISTS))
474 if(out_path) *out_path = g_strdup(path);
482 gtk_image_set_from_icon_name(GTK_IMAGE(image),
"ansel", GTK_ICON_SIZE_DIALOG);
483 gtk_image_set_pixel_size(GTK_IMAGE(image), target_size);
486 g_ptr_array_free(paths,
TRUE);
529 gtk_window_set_position(GTK_WINDOW(
splash->
window), GTK_WIN_POS_CENTER);
530 gtk_window_set_type_hint(GTK_WINDOW(
splash->
window), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
532 gtk_window_set_default_size(GTK_WINDOW(
splash->
window), 960, 600);
535 g_signal_connect(G_OBJECT(
splash->
window),
"notify::scale-factor",
539 gtk_container_add(GTK_CONTAINER(
splash->
window), overlay);
549 gtk_widget_set_name(info_box,
"splash-info");
550 gtk_widget_set_halign(info_box, GTK_ALIGN_START);
551 gtk_widget_set_valign(info_box, GTK_ALIGN_END);
552 gtk_overlay_add_overlay(GTK_OVERLAY(overlay), info_box);
555 gtk_widget_set_name(header,
"splash-header");
556 gtk_box_pack_start(GTK_BOX(info_box), header,
FALSE,
FALSE, 0);
563 gtk_widget_set_name(
splash->
logo,
"splash-logo");
564 gtk_widget_set_size_request(
splash->
logo, 128, 128);
565 gtk_widget_set_halign(
splash->
logo, GTK_ALIGN_START);
566 gtk_widget_set_valign(
splash->
logo, GTK_ALIGN_START);
571 gtk_widget_set_name(title_box,
"splash-title-box");
572 gtk_box_pack_start(GTK_BOX(header), title_box,
FALSE,
FALSE, 0);
577 gtk_box_pack_start(GTK_BOX(title_box), title_fixed,
FALSE,
FALSE, 0);
580 "splash-version-shadow", NULL);
581 gtk_box_pack_start(GTK_BOX(title_box), version_fixed,
FALSE,
FALSE, 0);
586 gtk_box_pack_start(GTK_BOX(title_box), authors_fixed,
FALSE,
FALSE, 0);
589 gtk_widget_set_name(ticker_box,
"splash-ticker");
590 gtk_widget_set_halign(ticker_box, GTK_ALIGN_FILL);
591 gtk_widget_set_valign(ticker_box, GTK_ALIGN_END);
592 gtk_widget_set_hexpand(ticker_box,
TRUE);
593 gtk_widget_set_size_request(ticker_box, -1, 28);
594 gtk_overlay_add_overlay(GTK_OVERLAY(overlay), ticker_box);
597 "splash-message-shadow",
599 gtk_box_pack_start(GTK_BOX(ticker_box), message_fixed,
FALSE,
FALSE, 0);
604 " background-color: #777777;"
607 " background-color: transparent;"
608 " background-image: none;"
612 " -GtkBox-spacing: 12px;"
615 " -GtkBox-spacing: 12px;"
619 "#splash-title-box {"
620 " -GtkBox-spacing: 12px;"
621 " padding-top: 18px;"
629 " font: 700 40px \"Roboto\";"
631 "#splash-title-shadow {"
632 " color: rgba(0,0,0,0.75);"
633 " font: 700 40px \"Roboto\";"
636 " color: rgb(255,255,255);"
637 " font: 16px \"Roboto\";"
639 "#splash-version-shadow {"
640 " color: rgba(0,0,0,0.75);"
641 " font: 16px \"Roboto\";"
644 " color: rgba(255,255,255,0.9);"
645 " font: 16px \"Roboto\";"
647 "#splash-message-shadow {"
648 " color: rgba(0,0,0,0.75);"
649 " font: 16px \"Roboto\";"
652 " background: transparent;"
654 " background-image: none;"
659 " color: rgba(255,255,255,0.92);"
660 " font: 16px \"Roboto\";"
663 "#splash-authors-shadow {"
664 " color: rgba(0,0,0,0.75);"
665 " font: 16px \"Roboto\";"
670 GdkScreen *screen = gdk_screen_get_default();
672 gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(
splash->
css),
673 GTK_STYLE_PROVIDER_PRIORITY_USER + 2);