diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 89df11b26..d8874eb31 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,7 @@ jobs: - name: Install Dependencies run: | apt update - apt install -y gettext libappstream-dev libflatpak-dev libportal-dev libportal-gtk3-dev libgee-0.8-dev libgranite-dev libgtk-3-dev libhandy-1-dev libjson-glib-dev libpackagekit-glib2-dev libsoup-3.0-dev libxml2-dev libxml2-utils libpolkit-gobject-1-dev meson valac + apt install -y gettext libadwaita-1-dev libappstream-dev libflatpak-dev libgee-0.8-dev libgranite-7-dev libgtk-4-dev libjson-glib-dev libpackagekit-glib2-dev libportal-dev libportal-gtk4-dev libsoup-3.0-dev libxml2-dev libxml2-utils libpolkit-gobject-1-dev meson valac - name: Build and Test env: DESTDIR: out diff --git a/README.md b/README.md index 468cf6503..75a5f73fc 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,12 @@ An open, pay-what-you-want app store for indie developers. You'll need the following dependencies: * gettext -* libappstream-dev (>= 0.10) -* libflatpak-dev +* libadwaita-1-dev +* libappstream-dev (>= 0.15.2) +* libflatpak-dev (>= 1.0.7) * libgee-0.8-dev -* libgranite-dev (>=5.2.5) -* libgtk-3-dev -* libhandy-1-dev (>=1.3.0) +* libgranite-7-dev (>=7.1.0) +* libgtk-4-dev * libjson-glib-dev * libpackagekit-glib2-dev * libpolkit-gobject-1-dev diff --git a/data/io.elementary.appcenter.gresource.xml b/data/io.elementary.appcenter.gresource.xml index 99a170a36..4bdc4a3b2 100644 --- a/data/io.elementary.appcenter.gresource.xml +++ b/data/io.elementary.appcenter.gresource.xml @@ -1,14 +1,13 @@ - styles/application.css + styles/application.css styles/AppInfoView.css styles/AppListUpdateView.css styles/arrow.css styles/badge.css styles/banner.css styles/categories.css - styles/fallback.css styles/loading.css styles/ProgressButton.css diff --git a/data/styles/arrow.css b/data/styles/arrow.css index 12fc0c43b..c6e41eea7 100644 --- a/data/styles/arrow.css +++ b/data/styles/arrow.css @@ -29,6 +29,7 @@ margin: 12px; padding: 6px; color: @text_color; + -gtk-icon-size: 24px; } .arrow:active, diff --git a/data/styles/banner.css b/data/styles/banner.css index cc03591da..8e4c71801 100644 --- a/data/styles/banner.css +++ b/data/styles/banner.css @@ -77,7 +77,7 @@ /*Hack to make the button square-ish*/ .banner button.image-button.raised { - padding: 0.333rem 0.444rem; + padding: 0 0.333em; } .banner button:not(.suggested-action) { diff --git a/data/styles/categories.css b/data/styles/categories.css index 2f7716a14..6195f7ea2 100644 --- a/data/styles/categories.css +++ b/data/styles/categories.css @@ -599,7 +599,7 @@ radial-gradient( circle, alpha(@STRAWBERRY_900, 0) 65%, - alpha(shade(@STRAWBERRY_900, 0.6), 0.35) 4% + alpha(shade(@STRAWBERRY_900, 0.6), 0.35) 66% ), linear-gradient( to bottom, @@ -651,19 +651,19 @@ background-image: linear-gradient( to right, - transparent 42px, - alpha(@STRAWBERRY_100, 0.25) 42px, - alpha(@STRAWBERRY_100, 0.25) 44px, - transparent 44px + transparent 1.3em, + alpha(@STRAWBERRY_100, 0.25) 1.3em, + alpha(@STRAWBERRY_100, 0.25) calc(1.3em + 2px), + transparent calc(1.3em + 2px) ), linear-gradient( to bottom, - white 90%, - alpha(@BLUEBERRY_100, 0.2) 90% + transparent 0.9em, + alpha(@BLUEBERRY_100, 0.2) 0.9em ); - background-position: center center; - background-repeat: repeat-y; - background-size: 100% 1em; + background-position: center center, center 0.7em; + background-repeat: no-repeat, repeat-y; + background-size: auto auto, 110% 1em; /* Gtk.CSS bug requiring over 100% width maybe? */ color: @BLACK_300; font-size: 24px; } diff --git a/data/styles/fallback.css b/data/styles/fallback.css deleted file mode 100644 index 2d9816367..000000000 --- a/data/styles/fallback.css +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2020 elementary, Inc. (https://elementary.io) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* elementary-specific stylesheet variables */ - -@define-color fg_color @theme_text_color; - -/* Palette */ -@define-color STRAWBERRY_100 #ff8c82; -@define-color STRAWBERRY_300 #ed5353; -@define-color STRAWBERRY_500 #c6262e; -@define-color STRAWBERRY_700 #a10705; -@define-color STRAWBERRY_900 #7a0000; - -@define-color ORANGE_100 #ffc27d; -@define-color ORANGE_300 #ffa154; -@define-color ORANGE_500 #f37329; -@define-color ORANGE_700 #cc3b02; -@define-color ORANGE_900 #a62100; - -@define-color BANANA_100 #fff394; -@define-color BANANA_300 #ffe16b; -@define-color BANANA_500 #f9c440; -@define-color BANANA_700 #d48e15; -@define-color BANANA_900 #ad5f00; - -@define-color LIME_100 #d1ff82; -@define-color LIME_300 #9bdb4d; -@define-color LIME_500 #68b723; -@define-color LIME_700 #3a9104; -@define-color LIME_900 #206b00; - -@define-color BLUEBERRY_100 #8cd5ff; -@define-color BLUEBERRY_300 #64baff; -@define-color BLUEBERRY_500 #3689e6; -@define-color BLUEBERRY_700 #0d52bf; -@define-color BLUEBERRY_900 #002e99; - -@define-color GRAPE_100 #e4c6fa; -@define-color GRAPE_300 #cd9ef7; -@define-color GRAPE_500 #a56de2; -@define-color GRAPE_700 #7239b3; -@define-color GRAPE_900 #452981; - -@define-color COCOA_100 #a3907c; -@define-color COCOA_300 #8a715e; -@define-color COCOA_500 #715344; -@define-color COCOA_700 #57392d; -@define-color COCOA_900 #3d211b; - -@define-color SILVER_100 #fafafa; -@define-color SILVER_300 #d4d4d4; -@define-color SILVER_500 #abacae; -@define-color SILVER_700 #7e8087; -@define-color SILVER_900 #555761; - -@define-color SLATE_100 #95a3ab; -@define-color SLATE_300 #667885; -@define-color SLATE_500 #485a6c; -@define-color SLATE_700 #273445; -@define-color SLATE_900 #0e141f; - -@define-color BLACK_100 #666; -@define-color BLACK_300 #4d4d4d; -@define-color BLACK_500 #333; -@define-color BLACK_700 #1a1a1a; -@define-color BLACK_900 #000; diff --git a/meson.build b/meson.build index eeca27d3b..0c198602c 100644 --- a/meson.build +++ b/meson.build @@ -11,7 +11,6 @@ i18n = import('i18n') add_project_arguments( '-DGETTEXT_PACKAGE="@0@"'.format(gettext_name), - '-DHANDY_USE_UNSTABLE_API', '-DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE', language:'c' ) @@ -23,9 +22,9 @@ glib = dependency ('glib-2.0') gobject = dependency ('gobject-2.0') gio = dependency ('gio-2.0') gee = dependency ('gee-0.8') -gtk = dependency ('gtk+-3.0', version: '>=3.10') -granite = dependency ('granite', version: '>=6.0.0') -handy = dependency('libhandy-1', version: '>=1.4.0') +gtk = dependency ('gtk4') +granite = dependency ('granite-7', version: '>=7.3.0') +adwaita = dependency('libadwaita-1') appstream = dependency ('appstream', version: '>=0.15.2') libsoup = dependency ('libsoup-3.0') json = dependency ('json-glib-1.0') @@ -33,7 +32,7 @@ flatpak = dependency ('flatpak') xml = dependency ('libxml-2.0') polkit = dependency ('polkit-gobject-1') portal = dependency('libportal') -portal_gtk3 = dependency('libportal-gtk3') +portal_gtk4 = dependency('libportal-gtk4') posix = meson.get_compiler('vala').find_library('posix') dbus = dependency ('dbus-1') @@ -49,13 +48,13 @@ core_deps = [ dependencies = core_deps + [ gtk, granite, - handy, + adwaita, appstream, flatpak, xml, polkit, portal, - portal_gtk3, + portal_gtk4, posix ] diff --git a/src/Application.vala b/src/Application.vala index 14c41e472..b6c102e18 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -116,7 +116,7 @@ public class AppCenter.App : Gtk.Application { protected override void startup () { base.startup (); - Hdy.init (); + Granite.init (); var granite_settings = Granite.Settings.get_default (); var gtk_settings = Gtk.Settings.get_default (); @@ -127,22 +127,6 @@ public class AppCenter.App : Gtk.Application { gtk_settings.gtk_application_prefer_dark_theme = granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK; }); - var provider = new Gtk.CssProvider (); - provider.load_from_resource ("io/elementary/appcenter/application.css"); - Gtk.StyleContext.add_provider_for_screen ( - Gdk.Screen.get_default (), - provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION - ); - - var fallback_provider = new Gtk.CssProvider (); - fallback_provider.load_from_resource ("io/elementary/appcenter/fallback.css"); - Gtk.StyleContext.add_provider_for_screen ( - Gdk.Screen.get_default (), - fallback_provider, - Gtk.STYLE_PROVIDER_PRIORITY_FALLBACK - ); - var quit_action = new SimpleAction ("quit", null); quit_action.activate.connect (() => { if (active_window != null) { @@ -250,13 +234,19 @@ public class AppCenter.App : Gtk.Application { var main_window = new MainWindow (this); add_window (main_window); - var window_height = App.settings.get_int ("window-height"); - var window_width = App.settings.get_int ("window-width"); - main_window.resize (window_width, window_height); + /* + * This is very finicky. Bind size after present else set_titlebar gives us bad sizes + * Set maximize after height/width else window is min size on unmaximize + * Bind maximize as SET else get get bad sizes + */ + settings.bind ("window-height", main_window, "default-height", SettingsBindFlags.DEFAULT); + settings.bind ("window-width", main_window, "default-width", SettingsBindFlags.DEFAULT); if (settings.get_boolean ("window-maximized")) { main_window.maximize (); } + + settings.bind ("window-maximized", main_window, "maximized", SettingsBindFlags.SET); } if (show_updates) { @@ -356,14 +346,9 @@ public class AppCenter.App : Gtk.Application { if (error == null) { if (package.get_can_launch ()) { // Check if window is focused - if (active_window != null) { - var main_window = (MainWindow) active_window; - var win = main_window.get_window (); - if (win != null && (win.get_state () & Gdk.WindowState.FOCUSED) != 0) { - main_window.send_installed_toast (package); - - break; - } + if (active_window != null && active_window.is_active) { + ((MainWindow) active_window).send_installed_toast (package); + break; } var notification = new Notification (_("The app has been installed")); @@ -406,8 +391,9 @@ public class AppCenter.App : Gtk.Application { transient_for = active_window }; - update_fail_dialog.destroy.connect (() => { + update_fail_dialog.close_request.connect (() => { update_fail_dialog = null; + return Gdk.EVENT_PROPAGATE; }); } diff --git a/src/Core/Package.vala b/src/Core/Package.vala index de051201d..6738f2a80 100644 --- a/src/Core/Package.vala +++ b/src/Core/Package.vala @@ -718,13 +718,12 @@ public class AppCenterCore.Package : Object { uint current_scale = 0; uint pixel_size = size * scale_factor; - weak GenericArray icons = component.get_icons (); - for (int i = 0; i < icons.length; i++) { - weak AppStream.Icon _icon = icons[i]; + unowned var icons = component.get_icons (); + foreach (unowned var _icon in icons) { switch (_icon.get_kind ()) { case AppStream.IconKind.STOCK: unowned string icon_name = _icon.get_name (); - if (Gtk.IconTheme.get_default ().has_icon (icon_name)) { + if (Gtk.IconTheme.get_for_display (Gdk.Display.get_default ()).has_icon (icon_name)) { return new ThemedIcon (icon_name); } @@ -742,19 +741,6 @@ public class AppCenterCore.Package : Object { current_scale = icon_scale; } - break; - case AppStream.IconKind.REMOTE: - var icon_scale = _icon.get_scale (); - var icon_width = _icon.get_width () * icon_scale; - bool is_bigger = (icon_width > current_size && current_size < pixel_size); - bool has_better_dpi = (icon_width == current_size && current_scale < icon_scale && scale_factor <= icon_scale); - if (is_bigger || has_better_dpi) { - var file = File.new_for_uri (_icon.get_url ()); - icon = new FileIcon (file); - current_size = icon_width; - current_scale = icon_scale; - } - break; case AppStream.IconKind.UNKNOWN: diff --git a/src/Dialogs/InstallFailDialog.vala b/src/Dialogs/InstallFailDialog.vala index c2247f6c9..9e12c5785 100644 --- a/src/Dialogs/InstallFailDialog.vala +++ b/src/Dialogs/InstallFailDialog.vala @@ -43,7 +43,7 @@ public class InstallFailDialog : Granite.MessageDialog { if (package.is_flatpak) { var repair_button = add_button (_("Repair"), REPAIR_RESPONSE_ID); - repair_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + repair_button.get_style_context ().add_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); } response.connect ((response) => { diff --git a/src/Dialogs/StripeDialog.vala b/src/Dialogs/StripeDialog.vala index e7fd2b721..5a43e2003 100644 --- a/src/Dialogs/StripeDialog.vala +++ b/src/Dialogs/StripeDialog.vala @@ -53,12 +53,12 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { } construct { - var image = new Gtk.Image.from_icon_name ("payment-card", Gtk.IconSize.DIALOG) { + var image = new Gtk.Image.from_icon_name ("payment-card") { pixel_size = 48, valign = Gtk.Align.START }; - var overlay_image = new Gtk.Image.from_icon_name (Build.PROJECT_NAME, Gtk.IconSize.LARGE_TOOLBAR) { + var overlay_image = new Gtk.Image.from_icon_name (Build.PROJECT_NAME) { halign = Gtk.Align.END, valign = Gtk.Align.END, pixel_size = 24 @@ -76,7 +76,7 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { var primary_label = new Gtk.Label (_("Pay $%d for %s").printf (amount, app_name)) { xalign = 0 }; - primary_label.get_style_context ().add_class ("primary"); + primary_label.add_css_class (Granite.STYLE_CLASS_TITLE_LABEL); var secondary_label = new Gtk.Label ( _("This is a one time payment suggested by the developer. You can also choose your own price.") @@ -105,19 +105,23 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { margin_end = 3 }; + var custom_amount_controllerkey = new Gtk.EventControllerKey (); + var custom_amount = new Gtk.SpinButton.with_range (0, 100, 1) { - activates_default = true, hexpand = true, - primary_icon_name = "currency-dollar-symbolic", value = amount }; + custom_amount.add_controller (custom_amount_controllerkey); + + var custom_image = new Gtk.Image.from_icon_name ("currency-dollar-symbolic"); + custom_image.insert_before (custom_amount, custom_amount.get_first_child ()); var selection_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); - selection_box.add (custom_amount); - selection_box.add (or_label); - selection_box.add (one_dollar); - selection_box.add (five_dollar); - selection_box.add (ten_dollar); + selection_box.append (custom_amount); + selection_box.append (or_label); + selection_box.append (one_dollar); + selection_box.append (five_dollar); + selection_box.append (ten_dollar); Regex? email_regex = null; Regex? expiration_regex = null; @@ -151,13 +155,18 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { wrap = true, xalign = 0 }; - email_label.get_style_context ().add_class (Granite.STYLE_CLASS_SMALL_LABEL); + email_label.add_css_class (Granite.STYLE_CLASS_SMALL_LABEL); + + var card_number_entry_controllerfocus = new Gtk.EventControllerFocus (); card_number_entry = new AppCenter.Widgets.CardNumberEntry () { activates_default = true, hexpand = true, margin_bottom = 6 }; + card_number_entry.add_controller (card_number_entry_controllerfocus); + + var expiration_focus_controller = new Gtk.EventControllerFocus (); card_expiration_entry = new Granite.ValidatedEntry.from_regex (expiration_regex) { activates_default = true, @@ -167,6 +176,7 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { /// TRANSLATORS: Don't change the order, only transliterate placeholder_text = _("MM / YY") }; + card_expiration_entry.add_controller (expiration_focus_controller); card_cvc_entry = new Granite.ValidatedEntry.from_regex (cvc_regex) { activates_default = true, @@ -196,7 +206,7 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { card_layout = new Gtk.Grid () { column_spacing = 12 }; - card_layout.get_style_context ().add_class ("login"); + card_layout.add_css_class ("login"); card_layout.attach (overlay, 0, 0, 1, 2); card_layout.attach (primary_label, 1, 0); card_layout.attach (secondary_label, 1, 1); @@ -213,19 +223,17 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { layouts.add_named (card_layout, "card"); layouts.set_visible_child_name ("card"); - var content_area = get_content_area (); - content_area.add (layouts); - content_area.show_all (); + get_content_area ().append (layouts); custom_amount.grab_focus (); cancel_button = (Gtk.Button) add_button (_("Cancel"), Gtk.ResponseType.CLOSE); pay_button = (Gtk.Button) add_button (_("Pay $%d.00").printf (amount), Gtk.ResponseType.APPLY); - pay_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + pay_button.add_css_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); pay_button.sensitive = false; - set_default (pay_button); + set_default_widget (pay_button); response.connect (on_response); @@ -255,6 +263,12 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { amount = 10; }); + custom_amount_controllerkey.key_released.connect ((keyval, keycode, state) => { + if (keyval == Gdk.Key.Return || keyval == Gdk.Key.KP_Enter) { + activate_default (); + } + }); + email_entry.changed.connect (() => { if (" " in email_entry.text) { email_entry.text = email_entry.text.replace (" ", ""); @@ -268,7 +282,7 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { is_payment_sensitive (); }); - card_number_entry.bind_property ("has-focus", card_number_entry, "visibility"); + card_number_entry_controllerfocus.bind_property ("contains-focus", card_number_entry, "visibility"); card_expiration_entry.changed.connect (() => { if (" " in card_expiration_entry.text) { @@ -282,7 +296,7 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { is_payment_sensitive (); }); - card_expiration_entry.focus_out_event.connect (() => { + expiration_focus_controller.leave.connect (() => { var expiration_text = card_expiration_entry.text; if (!("/" in expiration_text) && expiration_text.char_count () > 2) { int position = 2; @@ -310,21 +324,19 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { var label = new Gtk.Label (_("Processing")) { hexpand = true }; - label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); + label.add_css_class (Granite.STYLE_CLASS_H2_LABEL); var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12) { valign = Gtk.Align.CENTER, vexpand = true }; - - box.add (spinner); - box.add (label); + box.append (spinner); + box.append (label); processing_layout = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); - processing_layout.add (box); + processing_layout.append (box); layouts.add_named (processing_layout, "processing"); - layouts.show_all (); } layouts.set_visible_child_name ("processing"); @@ -339,7 +351,7 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { wrap = true, xalign = 0 }; - primary_label.get_style_context ().add_class (Granite.STYLE_CLASS_PRIMARY_LABEL); + primary_label.add_css_class ("primary"); secondary_error_label = new Gtk.Label (error_reason) { max_width_chars = 35, @@ -347,11 +359,11 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { xalign = 0 }; - var icon = new Gtk.Image.from_icon_name (Build.PROJECT_NAME, Gtk.IconSize.DIALOG) { + var icon = new Gtk.Image.from_icon_name (Build.PROJECT_NAME) { pixel_size = 48 }; - var overlay_icon = new Gtk.Image.from_icon_name ("dialog-warning", Gtk.IconSize.LARGE_TOOLBAR) { + var overlay_icon = new Gtk.Image.from_icon_name ("dialog-warning") { halign = Gtk.Align.END, valign = Gtk.Align.END, pixel_size = 24 @@ -372,10 +384,9 @@ public class AppCenter.Widgets.StripeDialog : Granite.Dialog { grid.attach (secondary_error_label, 1, 1); error_layout = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); - error_layout.add (grid); + error_layout.append (grid); layouts.add_named (error_layout, "error"); - layouts.show_all (); } else { secondary_error_label.label = error_reason; } diff --git a/src/Dialogs/UninstallConfirmDialog.vala b/src/Dialogs/UninstallConfirmDialog.vala index 91b04a914..39702ac48 100644 --- a/src/Dialogs/UninstallConfirmDialog.vala +++ b/src/Dialogs/UninstallConfirmDialog.vala @@ -39,6 +39,6 @@ public class UninstallConfirmDialog : Granite.MessageDialog { } var uninstall_button = add_button (_("Uninstall"), Gtk.ResponseType.ACCEPT); - uninstall_button.get_style_context ().add_class (Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); + uninstall_button.get_style_context ().add_class (Granite.STYLE_CLASS_DESTRUCTIVE_ACTION); } } diff --git a/src/Dialogs/UpgradeFailDialog.vala b/src/Dialogs/UpgradeFailDialog.vala index 2835977b3..41dd79e58 100644 --- a/src/Dialogs/UpgradeFailDialog.vala +++ b/src/Dialogs/UpgradeFailDialog.vala @@ -45,7 +45,7 @@ public class UpgradeFailDialog : Granite.MessageDialog { if (package.is_flatpak) { var repair_button = add_button (_("Repair"), REPAIR_RESPONSE_ID); - repair_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + repair_button.get_style_context ().add_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); } show_error_details (error_message); diff --git a/src/MainWindow.vala b/src/MainWindow.vala index bb9c33ef1..7bcc90273 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -14,27 +14,23 @@ * with this program. If not, see http://www.gnu.org/licenses/. */ -public class AppCenter.MainWindow : Hdy.ApplicationWindow { +public class AppCenter.MainWindow : Gtk.ApplicationWindow { public const int VALID_QUERY_LENGTH = 3; - public bool working { get; set; } private AppCenter.SearchView search_view; - private Gtk.EventControllerKey search_entry_eventcontrollerkey; private Gtk.Revealer view_mode_revealer; private Gtk.SearchEntry search_entry; - private Gtk.ModelButton refresh_menuitem; + private Gtk.Button refresh_menuitem; private Gtk.Button return_button; private Gtk.Label updates_badge; private Gtk.Revealer updates_badge_revealer; - private Granite.Widgets.Toast toast; - private Granite.Widgets.OverlayBar overlaybar; - private Hdy.Deck deck; + private Granite.Toast toast; + private Granite.OverlayBar overlaybar; + private Adw.Leaflet leaflet; private AppCenterCore.Package? last_installed_package; - private uint configure_id; - private bool mimetype; public static Views.AppListUpdateView installed_view { get; private set; } @@ -42,10 +38,10 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { public MainWindow (Gtk.Application app) { Object (application: app); - search_entry.grab_focus_without_selecting (); + search_entry.grab_focus (); var go_back = new SimpleAction ("go-back", null); - go_back.activate.connect (() => deck.navigate (BACK)); + go_back.activate.connect (() => leaflet.navigate (BACK)); add_action (go_back); var focus_search = new SimpleAction ("focus-search", null); @@ -55,16 +51,6 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { app.set_accels_for_action ("win.go-back", {"Left", "Back"}); app.set_accels_for_action ("win.focus-search", {"f"}); - button_release_event.connect ((event) => { - // On back mouse button pressed - if (event.button == 8) { - deck.navigate (BACK); - return true; - } - - return false; - }); - search_entry.search_changed.connect (() => trigger_search ()); unowned var aggregator = AppCenterCore.BackendAggregator.get_default (); @@ -93,7 +79,7 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { title = _(Build.APP_NAME); - toast = new Granite.Widgets.Toast (""); + toast = new Granite.Toast (""); toast.default_action.connect (() => { if (last_installed_package != null) { @@ -121,12 +107,13 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { return_button = new Gtk.Button () { action_name = "win.go-back", - no_show_all = true, - valign = Gtk.Align.CENTER + valign = Gtk.Align.CENTER, + visible = false }; - return_button.get_style_context ().add_class (Granite.STYLE_CLASS_BACK_BUTTON); + return_button.add_css_class (Granite.STYLE_CLASS_BACK_BUTTON); - var updates_button = new Gtk.Button.from_icon_name ("software-update-available", Gtk.IconSize.LARGE_TOOLBAR); + var updates_button = new Gtk.Button.from_icon_name ("software-update-available"); + updates_button.add_css_class (Granite.STYLE_CLASS_LARGE_ICONS); var badge_provider = new Gtk.CssProvider (); badge_provider.load_from_resource ("io/elementary/appcenter/badge.css"); @@ -138,22 +125,18 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { badge_context.add_provider (badge_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); updates_badge_revealer = new Gtk.Revealer () { + can_target = false, child = updates_badge, halign = Gtk.Align.END, valign = Gtk.Align.START, transition_type = Gtk.RevealerTransitionType.CROSSFADE }; - var eventbox_badge = new Gtk.EventBox () { - child = updates_badge_revealer, - halign = Gtk.Align.END - }; - var updates_overlay = new Gtk.Overlay () { child = updates_button, tooltip_text = C_("view", "Updates & installed apps") }; - updates_overlay.add_overlay (eventbox_badge); + updates_overlay.add_overlay (updates_badge_revealer); view_mode_revealer = new Gtk.Revealer () { child = updates_overlay, @@ -161,15 +144,16 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { transition_type = Gtk.RevealerTransitionType.SLIDE_LEFT }; + var search_entry_eventcontrollerkey = new Gtk.EventControllerKey (); + search_entry = new Gtk.SearchEntry () { hexpand = true, placeholder_text = _("Search Apps"), valign = Gtk.Align.CENTER }; + search_entry.add_controller (search_entry_eventcontrollerkey); - search_entry_eventcontrollerkey = new Gtk.EventControllerKey (search_entry); - - var search_clamp = new Hdy.Clamp () { + var search_clamp = new Adw.Clamp () { child = search_entry }; @@ -182,35 +166,33 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { "app.refresh" ); - refresh_menuitem = new Gtk.ModelButton () { - action_name = "app.refresh" + refresh_menuitem = new Gtk.Button () { + action_name = "app.refresh", + child = refresh_accellabel }; - refresh_menuitem.get_child ().destroy (); - refresh_menuitem.add (refresh_accellabel); + refresh_menuitem.add_css_class (Granite.STYLE_CLASS_MENUITEM); - var menu_popover_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { - margin_bottom = 6, - margin_top = 6 - }; - menu_popover_box.add (automatic_updates_button); - menu_popover_box.add (refresh_menuitem); - menu_popover_box.show_all (); + var menu_popover_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + menu_popover_box.append (automatic_updates_button); + menu_popover_box.append (refresh_menuitem); - var menu_popover = new Gtk.Popover (null) { + var menu_popover = new Gtk.Popover () { child = menu_popover_box }; + menu_popover.add_css_class (Granite.STYLE_CLASS_MENU); var menu_button = new Gtk.MenuButton () { - image = new Gtk.Image.from_icon_name ("open-menu", Gtk.IconSize.LARGE_TOOLBAR), + icon_name = "open-menu", popover = menu_popover, tooltip_text = _("Settings"), valign = Gtk.Align.CENTER }; + menu_button.add_css_class (Granite.STYLE_CLASS_LARGE_ICONS); - var headerbar = new Hdy.HeaderBar () { - show_close_button = true + var headerbar = new Gtk.HeaderBar () { + show_title_buttons = true, + title_widget = search_clamp }; - headerbar.set_custom_title (search_clamp); headerbar.pack_start (return_button); headerbar.pack_end (menu_button); headerbar.pack_end (view_mode_revealer); @@ -218,17 +200,18 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { var homepage = new Homepage (); installed_view = new Views.AppListUpdateView (); - deck = new Hdy.Deck () { - can_swipe_back = true + leaflet = new Adw.Leaflet () { + can_navigate_back = true, + can_unfold = false }; - deck.add (homepage); + leaflet.append (homepage); var overlay = new Gtk.Overlay () { - child = deck + child = leaflet }; overlay.add_overlay (toast); - overlaybar = new Granite.Widgets.OverlayBar (overlay); + overlaybar = new Granite.OverlayBar (overlay); overlaybar.bind_property ("active", overlaybar, "visible"); var network_info_bar_label = new Gtk.Label ("%s %s".printf ( @@ -242,12 +225,11 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { var network_info_bar = new Gtk.InfoBar () { message_type = Gtk.MessageType.WARNING }; - network_info_bar.get_content_area ().add (network_info_bar_label); + network_info_bar.add_child (network_info_bar_label); network_info_bar.add_button (_("Network Settingsā€¦"), Gtk.ResponseType.ACCEPT); var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); - box.add (headerbar); - box.add (network_info_bar); + box.append (network_info_bar); if (Utils.is_running_in_demo_mode ()) { var demo_mode_info_bar_label = new Gtk.Label ("%s %s".printf ( @@ -259,17 +241,17 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { }; var demo_mode_info_bar = new Gtk.InfoBar () { - message_type = Gtk.MessageType.WARNING + message_type = WARNING }; - demo_mode_info_bar.get_content_area ().add (demo_mode_info_bar_label); + demo_mode_info_bar.add_child (demo_mode_info_bar_label); - box.add (demo_mode_info_bar); + box.append (demo_mode_info_bar); } - box.add (overlay); - box.show_all (); + box.append (overlay); child = box; + set_titlebar (headerbar); App.settings.bind ( "automatic-updates", @@ -279,7 +261,6 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { ); var client = AppCenterCore.Client.get_default (); - automatic_updates_button.notify["active"].connect (() => { if (automatic_updates_button.active) { client.update_cache.begin (true, AppCenterCore.Client.CacheUpdateType.FLATPAK); @@ -297,7 +278,7 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { network_info_bar.response.connect (() => { try { - Gtk.show_uri_on_window (this, "settings://network", Gdk.CURRENT_TIME); + Gtk.show_uri (this, "settings://network", Gdk.CURRENT_TIME); } catch (GLib.Error e) { critical (e.message); } @@ -307,10 +288,6 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { go_to_installed (); }); - eventbox_badge.button_release_event.connect (() => { - go_to_installed (); - }); - homepage.show_category.connect ((category) => { show_category (category); }); @@ -323,14 +300,14 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { show_package (package); }); - deck.notify["visible-child"].connect (() => { - if (!deck.transition_running) { + leaflet.notify["visible-child"].connect (() => { + if (!leaflet.child_transition_running) { update_navigation (); } }); - deck.notify["transition-running"].connect (() => { - if (!deck.transition_running) { + leaflet.notify["child-transition-running"].connect (() => { + if (!leaflet.child_transition_running) { update_navigation (); } }); @@ -347,37 +324,9 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { break; } }); - - delete_event.connect (() => { - ((AppCenter.App) application).request_background.begin (() => destroy ()); - - return Gdk.EVENT_STOP; - }); - } - - public override bool configure_event (Gdk.EventConfigure event) { - if (configure_id == 0) { - /* Avoid spamming the settings */ - configure_id = Timeout.add (200, () => { - configure_id = 0; - - App.settings.set_boolean ("window-maximized", is_maximized); - - if (!is_maximized) { - int width, height; - get_size (out width, out height); - App.settings.set_int ("window-height", height); - App.settings.set_int ("window-width", width); - } - - return GLib.Source.REMOVE; - }); - } - - return base.configure_event (event); } - public override bool delete_event (Gdk.EventAny event) { + public override bool close_request () { installed_view.clear (); if (working) { @@ -393,6 +342,8 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { return true; } + ((AppCenter.App) application).request_background.begin (() => destroy ()); + return false; } @@ -410,13 +361,13 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { } public void show_package (AppCenterCore.Package package, bool remember_history = true) { - if (deck.transition_running) { + if (leaflet.child_transition_running) { return; } var package_hash = package.hash; - var pk_child = deck.get_child_by_name (package_hash) as Views.AppInfoView; + var pk_child = leaflet.get_child_by_name (package_hash) as Views.AppInfoView; if (pk_child != null && pk_child.to_recycle) { // Don't switch to a view that needs recycling pk_child.destroy (); @@ -425,49 +376,48 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { if (pk_child != null) { pk_child.view_entered (); - deck.visible_child = pk_child; + leaflet.visible_child = pk_child; return; } var app_info_view = new Views.AppInfoView (package); - app_info_view.show_all (); - deck.add (app_info_view); - deck.visible_child = app_info_view; + leaflet.append (app_info_view); + leaflet.visible_child = app_info_view; - if (deck.get_adjacent_child (BACK) is Views.AppInfoView) { - var adjacent_app_info_view = (Views.AppInfoView)deck.get_adjacent_child (BACK); + if (leaflet.get_adjacent_child (BACK) is Views.AppInfoView) { + var adjacent_app_info_view = (Views.AppInfoView)leaflet.get_adjacent_child (BACK); if ( !remember_history && adjacent_app_info_view.package.normalized_component_id == package.normalized_component_id ) { - deck.remove (adjacent_app_info_view); + leaflet.remove (adjacent_app_info_view); update_navigation (); } } app_info_view.show_other_package.connect ((_package, remember_history, transition) => { if (!transition) { - deck.transition_duration = 0; + leaflet.mode_transition_duration = 0; } show_package (_package, remember_history); - deck.transition_duration = 200; + leaflet.mode_transition_duration = 200; }); } private void update_navigation () { - var previous_child = deck.get_adjacent_child (BACK); + var previous_child = leaflet.get_adjacent_child (BACK); - if (deck.visible_child is Homepage) { + if (leaflet.visible_child is Homepage) { view_mode_revealer.reveal_child = true; configure_search (true, _("Search Apps"), ""); - } else if (deck.visible_child is CategoryView) { - var current_category = ((CategoryView) deck.visible_child).category; + } else if (leaflet.visible_child is CategoryView) { + var current_category = ((CategoryView) leaflet.visible_child).category; view_mode_revealer.reveal_child = false; configure_search (true, _("Search %s").printf (current_category.name), ""); - } else if (deck.visible_child == search_view) { + } else if (leaflet.visible_child == search_view) { if (previous_child is CategoryView) { var previous_category = ((CategoryView) previous_child).category; configure_search (true, _("Search %s").printf (previous_category.name)); @@ -476,10 +426,10 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { configure_search (true); view_mode_revealer.reveal_child = true; } - } else if (deck.visible_child is Views.AppInfoView) { + } else if (leaflet.visible_child is Views.AppInfoView) { view_mode_revealer.reveal_child = false; configure_search (false); - } else if (deck.visible_child is Views.AppListUpdateView) { + } else if (leaflet.visible_child is Views.AppListUpdateView) { view_mode_revealer.reveal_child = true; configure_search (false); } @@ -499,11 +449,11 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { set_return_name (C_("view", "Installed")); } - while (deck.get_adjacent_child (FORWARD) != null) { - var next_child = deck.get_adjacent_child (FORWARD); - if (next_child is AppCenter.Views.AppListUpdateView) { - deck.remove (next_child); - } else { + while (leaflet.get_adjacent_child (FORWARD) != null) { + var next_child = leaflet.get_adjacent_child (FORWARD); + leaflet.remove (next_child); + + if (!(next_child is AppCenter.Views.AppListUpdateView)) { next_child.destroy (); } } @@ -511,10 +461,10 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { public void go_to_installed () { if (installed_view.parent == null) { - deck.add (installed_view); + leaflet.append (installed_view); } - installed_view.show_all (); - deck.visible_child = installed_view; + + leaflet.visible_child = installed_view; } public void search (string term, bool mimetype = false) { @@ -526,7 +476,7 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { last_installed_package = package; // Only show a toast when we're not on the installed app's page - if (deck.visible_child is Views.AppInfoView && ((Views.AppInfoView) deck.visible_child).package == package) { + if (leaflet.visible_child is Views.AppInfoView && ((Views.AppInfoView) leaflet.visible_child).package == package) { return; } @@ -549,16 +499,15 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { view_mode_revealer.reveal_child = !query_valid; if (query_valid) { - if (deck.visible_child != search_view) { + if (leaflet.visible_child != search_view) { search_view = new AppCenter.SearchView (); - search_view.show_all (); search_view.show_app.connect ((package) => { show_package (package); }); - deck.add (search_view); - deck.visible_child = search_view; + leaflet.append (search_view); + leaflet.visible_child = search_view; } search_view.clear (); @@ -574,7 +523,7 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { } else { AppStream.Category current_category = null; - var previous_child = deck.get_adjacent_child (BACK); + var previous_child = leaflet.get_adjacent_child (BACK); if (previous_child is CategoryView) { current_category = ((CategoryView) previous_child).category; } @@ -585,14 +534,14 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { } else { // Prevent navigating away from category views when backspacing - if (deck.visible_child == search_view) { + if (leaflet.visible_child == search_view) { search_view.clear (); search_view.current_search_term = search_entry.text; // When replacing text with text don't go back Idle.add (() => { if (search_entry.text.length == 0) { - deck.navigate (BACK); + leaflet.navigate (BACK); } return Source.REMOVE; @@ -610,7 +559,6 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { return_button.label = return_name; } - return_button.no_show_all = return_name == null; return_button.visible = return_name != null; } @@ -623,21 +571,21 @@ public class AppCenter.MainWindow : Hdy.ApplicationWindow { } if (sensitive) { - search_entry.grab_focus_without_selecting (); + search_entry.grab_focus (); } } private void show_category (AppStream.Category category) { - var child = deck.get_child_by_name (category.name); + var child = leaflet.get_child_by_name (category.name); if (child != null) { - deck.visible_child = child; + leaflet.visible_child = child; return; } var category_view = new CategoryView (category); - deck.add (category_view); - deck.visible_child = category_view; + leaflet.append (category_view); + leaflet.visible_child = category_view; category_view.show_app.connect ((package) => { show_package (package); diff --git a/src/Views/AppInfoView.vala b/src/Views/AppInfoView.vala index 93f35f44e..df0264627 100644 --- a/src/Views/AppInfoView.vala +++ b/src/Views/AppInfoView.vala @@ -39,9 +39,9 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { private Gtk.ListStore origin_liststore; private Gtk.Overlay screenshot_overlay; private Gtk.Revealer origin_combo_revealer; - private Hdy.Carousel release_carousel; - private Hdy.Carousel screenshot_carousel; - private Hdy.Clamp screenshot_not_found_clamp; + private Adw.Carousel release_carousel; + private Adw.Carousel screenshot_carousel; + private Adw.Clamp screenshot_not_found_clamp; private Gtk.Stack screenshot_stack; private Gtk.Label app_description; private Widgets.SizeLabel size_label; @@ -70,8 +70,8 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { var appinfoview_provider = new Gtk.CssProvider (); appinfoview_provider.load_from_resource ("io/elementary/appcenter/AppInfoView.css"); - Gtk.StyleContext.add_provider_for_screen ( - Gdk.Screen.get_default (), + Gtk.StyleContext.add_provider_for_display ( + Gdk.Display.get_default (), appinfoview_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION ); @@ -105,14 +105,14 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { text_color = Granite.contrasting_foreground_color (bg_rgba).to_string (); accent_css = "@define-color accent_color %s;".printf (primary_color); - accent_provider.load_from_data (accent_css, accent_css.length); + accent_provider.load_from_data (accent_css.data); } } var colored_css = BANNER_STYLE_CSS.printf (bg_color, text_color); colored_css += accent_css; - accent_provider.load_from_data (colored_css, colored_css.length); + accent_provider.load_from_data (colored_css.data); } catch (GLib.Error e) { critical ("Unable to set accent color: %s", e.message); } @@ -154,7 +154,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { wrap = true, xalign = 0 }; - app_title.get_style_context ().add_class (Granite.STYLE_CLASS_H1_LABEL); + app_title.add_css_class (Granite.STYLE_CLASS_H1_LABEL); app_subtitle = new Gtk.Label (null) { label = package.get_summary (), @@ -163,8 +163,8 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { wrap_mode = Pango.WrapMode.WORD_CHAR, xalign = 0 }; - app_subtitle.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL); - app_subtitle.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + app_subtitle.add_css_class (Granite.STYLE_CLASS_H3_LABEL); + app_subtitle.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); origin_liststore = new Gtk.ListStore (2, typeof (AppCenterCore.Package), typeof (string)); origin_combo = new Gtk.ComboBox.with_model (origin_liststore) { @@ -185,15 +185,16 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { tooltip_text = _("Uninstall"), margin_end = 12 }; + uninstall_button.add_css_class ("raised"); unowned var uninstall_button_context = uninstall_button.get_style_context (); - uninstall_button_context.add_class (Gtk.STYLE_CLASS_RAISED); uninstall_button_context.add_provider (banner_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); uninstall_button_context.add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); uninstall_button_revealer = new Gtk.Revealer () { child = uninstall_button, - transition_type = Gtk.RevealerTransitionType.SLIDE_LEFT + transition_type = Gtk.RevealerTransitionType.SLIDE_LEFT, + overflow = VISIBLE }; var button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0) { @@ -201,8 +202,8 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { valign = Gtk.Align.CENTER, hexpand = true }; - button_box.add (uninstall_button_revealer); - button_box.add (action_stack); + button_box.append (uninstall_button_revealer); + button_box.append (action_stack); var header_grid = new Gtk.Grid () { column_spacing = 12, @@ -217,24 +218,24 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { size_label = new Widgets.SizeLabel () { halign = Gtk.Align.END }; - size_label.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + size_label.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); header_grid.attach (size_label, 1, 1); } var header_box = new Gtk.Box (HORIZONTAL, 6); - header_box.add (app_icon_overlay); - header_box.add (header_grid); + header_box.append (app_icon_overlay); + header_box.append (header_grid); - var header_clamp = new Hdy.Clamp () { + var header_clamp = new Adw.Clamp () { child = header_box, maximum_size = MAX_WIDTH }; - var header = new Gtk.Grid () { + var header = new Gtk.Box (HORIZONTAL, 0) { hexpand = true }; - header.add (header_clamp); + header.append (header_clamp); unowned var header_context = header.get_style_context (); header_context.add_class ("banner"); @@ -242,17 +243,17 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { header_context.add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); unowned var action_button_context = action_button.get_style_context (); - action_button_context.add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + action_button_context.add_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); action_button_context.add_provider (banner_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); action_button_context.add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); unowned var open_button_context = open_button.get_style_context (); - open_button_context.add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + open_button_context.add_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); open_button_context.add_provider (banner_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); open_button_context.add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); unowned var cancel_button_context = cancel_button.get_style_context (); - cancel_button_context.add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + cancel_button_context.add_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); cancel_button_context.add_provider (banner_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); cancel_button_context.add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); @@ -287,13 +288,13 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { row_spacing = 24, selection_mode = Gtk.SelectionMode.NONE }; - oars_flowbox.get_style_context ().add_class ("content-warning-box"); + oars_flowbox.add_css_class ("content-warning-box"); oars_flowbox_revealer = new Gtk.Revealer () { child = oars_flowbox }; - var content_warning_clamp = new Hdy.Clamp () { + var content_warning_clamp = new Adw.Clamp () { child = oars_flowbox_revealer, maximum_size = MAX_WIDTH }; @@ -307,7 +308,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "security-low-symbolic" ); - oars_flowbox.add (uncurated); + oars_flowbox.append (uncurated); } #endif @@ -333,7 +334,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "metainfo-locale" ); - oars_flowbox.add (locale); + oars_flowbox.append (locale); } else if (percent_translated == 0) { var locale = new ContentType ( _("Not Translated"), @@ -341,7 +342,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "metainfo-locale" ); - oars_flowbox.add (locale); + oars_flowbox.append (locale); } else { var locale = new ContentType ( _("Not Fully Translated"), @@ -349,7 +350,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "metainfo-locale" ); - oars_flowbox.add (locale); + oars_flowbox.append (locale); } } } @@ -374,7 +375,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "oars-conflict-symbolic" ); - oars_flowbox.add (conflict); + oars_flowbox.append (conflict); } if ( @@ -397,13 +398,13 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "oars-violence-symbolic" ); - oars_flowbox.add (violence); + oars_flowbox.append (violence); } if ( rating.get_value ("drugs-narcotics") > AppStream.ContentRatingValue.NONE ) { - oars_flowbox.add (drugs); + oars_flowbox.append (drugs); } if ( @@ -411,7 +412,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { rating.get_value ("sex-themes") > AppStream.ContentRatingValue.NONE || rating.get_value ("sex-prostitution") > AppStream.ContentRatingValue.NONE ) { - oars_flowbox.add (sex_nudity); + oars_flowbox.append (sex_nudity); } if ( @@ -421,13 +422,13 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { rating.get_value ("language-humor") > AppStream.ContentRatingValue.MILD || rating.get_value ("language-discrimination") > AppStream.ContentRatingValue.NONE ) { - oars_flowbox.add (language); + oars_flowbox.append (language); } if ( rating.get_value ("money-gambling") > AppStream.ContentRatingValue.NONE ) { - oars_flowbox.add (gambling); + oars_flowbox.append (gambling); } var social_chat_value = rating.get_value ("social-chat"); @@ -442,7 +443,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "system-users-symbolic" ); - oars_flowbox.add (multiplayer); + oars_flowbox.append (multiplayer); } var social_audio_value = rating.get_value ("social-audio"); @@ -465,7 +466,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "oars-chat-symbolic" ); - oars_flowbox.add (social); + oars_flowbox.append (social); } if (rating.get_value ("social-location") > AppStream.ContentRatingValue.NONE) { @@ -475,7 +476,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "oars-social-location-symbolic" ); - oars_flowbox.add (location); + oars_flowbox.append (location); } var social_info_value = rating.get_value ("social-info"); @@ -496,7 +497,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "oars-socal-info-symbolic" ); - oars_flowbox.add (social_info); + oars_flowbox.append (social_info); } } @@ -507,51 +508,48 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { #endif if (screenshots.length > 0) { - screenshot_carousel = new Hdy.Carousel () { + screenshot_carousel = new Adw.Carousel () { allow_mouse_drag = true, allow_scroll_wheel = false, height_request = 500 }; - var screenshot_switcher = new Hdy.CarouselIndicatorDots () { + var screenshot_switcher = new Adw.CarouselIndicatorDots () { carousel = screenshot_carousel }; var screenshot_box = new Gtk.Box (VERTICAL, 0); - screenshot_box.add (screenshot_carousel); - screenshot_box.add (screenshot_switcher); + screenshot_box.append (screenshot_carousel); + screenshot_box.append (screenshot_switcher); screenshot_previous = new ArrowButton ("go-previous-symbolic") { sensitive = false, - no_show_all = true + visible = false }; screenshot_previous.clicked.connect (() => { - GLib.List screenshot_children = screenshot_carousel.get_children (); - var index = screenshot_carousel.get_position (); + var index = (int) screenshot_carousel.position; if (index > 0) { - screenshot_carousel.scroll_to (screenshot_children.nth_data ((uint) index - 1)); + screenshot_carousel.scroll_to (screenshot_carousel.get_nth_page (index - 1), true); } }); screenshot_next = new ArrowButton ("go-next-symbolic") { - no_show_all = true + visible = false }; + screenshot_next.clicked.connect (() => { - GLib.List screenshot_children = screenshot_carousel.get_children (); - var index = screenshot_carousel.get_position (); - if (index < screenshot_children.length () - 1) { - screenshot_carousel.scroll_to (screenshot_children.nth_data ((uint) index + 1)); + var index = (int) screenshot_carousel.position; + if (index < screenshot_carousel.n_pages - 1) { + screenshot_carousel.scroll_to (screenshot_carousel.get_nth_page (index + 1), true); } }); screenshot_carousel.page_changed.connect ((index) => { screenshot_previous.sensitive = screenshot_next.sensitive = true; - GLib.List screenshot_children = screenshot_carousel.get_children (); - if (index == 0) { screenshot_previous.sensitive = false; - } else if (index == screenshot_children.length () - 1) { + } else if (index == screenshot_carousel.n_pages - 1) { screenshot_next.sensitive = false; } }); @@ -570,52 +568,27 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { transition_type = Gtk.RevealerTransitionType.CROSSFADE }; + var screenshot_motion_controller = new Gtk.EventControllerMotion (); + screenshot_overlay = new Gtk.Overlay () { child = screenshot_box }; screenshot_overlay.add_overlay (screenshot_arrow_revealer_p); screenshot_overlay.add_overlay (screenshot_arrow_revealer_n); + screenshot_overlay.add_controller (screenshot_motion_controller); - screenshot_carousel.add_events (Gdk.EventMask.ENTER_NOTIFY_MASK); - screenshot_carousel.add_events (Gdk.EventMask.LEAVE_NOTIFY_MASK); - - screenshot_overlay.add_events (Gdk.EventMask.ENTER_NOTIFY_MASK); - screenshot_overlay.add_events (Gdk.EventMask.LEAVE_NOTIFY_MASK); - - screenshot_overlay.enter_notify_event.connect (() => { + screenshot_motion_controller.enter.connect (() => { screenshot_arrow_revealer_n.reveal_child = true; screenshot_arrow_revealer_p.reveal_child = true; - return false; }); - screenshot_overlay.leave_notify_event.connect ((event) => { - // Prevent hiding prev/next button when they're marked as insensitive - if (event.mode != Gdk.CrossingMode.STATE_CHANGED) { - screenshot_arrow_revealer_n.reveal_child = false; - screenshot_arrow_revealer_p.reveal_child = false; - } - - return false; - }); - - screenshot_carousel.enter_notify_event.connect (() => { - screenshot_arrow_revealer_n.reveal_child = true; - screenshot_arrow_revealer_p.reveal_child = true; - return false; - }); - - screenshot_carousel.leave_notify_event.connect ((event) => { - // Prevent hiding prev/next button when they're marked as insensitive - if (event.mode != Gdk.CrossingMode.STATE_CHANGED) { - screenshot_arrow_revealer_n.reveal_child = false; - screenshot_arrow_revealer_p.reveal_child = false; - } - - return false; + screenshot_motion_controller.leave.connect (() => { + screenshot_arrow_revealer_n.reveal_child = false; + screenshot_arrow_revealer_p.reveal_child = false; }); var app_screenshot_spinner = new Gtk.Spinner () { - active = true, + spinning = true, halign = Gtk.Align.CENTER, valign = Gtk.Align.CENTER }; @@ -625,9 +598,9 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { unowned var screenshot_not_found_context = screenshot_not_found.get_style_context (); screenshot_not_found_context.add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); screenshot_not_found_context.add_class ("screenshot"); - screenshot_not_found_context.add_class (Gtk.STYLE_CLASS_DIM_LABEL); + screenshot_not_found_context.add_class (Granite.STYLE_CLASS_DIM_LABEL); - screenshot_not_found_clamp = new Hdy.Clamp () { + screenshot_not_found_clamp = new Adw.Clamp () { child = screenshot_not_found, maximum_size = MAX_WIDTH }; @@ -635,9 +608,9 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { screenshot_stack = new Gtk.Stack () { transition_type = Gtk.StackTransitionType.CROSSFADE }; - screenshot_stack.add (app_screenshot_spinner); - screenshot_stack.add (screenshot_overlay); - screenshot_stack.add (screenshot_not_found_clamp); + screenshot_stack.add_child (app_screenshot_spinner); + screenshot_stack.add_child (screenshot_overlay); + screenshot_stack.add_child (screenshot_not_found_clamp); stack_context = screenshot_stack.get_style_context (); stack_context.add_class ("loading"); @@ -653,19 +626,19 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { }; whats_new_label = new Granite.HeaderLabel (_("What's New:")) { - no_show_all = true + visible = false }; - release_carousel = new Hdy.Carousel () { + release_carousel = new Adw.Carousel () { allow_mouse_drag = true, allow_long_swipes = true, allow_scroll_wheel = false }; var content_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 24); - content_box.add (app_description); - content_box.add (whats_new_label); - content_box.get_style_context ().add_class ("content-box"); + content_box.append (app_description); + content_box.append (whats_new_label); + content_box.add_css_class ("content-box"); if (package_component.get_addons ().length > 0) { extension_box = new Gtk.ListBox () { @@ -683,10 +656,10 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { halign = Gtk.Align.START, margin_top = 12 }; - extension_label.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); + extension_label.add_css_class (Granite.STYLE_CLASS_H2_LABEL); - content_box.add (extension_label); - content_box.add (extension_box); + content_box.append (extension_label); + content_box.append (extension_box); load_extensions.begin (); } @@ -705,50 +678,50 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { var license_button = new UrlButton (_(license_copy), license_url, "text-x-copying-symbolic"); - links_flowbox.add (license_button); + links_flowbox.append (license_button); } var homepage_url = package_component.get_url (AppStream.UrlKind.HOMEPAGE); if (homepage_url != null) { var website_button = new UrlButton (_("Homepage"), homepage_url, "web-browser-symbolic"); - links_flowbox.add (website_button); + links_flowbox.append (website_button); } var translate_url = package_component.get_url (AppStream.UrlKind.TRANSLATE); if (translate_url != null) { var translate_button = new UrlButton (_("Translate"), translate_url, "preferences-desktop-locale-symbolic"); - links_flowbox.add (translate_button); + links_flowbox.append (translate_button); } var bugtracker_url = package_component.get_url (AppStream.UrlKind.BUGTRACKER); if (bugtracker_url != null) { var bugtracker_button = new UrlButton (_("Send Feedback"), bugtracker_url, "bug-symbolic"); - links_flowbox.add (bugtracker_button); + links_flowbox.append (bugtracker_button); } var help_url = package_component.get_url (AppStream.UrlKind.HELP); if (help_url != null) { var help_button = new UrlButton (_("Help"), help_url, "dialog-question-symbolic"); - links_flowbox.add (help_button); + links_flowbox.append (help_button); } #if PAYMENTS if (package.get_payments_key () != null) { var fund_button = new FundButton (package); - links_flowbox.add (fund_button); + links_flowbox.append (fund_button); } #endif - var body_clamp = new Hdy.Clamp () { + var body_clamp = new Adw.Clamp () { child = content_box, maximum_size = MAX_WIDTH }; - var links_clamp = new Hdy.Clamp () { + var links_clamp = new Adw.Clamp () { child = links_flowbox, maximum_size = MAX_WIDTH }; - links_clamp.get_style_context ().add_class ("content-box"); + links_clamp.add_css_class ("content-box"); var author_view = new AuthorView (package, MAX_WIDTH); @@ -757,72 +730,70 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { }); var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12); - box.add (header); - box.add (content_warning_clamp); + box.append (header); + box.append (content_warning_clamp); if (screenshots.length > 0) { - box.add (screenshot_stack); + box.append (screenshot_stack); } - box.add (body_clamp); - box.add (release_carousel); - box.add (links_clamp); - box.add (author_view); + box.append (body_clamp); + box.append (release_carousel); + box.append (links_clamp); + box.append (author_view); - var scrolled = new Gtk.ScrolledWindow (null, null) { + var scrolled = new Gtk.ScrolledWindow () { child = box, hscrollbar_policy = Gtk.PolicyType.NEVER, hexpand = true, vexpand = true }; - var toast = new Granite.Widgets.Toast (_("Link copied to clipboard")); + var toast = new Granite.Toast (_("Link copied to clipboard")); var overlay = new Gtk.Overlay () { child = scrolled }; overlay.add_overlay (toast); - add (overlay); + append (overlay); - open_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + open_button.add_css_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); #if SHARING if (package.is_shareable) { var body = _("Check out %s on AppCenter:").printf (package.get_name ()); var uri = "https://appcenter.elementary.io/%s".printf (package.component.get_id ()); var share_popover = new SharePopover (body, uri); - var share_icon = new Gtk.Image.from_icon_name ("send-to-symbolic", Gtk.IconSize.SMALL_TOOLBAR) { + var share_icon = new Gtk.Image.from_icon_name ("send-to-symbolic") { valign = Gtk.Align.CENTER }; var share_label = new Gtk.Label (_("Share")); var share_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); - share_box.add (share_icon); - share_box.add (share_label); + share_box.append (share_icon); + share_box.append (share_label); var share_button = new Gtk.MenuButton () { child = share_box, + has_frame = false, direction = Gtk.ArrowType.UP, popover = share_popover }; - - unowned var share_button_context = share_button.get_style_context (); - share_button_context.add_class (Gtk.STYLE_CLASS_DIM_LABEL); - share_button_context.add_class (Gtk.STYLE_CLASS_FLAT); + share_button.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); share_popover.link_copied.connect (() => { toast.send_notification (); }); - links_flowbox.add (share_button); + links_flowbox.append (share_button); } #endif view_entered (); set_up_package (); - if (oars_flowbox.get_children ().length () > 0) { + if (oars_flowbox.get_first_child () != null) { oars_flowbox_revealer.reveal_child = true; } @@ -873,7 +844,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { var row = new Widgets.PackageRow.list (extension_package); if (extension_box != null) { - extension_box.add (row); + extension_box.append (row); } }); } @@ -925,7 +896,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "sandbox-escape-symbolic" ); - oars_flowbox.add (sandbox_escape); + oars_flowbox.append (sandbox_escape); } if (AppCenterCore.Package.PermissionsFlags.FILESYSTEM_FULL in package.permissions_flags || AppCenterCore.Package.PermissionsFlags.FILESYSTEM_READ in package.permissions_flags) { @@ -935,7 +906,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "sandbox-files-warning-symbolic" ); - oars_flowbox.add (filesystem); + oars_flowbox.append (filesystem); } else if (AppCenterCore.Package.PermissionsFlags.HOME_FULL in package.permissions_flags || AppCenterCore.Package.PermissionsFlags.HOME_READ in package.permissions_flags) { var home = new ContentType ( _("Home Folder Access"), @@ -943,7 +914,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "sandbox-files-symbolic" ); - oars_flowbox.add (home); + oars_flowbox.append (home); } if (AppCenterCore.Package.PermissionsFlags.AUTOSTART in package.permissions_flags) { @@ -953,7 +924,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "sandbox-autostart-symbolic" ); - oars_flowbox.add (autostart); + oars_flowbox.append (autostart); } if (AppCenterCore.Package.PermissionsFlags.LOCATION in package.permissions_flags) { @@ -963,7 +934,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "sandbox-location-symbolic" ); - oars_flowbox.add (location); + oars_flowbox.append (location); } if (AppCenterCore.Package.PermissionsFlags.NOTIFICATIONS in package.permissions_flags) { @@ -973,7 +944,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "sandbox-notifications-symbolic" ); - oars_flowbox.add (notifications); + oars_flowbox.append (notifications); } if (AppCenterCore.Package.PermissionsFlags.SETTINGS in package.permissions_flags) { @@ -983,7 +954,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { "sandbox-settings-symbolic" ); - oars_flowbox.add (filesystem); + oars_flowbox.append (filesystem); } } @@ -993,8 +964,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { oars_flowbox.insert (runtime_warning, 0); } - if (oars_flowbox.get_children ().length () > 0) { - oars_flowbox.show_all (); + if (oars_flowbox.get_first_child () != null) { oars_flowbox_revealer.reveal_child = true; } } @@ -1063,7 +1033,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { var release_row = new Widgets.ReleaseRow (release); release_row.get_style_context ().add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - release_carousel.add (release_row); + release_carousel.append (release_row); #if HAS_APPSTREAM_1_0 if (package.installed && AppStream.vercmp_simple (release.get_version (), package.get_version ()) <= 0) { @@ -1074,9 +1044,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { } } - whats_new_label.no_show_all = false; - whats_new_label.show (); - release_carousel.show_all (); + whats_new_label.visible = true; } return false; @@ -1153,17 +1121,13 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { } Idle.add (() => { - var number_of_screenshots = screenshot_carousel.get_children ().length (); - - if (number_of_screenshots > 0) { + if (screenshot_carousel.n_pages > 0) { screenshot_stack.visible_child = screenshot_overlay; stack_context.remove_class ("loading"); - if (number_of_screenshots > 1) { - screenshot_next.no_show_all = false; - screenshot_next.show_all (); - screenshot_previous.no_show_all = false; - screenshot_previous.show_all (); + if (screenshot_carousel.n_pages > 1) { + screenshot_next.visible = true; + screenshot_previous.visible = true; } } else { screenshot_stack.visible_child = screenshot_not_found_clamp; @@ -1179,47 +1143,37 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { // 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 scale_factor = get_scale_factor (); - try { - var pixbuf = new Gdk.Pixbuf.from_file_at_scale (path, MAX_WIDTH * scale_factor, 600 * scale_factor, true); - - var image = new Gtk.Image () { - height_request = 500, - icon_name = "image-x-generic", - vexpand = true - }; - image.gicon = pixbuf; + var image = new Gtk.Picture.for_filename (path) { + height_request = 500, + vexpand = true + }; - var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { - halign = Gtk.Align.CENTER - }; + var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { + halign = Gtk.Align.CENTER + }; - unowned var box_context = box.get_style_context (); - box_context.add_class ("screenshot"); - box_context.add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + unowned var box_context = box.get_style_context (); + box_context.add_class ("screenshot"); + box_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 - }; + if (caption != null) { + var label = new Gtk.Label (caption) { + max_width_chars = 50, + wrap = true + }; - unowned var label_context = label.get_style_context (); - label_context.add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + unowned var label_context = label.get_style_context (); + label_context.add_provider (accent_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - box.add (label); - } + box.append (label); + } - box.add (image); + box.append (image); - Idle.add (() => { - box.show_all (); - screenshot_carousel.add (box); - return GLib.Source.REMOVE; - }); - } catch (Error e) { - critical (e.message); - } + Idle.add (() => { + screenshot_carousel.append (box); + return GLib.Source.REMOVE; + }); } private void parse_license (string project_license, out string license_copy, out string license_url) { @@ -1306,54 +1260,50 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { class UrlButton : Gtk.Box { public UrlButton (string label, string? uri, string icon_name) { - get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + add_css_class (Granite.STYLE_CLASS_DIM_LABEL); tooltip_text = uri; - var icon = new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.SMALL_TOOLBAR) { + var icon = new Gtk.Image.from_icon_name (icon_name) { valign = Gtk.Align.CENTER }; var title = new Gtk.Label (label); var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); - box.add (icon); - box.add (title); + box.append (icon); + box.append (title); if (uri != null) { var button = new Gtk.Button () { child = box }; - button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); + button.add_css_class (Granite.STYLE_CLASS_FLAT); - add (button); + append (button); button.clicked.connect (() => { - try { - Gtk.show_uri_on_window ((Gtk.Window) get_toplevel (), uri, Gdk.CURRENT_TIME); - } catch (Error e) { - critical (e.message); - } + Gtk.show_uri ((Gtk.Window) get_root (), uri, Gdk.CURRENT_TIME); }); } else { - add (box); + append (box); } } } class FundButton : Gtk.Button { public FundButton (AppCenterCore.Package package) { - get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); - get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); + add_css_class (Granite.STYLE_CLASS_DIM_LABEL); + add_css_class (Granite.STYLE_CLASS_FLAT); - var icon = new Gtk.Image.from_icon_name ("credit-card-symbolic", Gtk.IconSize.SMALL_TOOLBAR) { + var icon = new Gtk.Image.from_icon_name ("credit-card-symbolic") { valign = Gtk.Align.CENTER }; var title = new Gtk.Label (_("Fund")); var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); - box.add (icon); - box.add (title); + box.append (icon); + box.append (title); tooltip_text = _("Fund the development of this app"); @@ -1366,7 +1316,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { package.normalized_component_id, package.get_payments_key () ); - stripe.transient_for = (Gtk.Window) get_toplevel (); + stripe.transient_for = ((Gtk.Application) Application.get_default ()).active_window; stripe.download_requested.connect (() => { if (stripe.amount != 0) { @@ -1383,9 +1333,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { private static Gtk.CssProvider arrow_provider; public ArrowButton (string icon_name) { - Object ( - image: new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.LARGE_TOOLBAR) - ); + Object (icon_name: icon_name); } static construct { @@ -1398,11 +1346,11 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { vexpand = true; valign = Gtk.Align.CENTER; - unowned var context = get_style_context (); - context.add_class (Gtk.STYLE_CLASS_FLAT); - context.add_class ("circular"); - context.add_class ("arrow"); - context.add_provider (arrow_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + add_css_class (Granite.STYLE_CLASS_FLAT); + add_css_class (Granite.STYLE_CLASS_CIRCULAR); + add_css_class ("arrow"); + + get_style_context ().add_provider (arrow_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } } @@ -1419,7 +1367,7 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { public ContentType (string title, string description, string icon_name) { can_focus = false; - var icon = new Gtk.Image.from_icon_name (icon_name, Gtk.IconSize.DND) { + var icon = new Gtk.Image.from_icon_name (icon_name) { halign = Gtk.Align.START, margin_bottom = 6, pixel_size = 32 @@ -1434,15 +1382,13 @@ public class AppCenter.Views.AppInfoView : AppCenter.AbstractAppContainer { wrap = true, xalign = 0 }; - - unowned var description_label_context = description_label.get_style_context (); - description_label_context.add_class (Granite.STYLE_CLASS_SMALL_LABEL); - description_label_context.add_class (Gtk.STYLE_CLASS_DIM_LABEL); + description_label.add_css_class (Granite.STYLE_CLASS_SMALL_LABEL); + description_label.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 3); - box.add (icon); - box.add (label); - box.add (description_label); + box.append (icon); + box.append (label); + box.append (description_label); child = box; } diff --git a/src/Views/AppListUpdateView.vala b/src/Views/AppListUpdateView.vala index 8201ea2b4..4406b6379 100644 --- a/src/Views/AppListUpdateView.vala +++ b/src/Views/AppListUpdateView.vala @@ -46,12 +46,10 @@ namespace AppCenter.Views { var css_provider = new Gtk.CssProvider (); css_provider.load_from_resource ("io/elementary/appcenter/AppListUpdateView.css"); - var loading_view = new Granite.Widgets.AlertView ( - _("Checking for Updates"), - _("Downloading a list of available updates to the OS and installed apps"), - "sync-synchronizing" - ); - loading_view.show_all (); + var loading_view = new Granite.Placeholder (_("Checking for Updates")) { + description = _("Downloading a list of available updates to the OS and installed apps"), + icon = new ThemedIcon ("sync-synchronizing") + }; header_label = new Granite.HeaderLabel ("") { hexpand = true @@ -63,31 +61,36 @@ namespace AppCenter.Views { }; updated_label = new Gtk.Label (""); - updated_label.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + updated_label.add_css_class (Granite.STYLE_CLASS_DIM_LABEL); var updated_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) { - margin = 12 + margin_top = 12, + margin_end = 12, + margin_bottom = 12, + margin_start = 12 }; - updated_box.add (new Gtk.Image.from_icon_name ("process-completed-symbolic", Gtk.IconSize.SMALL_TOOLBAR)); - updated_box.add (updated_label); + updated_box.append (new Gtk.Image.from_icon_name ("process-completed-symbolic")); + updated_box.append (updated_label); - updated_revealer = new Gtk.Revealer (); - updated_revealer.add (updated_box); + updated_revealer = new Gtk.Revealer () { + child = updated_box + }; update_all_button = new Gtk.Button.with_label (_("Update All")) { valign = Gtk.Align.CENTER }; - update_all_button.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION); + update_all_button.add_css_class (Granite.STYLE_CLASS_SUGGESTED_ACTION); var header = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 16); - header.add (header_label); - header.add (size_label); - header.add (update_all_button); + header.append (header_label); + header.append (size_label); + header.append (update_all_button); header.get_style_context ().add_provider (css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - header_revealer = new Gtk.Revealer (); - header_revealer.add (header); - header_revealer.get_style_context ().add_class ("header"); + header_revealer = new Gtk.Revealer () { + child = header + }; + header_revealer.add_css_class ("header"); header_revealer.get_style_context ().add_provider (css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); list_box = new Gtk.ListBox () { @@ -114,60 +117,32 @@ namespace AppCenter.Views { installed_flowbox.bind_model (installed_liststore, create_installed_from_package); var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); - box.add (list_box); - box.add (installed_header); - box.add (installed_flowbox); + box.append (list_box); + box.append (installed_header); + box.append (installed_flowbox); - var scrolled = new Gtk.ScrolledWindow (null, null) { + var scrolled = new Gtk.ScrolledWindow () { child = box, hscrollbar_policy = Gtk.PolicyType.NEVER }; scrolled.get_style_context ().add_provider (css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - var info_label = new Gtk.Label (_("A restart is required to finish installing updates")); - info_label.show (); - - var infobar = new Gtk.InfoBar (); - infobar.message_type = Gtk.MessageType.WARNING; - infobar.no_show_all = true; - infobar.get_content_area ().add (info_label); - - var restart_button = infobar.add_button (_("Restart Now"), 0); - action_button_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.BOTH); action_button_group.add_widget (update_all_button); - action_button_group.add_widget (restart_button); - - infobar.response.connect ((response) => { - if (response == 0) { - try { - SuspendControl.get_default ().reboot (); - } catch (GLib.Error e) { - if (!(e is IOError.CANCELLED)) { - info_label.label = _("Requesting a restart failed. Restart manually to finish installing updates"); - infobar.message_type = Gtk.MessageType.ERROR; - restart_button.visible = false; - } - } - } - }); - - AppCenterCore.UpdateManager.get_default ().bind_property ("restart-required", infobar, "visible", BindingFlags.SYNC_CREATE); var main_box = new Gtk.Box (VERTICAL, 0); - main_box.add (infobar); - main_box.add (updated_revealer); - main_box.add (header_revealer); - main_box.add (scrolled); - main_box.get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW); + main_box.append (updated_revealer); + main_box.append (header_revealer); + main_box.append (scrolled); + main_box.add_css_class (Granite.STYLE_CLASS_VIEW); var stack = new Gtk.Stack () { transition_type = UNDER_UP }; - stack.add (main_box); - stack.add (loading_view); + stack.add_child (main_box); + stack.add_child (loading_view); - add (stack); + append (stack); get_apps.begin ((obj, res) => { get_apps.end (res); @@ -182,14 +157,6 @@ namespace AppCenter.Views { }); }); - updates_liststore.items_changed.connect (() => { - list_box.show_all (); - }); - - installed_liststore.items_changed.connect (() => { - installed_flowbox.show_all (); - }); - list_box.row_activated.connect ((row) => { if (row is Widgets.PackageRow) { show_app (((Widgets.PackageRow) row).get_package ()); @@ -373,7 +340,7 @@ namespace AppCenter.Views { margin_end = 9, margin_start = 9 }; - header.show_all (); + row.set_header (header); } else { row.set_header (null); @@ -392,10 +359,13 @@ namespace AppCenter.Views { update_all_button.sensitive = false; updating_all_apps = true; - foreach (unowned var child in list_box.get_children ()) { + var child = list_box.get_first_child (); + while (child != null) { if (child is Widgets.PackageRow) { ((Widgets.PackageRow) child).set_action_sensitive (false); } + + child = child.get_next_sibling (); } for (int i = 0; i < updates_liststore.get_n_items (); i++) { @@ -410,7 +380,7 @@ namespace AppCenter.Views { } else { var fail_dialog = new UpgradeFailDialog (package, e.message) { modal = true, - transient_for = (Gtk.Window) get_toplevel () + transient_for = (Gtk.Window) get_root () }; fail_dialog.present (); break; diff --git a/src/Views/AuthorView.vala b/src/Views/AuthorView.vala index 6b9533591..381dcb5c6 100644 --- a/src/Views/AuthorView.vala +++ b/src/Views/AuthorView.vala @@ -3,7 +3,7 @@ * SPDX-FileCopyrightText: 2023 elementary, Inc. (https://elementary.io) */ -private class AppCenter.AuthorView : Gtk.Grid { +private class AppCenter.AuthorView : Gtk.Box { public signal void show_other_package (AppCenterCore.Package package); public AppCenterCore.Package package { get; construct; } @@ -43,24 +43,25 @@ private class AppCenter.AuthorView : Gtk.Grid { } var other_app = new AppCenter.Widgets.ListPackageRowGrid (author_package); - flowbox.add (other_app); + flowbox.append (other_app); } var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12); - box.add (header); - box.add (flowbox); + box.append (header); + box.append (flowbox); - var clamp = new Hdy.Clamp () { + var clamp = new Adw.Clamp () { + child = box, margin_top = 24, margin_end = 24, margin_bottom = 24, margin_start = 24, maximum_size = max_width }; - clamp.add (box); - add (clamp); - get_style_context ().add_class (Gtk.STYLE_CLASS_INLINE_TOOLBAR); + append (clamp); + add_css_class ("bottom-toolbar"); + add_css_class (Granite.STYLE_CLASS_FLAT); flowbox.child_activated.connect ((child) => { var package_row_grid = (AppCenter.Widgets.ListPackageRowGrid) child.get_child (); diff --git a/src/Views/CategoryView.vala b/src/Views/CategoryView.vala index 3bf093d15..48c544a98 100644 --- a/src/Views/CategoryView.vala +++ b/src/Views/CategoryView.vala @@ -45,7 +45,7 @@ public class AppCenter.CategoryView : Gtk.Box { margin_start = 12 }; - scrolled = new Gtk.ScrolledWindow (null, null) { + scrolled = new Gtk.ScrolledWindow () { child = box, hscrollbar_policy = Gtk.PolicyType.NEVER }; @@ -57,11 +57,10 @@ public class AppCenter.CategoryView : Gtk.Box { spinner.start (); stack = new Gtk.Stack (); - stack.add (spinner); - stack.add (scrolled); + stack.add_child (spinner); + stack.add_child (scrolled); - add (stack); - show_all (); + append (stack); populate (); @@ -84,9 +83,9 @@ public class AppCenter.CategoryView : Gtk.Box { private void populate () { get_packages.begin ((obj, res) => { - foreach (unowned var child in box.get_children ()) { - box.remove (child); - } + while (box.get_first_child () != null) { + box.remove (box.get_first_child ()); + }; recently_updated_flowbox.clear (); free_flowbox.clear (); @@ -141,18 +140,17 @@ public class AppCenter.CategoryView : Gtk.Box { } if (recently_updated_flowbox.has_children) { - box.add (recently_updated_flowbox); + box.append (recently_updated_flowbox); } if (paid_flowbox.has_children) { - box.add (paid_flowbox); + box.append (paid_flowbox); } if (free_flowbox.has_children) { - box.add (free_flowbox); + box.append (free_flowbox); } - show_all (); stack.visible_child = scrolled; }); } @@ -182,7 +180,7 @@ public class AppCenter.CategoryView : Gtk.Box { public bool has_children { get { - return flowbox.get_child_at_index (0) != null; + return flowbox.get_first_child () != null; } } @@ -214,9 +212,9 @@ public class AppCenter.CategoryView : Gtk.Box { margin_start = 12 }; header.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL); - add (header); + append (header); } - add (flowbox); + append (flowbox); flowbox.child_activated.connect ((child) => { var row = (Widgets.ListPackageRowGrid) child.get_child (); @@ -228,12 +226,12 @@ public class AppCenter.CategoryView : Gtk.Box { var package_row = new Widgets.ListPackageRowGrid (package); size_group.add_widget (package_row); - flowbox.add (package_row); + flowbox.append (package_row); } public void clear () { - foreach (unowned var child in flowbox.get_children ()) { - child.destroy (); + while (flowbox.get_first_child () != null) { + flowbox.remove (flowbox.get_first_child ()); } } diff --git a/src/Views/Homepage.vala b/src/Views/Homepage.vala index 96c09bddb..00b2471d9 100644 --- a/src/Views/Homepage.vala +++ b/src/Views/Homepage.vala @@ -25,11 +25,10 @@ public class AppCenter.Homepage : Gtk.Box { private const int MAX_PACKAGES_IN_BANNER = 5; private const int MAX_PACKAGES_IN_CAROUSEL = 12; - private Gtk.EventControllerMotion banner_motion_controller; private Gtk.FlowBox category_flow; private Gtk.ScrolledWindow scrolled_window; - private Hdy.Carousel banner_carousel; + private Adw.Carousel banner_carousel; private Gtk.FlowBox recently_updated_carousel; private Gtk.Revealer recently_updated_revealer; private Widgets.Banner appcenter_banner; @@ -37,19 +36,18 @@ public class AppCenter.Homepage : Gtk.Box { private uint banner_timeout_id; construct { - get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW); + add_css_class (Granite.STYLE_CLASS_VIEW); hexpand = true; vexpand = true; - banner_carousel = new Hdy.Carousel () { - allow_long_swipes = true - }; + var banner_motion_controller = new Gtk.EventControllerMotion (); - banner_motion_controller = new Gtk.EventControllerMotion (banner_carousel) { - propagation_phase = CAPTURE + banner_carousel = new Adw.Carousel () { + allow_long_swipes = true }; + banner_carousel.add_controller (banner_motion_controller); - var banner_dots = new Hdy.CarouselIndicatorDots () { + var banner_dots = new Adw.CarouselIndicatorDots () { carousel = banner_carousel }; @@ -102,9 +100,9 @@ public class AppCenter.Homepage : Gtk.Box { var games_card = new GamesCard (); - category_flow.add (new LegacyCard (_("Accessories"), "applications-accessories", {"Utility"}, "accessories")); - category_flow.add (new LegacyCard (_("Audio"), "appcenter-audio-symbolic", {"Audio", "Music"}, "audio")); - category_flow.add (new LegacyCard (_("Communication"), "", { + category_flow.append (new LegacyCard (_("Accessories"), "applications-accessories", {"Utility"}, "accessories")); + category_flow.append (new LegacyCard (_("Audio"), "appcenter-audio-symbolic", {"Audio", "Music"}, "audio")); + category_flow.append (new LegacyCard (_("Communication"), "", { "Chat", "ContactManagement", "Email", @@ -113,7 +111,7 @@ public class AppCenter.Homepage : Gtk.Box { "Telephony", "VideoConference" }, "communication")); - category_flow.add (new LegacyCard (_("Development"), "", { + category_flow.append (new LegacyCard (_("Development"), "", { "Database", "Debugger", "Development", @@ -123,13 +121,13 @@ public class AppCenter.Homepage : Gtk.Box { "TerminalEmulator", "WebDevelopment" }, "development")); - category_flow.add (new LegacyCard (_("Education"), "", {"Education"}, "education")); - category_flow.add (new LegacyCard (_("Finance"), "appcenter-finance-symbolic", { + category_flow.append (new LegacyCard (_("Education"), "", {"Education"}, "education")); + category_flow.append (new LegacyCard (_("Finance"), "appcenter-finance-symbolic", { "Economy", "Finance" }, "finance")); - category_flow.add (games_card); - category_flow.add (new LegacyCard (_("Graphics"), "", { + category_flow.append (games_card); + category_flow.append (new LegacyCard (_("Graphics"), "", { "2DGraphics", "3DGraphics", "Graphics", @@ -138,11 +136,11 @@ public class AppCenter.Homepage : Gtk.Box { "RasterGraphics", "VectorGraphics" }, "graphics")); - category_flow.add (new LegacyCard (_("Internet"), "applications-internet", { + category_flow.append (new LegacyCard (_("Internet"), "applications-internet", { "Network", "P2P" }, "internet")); - category_flow.add (new LegacyCard (_("Math, Science, & Engineering"), "", { + category_flow.append (new LegacyCard (_("Math, Science, & Engineering"), "", { "ArtificialIntelligence", "Astronomy", "Biology", @@ -161,31 +159,31 @@ public class AppCenter.Homepage : Gtk.Box { "Robotics", "Science" }, "science")); - category_flow.add (new LegacyCard (_("Media Production"), "appcenter-multimedia-symbolic", { + category_flow.append (new LegacyCard (_("Media Production"), "appcenter-multimedia-symbolic", { "AudioVideoEditing", "Midi", "Mixer", "Recorder", "Sequencer" }, "media-production")); - category_flow.add (new LegacyCard (_("Office"), "appcenter-office-symbolic", { + category_flow.append (new LegacyCard (_("Office"), "appcenter-office-symbolic", { "Office", "Presentation", "Publishing", "Spreadsheet", "WordProcessor" }, "office")); - category_flow.add (new LegacyCard (_("System"), "applications-system-symbolic", { + category_flow.append (new LegacyCard (_("System"), "applications-system-symbolic", { "Monitor", "System" }, "system")); - category_flow.add (new LegacyCard (_("Universal Access"), "appcenter-accessibility-symbolic", {"Accessibility"}, "accessibility")); - category_flow.add (new LegacyCard (_("Video"), "appcenter-video-symbolic", { + category_flow.append (new LegacyCard (_("Universal Access"), "appcenter-accessibility-symbolic", {"Accessibility"}, "accessibility")); + category_flow.append (new LegacyCard (_("Video"), "appcenter-video-symbolic", { "Tuner", "TV", "Video" }, "video")); - category_flow.add (new LegacyCard (_("Writing & Language"), "preferences-desktop-locale", { + category_flow.append (new LegacyCard (_("Writing & Language"), "preferences-desktop-locale", { "Dictionary", "Languages", "Literature", @@ -195,23 +193,23 @@ public class AppCenter.Homepage : Gtk.Box { "Translation", "WordProcessor" }, "writing-language")); - category_flow.add (new LegacyCard (_("Privacy & Security"), "preferences-system-privacy", { + category_flow.append (new LegacyCard (_("Privacy & Security"), "preferences-system-privacy", { "Security", }, "privacy-security")); var box = new Gtk.Box (VERTICAL, 0); - box.add (banner_carousel); - box.add (banner_dots); - box.add (recently_updated_revealer); - box.add (categories_label); - box.add (category_flow); + box.append (banner_carousel); + box.append (banner_dots); + box.append (recently_updated_revealer); + box.append (categories_label); + box.append (category_flow); - scrolled_window = new Gtk.ScrolledWindow (null, null) { + scrolled_window = new Gtk.ScrolledWindow () { child = box, hscrollbar_policy = Gtk.PolicyType.NEVER }; - add (scrolled_window); + append (scrolled_window); var local_package = App.local_package; if (local_package != null) { @@ -227,7 +225,7 @@ public class AppCenter.Homepage : Gtk.Box { appcenter_banner = new Widgets.Banner ( AppCenterCore.PackageKitBackend.get_default ().lookup_package_by_id ("appcenter") ); - banner_carousel.add (appcenter_banner); + banner_carousel.append (appcenter_banner); #endif banner_carousel.page_changed.connect (page_changed_handler ); @@ -243,22 +241,6 @@ public class AppCenter.Homepage : Gtk.Box { show_category (card.category); }); - AppCenterCore.Client.get_default ().installed_apps_changed.connect (() => { - Idle.add (() => { - // Clear the cached categories when the AppStream pool is updated - foreach (unowned var child in category_flow.get_children ()) { - var item = (AbstractCategoryCard) child; - if (item.visible) { - continue; - } - var category_components = item.category.get_components (); - category_components.remove_range (0, category_components.length); - } - - return GLib.Source.REMOVE; - }); - }); - banner_motion_controller.enter.connect (() => { banner_timeout_stop (); }); @@ -313,15 +295,14 @@ public class AppCenter.Homepage : Gtk.Box { show_package (package); }); - banner_carousel.add (banner); + banner_carousel.append (banner); } } - banner_carousel.show_all (); - banner_carousel.switch_child (1, Granite.TRANSITION_DURATION_OPEN); + banner_carousel.scroll_to (banner_carousel.get_nth_page (1), true); foreach (var package in packages_by_release_date) { - if (recently_updated_carousel.get_children ().length () >= MAX_PACKAGES_IN_CAROUSEL) { + if (recently_updated_carousel.get_child_at_index (MAX_PACKAGES_IN_CAROUSEL - 1) != null) { break; } @@ -343,12 +324,11 @@ public class AppCenter.Homepage : Gtk.Box { if (!installed) { var package_row = new AppCenter.Widgets.ListPackageRowGrid (package); - recently_updated_carousel.add (package_row); + recently_updated_carousel.append (package_row); } } - recently_updated_carousel.show_all (); - recently_updated_revealer.reveal_child = recently_updated_carousel.get_children ().length () > 0; + recently_updated_revealer.reveal_child = recently_updated_carousel.get_first_child () != null; } private void banner_timeout_start () { @@ -368,7 +348,7 @@ public class AppCenter.Homepage : Gtk.Box { new_index = 0; } - banner_carousel.switch_child (new_index, Granite.TRANSITION_DURATION_OPEN); + banner_carousel.scroll_to (banner_carousel.get_nth_page (new_index), true); return Source.CONTINUE; }); @@ -385,7 +365,6 @@ public class AppCenter.Homepage : Gtk.Box { public AppStream.Category category { get; protected set; } protected Gtk.Grid content_area; - protected unowned Gtk.StyleContext style_context; protected static Gtk.CssProvider category_provider; @@ -401,15 +380,27 @@ public class AppCenter.Homepage : Gtk.Box { }; content_area = new Gtk.Grid (); - content_area.add (expanded_grid); - - style_context = content_area.get_style_context (); - style_context.add_class (Granite.STYLE_CLASS_CARD); - style_context.add_class (Granite.STYLE_CLASS_ROUNDED); - style_context.add_class ("category"); - style_context.add_provider (category_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + content_area.attach (expanded_grid, 0, 0); + content_area.add_css_class (Granite.STYLE_CLASS_CARD); + content_area.add_css_class (Granite.STYLE_CLASS_ROUNDED); + content_area.add_css_class ("category"); + content_area.get_style_context ().add_provider (category_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); child = content_area; + + AppCenterCore.Client.get_default ().installed_apps_changed.connect (() => { + Idle.add (() => { + // Clear the cached categories when the AppStream pool is updated + if (visible) { + return GLib.Source.REMOVE; + } + + var category_components = category.get_components (); + category_components.remove_range (0, category_components.length); + + return GLib.Source.REMOVE; + }); + }); } } @@ -434,13 +425,13 @@ public class AppCenter.Homepage : Gtk.Box { }; if (category.icon != "") { - var display_image = new Gtk.Image.from_icon_name (category.icon, Gtk.IconSize.DIALOG) { + var display_image = new Gtk.Image.from_icon_name (category.icon) { halign = Gtk.Align.END, valign = Gtk.Align.CENTER, pixel_size = 48 }; - box.add (display_image); + box.append (display_image); name_label.xalign = 0; name_label.halign = Gtk.Align.START; @@ -448,10 +439,10 @@ public class AppCenter.Homepage : Gtk.Box { name_label.justify = Gtk.Justification.CENTER; } - box.add (name_label); + box.append (name_label); content_area.attach (box, 0, 0); - style_context.add_class (style); + content_area.add_css_class (style); if (style == "accessibility") { name_label.label = category.name.up (); @@ -491,10 +482,8 @@ public class AppCenter.Homepage : Gtk.Box { icon_name = "appcenter-games-symbolic", pixel_size = 64 }; - - unowned var image_context = image.get_style_context (); - image_context.add_class (Granite.STYLE_CLASS_ACCENT); - image_context.add_class ("slate"); + image.add_css_class (Granite.STYLE_CLASS_ACCENT); + image.add_css_class ("slate"); var fun_label = new Gtk.Label (_("Fun &")) { halign = Gtk.Align.START @@ -506,11 +495,9 @@ public class AppCenter.Homepage : Gtk.Box { fun_label_context.add_provider (category_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); var games_label = new Gtk.Label (_("Games")); - - unowned var games_label_context = games_label.get_style_context (); - games_label_context.add_class (Granite.STYLE_CLASS_ACCENT); - games_label_context.add_class ("blue"); - games_label_context.add_provider (category_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + games_label.add_css_class (Granite.STYLE_CLASS_ACCENT); + games_label.add_css_class ("blue"); + games_label.get_style_context ().add_provider (category_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); var grid = new Gtk.Grid () { column_spacing = 12, @@ -522,8 +509,7 @@ public class AppCenter.Homepage : Gtk.Box { grid.attach (games_label, 1, 1); content_area.attach (grid, 0, 0); - - style_context.add_class ("games"); + content_area.add_css_class ("games"); } } } diff --git a/src/Views/SearchView.vala b/src/Views/SearchView.vala index 26c564ad2..6a0d016ef 100644 --- a/src/Views/SearchView.vala +++ b/src/Views/SearchView.vala @@ -28,12 +28,10 @@ public class AppCenter.SearchView : Gtk.Box { construct { var flathub_link = "%s".printf (_("Flathub")); - var alert_view = new Granite.Widgets.AlertView ( - _("No Apps Found"), - _("Try changing search terms. You can also sideload Flatpak apps e.g. from %s").printf (flathub_link), - "edit-find-symbolic" - ); - alert_view.show_all (); + var alert_view = new Granite.Placeholder (_("No Apps Found")) { + description = _("Try changing search terms. You can also sideload Flatpak apps e.g. from %s").printf (flathub_link), + icon = new ThemedIcon ("edit-find-symbolic") + }; list_store = new GLib.ListStore (typeof (AppCenterCore.Package)); @@ -45,16 +43,12 @@ public class AppCenter.SearchView : Gtk.Box { list_box.bind_model (list_store, create_row_from_package); list_box.set_placeholder (alert_view); - var scrolled = new Gtk.ScrolledWindow (null, null) { + var scrolled = new Gtk.ScrolledWindow () { child = list_box, hscrollbar_policy = Gtk.PolicyType.NEVER }; - add (scrolled); - - list_store.items_changed.connect (() => { - list_box.show_all (); - }); + append (scrolled); notify["current-search-term"].connect (() => { if (current_search_term == null) { diff --git a/src/Widgets/AppContainers/AbstractAppContainer.vala b/src/Widgets/AppContainers/AbstractAppContainer.vala index 5c12d926f..99607f4c0 100644 --- a/src/Widgets/AppContainers/AbstractAppContainer.vala +++ b/src/Widgets/AppContainers/AbstractAppContainer.vala @@ -46,6 +46,7 @@ public abstract class AppCenter.AbstractAppContainer : Gtk.Box { action_button_revealer = new Gtk.Revealer () { child = action_button, + overflow = Gtk.Overflow.VISIBLE, transition_type = SLIDE_LEFT }; @@ -63,8 +64,8 @@ public abstract class AppCenter.AbstractAppContainer : Gtk.Box { open_button.clicked.connect (launch_package_app); button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); - button_box.add (action_button_revealer); - button_box.add (open_button_revealer); + button_box.append (action_button_revealer); + button_box.append (open_button_revealer); cancel_button = new ProgressButton () { label = _("Cancel") @@ -84,7 +85,6 @@ public abstract class AppCenter.AbstractAppContainer : Gtk.Box { }; action_stack.add_named (button_box, "buttons"); action_stack.add_named (cancel_button, "progress"); - action_stack.show_all (); destroy.connect (() => { if (state_source > 0) { @@ -126,7 +126,7 @@ public abstract class AppCenter.AbstractAppContainer : Gtk.Box { var css = CSS.printf ((int) (fraction * 100)); try { - provider.load_from_data (css, css.length); + provider.load_from_data (css.data); style_context.add_provider (provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } catch (Error e) { critical (e.message); @@ -268,7 +268,7 @@ public abstract class AppCenter.AbstractAppContainer : Gtk.Box { if (!(e is GLib.IOError.CANCELLED)) { var fail_dialog = new UpgradeFailDialog (package, e.message) { modal = true, - transient_for = (Gtk.Window) get_toplevel () + transient_for = (Gtk.Window) get_root () }; fail_dialog.present (); } diff --git a/src/Widgets/AppContainers/AbstractPackageRowGrid.vala b/src/Widgets/AppContainers/AbstractPackageRowGrid.vala index dfedbe546..1dcb1a417 100644 --- a/src/Widgets/AppContainers/AbstractPackageRowGrid.vala +++ b/src/Widgets/AppContainers/AbstractPackageRowGrid.vala @@ -39,8 +39,9 @@ public abstract class AppCenter.Widgets.AbstractPackageRowGrid : AbstractAppCont pixel_size = 24 }; - app_icon_overlay = new Gtk.Overlay (); - app_icon_overlay.add (app_icon); + app_icon_overlay = new Gtk.Overlay () { + child = app_icon + }; var scale_factor = get_scale_factor (); diff --git a/src/Widgets/AppContainers/InstalledPackageRowGrid.vala b/src/Widgets/AppContainers/InstalledPackageRowGrid.vala index e300ab7ef..a906e6981 100644 --- a/src/Widgets/AppContainers/InstalledPackageRowGrid.vala +++ b/src/Widgets/AppContainers/InstalledPackageRowGrid.vala @@ -49,19 +49,19 @@ public class AppCenter.Widgets.InstalledPackageRowGrid : AbstractPackageRowGrid valign = Gtk.Align.START, xalign = 0 }; - app_version.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + app_version.get_style_context ().add_class (Granite.STYLE_CLASS_DIM_LABEL); - var release_button = new Gtk.Button.from_icon_name ("dialog-information-symbolic", Gtk.IconSize.SMALL_TOOLBAR) { + var release_button = new Gtk.Button.from_icon_name ("dialog-information-symbolic") { valign = Gtk.Align.CENTER }; release_button_revealer = new Gtk.Revealer () { + child = release_button, halign = Gtk.Align.END, hexpand = true, tooltip_text = _("Release notes"), transition_type = Gtk.RevealerTransitionType.CROSSFADE }; - release_button_revealer.add (release_button); action_stack.hexpand = false; @@ -75,11 +75,11 @@ public class AppCenter.Widgets.InstalledPackageRowGrid : AbstractPackageRowGrid grid.attach (release_button_revealer, 2, 0, 1, 2); grid.attach (action_stack, 3, 0, 1, 2); - add (grid); + append (grid); release_button.clicked.connect (() => { var releases_dialog = new ReleaseDialog (package) { - transient_for = (Gtk.Window) get_toplevel () + transient_for = ((Gtk.Application) Application.get_default ()).active_window }; releases_dialog.present (); }); @@ -146,11 +146,10 @@ public class AppCenter.Widgets.InstalledPackageRowGrid : AbstractPackageRowGrid margin_start = 12, vexpand = true }; - releases_dialog_box.add (releases_title); - releases_dialog_box.add (release_row); - releases_dialog_box.show_all (); + releases_dialog_box.append (releases_title); + releases_dialog_box.append (release_row); - get_content_area ().add (releases_dialog_box); + get_content_area ().append (releases_dialog_box); add_button (_("Close"), Gtk.ResponseType.CLOSE); diff --git a/src/Widgets/AppContainers/ListPackageRowGrid.vala b/src/Widgets/AppContainers/ListPackageRowGrid.vala index e22cc20d6..dc869d547 100644 --- a/src/Widgets/AppContainers/ListPackageRowGrid.vala +++ b/src/Widgets/AppContainers/ListPackageRowGrid.vala @@ -46,7 +46,7 @@ public class AppCenter.Widgets.ListPackageRowGrid : AbstractPackageRowGrid { wrap = true, xalign = 0 }; - package_summary.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + package_summary.get_style_context ().add_class (Granite.STYLE_CLASS_DIM_LABEL); var grid = new Gtk.Grid () { column_spacing = 12, @@ -57,14 +57,13 @@ public class AppCenter.Widgets.ListPackageRowGrid : AbstractPackageRowGrid { grid.attach (package_summary, 1, 1); grid.attach (action_stack, 2, 0, 1, 2); - add (grid); + append (grid); } protected override void set_up_package () { package_summary.label = package.get_summary (); if (package.is_local) { - action_stack.no_show_all = true; action_stack.visible = false; } diff --git a/src/Widgets/Banner.vala b/src/Widgets/Banner.vala index 618b33da3..3535e7f5d 100644 --- a/src/Widgets/Banner.vala +++ b/src/Widgets/Banner.vala @@ -73,8 +73,7 @@ public class AppCenter.Widgets.Banner : Gtk.Button { }; var icon_image = new Gtk.Image.from_gicon ( - package.get_icon (128, get_scale_factor ()), - Gtk.IconSize.INVALID + package.get_icon (128, get_scale_factor ()) ) { pixel_size = 128 }; @@ -99,7 +98,7 @@ public class AppCenter.Widgets.Banner : Gtk.Button { style_context.add_provider (style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); hexpand = true; - add (package_grid); + child = package_grid; var provider = new Gtk.CssProvider (); try { @@ -119,7 +118,7 @@ public class AppCenter.Widgets.Banner : Gtk.Button { } var colored_css = BANNER_STYLE_CSS.printf (bg_color, text_color); - provider.load_from_data (colored_css, colored_css.length); + provider.load_from_data (colored_css.data); style_context.add_provider (provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } catch (GLib.Error e) { critical ("Unable to set accent color: %s", e.message); diff --git a/src/Widgets/HumbleButton.vala b/src/Widgets/HumbleButton.vala index 1a37828c1..81603db9b 100644 --- a/src/Widgets/HumbleButton.vala +++ b/src/Widgets/HumbleButton.vala @@ -98,7 +98,7 @@ public class AppCenter.Widgets.HumbleButton : Gtk.Button { package.normalized_component_id, package.get_payments_key () ) { - transient_for = (Gtk.Window) get_toplevel () + transient_for = ((Gtk.Application) Application.get_default ()).active_window }; stripe_dialog.download_requested.connect (() => { diff --git a/src/Widgets/PackageRow.vala b/src/Widgets/PackageRow.vala index 1cc2adbe8..c5aad1807 100644 --- a/src/Widgets/PackageRow.vala +++ b/src/Widgets/PackageRow.vala @@ -24,7 +24,7 @@ namespace AppCenter.Widgets { public PackageRow.installed (AppCenterCore.Package package, Gtk.SizeGroup? action_size_group) { grid = new InstalledPackageRowGrid (package, action_size_group); - add (grid); + child = grid; ((InstalledPackageRowGrid) grid).changed.connect (() => { changed (); }); @@ -32,7 +32,7 @@ namespace AppCenter.Widgets { public PackageRow.list (AppCenterCore.Package package) { grid = new ListPackageRowGrid (package); - add (grid); + child = grid; } public AppCenterCore.Package? get_package () { diff --git a/src/Widgets/ReleaseRow.vala b/src/Widgets/ReleaseRow.vala index 36fcbc766..d9834bfa7 100644 --- a/src/Widgets/ReleaseRow.vala +++ b/src/Widgets/ReleaseRow.vala @@ -29,7 +29,7 @@ public class AppCenter.Widgets.ReleaseRow : Gtk.Box { } construct { - var header_icon = new Gtk.Image.from_icon_name ("tag-symbolic", Gtk.IconSize.MENU); + var header_icon = new Gtk.Image.from_icon_name ("tag-symbolic"); var header_label = new Gtk.Label (format_version (release.get_version ())) { use_markup = true @@ -40,7 +40,7 @@ public class AppCenter.Widgets.ReleaseRow : Gtk.Box { halign = Gtk.Align.START, hexpand = true }; - date_label.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL); + date_label.get_style_context ().add_class (Granite.STYLE_CLASS_DIM_LABEL); var description_label = new Gtk.Label (format_release_description (release.get_description ())) { selectable = true, @@ -62,7 +62,8 @@ public class AppCenter.Widgets.ReleaseRow : Gtk.Box { orientation = Gtk.Orientation.VERTICAL; spacing = 6; - add (grid); + + append (grid); var issues = release.get_issues (); @@ -72,11 +73,11 @@ public class AppCenter.Widgets.ReleaseRow : Gtk.Box { }; issue_header.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL); - add (issue_header); + append (issue_header); } foreach (unowned AppStream.Issue issue in issues) { - var issue_image = new Gtk.Image.from_icon_name ("bug-symbolic", Gtk.IconSize.MENU) { + var issue_image = new Gtk.Image.from_icon_name ("bug-symbolic") { valign = Gtk.Align.START }; @@ -87,13 +88,13 @@ public class AppCenter.Widgets.ReleaseRow : Gtk.Box { var issue_linkbutton = new Gtk.LinkButton (issue.get_url ()); issue_linkbutton.get_child ().destroy (); - issue_linkbutton.add (issue_label); + issue_linkbutton.child = issue_label; var issue_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 3); - issue_box.add (issue_image); - issue_box.add (issue_linkbutton); + issue_box.append (issue_image); + issue_box.append (issue_linkbutton); - add (issue_box); + append (issue_box); } } diff --git a/src/Widgets/SharePopover.vala b/src/Widgets/SharePopover.vala index fda7739d9..5a5b67c3d 100644 --- a/src/Widgets/SharePopover.vala +++ b/src/Widgets/SharePopover.vala @@ -31,29 +31,30 @@ public class SharePopover : Gtk.Popover { } construct { - var facebook_button = new Gtk.Button.from_icon_name ("online-account-facebook", Gtk.IconSize.DND) { + var facebook_button = new Gtk.Button.from_icon_name ("online-account-facebook") { tooltip_text = _("Facebook") }; - var twitter_button = new Gtk.Button.from_icon_name ("online-account-twitter", Gtk.IconSize.DND) { + var twitter_button = new Gtk.Button.from_icon_name ("online-account-twitter") { tooltip_text = _("Twitter") }; - var reddit_button = new Gtk.Button.from_icon_name ("online-account-reddit", Gtk.IconSize.DND) { + var reddit_button = new Gtk.Button.from_icon_name ("online-account-reddit") { tooltip_text = _("Reddit") }; - var tumblr_button = new Gtk.Button.from_icon_name ("online-account-tumblr", Gtk.IconSize.DND) { + var tumblr_button = new Gtk.Button.from_icon_name ("online-account-tumblr") { tooltip_text = _("Tumblr") }; - var telegram_button = new Gtk.Button.from_icon_name ("online-account-telegram", Gtk.IconSize.DND) { + var telegram_button = new Gtk.Button.from_icon_name ("online-account-telegram") { tooltip_text = _("Telegram") }; - var copy_link_button = new Gtk.Button.from_icon_name ("edit-copy-symbolic", Gtk.IconSize.LARGE_TOOLBAR) { + var copy_link_button = new Gtk.Button.from_icon_name ("edit-copy-symbolic") { tooltip_text = _("Copy link") }; + ((Gtk.Image) copy_link_button.child).pixel_size = 24; var size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.BOTH); size_group.add_widget (facebook_button); @@ -65,26 +66,28 @@ public class SharePopover : Gtk.Popover { margin_bottom = 6, margin_start = 6 }; + service_box.add_css_class (Granite.STYLE_CLASS_LARGE_ICONS); var mail_appinfo = AppInfo.get_default_for_uri_scheme ("mailto"); if (mail_appinfo != null) { var email_button = new Gtk.Button () { - image = new Gtk.Image.from_gicon (mail_appinfo.get_icon (), Gtk.IconSize.DND), + child = new Gtk.Image.from_gicon (mail_appinfo.get_icon ()), tooltip_text = mail_appinfo.get_display_name () }; + email_button.add_css_class ("image-button"); - service_box.add (email_button); + service_box.append (email_button); email_button.clicked.connect (() => { show_uri ("mailto:?subject=%s&body=%s".printf (body, uri)); }); } - service_box.add (facebook_button); - service_box.add (twitter_button); - service_box.add (reddit_button); - service_box.add (tumblr_button); - service_box.add (telegram_button); + service_box.append (facebook_button); + service_box.append (twitter_button); + service_box.append (reddit_button); + service_box.append (tumblr_button); + service_box.append (telegram_button); var system_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0) { margin_top = 6, @@ -92,22 +95,18 @@ public class SharePopover : Gtk.Popover { margin_bottom = 6, margin_start = 6 }; - system_box.add (copy_link_button); + system_box.append (copy_link_button); var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); - box.add (service_box); - box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); - box.add (system_box); - box.show_all (); + box.append (service_box); + box.append (new Gtk.Separator (Gtk.Orientation.HORIZONTAL)); + box.append (system_box); - add (box); + child = box; copy_link_button.clicked.connect (() => { - var clipboard = Gtk.Clipboard.get_for_display (get_display (), Gdk.SELECTION_CLIPBOARD); - clipboard.set_text (uri, -1); - + Gdk.Display.get_default ().get_clipboard ().set_text (uri); link_copied (); - popdown (); }); @@ -134,12 +133,7 @@ public class SharePopover : Gtk.Popover { private void show_uri (string uri) { var main_window = ((Gtk.Application) Application.get_default ()).active_window; - try { - Gtk.show_uri_on_window (main_window, uri, Gdk.CURRENT_TIME); - } catch (Error e) { - critical (e.message); - } - + Gtk.show_uri (main_window, uri, Gdk.CURRENT_TIME); popdown (); } } diff --git a/src/Widgets/SizeLabel.vala b/src/Widgets/SizeLabel.vala index e54b83c44..8b7814730 100644 --- a/src/Widgets/SizeLabel.vala +++ b/src/Widgets/SizeLabel.vala @@ -35,21 +35,20 @@ public class AppCenter.Widgets.SizeLabel : Gtk.Box { size_label = new Gtk.Label (null); - icon = new Gtk.Image.from_icon_name ("dialog-information-symbolic", Gtk.IconSize.BUTTON) { + icon = new Gtk.Image.from_icon_name ("dialog-information-symbolic") { margin_start = 6 }; var box = new Gtk.Box (HORIZONTAL, 0); - box.add (size_label); - box.add (icon); + box.append (size_label); + box.append (icon); revealer = new Gtk.Revealer () { transition_type = SLIDE_LEFT, child = box }; - add (revealer); - show_all (); + append (revealer); update (size); }