159 GtkWidget *shadow1 = gtk_label_new(text);
160 GtkWidget *shadow2 = gtk_label_new(text);
163 if(shadow_name) gtk_widget_set_name(shadow1, shadow_name);
164 if(shadow_name) gtk_widget_set_name(shadow2, shadow_name);
165 if(
name) gtk_widget_set_name(label,
name);
167 PangoAttrList *shadow_attrs = pango_attr_list_new();
168 PangoAttribute *fg = pango_attr_foreground_new(0, 0, 0);
169 PangoAttribute *alpha = pango_attr_foreground_alpha_new((guint16)(0.75 * 65535));
170 pango_attr_list_insert(shadow_attrs, fg);
171 pango_attr_list_insert(shadow_attrs, alpha);
172 gtk_label_set_attributes(GTK_LABEL(shadow1), shadow_attrs);
173 gtk_label_set_attributes(GTK_LABEL(shadow2), shadow_attrs);
174 pango_attr_list_unref(shadow_attrs);
176 PangoAttrList *main_attrs = pango_attr_list_new();
177 PangoAttribute *main_fg = pango_attr_foreground_new(65535, 65535, 65535);
178 PangoAttribute *main_alpha = pango_attr_foreground_alpha_new(65535);
179 pango_attr_list_insert(main_attrs, main_fg);
180 pango_attr_list_insert(main_attrs, main_alpha);
181 gtk_label_set_attributes(GTK_LABEL(label), main_attrs);
182 pango_attr_list_unref(main_attrs);
184 gtk_fixed_put(GTK_FIXED(fixed), shadow1, 1, 1);
185 gtk_fixed_put(GTK_FIXED(fixed), shadow2, 2, 2);
186 gtk_fixed_put(GTK_FIXED(fixed), label, 0, 0);
188 GList *shadows = NULL;
189 shadows = g_list_append(shadows, shadow1);
190 shadows = g_list_append(shadows, shadow2);
191 g_object_set_data_full(G_OBJECT(label),
"splash-shadow-labels", shadows, (GDestroyNotify)g_list_free);
193 if(out_main) *out_main = label;
229 gtk_widget_get_allocation(widget, &alloc);
230 const int width = alloc.width;
231 const int height = alloc.height;
236 int scale_factor = gtk_widget_get_scale_factor(widget);
237 if(scale_factor < 1) scale_factor = 1;
238 const int dev_width =
width * scale_factor;
239 const int dev_height =
height * scale_factor;
252 GError *
error = NULL;
253 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(slide->
path, &
error);
260 const int img_w = gdk_pixbuf_get_width(pixbuf);
261 const int img_h = gdk_pixbuf_get_height(pixbuf);
262 const double scale = fmax((
double)dev_width / img_w, (
double)dev_height / img_h);
263 const int scaled_w = (int)ceil(img_w * scale);
264 const int scaled_h = (int)ceil(img_h * scale);
266 splash->
slide_pixbuf = gdk_pixbuf_scale_simple(pixbuf, scaled_w, scaled_h, GDK_INTERP_HYPER);
267 g_object_unref(pixbuf);
276 const int offset_x = (dev_width - scaled_w) / 2;
277 const int offset_y = (dev_height - scaled_h) / 2;
280 cairo_scale(cr, 1.0 / scale_factor, 1.0 / scale_factor);
281 cairo_rectangle(cr, 0, 0, dev_width, dev_height);
291 gchar *label = g_strdup_printf(_(
"© %s"), slide->
author);
292 PangoLayout *layout = gtk_widget_create_pango_layout(widget, label);
293 PangoFontDescription *desc = pango_font_description_from_string(
"14px Roboto");
294 pango_layout_set_font_description(layout, desc);
295 pango_font_description_free(desc);
296 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
297 pango_layout_set_width(layout, (
width - 32) * PANGO_SCALE);
299 int text_w = 0, text_h = 0;
300 pango_layout_get_pixel_size(layout, &text_w, &text_h);
303 const int margin = 0;
304 int box_w = text_w + pad * 2;
305 int box_h = text_h + pad * 2;
306 int x =
width - box_w - margin;
310 cairo_rectangle(cr,
x, y, box_w, box_h);
311 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.55);
314 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.85);
315 cairo_move_to(cr,
x + pad, y + pad);
316 pango_cairo_show_layout(cr, layout);
319 g_object_unref(layout);
367 const gchar *default_author = _(
"Boilerplate image");
369 gchar *content = NULL;
371 if(g_file_get_contents(list_path, &content, &len, NULL) && content)
373 gchar **lines = g_strsplit(content,
"\n", -1);
374 for(gint
i = 0; lines[
i];
i++)
376 gchar *line = g_strstrip(lines[
i]);
377 if(line[0] ==
'\0' || line[0] ==
'#')
continue;
379 gchar **parts = g_strsplit(line,
"|", 2);
380 const gchar *
name = parts[0] ? g_strstrip(parts[0]) : NULL;
381 const gchar *author = (parts[1] && parts[1][0]) ? g_strstrip(parts[1]) : default_author;
385 if(g_path_is_absolute(
name))
386 path = g_strdup(
name);
390 if(g_file_test(path, G_FILE_TEST_EXISTS))
424 if(scale_factor < 1) scale_factor = 1;
426 const int target_px = target_size * scale_factor;
427 GError *
error = NULL;
428 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale(path, target_px, target_px,
TRUE, &
error);
435 cairo_surface_t *surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, scale_factor, NULL);
436 g_object_unref(pixbuf);
439 gtk_image_set_from_surface(GTK_IMAGE(logo), surface);
440 cairo_surface_destroy(surface);
453 GPtrArray *paths = g_ptr_array_new_with_free_func(g_free);
454 g_ptr_array_add(paths, g_build_filename(datadir,
"pixmaps",
"scalable",
"ansel.svg", NULL));
455 g_ptr_array_add(paths, g_build_filename(sharedir,
"icons",
"hicolor",
"scalable",
"apps",
"ansel.svg", NULL));
456 const char *sizes[] = {
"256x256",
"128x128",
"64x64", NULL };
457 for(guint
i = 0; sizes[
i];
i++)
459 g_ptr_array_add(paths, g_build_filename(datadir,
"pixmaps", sizes[
i],
"ansel.png", NULL));
460 g_ptr_array_add(paths, g_build_filename(sharedir,
"icons",
"hicolor", sizes[
i],
"apps",
"ansel.png", NULL));
463 gboolean loaded =
FALSE;
464 for(guint
i = 0;
i < paths->len && !loaded;
i++)
466 const gchar *path = (
const gchar *)paths->pdata[
i];
467 if(path && g_file_test(path, G_FILE_TEST_EXISTS))
471 if(out_path) *out_path = g_strdup(path);
479 gtk_image_set_from_icon_name(GTK_IMAGE(image),
"ansel", GTK_ICON_SIZE_DIALOG);
480 gtk_image_set_pixel_size(GTK_IMAGE(image), target_size);
483 g_ptr_array_free(paths,
TRUE);
526 gtk_window_set_position(GTK_WINDOW(
splash->
window), GTK_WIN_POS_CENTER);
527 gtk_window_set_type_hint(GTK_WINDOW(
splash->
window), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
529 gtk_window_set_default_size(GTK_WINDOW(
splash->
window), 960, 600);
532 g_signal_connect(G_OBJECT(
splash->
window),
"notify::scale-factor",
536 gtk_container_add(GTK_CONTAINER(
splash->
window), overlay);
546 gtk_widget_set_name(info_box,
"splash-info");
547 gtk_widget_set_halign(info_box, GTK_ALIGN_START);
548 gtk_widget_set_valign(info_box, GTK_ALIGN_END);
549 gtk_overlay_add_overlay(GTK_OVERLAY(overlay), info_box);
552 gtk_widget_set_name(header,
"splash-header");
553 gtk_box_pack_start(GTK_BOX(info_box), header,
FALSE,
FALSE, 0);
560 gtk_widget_set_name(
splash->
logo,
"splash-logo");
561 gtk_widget_set_size_request(
splash->
logo, 128, 128);
562 gtk_widget_set_halign(
splash->
logo, GTK_ALIGN_START);
563 gtk_widget_set_valign(
splash->
logo, GTK_ALIGN_START);
568 gtk_widget_set_name(title_box,
"splash-title-box");
569 gtk_box_pack_start(GTK_BOX(header), title_box,
FALSE,
FALSE, 0);
574 gtk_box_pack_start(GTK_BOX(title_box), title_fixed,
FALSE,
FALSE, 0);
577 "splash-version-shadow", NULL);
578 gtk_box_pack_start(GTK_BOX(title_box), version_fixed,
FALSE,
FALSE, 0);
583 gtk_box_pack_start(GTK_BOX(title_box), authors_fixed,
FALSE,
FALSE, 0);
586 gtk_widget_set_name(ticker_box,
"splash-ticker");
587 gtk_widget_set_halign(ticker_box, GTK_ALIGN_FILL);
588 gtk_widget_set_valign(ticker_box, GTK_ALIGN_END);
589 gtk_widget_set_hexpand(ticker_box,
TRUE);
590 gtk_widget_set_size_request(ticker_box, -1, 28);
591 gtk_overlay_add_overlay(GTK_OVERLAY(overlay), ticker_box);
594 "splash-message-shadow",
596 gtk_box_pack_start(GTK_BOX(ticker_box), message_fixed,
FALSE,
FALSE, 0);
601 " background-color: #777777;"
604 " background-color: transparent;"
605 " background-image: none;"
609 " -GtkBox-spacing: 12px;"
612 " -GtkBox-spacing: 12px;"
616 "#splash-title-box {"
617 " -GtkBox-spacing: 12px;"
618 " padding-top: 18px;"
626 " font: 700 40px \"Roboto\";"
628 "#splash-title-shadow {"
629 " color: rgba(0,0,0,0.75);"
630 " font: 700 40px \"Roboto\";"
633 " color: rgb(255,255,255);"
634 " font: 16px \"Roboto\";"
636 "#splash-version-shadow {"
637 " color: rgba(0,0,0,0.75);"
638 " font: 16px \"Roboto\";"
641 " color: rgba(255,255,255,0.9);"
642 " font: 16px \"Roboto\";"
644 "#splash-message-shadow {"
645 " color: rgba(0,0,0,0.75);"
646 " font: 16px \"Roboto\";"
649 " background: transparent;"
651 " background-image: none;"
656 " color: rgba(255,255,255,0.92);"
657 " font: 16px \"Roboto\";"
660 "#splash-authors-shadow {"
661 " color: rgba(0,0,0,0.75);"
662 " font: 16px \"Roboto\";"
667 GdkScreen *screen = gdk_screen_get_default();
669 gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(
splash->
css),
670 GTK_STYLE_PROVIDER_PRIORITY_USER + 2);