From 830df2442b6a2b82b9b7e442c6f4f7e83c7529eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Sat, 18 May 2024 14:12:59 -0700 Subject: [PATCH] Appearance: use current wallpaper on light/dark preview (#399) * Appearance: use current wallpaper on light/dark preview * Cleanup * Handle solid color, separate dark picture * Follow dim setting in preview * animate background transition --- data/appearance-dark.svg | 432 --------------------------- data/appearance-default.svg | 407 ------------------------- data/dock-dark.svg | 154 ++++++++++ data/dock.svg | 121 ++++++++ data/icons.gresource.xml | 6 +- data/notify-center-dark.svg | 114 +++++++ data/notify-center.svg | 114 +++++++ data/plug.css | 83 +++-- src/Views/Appearance.vala | 125 +++++++- src/Widgets/SolidColorContainer.vala | 2 +- 10 files changed, 684 insertions(+), 874 deletions(-) delete mode 100644 data/appearance-dark.svg delete mode 100644 data/appearance-default.svg create mode 100644 data/dock-dark.svg create mode 100644 data/dock.svg create mode 100644 data/notify-center-dark.svg create mode 100644 data/notify-center.svg diff --git a/data/appearance-dark.svg b/data/appearance-dark.svg deleted file mode 100644 index d3d040051..000000000 --- a/data/appearance-dark.svg +++ /dev/null @@ -1,432 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data/appearance-default.svg b/data/appearance-default.svg deleted file mode 100644 index c1a479795..000000000 --- a/data/appearance-default.svg +++ /dev/null @@ -1,407 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data/dock-dark.svg b/data/dock-dark.svg new file mode 100644 index 000000000..926cad016 --- /dev/null +++ b/data/dock-dark.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/data/dock.svg b/data/dock.svg new file mode 100644 index 000000000..521edaf4f --- /dev/null +++ b/data/dock.svg @@ -0,0 +1,121 @@ + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/data/icons.gresource.xml b/data/icons.gresource.xml index 828e9a714..99b68fab3 100644 --- a/data/icons.gresource.xml +++ b/data/icons.gresource.xml @@ -1,8 +1,10 @@ - appearance-default.svg - appearance-dark.svg + dock.svg + dock-dark.svg + notify-center.svg + notify-center-dark.svg plug.css diff --git a/data/notify-center-dark.svg b/data/notify-center-dark.svg new file mode 100644 index 000000000..b93ee7194 --- /dev/null +++ b/data/notify-center-dark.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/notify-center.svg b/data/notify-center.svg new file mode 100644 index 000000000..00bf0a68d --- /dev/null +++ b/data/notify-center.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/plug.css b/data/plug.css index c6e14777d..b148dd330 100644 --- a/data/plug.css +++ b/data/plug.css @@ -83,33 +83,72 @@ -gtk-icon-transform: scale(0.6); } -appearance-view checkbutton .card { - background-position: center; - background-repeat: no-repeat; - background-size: 86px 64px, cover; - min-width: 92px; - min-height: 64px; +appearance-view desktop-preview { + min-height: 96px; margin: 6px 6px 12px 12px; } -appearance-view checkbutton .card.prefer-default { - background-color: white; +appearance-view desktop-preview .shell { background-image: - url("resource:///io/elementary/settings/desktop/appearance-default.svg"), - linear-gradient( - to bottom, - alpha(@accent_color_300, 0.1), - alpha(@accent_color_500, 0.1) - ); + url("resource:///io/elementary/settings/desktop/notify-center.svg"), + url("resource:///io/elementary/settings/desktop/dock.svg"); + background-repeat: no-repeat; + background-size: 40px 55px, 54px 12px; + background-position: calc(100% - 3px) 3px, calc(50% + 0.5px) bottom; + transition: all 300ms ease-in-out; } -appearance-view checkbutton .card.prefer-dark { - background-color: mix(@BLACK_300, @BLACK_500, 0.25); +appearance-view desktop-preview box:dir(rtl) { + background-position: 3px 3px, calc(50% + 0.5px) bottom; +} + +appearance-view desktop-preview.dark .shell { background-image: - url("resource:///io/elementary/settings/desktop/appearance-dark.svg"), - linear-gradient( - to bottom, - alpha(@accent_color_300, 0.1), - alpha(@accent_color_500, 0.1) - ); + url("resource:///io/elementary/settings/desktop/notify-center-dark.svg"), + url("resource:///io/elementary/settings/desktop/dock-dark.svg"); +} + +appearance-view desktop-preview.dim .shell { + background-color: alpha(black, 0.3); +} + +appearance-view desktop-preview .window { + border-radius: 0.25em; + min-height: 32px; + min-width: 40px; +} + +appearance-view desktop-preview .window.back { + margin-right: 24px; + margin-bottom: 12px; +} + +appearance-view desktop-preview .window.front { + margin-left: 24px; + margin-top: 12px; +} + +appearance-view desktop-preview .window.front { + background: #fafafa; + box-shadow: + inset 0 1px 0 0 white, + inset 0 -1px 0 0 alpha(white, 0.8), + inset 1px 0 0 0 alpha(white, 0.5), + inset -1px 0 0 0 alpha(white, 0.5), + 0 0 0 1px alpha(black, 0.1), + 0 1px 2px alpha(black, 0.1), + 0 2px 4px alpha(black, 0.3); +} + +appearance-view desktop-preview .window.back, +appearance-view desktop-preview.dark .window.front { + background: #444; + box-shadow: + inset 0 1px 0 0 alpha(white, 0.15), + inset 0 -1px 0 0 alpha(white, 0.1), + inset 1px 0 0 0 alpha(white, 0.035), + inset -1px 0 0 0 alpha(white, 0.035), + 0 0 0 1px alpha(black, 0.7), + 0 1px 2px alpha(black, 0.1), + 0 2px 4px alpha(black, 0.3); } diff --git a/src/Views/Appearance.vala b/src/Views/Appearance.vala index 71c412ed2..097eb49b6 100644 --- a/src/Views/Appearance.vala +++ b/src/Views/Appearance.vala @@ -73,23 +73,17 @@ public class PantheonShell.Appearance : Gtk.Box { secondary_text = _("Preferred visual style for system components. Apps may also choose to follow this preference.") }; - var prefer_default_card = new Gtk.Grid (); - prefer_default_card.add_css_class (Granite.STYLE_CLASS_CARD); - prefer_default_card.add_css_class (Granite.STYLE_CLASS_ROUNDED); - prefer_default_card.add_css_class ("prefer-default"); + var default_preview = new DesktopPreview ("default"); var prefer_default_radio = new Gtk.CheckButton (); prefer_default_radio.add_css_class ("image-button"); var prefer_default_grid = new Gtk.Grid (); - prefer_default_grid.attach (prefer_default_card, 0, 0); + prefer_default_grid.attach (default_preview, 0, 0); prefer_default_grid.attach (new Gtk.Label (_("Default")), 0, 1); prefer_default_grid.set_parent (prefer_default_radio); - var prefer_dark_card = new Gtk.Grid (); - prefer_dark_card.add_css_class (Granite.STYLE_CLASS_CARD); - prefer_dark_card.add_css_class (Granite.STYLE_CLASS_ROUNDED); - prefer_dark_card.add_css_class ("prefer-dark"); + var dark_preview = new DesktopPreview ("dark"); var prefer_dark_radio = new Gtk.CheckButton () { group = prefer_default_radio @@ -97,7 +91,7 @@ public class PantheonShell.Appearance : Gtk.Box { prefer_dark_radio.add_css_class ("image-button"); var prefer_dark_grid = new Gtk.Grid (); - prefer_dark_grid.attach (prefer_dark_card, 0, 0); + prefer_dark_grid.attach (dark_preview, 0, 0); prefer_dark_grid.attach (new Gtk.Label (_("Dark")), 0, 1); prefer_dark_grid.set_parent (prefer_dark_radio); @@ -466,4 +460,115 @@ public class PantheonShell.Appearance : Gtk.Box { return time_double; } + + private class DesktopPreview : Gtk.Widget { + private static Settings pantheon_settings; + private static Settings gnome_settings; + private Gtk.Picture picture; + + class construct { + set_css_name ("desktop-preview"); + } + + static construct { + set_layout_manager_type (typeof (Gtk.BinLayout)); + + pantheon_settings = new Settings ("io.elementary.desktop.background"); + gnome_settings = new Settings ("org.gnome.desktop.background"); + } + + public DesktopPreview (string style_class) { + picture = new Gtk.Picture () { + content_fit = COVER + }; + + var window_back = new Gtk.Box (HORIZONTAL, 0) { + halign = CENTER, + valign = CENTER + }; + window_back.add_css_class ("window"); + window_back.add_css_class ("back"); + + var window_front = new Gtk.Box (HORIZONTAL, 0) { + halign = CENTER, + valign = CENTER + }; + window_front.add_css_class ("window"); + window_front.add_css_class ("front"); + + var shell = new Gtk.Box (HORIZONTAL, 0); + shell.add_css_class ("shell"); + + var overlay = new Gtk.Overlay () { + child = picture, + overflow = HIDDEN + }; + overlay.add_overlay (shell); + overlay.add_overlay (window_back); + overlay.add_overlay (window_front); + overlay.add_css_class (Granite.STYLE_CLASS_CARD); + overlay.add_css_class (Granite.STYLE_CLASS_ROUNDED); + + var monitor = Gdk.Display.get_default ().get_monitor_at_surface ( + (((Gtk.Application) Application.get_default ()).active_window).get_surface () + ); + + var monitor_ratio = (float) monitor.geometry.width / monitor.geometry.height; + + var frame = new Gtk.AspectFrame (0.5f, 0.5f, monitor_ratio, false) { + child = overlay + }; + frame.set_parent (this); + + add_css_class (style_class); + + update_picture (); + gnome_settings.changed.connect (update_picture); + + if (has_css_class ("dark")) { + update_dim (); + pantheon_settings.changed.connect (update_dim); + } + } + + private void update_dim () { + if (pantheon_settings.get_boolean ("dim-wallpaper-in-dark-style")) { + add_css_class ("dim"); + } else { + remove_css_class ("dim"); + } + } + + private void update_picture () { + if (gnome_settings.get_string ("picture-options") == "none") { + Gdk.RGBA rgba = {}; + rgba.parse (gnome_settings.get_string ("primary-color")); + + var pixbuf = new Gdk.Pixbuf (RGB, false, 8, 500, 500); + pixbuf.fill (PantheonShell.SolidColorContainer.rgba_to_pixel (rgba)); + + picture.paintable = Gdk.Texture.for_pixbuf (pixbuf); + return; + } + + if (has_css_class ("dark")) { + var dark_file = File.new_for_uri ( + gnome_settings.get_string ("picture-uri-dark") + ); + + if (dark_file.query_exists ()) { + picture.file = dark_file; + return; + } + } + + picture.file = File.new_for_uri ( + gnome_settings.get_string ("picture-uri") + ); + } + + ~DesktopPreview () { + get_first_child ().unparent (); + } + } } diff --git a/src/Widgets/SolidColorContainer.vala b/src/Widgets/SolidColorContainer.vala index 80fc92c17..e8ac8f500 100644 --- a/src/Widgets/SolidColorContainer.vala +++ b/src/Widgets/SolidColorContainer.vala @@ -42,7 +42,7 @@ public class PantheonShell.SolidColorContainer : WallpaperContainer { // Borrowed from // https://github.com/GNOME/california/blob/master/src/util/util-gfx.vala - private static uint32 rgba_to_pixel (Gdk.RGBA rgba) { + public static uint32 rgba_to_pixel (Gdk.RGBA rgba) { return (uint32) fp_to_uint8 (rgba.red) << 24 | (uint32) fp_to_uint8 (rgba.green) << 16 | (uint32) fp_to_uint8 (rgba.blue) << 8