Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
22 changes: 21 additions & 1 deletion data/styles/SettingsSidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ settingssidebar {
background: inherit;
min-width: rem(200px);

row,
> .title-4 {
padding: rem(6px);
}
Expand All @@ -28,6 +27,27 @@ settingssidebar {
}
}

listview {
min-width: rem(200px);

header {
margin-bottom: 0;
margin-top: 0;
}

row {
padding: 0;

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)'};
Expand Down
136 changes: 54 additions & 82 deletions lib/SettingsSidebar.vala
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
/*
* Copyright 2017-2022 elementary, Inc. (https://elementary.io)
* Copyright 2017-2026 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

/**
* SettingsSidebar acts as a controller for a Gtk.Stack; it shows a row of buttons
* to switch between the various pages of the associated stack widget.
* SettingsSidebar acts as a controller for a Gtk.SelectionModel; it shows a row of buttons
* to switch between the various pages of the associated model.
*
* All the content for the rows comes from the child properties of a Granite.SettingsPage
* inside of the Gtk.Stack
* inside of the model
*/
public class Switchboard.SettingsSidebar : Gtk.Widget {
private Gtk.ListBox listbox;

/**
* The Gtk.Stack to control
*/
public Gtk.Stack stack { get; construct; }
[Version (deprecated = true, deprecated_since = "9.0.0")]
public Gtk.Stack? stack { get; construct; default = null; }

/**
* The Gtk.SingleSelection to control
*/
public Gtk.SingleSelection model { get; construct; }

/**
* Whether to show back and title buttons in the header area
Expand All @@ -26,39 +30,30 @@ public class Switchboard.SettingsSidebar : Gtk.Widget {
/**
* The name of the currently visible Granite.SettingsPage
*/
public string? visible_child_name {
get {
var selected_row = listbox.get_selected_row ();

if (selected_row == null) {
return null;
} else {
return ((SettingsSidebarRow) selected_row).page.title;
}
}
set {
weak Gtk.Widget listbox_child = listbox.get_first_child ();
while (listbox_child != null) {
if (!(listbox_child is SettingsSidebarRow)) {
listbox_child = listbox_child.get_next_sibling ();
continue;
}

if (((SettingsSidebarRow) listbox_child).page.title == value) {
listbox.select_row ((Gtk.ListBoxRow) listbox_child);
break;
}

listbox_child = listbox_child.get_next_sibling ();
}
}
}
[Version (deprecated = true, deprecated_since = "9.0.0")]
public string? visible_child_name { get; set; default = null; }

/**
* Create a new SettingsSidebar
*/
public SettingsSidebar (Gtk.Stack stack) {
Object (stack: stack);
var selection_model = new Gtk.SingleSelection (stack.pages);
selection_model.notify["selected"].connect (() => {
stack.pages.select_item (selection_model.selected, true);
});

stack.pages.selection_changed.connect ((pos, n_items) => {
selection_model.selected = stack.pages.get_selection ().get_minimum ();
});

Object (
model: selection_model,
stack: stack
);
}

public SettingsSidebar.from_model (Gtk.SingleSelection selection_model) {
Object (model: selection_model);
}

static construct {
Expand All @@ -70,16 +65,19 @@ public class Switchboard.SettingsSidebar : Gtk.Widget {
}

construct {
listbox = new Gtk.ListBox () {
hexpand = true,
activate_on_single_click = true,
selection_mode = Gtk.SelectionMode.SINGLE
var factory = new Gtk.SignalListItemFactory ();
factory.bind.connect (bind_item);

var header_factory = new Gtk.SignalListItemFactory ();
header_factory.bind.connect (bind_header);

var listview = new Gtk.ListView (model, factory) {
header_factory = header_factory
};
listbox.bind_model (stack.pages, create_widget_func);

var scrolled = new Gtk.ScrolledWindow () {
hscrollbar_policy = Gtk.PolicyType.NEVER,
child = listbox
child = listview
};

var headerbar = new Adw.HeaderBar () {
Expand All @@ -96,56 +94,30 @@ public class Switchboard.SettingsSidebar : Gtk.Widget {

add_css_class (Granite.STYLE_CLASS_SIDEBAR);

listbox.row_selected.connect ((row) => {
if (row == null) {
return;
}

stack.visible_child = ((SettingsSidebarRow) row).page;
});

listbox.set_header_func ((row, before) => {
var header = ((SettingsSidebarRow) row).header;
if (header != null) {
if (before != null) {
var before_header = ((SettingsSidebarRow) before).header;
if (before_header != null && before_header == header) {
return;
}
}

var label = new Granite.HeaderLabel (header);

row.set_header (label);
}
});

stack.notify["visible-child"].connect (update_selection);

bind_property ("show-title-buttons", toolbarview, "reveal-top-bars", SYNC_CREATE);
}

~SettingsSidebar () {
get_first_child ().unparent ();
}

private void update_selection () {
for (var child = listbox.get_first_child (); child != null; child = child.get_next_sibling ()) {
if (child is SettingsSidebarRow) {
var row = (SettingsSidebarRow) child;
if (row.page == stack.visible_child) {
listbox.select_row ((Gtk.ListBoxRow) row);
break;
}
}
}
private void bind_item (Object object) {
var list_item = (Gtk.ListItem) object;
//FIXME: check type of item in model;
unowned var stack_page = (Gtk.StackPage) list_item.item;
unowned var settings_page = (SettingsPage) stack_page.child;
list_item.child = new SettingsSidebarRow (settings_page);
}

private Gtk.Widget create_widget_func (Object object) {
unowned var stack_page = (Gtk.StackPage) object;
unowned var page = (SettingsPage) stack_page.child;
var row = new SettingsSidebarRow (page);
private void bind_header (Object item) {
var list_item = (Gtk.ListHeader) item;
unowned var stack_page = (Gtk.StackPage) list_item.item;
unowned var settings_page = (SettingsPage) stack_page.child;

return row;
if (settings_page.header != null) {
((Gtk.ListHeader) item).child = new Granite.HeaderLabel (settings_page.header);
} else {
((Gtk.ListHeader) item).child = null;
}
}
}
5 changes: 1 addition & 4 deletions lib/SettingsSidebarRow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

private class Switchboard.SettingsSidebarRow : Gtk.ListBoxRow {
private class Switchboard.SettingsSidebarRow : Granite.ListItem {
public SettingsPage.StatusType status_type {
set {
switch (value) {
Expand All @@ -26,8 +26,6 @@ private class Switchboard.SettingsSidebarRow : Gtk.ListBoxRow {
}
}

public string? header { get; set; }

public unowned SettingsPage page { get; construct; }

public Icon icon { get; set; }
Expand Down Expand Up @@ -112,7 +110,6 @@ private class Switchboard.SettingsSidebarRow : Gtk.ListBoxRow {
accessible_role = TAB;
child = grid;

header = page.header;
page.bind_property ("icon", this, "icon", BindingFlags.DEFAULT);
page.bind_property ("status", this, "status", BindingFlags.DEFAULT);
page.bind_property ("status-type", this, "status-type", BindingFlags.DEFAULT);
Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
project(
'io.elementary.settings',
'c', 'vala',
version: '8.0.3',
version: '9.0.0',
meson_version: '>= 0.57.0'
)

Expand Down
Loading