Member avatar with the avatar widget

This commit is contained in:
Daniel García Moreno 2017-12-22 21:10:38 +01:00
parent 8d42e3e928
commit 3c23922708
4 changed files with 50 additions and 29 deletions

View file

@ -1 +1,3 @@
pub static CACHE_SIZE: usize = 40;
pub static MSG_ICON_SIZE: i32 = 40;
pub static USERLIST_ICON_SIZE: i32 = 30;

View file

@ -64,12 +64,13 @@ impl AvatarExt for gtk::Box {
fn default(&self, icon: String, size: Option<i32>) {
self.clean();
let da = self.create_da(size);
let s = size.unwrap_or(40);
da.connect_draw(move |da, g| {
use std::f64::consts::PI;
let width = da.get_allocated_width() as f64;
let height = da.get_allocated_height() as f64;
let width = s as f64;
let height = s as f64;
let context = da.get_style_context().unwrap();
@ -77,7 +78,15 @@ impl AvatarExt for gtk::Box {
g.set_antialias(cairo::Antialias::Best);
let img = gtk::Image::new_from_icon_name(&icon[..], 5);
let pb = img.get_pixbuf().unwrap();
let icon = gtk::IconTheme::get_default().unwrap()
.load_icon(&icon[..], s, gtk::IconLookupFlags::empty())
.unwrap();
if let None = icon {
eprintln!("BAD IMAGE");
return Inhibit(false);
}
let pb = icon.unwrap();
let hpos: f64 = (width - (pb.get_height()) as f64) / 2.0;
g.set_source_pixbuf(&pb, 0.0, hpos);
@ -94,28 +103,31 @@ impl AvatarExt for gtk::Box {
fn circle(&self, path: String, size: Option<i32>) {
self.clean();
let da = self.create_da(size);
let s = size.unwrap_or(40);
let p = path.clone();
da.connect_draw(move |da, g| {
use std::f64::consts::PI;
let width = da.get_allocated_width() as f64;
let height = da.get_allocated_height() as f64;
let width = s as f64;
let height = s as f64;
let context = da.get_style_context().unwrap();
gtk::render_background(&context, g, 0.0, 0.0, width, height);
g.set_antialias(cairo::Antialias::Best);
let pb = Pixbuf::new_from_file_at_scale(&p, width as i32, -1, true).unwrap();
let hpos: f64 = (width - (pb.get_height()) as f64) / 2.0;
if let Ok(pb) = Pixbuf::new_from_file_at_scale(&p, width as i32, -1, true) {
let hpos: f64 = (width - (pb.get_height()) as f64) / 2.0;
g.arc(width / 2.0, height / 2.0, width.min(height) / 2.0, 0.0, 2.0 * PI);
g.clip();
g.arc(width / 2.0, height / 2.0, width.min(height) / 2.0, 0.0, 2.0 * PI);
g.clip();
g.set_source_pixbuf(&pb, 0.0, hpos);
g.rectangle(0.0, 0.0, width, height);
g.fill();
g.set_source_pixbuf(&pb, 0.0, hpos);
g.rectangle(0.0, 0.0, width, height);
g.fill();
da.queue_draw();
}
Inhibit(false)
});

View file

@ -14,6 +14,10 @@ use std::sync::mpsc::{Sender, Receiver};
use app::AppOp;
use globals;
use widgets;
use widgets::AvatarExt;
// Room Search item
pub struct MemberBox<'a> {
member: &'a Member,
@ -39,9 +43,10 @@ impl<'a> MemberBox<'a> {
username.set_margin_end(5);
username.set_ellipsize(pango::EllipsizeMode::End);
let avatar = gtk::Image::new_from_icon_name("avatar-default-symbolic", 3);
get_member_avatar(backend.clone(), avatar.clone(), Some(self.member.clone()), 30, 10);
avatar.set_alignment(0.5, 0.5);
let avatar = widgets::Avatar::avatar_new(Some(globals::USERLIST_ICON_SIZE));
avatar.default(String::from("avatar-default-symbolic"),
Some(globals::USERLIST_ICON_SIZE));
get_member_avatar(backend.clone(), avatar.clone(), Some(self.member.clone()), globals::USERLIST_ICON_SIZE, 10);
avatar.set_margin_start(5);
w.add(&avatar);
@ -53,7 +58,7 @@ impl<'a> MemberBox<'a> {
}
}
pub fn get_member_avatar(backend: Sender<BKCommand>, img: gtk::Image, m: Option<Member>, size: i32, tries: i32) {
pub fn get_member_avatar(backend: Sender<BKCommand>, img: widgets::Avatar, m: Option<Member>, size: i32, tries: i32) {
if tries <= 0 {
return;
}
@ -63,11 +68,11 @@ pub fn get_member_avatar(backend: Sender<BKCommand>, img: gtk::Image, m: Option<
gtk::timeout_add(50, move || match rx.try_recv() {
Err(_) => gtk::Continue(true),
Ok(avatar) => {
if let Ok(pixbuf) = Pixbuf::new_from_file_at_scale(&avatar, size, size, false) {
img.set_from_pixbuf(&pixbuf);
if let Ok(_) = Pixbuf::new_from_file_at_scale(&avatar, size, size, false) {
img.circle(avatar, Some(size));
} else {
// trying again if fail
img.set_from_icon_name("avatar-default-symbolic", 5);
img.default(String::from("avatar-default-symbolic"), Some(size));
get_member_avatar(backend.clone(), img.clone(), m.clone(), size, tries - 1);
}
@ -78,17 +83,17 @@ pub fn get_member_avatar(backend: Sender<BKCommand>, img: gtk::Image, m: Option<
pub fn get_member_info(backend: Sender<BKCommand>, img: gtk::Image, username: gtk::Label, sender: String, size: i32, tries: i32) {
pub fn get_member_info(backend: Sender<BKCommand>, img: widgets::Avatar, username: gtk::Label, sender: String, size: i32, tries: i32) {
let (tx, rx): (Sender<(String, String)>, Receiver<(String, String)>) = channel();
backend.send(BKCommand::GetUserInfoAsync(sender.clone(), tx)).unwrap();
gtk::timeout_add(50, move || match rx.try_recv() {
Err(_) => gtk::Continue(true),
Ok((name, avatar)) => {
if let Ok(pixbuf) = Pixbuf::new_from_file_at_scale(&avatar, size, size, false) {
img.set_from_pixbuf(&pixbuf);
if let Ok(_) = Pixbuf::new_from_file_at_scale(&avatar, size, size, false) {
img.circle(avatar, Some(size));
} else {
// trying again if fail
img.set_from_icon_name("avatar-default-symbolic", 5);
img.default(String::from("avatar-default-symbolic"), Some(size));
get_member_info(backend.clone(), img.clone(), username.clone(), sender.clone(), size, tries - 1);
return gtk::Continue(false);
}

View file

@ -20,6 +20,9 @@ use util;
use std::path::Path;
use app::AppOp;
use globals;
use widgets;
use widgets::AvatarExt;
use widgets::member::get_member_avatar;
use widgets::member::get_member_info;
@ -113,19 +116,20 @@ impl<'a> MessageBox<'a> {
content
}
fn build_room_msg_avatar(&self) -> gtk::Image {
fn build_room_msg_avatar(&self) -> widgets::Avatar {
let sender = self.msg.sender.clone();
let backend = self.op.backend.clone();
let avatar;
let avatar = widgets::Avatar::avatar_new(Some(globals::MSG_ICON_SIZE));
let fname = api::util::cache_path(&sender).unwrap_or(strn!(""));
let pathname = fname.clone();
let p = Path::new(&pathname);
if p.is_file() {
avatar = gtk::Image::new_from_file(&fname);
avatar.circle(fname, Some(globals::MSG_ICON_SIZE));
} else {
avatar = gtk::Image::new_from_icon_name("avatar-default-symbolic", 5);
avatar.default(String::from("avatar-default-symbolic"),
Some(globals::MSG_ICON_SIZE));
}
let m = self.room.members.get(&sender);
@ -141,8 +145,6 @@ impl<'a> MessageBox<'a> {
}
};
avatar.set_alignment(0.5, 0.0);
avatar
}