diff --git a/.github/workflows/gettext.yml b/.github/workflows/gettext.yml index 628e3f6f..22db604a 100644 --- a/.github/workflows/gettext.yml +++ b/.github/workflows/gettext.yml @@ -22,7 +22,7 @@ jobs: token: ${{ secrets.GIT_USER_TOKEN }} - name: Update Translation Files - uses: elementary/actions/gettext-template@next + uses: elementary/actions/gettext-template@main env: GIT_USER_TOKEN: ${{ secrets.GIT_USER_TOKEN }} GIT_USER_NAME: "elementaryBot" diff --git a/README.md b/README.md index ec25f88a..363f9fad 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ You'll need the following dependencies: * libglib2.0-dev * libgranite-7-dev * libgtk-4-dev -* libadwaita-1-dev +* libadwaita-1-dev (>= 1.4) * meson * valac diff --git a/data/styles/Index.scss b/data/styles/Index.scss index 83ba2a19..393183b8 100644 --- a/data/styles/Index.scss +++ b/data/styles/Index.scss @@ -2,5 +2,6 @@ @import '_common.scss'; @import 'CategoryView.scss'; +@import 'Plug.scss'; @import 'SettingsPage.scss'; @import 'SettingsSidebar.scss'; diff --git a/data/styles/Plug.scss b/data/styles/Plug.scss new file mode 100644 index 00000000..bcf74957 --- /dev/null +++ b/data/styles/Plug.scss @@ -0,0 +1,59 @@ +toolbarview { + &.undershoot-top scrolledwindow { + overshoot.top { + background: + linear-gradient( + to top, + #{'alpha(@accent_color, 0)'} 80%, + #{'alpha(@accent_color, 0.25)'} 100% + ), + linear-gradient( + #{'@borders'}, + rgba(black, 0.05) 1px, + rgba(black, 0.0) rem(3px) + ); + } + + undershoot.top { + background: + linear-gradient( + #{'@borders'}, + rgba(black, 0.05) 1px, + rgba(black, 0.0) rem(3px) + ); + } + } + + &.undershoot-bottom scrolledwindow { + overshoot.bottom { + background: + linear-gradient( + to bottom, + #{'alpha(@accent_color, 0)'} 80%, + #{'alpha(@accent_color, 0.25)'} 100% + ), + linear-gradient( + to top, + #{'@borders'}, + rgba(black, 0.05) 1px, + rgba(black, 0.0) rem(3px) + ); + } + + undershoot.bottom { + background: + linear-gradient( + to top, + #{'@borders'}, + rgba(black, 0.05) 1px, + rgba(black, 0.0) rem(3px) + ); + } + } + + headerbar, + actionbar { + background: inherit; + box-shadow: none; + } +} diff --git a/data/styles/SettingsSidebar.scss b/data/styles/SettingsSidebar.scss index f3512eb2..ae35e7be 100644 --- a/data/styles/SettingsSidebar.scss +++ b/data/styles/SettingsSidebar.scss @@ -1,23 +1,71 @@ -settingssidebar list { - min-width: rem(200px); +settingssidebar { + list { + background: inherit; + min-width: rem(200px); - row, - > .title-4 { - padding: rem(6px); - } - - row { - overlay { - // IconSize.LARGE + padding - min-width: calc(32px + #{rem(6px)}); + row, + > .title-4 { + padding: rem(6px); } - overlay:dir(ltr) { - margin-right: rem(6px); + row { + overlay { + // IconSize.LARGE + padding + min-width: calc(32px + #{rem(6px)}); + } + + overlay:dir(ltr) { + margin-right: rem(6px); + } + + overlay:dir(rtl) { + margin-left: rem(6px); + } } + } + + toolbarview { + revealer.bottom-bar { + color: #{'mix(@text_color, @insensitive_bg_color, 0.15)'}; + + &.raised { + box-shadow: 0 -1px #{'alpha(@highlight_color, 0.2)'}; + background-color: rgba(black, 0.01); + background-image: + linear-gradient( + to bottom, + #{'@borders'} 1px, + rgba(black, 0.07) 1px, + transparent rem(3px) + ); + } + + &.raised.border { + background: rgba(black, 0.03); + box-shadow: + 0 -1px #{'@borders'}, + inset 0 1px #{'alpha(@highlight_color, 0.3)'}; + } + + actionbar { + padding: rem(6px); + + box.start > label { + margin: rem(6px); + font-weight: 500; + } + + box.end > switch { + slider, + trough { + min-height: 1.5em; + } - overlay:dir(rtl) { - margin-left: rem(6px); + slider { + min-width: 1.5em; + } + } + } } } } diff --git a/lib/SettingsSidebar.vala b/lib/SettingsSidebar.vala index 1e9b4a37..cbfd93ec 100644 --- a/lib/SettingsSidebar.vala +++ b/lib/SettingsSidebar.vala @@ -18,6 +18,11 @@ public class Switchboard.SettingsSidebar : Gtk.Widget { */ public Gtk.Stack stack { get; construct; } + /** + * Whether to show back and title buttons in the header area + */ + public bool show_title_buttons { get; set;} + /** * The name of the currently visible Granite.SettingsPage */ @@ -75,7 +80,20 @@ public class Switchboard.SettingsSidebar : Gtk.Widget { hscrollbar_policy = Gtk.PolicyType.NEVER, child = listbox }; - scrolled.set_parent (this); + + var headerbar = new Adw.HeaderBar () { + show_end_title_buttons = false, + show_title = false + }; + + var toolbarview = new Adw.ToolbarView () { + content = scrolled, + top_bar_style = FLAT + }; + toolbarview.add_top_bar (headerbar); + toolbarview.set_parent (this); + + add_css_class (Granite.STYLE_CLASS_SIDEBAR); on_sidebar_changed (); stack.pages.items_changed.connect (on_sidebar_changed); @@ -100,6 +118,8 @@ public class Switchboard.SettingsSidebar : Gtk.Widget { stack.notify["visible-child-name"].connect (() => { visible_child_name = stack.visible_child_name; }); + + bind_property ("show-title-buttons", toolbarview, "reveal-top-bars", SYNC_CREATE); } ~SettingsSidebar () { diff --git a/meson.build b/meson.build index 6d845401..2de83923 100644 --- a/meson.build +++ b/meson.build @@ -35,7 +35,7 @@ gmodule_dep = dependency('gmodule-2.0') gtk_dep = dependency('gtk4', version: '>=3.10') gee_dep = dependency('gee-0.8') granite_dep = dependency('granite-7', version: '>=7.0.0') -adwaita_dep = dependency('libadwaita-1') +adwaita_dep = dependency('libadwaita-1', version: '>=1.4') m_dep = meson.get_compiler('c').find_library('m', required : false) subdir('data') diff --git a/src/Application.vala b/src/Application.vala index 0f6cddc4..11eac6b4 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -22,7 +22,7 @@ namespace Switchboard { public class SwitchboardApp : Gtk.Application { private GLib.HashTable plug_widgets; - private Adw.Leaflet leaflet; + private Adw.NavigationView navigation_view; private Gtk.Window main_window; private Switchboard.CategoryView category_view; @@ -89,7 +89,6 @@ namespace Switchboard { add_action (back_action); add_action (quit_action); - set_accels_for_action ("app.back", {"Left", "Back"}); set_accels_for_action ("app.quit", {"q"}); back_action.activate.connect (action_navigate_back); @@ -132,16 +131,12 @@ namespace Switchboard { category_view = new Switchboard.CategoryView (plug_to_open); - leaflet = new Adw.Leaflet () { - can_navigate_back = true, - can_navigate_forward = true, - can_unfold = false - }; - leaflet.append (category_view); + navigation_view = new Adw.NavigationView (); + navigation_view.add (category_view); main_window = new Gtk.Window () { application = this, - child = leaflet, + child = navigation_view, icon_name = application_id, title = _("System Settings"), titlebar = new Gtk.Grid () { visible = false } @@ -165,59 +160,26 @@ namespace Switchboard { settings.bind ("window-maximized", main_window, "maximized", SettingsBindFlags.SET); shutdown.connect (() => { - if (plug_widgets[leaflet.visible_child] != null && plug_widgets[leaflet.visible_child] is Switchboard.Plug) { - plug_widgets[leaflet.visible_child].hidden (); - } + navigation_view.visible_page.hidden (); }); - leaflet.notify["visible-child"].connect (() => { - update_navigation (); - }); - - leaflet.notify["child-transition-running"].connect (() => { - update_navigation (); - }); + navigation_view.popped.connect (update_navigation); + navigation_view.pushed.connect (update_navigation); } private void update_navigation () { - if (!leaflet.child_transition_running) { - if (plug_widgets[leaflet.get_adjacent_child (Adw.NavigationDirection.FORWARD)] != null) { - plug_widgets[leaflet.get_adjacent_child (Adw.NavigationDirection.FORWARD)].hidden (); - } - - var previous_child = plug_widgets[leaflet.get_adjacent_child (Adw.NavigationDirection.BACK)]; - if (previous_child != null && previous_child is Switchboard.Plug) { - previous_child.hidden (); - } - - var visible_widget = leaflet.visible_child; - if (visible_widget is Switchboard.CategoryView) { - main_window.title = _("System Settings"); - } else { - var plug = plug_widgets[visible_widget]; - if (plug != null) { - plug.shown (); - main_window.title = plug.display_name; - } else { - critical ("Visible child is not CategoryView nor is associated with a Plug."); - } - } - } + main_window.title = navigation_view.visible_page.title; } public void load_plug (Switchboard.Plug plug) { - if (leaflet.child_transition_running) { - return; - } - Idle.add (() => { - while (leaflet.get_adjacent_child (Adw.NavigationDirection.FORWARD) != null) { - leaflet.remove (leaflet.get_adjacent_child (Adw.NavigationDirection.FORWARD)); - } - var plug_widget = plug.get_widget (); if (plug_widget.parent == null) { - leaflet.append (plug_widget); + var navigation_page = new Adw.NavigationPage (plug_widget, plug.display_name); + navigation_page.hidden.connect (plug.hidden); + navigation_page.shown.connect (plug.shown); + + navigation_view.add (navigation_page); } if (plug_widgets[plug_widget] == null) { @@ -245,13 +207,13 @@ namespace Switchboard { } if (opened_directly) { - leaflet.mode_transition_duration = 0; + navigation_view.animate_transitions = false; opened_directly = false; - } else if (leaflet.mode_transition_duration == 0) { - leaflet.mode_transition_duration = 200; + } else if (navigation_view.animate_transitions == false) { + navigation_view.animate_transitions = true; } - leaflet.visible_child = plug.get_widget (); + navigation_view.push ((Adw.NavigationPage) plug.get_widget ().parent); return false; }, GLib.Priority.DEFAULT_IDLE); @@ -259,12 +221,12 @@ namespace Switchboard { // Handles clicking the navigation button private void action_navigate_back () { - if (leaflet.get_adjacent_child (Adw.NavigationDirection.BACK) == category_view) { + if (navigation_view.get_previous_page (navigation_view.visible_page) == category_view) { opened_directly = false; - leaflet.mode_transition_duration = 200; + navigation_view.animate_transitions = true; } - leaflet.navigate (Adw.NavigationDirection.BACK); + navigation_view.pop (); } // Try to find a supported plug, fallback paths like "foo/bar" to "foo" diff --git a/src/CategoryView.vala b/src/CategoryView.vala index 824105ca..cf548357 100644 --- a/src/CategoryView.vala +++ b/src/CategoryView.vala @@ -5,7 +5,7 @@ * Authored by: Avi Romanoff */ -public class Switchboard.CategoryView : Gtk.Box { +public class Switchboard.CategoryView : Adw.NavigationPage { public Gee.ArrayList plug_search_result { get; private set; } public string? plug_to_open { get; construct set; default = null; } @@ -83,9 +83,12 @@ public class Switchboard.CategoryView : Gtk.Box { hscrollbar_policy = NEVER }; - orientation = VERTICAL; - append (headerbar); - append (scrolled); + var box = new Gtk.Box (VERTICAL, 0); + box.append (headerbar); + box.append (scrolled); + + child = box; + title = _("All Settings"); load_default_plugs.begin ();