Member avatar with the avatar widget
This commit is contained in:
parent
8d42e3e928
commit
3c23922708
4 changed files with 50 additions and 29 deletions
|
@ -1 +1,3 @@
|
|||
pub static CACHE_SIZE: usize = 40;
|
||||
pub static MSG_ICON_SIZE: i32 = 40;
|
||||
pub static USERLIST_ICON_SIZE: i32 = 30;
|
||||
|
|
|
@ -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)
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue