Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BackButton #692

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Install Dependencies
run: |
apt update
apt install -y meson gobject-introspection libgee-0.8-dev libgirepository1.0-dev libgtk-4-dev sassc valac
apt install -y meson gobject-introspection libgee-0.8-dev libgirepository1.0-dev libgtk-4-dev libadwaita-1-dev sassc valac
- name: Build
env:
DESTDIR: out
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ You'll need the following dependencies:
* libgee-0.8-dev
* libgirepository1.0-dev
* libgtk-4-dev >= 4.4.0
* libadwaita-1-dev >= 1.4
* sassc
* valac

Expand Down
8 changes: 4 additions & 4 deletions demo/Views/CSSView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ public class CSSView : Gtk.Box {
};
terminal_scroll.add_css_class (Granite.STYLE_CLASS_TERMINAL);

var back_button_label = new Granite.HeaderLabel ("\"back-button\" style class") ;
var back_button_label = new Granite.HeaderLabel ("BackButton") ;

var back_button = new Gtk.Button.with_label ("Back Button") {
halign = Gtk.Align.START
var back_button = new Granite.BackButton () {
halign = START,
label = "Back"
};
back_button.add_css_class (Granite.STYLE_CLASS_BACK_BUTTON);

var scales_header = new Granite.HeaderLabel ("Scales") {
secondary_text = "\"warmth\" and \"temperature\" style classes"
Expand Down
1 change: 1 addition & 0 deletions lib/Constants.vala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Granite {
/**
* Style class for shaping a {@link Gtk.Button}
*/
[Version (deprecated = true, deprecated_since = "7.5.0", replacement = "Granite.BackButton")]
public const string STYLE_CLASS_BACK_BUTTON = "back-button";
/**
* Style class to match the window background
Expand Down
62 changes: 62 additions & 0 deletions lib/Widgets/BackButton.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2024 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: GPL-2.0-or-later
*/

/**
* BackButton is meant to be used in headers to navigate in
* {@link Adw.NavigationView}s. It will automatically detect when under a
* {@link Adw.NavigationView} and label itself with the title of the preceding page.
*/
[Version (since = "7.5.0")]
public class Granite.BackButton : Gtk.Button {
/**
* A manually set label when used outside of {@link Adw.NavigationView}
*/
public new string label { get; set; }

construct {
var image = new Gtk.Image.from_icon_name ("go-previous-symbolic");

var label_widget = new Gtk.Label ("");

var box = new Gtk.Box (HORIZONTAL, 0);
box.append (image);
box.append (label_widget);

child = box;

map.connect (on_map);
clicked.connect (on_click);

bind_property ("label", label_widget, "label");
}

private void on_map () {
var navigation_view = (Adw.NavigationView) get_ancestor (typeof (Adw.NavigationView));

if (navigation_view == null) {
return;
}

var navigation_page = (Adw.NavigationPage) get_ancestor (typeof (Adw.NavigationPage));

if (navigation_view == null) {
return;
}

var previous_page = navigation_view.get_previous_page (navigation_page);

if (previous_page != null) {
label = previous_page.title;
Copy link
Contributor

@alice-mkh alice-mkh Mar 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that page title can and will change.

The logic in libadwaita's own back buttons is also a lot more complicated because navigation views can be nested, and can also be structured like:

navigation split view
sidebar: navigation view
content: navigation view

and that situation is handled correctly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, tho the latter involves private api - forgot about that

Copy link
Member Author

@leolost2605 leolost2605 Mar 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that page title can and will change.

Should be fixed although I think that would be kinda questionable UX while the page itself is not visible?

The logic in libadwaita's own back buttons is also a lot more complicated because navigation views can be nested, and can also be structured like:

navigation split view
sidebar: navigation view
content: navigation view

and that situation is handled correctly

I'm guessing that if the button is on the deepest view and there is no page left it still appears and instead navigates one above?
I think for now and for our use case it might be enough to leave that out (since we also don't hide when there is no preceding page)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fixed although I think that would be kinda questionable UX while the page itself is not visible?

Questionable yes, but I mean the property is writable, so...

I'm guessing that if the button is on the deepest view and there is no page left it still appears and instead navigates one above?

Correct.

I think for now and for our use case it might be enough to leave that out (since we also don't hide when there is no preceding page)

As you prefer

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the nested part cc @danirabbit ?

}
}

private void on_click () {
var navigation_view = (Adw.NavigationView) get_ancestor (typeof (Adw.NavigationView));

if (navigation_view != null) {
navigation_view.pop ();
}
}
}
1 change: 1 addition & 0 deletions lib/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ libgranite_sources = files(
'Widgets/AbstractSettingsPage.vala',
'Widgets/AbstractSimpleSettingsPage.vala',
'Widgets/AccelLabel.vala',
'Widgets/BackButton.vala',
'Widgets/DatePicker.vala',
'Widgets/Dialog.vala',
'Widgets/HeaderLabel.vala',
Expand Down
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ libgranite_deps = [
dependency('glib-2.0', version: '>=' + glib_min_version),
dependency('gobject-2.0', version: '>=' + glib_min_version),
dependency('gtk4', version: '>=4.4'),
dependency('libadwaita-1', version: '>=1.4'),
]

icons_dir = join_paths(
Expand Down
Loading