diff --git a/README.md b/README.md index b1e580b74..6e203fb99 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ You'll need the following dependencies: * libappstream-dev (>= 1.0.0) * libflatpak-dev (>= 1.0.7) * libgee-0.8-dev -* libgranite-7-dev (>=7.1.0) +* libgranite-7-dev (>=7.6.0) * libgtk-4-dev (>=4.10) * libjson-glib-dev * libpolkit-gobject-1-dev diff --git a/data/styles/AppInfoView.scss b/data/styles/AppInfoView.scss index 9a7705079..b3ad2ecec 100644 --- a/data/styles/AppInfoView.scss +++ b/data/styles/AppInfoView.scss @@ -39,14 +39,8 @@ appinfoview { margin: rem(12px) rem(12px) 0; } - .screenshot { - background: #{'@selected_bg_color'}; - border-radius: rem(6px); - color: #{'@selected_fg_color'}; - font-size: 1.5rem; - font-weight: bold; + screenshot { margin: rem(12px); - padding: rem(12px); } .content-box { diff --git a/data/styles/Index.scss b/data/styles/Index.scss index 15a47a6e4..7dc21f880 100644 --- a/data/styles/Index.scss +++ b/data/styles/Index.scss @@ -8,4 +8,5 @@ @import 'MainWindow.scss'; @import 'ProgressButton.scss'; @import 'ReleaseRow.scss'; +@import 'Screenshot.scss'; @import 'SearchPage.scss'; diff --git a/data/styles/Screenshot.scss b/data/styles/Screenshot.scss new file mode 100644 index 000000000..e3b10542c --- /dev/null +++ b/data/styles/Screenshot.scss @@ -0,0 +1,8 @@ +screenshot { + background: #{'@selected_bg_color'}; + border-radius: rem(6px); + color: #{'@selected_fg_color'}; + font-size: 1.5rem; + font-weight: bold; + padding: rem(12px); +} diff --git a/meson.build b/meson.build index 6b2e92590..1ce452e0c 100644 --- a/meson.build +++ b/meson.build @@ -22,7 +22,7 @@ gobject = dependency ('gobject-2.0') gio = dependency ('gio-2.0') gee = dependency ('gee-0.8') gtk = dependency ('gtk4', version: '>=4.10') -granite = dependency ('granite-7', version: '>=7.3.0') +granite = dependency ('granite-7', version: '>=7.6.0') adwaita = dependency('libadwaita-1', version: '>=1.4') appstream = dependency ('appstream', version: '>=1.0') libsoup = dependency ('libsoup-3.0') diff --git a/src/Views/AppInfoView.vala b/src/Views/AppInfoView.vala index dbc63a47a..bb98664e2 100644 --- a/src/Views/AppInfoView.vala +++ b/src/Views/AppInfoView.vala @@ -1001,7 +1001,18 @@ public class AppCenter.Views.AppInfoView : Adw.NavigationPage { for (int i = 0; i < captioned_urls.length (); i++) { if (results[i] == true) { string caption = captioned_urls.nth_data (i).caption; - load_screenshot (caption, screenshot_files[i]); + + var screenshot = new AppCenter.Screenshot () { + caption = caption, + height_request = 500, + path = screenshot_files[i] + }; + screenshot.set_branding (package); + + Idle.add (() => { + screenshot_carousel.append (screenshot); + return GLib.Source.REMOVE; + }); } } @@ -1026,39 +1037,6 @@ public class AppCenter.Views.AppInfoView : Adw.NavigationPage { }); } - // We need to first download the screenshot locally so that it doesn't freeze the interface. - private void load_screenshot (string? caption, string path) { - var image = new Gtk.Picture.for_filename (path) { - content_fit = SCALE_DOWN, - height_request = 500, - vexpand = true - }; - - var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { - halign = Gtk.Align.CENTER - }; - box.add_css_class ("screenshot"); - box.get_style_context ().add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - - if (caption != null) { - var label = new Gtk.Label (caption) { - max_width_chars = 50, - wrap = true - }; - - label.get_style_context ().add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - - box.append (label); - } - - box.append (image); - - Idle.add (() => { - screenshot_carousel.append (box); - return GLib.Source.REMOVE; - }); - } - private async void uninstall_clicked () { package.uninstall.begin ((obj, res) => { try { diff --git a/src/Widgets/Screenshot.vala b/src/Widgets/Screenshot.vala new file mode 100644 index 000000000..dce55f1fa --- /dev/null +++ b/src/Widgets/Screenshot.vala @@ -0,0 +1,85 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2025 elementary, Inc. (https://elementary.io) + */ + +public class AppCenter.Screenshot : Granite.Bin { + public string caption { get; set; } + + public string path { + set { + picture.file = File.new_for_path (value); + } + } + + private static Gee.HashMap? providers; + private Gtk.Picture picture; + + class construct { + set_css_name ("screenshot"); + } + + construct { + picture = new Gtk.Picture () { + content_fit = SCALE_DOWN, + vexpand = true + }; + + var label = new Gtk.Label ("") { + max_width_chars = 50, + wrap = true + }; + + var box = new Gtk.Box (VERTICAL, 0) { + halign = CENTER + }; + box.append (label); + box.append (picture); + + child = box; + add_css_class (Granite.STYLE_CLASS_CARD); + + bind_property ("caption", label, "label"); + } + + public void set_branding (AppCenterCore.Package package) { + set_accent_color (package.get_color_primary ()); + + Granite.Settings.get_default ().notify["prefers-color-scheme"].connect (() => { + set_accent_color (package.get_color_primary ()); + }); + } + + private void set_accent_color (string color) { + if (providers == null) { + providers = new Gee.HashMap (); + } + + var color_class = color.replace ("#", "color-"); + css_classes = {Granite.STYLE_CLASS_CARD, color_class}; + + if (!providers.has_key (color)) { + var bg_rgba = Gdk.RGBA (); + bg_rgba.parse (color); + + var text_color = Granite.contrasting_foreground_color (bg_rgba).to_string (); + + string style = @" + screenshot.$color_class { + background-color: $color; + color: mix($color, $text_color, 0.9); + } + "; + + var style_provider = new Gtk.CssProvider (); + style_provider.load_from_string (style); + + providers[color] = style_provider; + Gtk.StyleContext.add_provider_for_display ( + Gdk.Display.get_default (), + providers[color], + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + ); + } + } +} diff --git a/src/meson.build b/src/meson.build index 3b2897a82..33c9f22d1 100644 --- a/src/meson.build +++ b/src/meson.build @@ -40,6 +40,7 @@ appcenter_files = files( 'Widgets/LinkListBox.vala', 'Widgets/ProgressButton.vala', 'Widgets/ReleaseRow.vala', + 'Widgets' / 'Screenshot.vala', 'Widgets/SizeLabel.vala', 'Widgets' / 'SearchListItem.vala', 'Widgets/AppContainers/AbstractPackageRowGrid.vala',