[seahorse/wip/nielsdg/adaptive: 1/2] Initial steps towards an adaptive UI
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse/wip/nielsdg/adaptive: 1/2] Initial steps towards an adaptive UI
- Date: Wed, 29 Jan 2020 07:00:49 +0000 (UTC)
commit da441cce8b0e4ebe3e13ad3bcaf373e887f935e0
Author: Niels De Graef <nielsdegraef gmail com>
Date: Tue Jan 28 22:01:41 2020 +0100
Initial steps towards an adaptive UI
We use Purism's `libhandy` for this. Since some distro's might not have
the version we need, we also add a meson subproject (backed by a git
submodule).
.gitmodules | 3 +
build-aux/org.gnome.Seahorse.json | 15 ++
libseahorse/seahorse.css | 7 -
meson.build | 19 +++
src/key-manager.vala | 56 +++++++-
src/main.vala | 2 +
src/meson.build | 6 +
src/seahorse-key-manager.ui | 293 ++++++++++++++++++++++++++------------
src/sidebar.vala | 23 +--
subprojects/libhandy | 1 +
10 files changed, 313 insertions(+), 112 deletions(-)
---
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..f4788ba4
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "subprojects/libhandy"]
+ path = subprojects/libhandy
+ url = https://source.puri.sm/Librem5/libhandy.git
diff --git a/build-aux/org.gnome.Seahorse.json b/build-aux/org.gnome.Seahorse.json
index 334b5ca7..ee0a2b41 100644
--- a/build-aux/org.gnome.Seahorse.json
+++ b/build-aux/org.gnome.Seahorse.json
@@ -123,6 +123,21 @@
}
]
},
+ {
+ "name": "libhandy",
+ "buildsystem": "meson",
+ "builddir": true,
+ "config-opts": [
+ "-Dglade_catalog=disabled"
+ ],
+ "sources": [
+ {
+ "type": "git",
+ "url": "https://source.puri.sm/Librem5/libhandy.git",
+ "branch": "libhandy-0-0"
+ }
+ ]
+ },
{
"name": "seahorse",
"buildsystem": "meson",
diff --git a/libseahorse/seahorse.css b/libseahorse/seahorse.css
index e0dfcbc7..1de94e86 100644
--- a/libseahorse/seahorse.css
+++ b/libseahorse/seahorse.css
@@ -1,10 +1,3 @@
-.sidebar {
- border-width: 1px 0 0 0;
- border-style: solid;
- border-color: shade (@theme_bg_color, 0.66);
- border-radius: 0;
-}
-
.seahorse-sidebar-item-header {
margin-top: 6px;
font-weight: bold;
diff --git a/meson.build b/meson.build
index d2e2f111..8347f31a 100644
--- a/meson.build
+++ b/meson.build
@@ -49,6 +49,25 @@ glib_deps = [
dependency('gmodule-2.0', version: '>=' + min_glib_version),
]
gtk = dependency('gtk+-3.0', version: '>= 3.22.0')
+libhandy_dep = dependency('libhandy-0.0', version: '>= 0.0.12', required: false)
+if not libhandy_dep.found()
+ libhandy_subproj = subproject(
+ 'libhandy',
+ default_options: [
+ 'examples=false',
+ 'glade_catalog=disabled',
+ 'tests=false',
+ ]
+ )
+
+ # Make sure to also get the VAPI file
+ libhandy_dep = declare_dependency(
+ dependencies: [
+ libhandy_subproj.get_variable('libhandy_dep'),
+ libhandy_subproj.get_variable('libhandy_vapi'),
+ ]
+ )
+endif
gcr = dependency('gcr-3', version: '>=' + min_gcr_version)
gcr_ui = dependency('gcr-ui-3', version: '>=' + min_gcr_version)
libsecret = dependency('libsecret-1', version: '>= 0.16')
diff --git a/src/key-manager.vala b/src/key-manager.vala
index 9049bbe1..95e6fb5a 100644
--- a/src/key-manager.vala
+++ b/src/key-manager.vala
@@ -23,13 +23,22 @@
[GtkTemplate (ui = "/org/gnome/Seahorse/seahorse-key-manager.ui")]
public class Seahorse.KeyManager : Catalog {
+ [GtkChild]
+ private Hdy.Leaflet header;
+ [GtkChild]
+ private Gtk.HeaderBar left_header;
+ [GtkChild]
+ private Gtk.HeaderBar right_header;
+ [GtkChild]
+ private Gtk.Revealer back_revealer;
+
[GtkChild]
private Gtk.SearchBar search_bar;
[GtkChild]
private Gtk.SearchEntry filter_entry;
[GtkChild]
- private Gtk.Paned sidebar_panes;
+ private Hdy.Leaflet content_box;
[GtkChild]
private Gtk.ScrolledWindow sidebar_area;
private Sidebar sidebar;
@@ -230,6 +239,39 @@ public class Seahorse.KeyManager : Catalog {
this.item_list.filter_text = this.filter_entry.text;
}
+ [GtkCallback]
+ private void on_back_clicked() {
+ show_sidebar_pane();
+ }
+
+ private void show_sidebar_pane() {
+ this.content_box.visible_child_name = "sidebar-pane";
+ update_header();
+ }
+
+ private void show_item_list_pane() {
+ this.content_box.visible_child_name = "item-list-pane";
+ update_header();
+ }
+
+ [GtkCallback]
+ private void on_fold () {
+ update_header();
+ }
+
+ private void update_header() {
+ bool folded = this.content_box.fold == Hdy.Fold.FOLDED;
+
+ this.left_header.show_close_button =
+ !folded || header.visible_child == left_header;
+
+ this.right_header.show_close_button =
+ !folded || header.visible_child == right_header;
+
+ this.back_revealer.reveal_child = this.back_revealer.visible =
+ folded && header.visible_child == right_header;
+ }
+
public void import_files(string[]? uris) {
ImportDialog dialog = new ImportDialog(this);
dialog.add_uris(uris);
@@ -387,16 +429,11 @@ public class Seahorse.KeyManager : Catalog {
private Gcr.Collection setup_sidebar() {
this.sidebar = new Sidebar();
- sidebar.hexpand = true;
/* Make sure we update the empty state on any change */
this.sidebar.selected_rows_changed.connect(on_sidebar_selected_rows_changed);
this.sidebar.current_collection_changed.connect((sidebar) => { check_empty_state (); });
- this.sidebar_panes.position = this.settings.get_int("sidebar-width");
- this.sidebar_panes.realize.connect(() => { this.sidebar_panes.position =
this.settings.get_int("sidebar-width"); });
- this.sidebar_panes.unrealize.connect(() => { this.settings.set_int("sidebar-width",
this.sidebar_panes.position); });
-
foreach (weak Backend backend in get_backends()) {
ActionGroup actions = backend.actions;
actions.catalog = this;
@@ -411,6 +448,13 @@ public class Seahorse.KeyManager : Catalog {
private void on_sidebar_selected_rows_changed(Gtk.ListBox sidebar) {
check_empty_state();
+
+ show_item_list_pane();
+
+ Place? place = this.sidebar.get_focused_place();
+ if (place != null)
+ this.right_header.title = place.label;
+
// FIXME
//this.settings.set_strv("keyrings-selected", );
}
diff --git a/src/main.vala b/src/main.vala
index 96d1f9f0..49bb1bb0 100644
--- a/src/main.vala
+++ b/src/main.vala
@@ -24,6 +24,8 @@ public int main (string[] args) {
Intl.bind_textdomain_codeset(Config.GETTEXT_PACKAGE, "UTF-8");
Intl.textdomain(Config.GETTEXT_PACKAGE);
+ Hdy.init (ref args);
+
Seahorse.Application app = new Seahorse.Application();
int status = app.run(args);
diff --git a/src/meson.build b/src/meson.build
index 6d07c18c..dea58a3d 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -20,6 +20,7 @@ seahorse_sources = [
seahorse_dependencies = [
glib_deps,
gtk,
+ libhandy_dep,
libsecret,
common_dep,
libseahorse_dep,
@@ -32,6 +33,10 @@ seahorse_linkedlibs = [
libtreemultidnd_lib,
]
+seahorse_c_flags = [
+ '-DHANDY_USE_UNSTABLE_API',
+]
+
seahorse_vala_flags = [
]
@@ -49,6 +54,7 @@ seahorse_exe = executable('seahorse',
seahorse_sources,
dependencies: seahorse_dependencies,
vala_args: seahorse_vala_flags,
+ c_args: seahorse_c_flags,
link_with: seahorse_linkedlibs,
install: true,
)
diff --git a/src/seahorse-key-manager.ui b/src/seahorse-key-manager.ui
index 664f2b73..d201e253 100644
--- a/src/seahorse-key-manager.ui
+++ b/src/seahorse-key-manager.ui
@@ -2,30 +2,6 @@
<interface>
<requires lib="gtk+" version="3.22"/>
<menu id="main_menu">
- <section>
- <attribute name="label" translatable="yes">Filter items:</attribute>
- <item>
- <attribute name="label" translatable="yes">Show p_ersonal</attribute>
- <attribute name="action">win.filter-items</attribute>
- <attribute name="target">personal</attribute>
- </item>
- <item>
- <attribute name="label" translatable="yes">Show _trusted</attribute>
- <attribute name="action">win.filter-items</attribute>
- <attribute name="target">trusted</attribute>
- </item>
- <item>
- <attribute name="label" translatable="yes">Show an_y</attribute>
- <attribute name="action">win.filter-items</attribute>
- <attribute name="target">any</attribute>
- </item>
- </section>
- <section>
- <item>
- <attribute name="label" translatable="yes">_Combine all keyrings</attribute>
- <attribute name="action">win.combine-keyrings</attribute>
- </item>
- </section>
<section>
<item>
<attribute name="label" translatable="yes">_Find remote keys…</attribute>
@@ -54,6 +30,34 @@
</item>
</section>
</menu>
+
+ <menu id="items_menu">
+ <section>
+ <attribute name="label" translatable="yes">Filter items:</attribute>
+ <item>
+ <attribute name="label" translatable="yes">Show p_ersonal</attribute>
+ <attribute name="action">win.filter-items</attribute>
+ <attribute name="target">personal</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Show _trusted</attribute>
+ <attribute name="action">win.filter-items</attribute>
+ <attribute name="target">trusted</attribute>
+ </item>
+ <item>
+ <attribute name="label" translatable="yes">Show an_y</attribute>
+ <attribute name="action">win.filter-items</attribute>
+ <attribute name="target">any</attribute>
+ </item>
+ </section>
+ <section>
+ <item>
+ <attribute name="label" translatable="yes">_Combine all keyrings</attribute>
+ <attribute name="action">win.combine-keyrings</attribute>
+ </item>
+ </section>
+ </menu>
+
<object class="GtkPopover" id="new_item_menu_popover">
<signal name="grab-notify" handler="on_popover_grab_notify" after="yes"/>
<child>
@@ -265,88 +269,190 @@
</object>
</child>
</object>
+
<template class="SeahorseKeyManager" parent="SeahorseCatalog">
<property name="default-width">600</property>
<property name="default-height">476</property>
<signal name="drag-data-received" handler="on_drag_data_received" />
<signal name="key-press-event" handler="on_key_pressed"/>
<child type="titlebar">
- <object class="GtkHeaderBar">
+ <object class="HdyTitleBar" id="titlebar">
<property name="visible">True</property>
- <property name="show-close-button">True</property>
- <property name="title" translatable="yes">Passwords and Keys</property>
<child>
- <object class="GtkMenuButton" id="new_item_button">
+ <object class="HdyLeaflet" id="header">
<property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="halign">start</property>
- <property name="tooltip_text" translatable="yes">Add a new key or item</property>
- <property name="popover">new_item_menu_popover</property>
+ <property name="can_focus">False</property>
+ <property name="mode-transition-duration" bind-source="content_box"
bind-property="mode-transition-duration" bind-flags="bidirectional|sync-create"/>
+ <property name="child-transition-duration" bind-source="content_box"
bind-property="child-transition-duration" bind-flags="bidirectional|sync-create"/>
+ <property name="transition-type" bind-source="content_box" bind-property="transition-type"
bind-flags="bidirectional|sync-create"/>
<child>
- <object class="GtkImage">
+ <object class="GtkHeaderBar" id="left_header">
<property name="visible">True</property>
- <property name="icon_name">list-add-symbolic</property>
+ <property name="hexpand">False</property>
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Passwords and Keys</property>
+ <property name="show_close_button">True</property>
+ <child>
+ <object class="GtkMenuButton" id="new_item_button">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="tooltip_text" translatable="yes">Add a new key or item</property>
+ <property name="popover">new_item_menu_popover</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon_name">list-add-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">start</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="main_menu_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="menu-model">main_menu</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">open-menu-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
</object>
+ <packing>
+ <property name="name">sidebar-pane</property>
+ </packing>
</child>
- </object>
- </child>
- <child>
- <object class="GtkMenuButton" id="main_menu_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="focus_on_click">False</property>
- <property name="menu-model">main_menu</property>
<child>
- <object class="GtkImage">
+ <object class="GtkSeparator" id="header_separator">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">open-menu-symbolic</property>
+ <style>
+ <class name="sidebar"/>
+ </style>
</object>
+ <packing>
+ <property name="allow-visible">False</property>
+ </packing>
</child>
- </object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
- </child>
- <child>
- <object class="GtkToggleButton" id="show_search_button">
- <property name="visible">True</property>
- <property name="tooltip_text" translatable="yes">Search for a key or password</property>
<child>
- <object class="GtkImage">
+ <object class="GtkHeaderBar" id="right_header">
<property name="visible">True</property>
- <property name="icon_name">edit-find-symbolic</property>
+ <property name="hexpand">True</property>
+ <property name="show_close_button">True</property>
+ <child>
+ <object class="GtkRevealer" id="back_revealer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="transition-type">slide-right</property>
+ <property name="transition-duration" bind-source="content_box"
bind-property="mode-transition-duration" bind-flags="bidirectional|sync-create"/>
+ <child>
+ <object class="GtkButton" id="back">
+ <property name="visible">True</property>
+ <property name="valign">center</property>
+ <property name="use-underline">True</property>
+ <signal name="clicked" handler="on_back_clicked"/>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="a11y-back">
+ <property name="accessible-name" translatable="yes">Back</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkImage" id="back_image">
+ <property name="visible">True</property>
+ <property name="icon-name">go-previous-symbolic</property>
+ <property name="icon-size">1</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="items_menu_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="focus_on_click">False</property>
+ <property name="menu-model">items_menu</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">view-more-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleButton" id="show_search_button">
+ <property name="visible">True</property>
+ <property name="tooltip_text" translatable="yes">Search for a key or password</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon_name">edit-find-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
</object>
+ <packing>
+ <property name="name">item-list-pane</property>
+ </packing>
</child>
</object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
</child>
</object>
</child>
+
<child>
- <object class="GtkPaned" id="sidebar_panes">
+ <object class="HdyLeaflet" id="content_box">
<property name="visible">True</property>
<property name="vexpand">True</property>
<property name="can_focus">True</property>
+ <property name="can-swipe-back">True</property>
+ <property name="transition-type">over</property>
+ <signal name="notify::fold" handler="on_fold" object="SeahorseKeyManager" after="yes" swapped="no"/>
<child>
<object class="GtkScrolledWindow" id="sidebar_area">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hscrollbar-policy">never</property>
- <property name="shadow-type">out</property>
- <property name="width-request">170</property>
+ </object>
+ <packing>
+ <property name="name">sidebar-pane</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
<style>
<class name="sidebar"/>
</style>
</object>
<packing>
- <property name="shrink">False</property>
+ <property name="allow-visible">False</property>
</packing>
</child>
<child>
- <object class="GtkBox">
+ <object class="GtkBox" id="right_content">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
@@ -374,37 +480,21 @@
<property name="can_focus">True</property>
<property name="hscrollbar-policy">never</property>
<child>
- <object class="GtkBox">
+ <object class="HdyColumn">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="orientation">horizontal</property>
- <property name="margin-top">24</property>
- <property name="margin-bottom">24</property>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- </object>
- </child>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- </object>
- <packing>
- <property name="pack_type">end</property>
- </packing>
- </child>
+ <property name="linear-growth-width">400</property>
+ <property name="maximum-width">800</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
<child>
<object class="GtkListBox" id="item_listbox">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="can-focus">True</property>
<property name="has-focus">True</property>
- <property name="margin-start">18</property>
- <property name="margin-end">18</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
<property name="activate-on-single-click">False</property>
<property name="selection-mode">multiple</property>
<style>
@@ -502,10 +592,37 @@
</child>
</object>
<packing>
- <property name="shrink">False</property>
+ <property name="name">item-list-pane</property>
</packing>
</child>
</object>
</child>
</template>
+
+ <object class="GtkSizeGroup" id="left_pane_size_group">
+ <property name="mode">horizontal</property>
+ <widgets>
+ <widget name="left_header"/>
+ <widget name="sidebar_area"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="right_pane_size_group">
+ <property name="mode">horizontal</property>
+ <widgets>
+ <widget name="right_header"/>
+ <widget name="right_content"/>
+ </widgets>
+ </object>
+ <object class="HdyHeaderGroup" id="header_group">
+ <headerbars>
+ <headerbar name="left_header"/>
+ <headerbar name="right_header"/>
+ </headerbars>
+ </object>
+ <object class="HdySwipeGroup" id="swipe_group">
+ <swipeables>
+ <swipeable name="header"/>
+ <swipeable name="content_box"/>
+ </swipeables>
+ </object>
</interface>
diff --git a/src/sidebar.vala b/src/sidebar.vala
index 76dc73cb..fc53e502 100644
--- a/src/sidebar.vala
+++ b/src/sidebar.vala
@@ -144,8 +144,9 @@ public class Seahorse.Sidebar : Gtk.ListBox {
label.tooltip_text = b.description;
label.get_style_context().add_class("seahorse-sidebar-item-header");
label.xalign = 0f;
- label.margin_start = 6;
+ label.margin_start = 9;
label.margin_top = 6;
+ label.margin_bottom = 3;
label.show();
row.set_header(label);
return;
@@ -343,27 +344,27 @@ internal class Seahorse.SidebarItem : Gtk.ListBoxRow {
public signal void place_changed();
construct {
- var grid = new Gtk.Grid();
- grid.get_style_context().add_class("seahorse-sidebar-item");
- grid.valign = Gtk.Align.CENTER;
- grid.row_spacing = 6;
- grid.column_spacing = 6;
- add(grid);
+ var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 6);
+ box.get_style_context().add_class("seahorse-sidebar-item");
+ box.valign = Gtk.Align.CENTER;
+ box.margin_top = 3;
+ box.margin_bottom = 3;
+ add(box);
var icon = new Gtk.Image.from_gicon(place.icon, Gtk.IconSize.BUTTON);
- grid.attach(icon, 0, 0);
+ box.pack_start(icon, false, false);
var label = new Gtk.Label(place.label);
- label.hexpand = true;
label.ellipsize = Pango.EllipsizeMode.END;
label.xalign = 0f;
- grid.attach(label, 1, 0);
+ box.pack_start(label);
var lockable = place as Lockable;
if (lockable != null && (lockable.lockable || lockable.unlockable)) {
this.lock_button = new Gtk.Button.from_icon_name(get_lock_icon_name(lockable),
Gtk.IconSize.BUTTON);
this.lock_button.get_style_context().add_class("flat");
+ this.lock_button.halign = Gtk.Align.END;
this.lock_button.clicked.connect((b) => {
if (lockable.unlockable)
place_unlock(lockable, (Gtk.Window) get_toplevel());
@@ -372,7 +373,7 @@ internal class Seahorse.SidebarItem : Gtk.ListBoxRow {
update_lock_icon(lockable);
});
- grid.attach(this.lock_button, 2, 0);
+ box.pack_end(this.lock_button, false, false);
}
show_all();
diff --git a/subprojects/libhandy b/subprojects/libhandy
new file mode 160000
index 00000000..aa6b6f43
--- /dev/null
+++ b/subprojects/libhandy
@@ -0,0 +1 @@
+Subproject commit aa6b6f43d505383538a2a3e7b4fcdd6a8ada85ff
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]