[fractal/multi-account: 1/2] Account switcher: Show hints in account entry for visible session




commit f33949b5f618a6697b35f2d379301b36ef8be701
Author: Alejandro Domínguez <adomu net-c com>
Date:   Mon Aug 16 05:41:05 2021 +0200

    Account switcher: Show hints in account entry for visible session

 data/resources/style.css                     | 10 ++++++++
 data/resources/ui/components-avatar.ui       | 28 +++++++++++++----------
 src/components/avatar.rs                     | 34 +++++++++++++++++++++++++++-
 src/session/sidebar/account_switcher/rows.rs | 27 ++++++++++++++++++++++
 4 files changed, 86 insertions(+), 13 deletions(-)
---
diff --git a/data/resources/style.css b/data/resources/style.css
index 355cf490..86a33d03 100644
--- a/data/resources/style.css
+++ b/data/resources/style.css
@@ -18,6 +18,16 @@
   background-color: alpha(@theme_bg_color, 0.2);
 }
 
+.selected-avatar avatar {
+  border: 2px solid @accent_bg_color;
+}
+
+.blue-checkmark {
+  color: @accent_bg_color;
+  border-radius: 9999px;
+  background-color: white;
+}
+
 /* Login */
 .login {
   min-width: 250px;
diff --git a/data/resources/ui/components-avatar.ui b/data/resources/ui/components-avatar.ui
index 3c4489e2..1a835c30 100644
--- a/data/resources/ui/components-avatar.ui
+++ b/data/resources/ui/components-avatar.ui
@@ -2,18 +2,22 @@
 <interface>
   <template class="ComponentsAvatar" parent="AdwBin">
     <property name="child">
-      <object class="AdwAvatar" id="avatar">
-        <property name="show-initials">True</property>
-        <binding name="custom-image">
-          <lookup name="image" type="Avatar">
-              <lookup name="item">ComponentsAvatar</lookup>
-          </lookup>
-        </binding>
-        <binding name="text">
-          <lookup name="display-name" type="Avatar">
-              <lookup name="item">ComponentsAvatar</lookup>
-          </lookup>
-        </binding>
+      <object class="GtkOverlay" id="checkmark_overlay">
+        <child>
+          <object class="AdwAvatar" id="avatar">
+            <property name="show-initials">True</property>
+            <binding name="custom-image">
+              <lookup name="image" type="Avatar">
+                <lookup name="item">ComponentsAvatar</lookup>
+              </lookup>
+            </binding>
+            <binding name="text">
+              <lookup name="display-name" type="Avatar">
+                <lookup name="item">ComponentsAvatar</lookup>
+              </lookup>
+            </binding>
+          </object>
+        </child>
       </object>
     </property>
   </template>
diff --git a/src/components/avatar.rs b/src/components/avatar.rs
index 1f0497ad..aa95145f 100644
--- a/src/components/avatar.rs
+++ b/src/components/avatar.rs
@@ -6,6 +6,7 @@ use crate::session::Avatar as AvatarItem;
 mod imp {
     use super::*;
     use glib::subclass::InitializingObject;
+    use once_cell::sync::{Lazy, OnceCell};
     use std::cell::RefCell;
 
     #[derive(Debug, Default, CompositeTemplate)]
@@ -15,6 +16,9 @@ mod imp {
         pub item: RefCell<Option<AvatarItem>>,
         #[template_child]
         pub avatar: TemplateChild<adw::Avatar>,
+        #[template_child]
+        pub checkmark_overlay: TemplateChild<gtk::Overlay>,
+        pub checkmark: OnceCell<gtk::Image>,
     }
 
     #[glib::object_subclass]
@@ -34,7 +38,6 @@ mod imp {
 
     impl ObjectImpl for Avatar {
         fn properties() -> &'static [glib::ParamSpec] {
-            use once_cell::sync::Lazy;
             static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
                 vec![
                     glib::ParamSpec::new_object(
@@ -53,6 +56,13 @@ mod imp {
                         -1,
                         glib::ParamFlags::READWRITE,
                     ),
+                    glib::ParamSpec::new_boolean(
+                        "selected",
+                        "Selected",
+                        "Style helper for the inner Avatar",
+                        false,
+                        glib::ParamFlags::READWRITE,
+                    ),
                 ]
             });
 
@@ -69,6 +79,7 @@ mod imp {
             match pspec.name() {
                 "item" => obj.set_item(value.get().unwrap()),
                 "size" => self.avatar.set_size(value.get().unwrap()),
+                "selected" => obj.set_selected(value.get().unwrap()),
                 _ => unimplemented!(),
             }
         }
@@ -105,6 +116,27 @@ impl Avatar {
         glib::Object::new(&[]).expect("Failed to create Avatar")
     }
 
+    pub fn set_selected(&self, selected: bool) {
+        let priv_ = imp::Avatar::from_instance(self);
+        let checkmark = priv_.checkmark.get_or_init(|| {
+            gtk::Image::builder()
+                .halign(gtk::Align::End)
+                .valign(gtk::Align::End)
+                .icon_name("emblem-default-symbolic")
+                .pixel_size(14)
+                .css_classes(vec!["blue-checkmark".into()])
+                .build()
+        });
+
+        if selected {
+            priv_.avatar.add_css_class("selected-avatar");
+            priv_.checkmark_overlay.add_overlay(checkmark);
+        } else {
+            priv_.avatar.remove_css_class("selected-avatar");
+            priv_.checkmark_overlay.remove_overlay(checkmark);
+        }
+    }
+
     pub fn set_size(&self, size: i32) {
         let priv_ = imp::Avatar::from_instance(self);
         priv_.avatar.set_size(size);
diff --git a/src/session/sidebar/account_switcher/rows.rs b/src/session/sidebar/account_switcher/rows.rs
index 5e3a32b1..74354f17 100644
--- a/src/session/sidebar/account_switcher/rows.rs
+++ b/src/session/sidebar/account_switcher/rows.rs
@@ -18,6 +18,16 @@ pub fn user_entry(session_page: &gtk::StackPage) -> gtk::Box {
         "avatar",
     );
     avatar_exp.bind::<glib::Object>(avatar.upcast_ref(), "item", Some(user.upcast_ref()));
+    let selected_avatar_exp = gtk::PropertyExpression::new::<gtk::PropertyExpression>(
+        gtk::StackPage::static_type(),
+        None,
+        "visible",
+    );
+    selected_avatar_exp.bind::<glib::Object>(
+        avatar.upcast_ref(),
+        "selected",
+        Some(session_page.upcast_ref()),
+    );
 
     let ref identifiers = gtk::Box::new(gtk::Orientation::Vertical, 5);
 
@@ -35,6 +45,23 @@ pub fn user_entry(session_page: &gtk::StackPage) -> gtk::Box {
         "label",
         Some(user.upcast_ref()),
     );
+    let boldness_exp = gtk::ClosureExpression::new(
+        |params| {
+            let stack_page = params[0].get::<gtk::StackPage>().unwrap();
+
+            if stack_page.is_visible() {
+                vec![String::from("bold")]
+            } else {
+                vec![]
+            }
+        },
+        &[],
+    );
+    boldness_exp.bind::<glib::Object>(
+        display_name.upcast_ref(),
+        "css-classes",
+        Some(session_page.upcast_ref()),
+    );
 
     let ref user_id = gtk::Label::builder()
         .xalign(0.0)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]