Imported Upstream version 0.3~20101209
[debian/pino.git] / src / avatar.vala
1 using Gtk;
2 using Cairo;
3
4 /** Special class for avatars. With rounded corners and shadows */
5 public class Avatar : Image {
6         
7         public string url {get; set; default = "";}
8         public int pix_size {get; set; default = 1;}
9         
10         private const double M_PI = 3.1415926535;
11         private const double MAX_RGB = (double) uint16.MAX;
12         
13         public Avatar() {
14                 GLib.Object();
15         }
16         
17         public Avatar.from_url(string url, int pix_size) {
18                 this.url = url;
19                 this.pix_size = pix_size;
20                 load_pic();
21         }
22         
23         public void set_file_name(string file_name) {
24                 //this.set_from_file(file_name);
25                 pixbuf = img_cache.from_cache(file_name);
26                 
27                 if(pixbuf.width > pix_size || pixbuf.height > pix_size) {
28                         pixbuf = pixbuf.scale_simple(pix_size, pix_size, Gdk.InterpType.BILINEAR);
29                 }
30                 
31                 redraw();
32         }
33         
34         public override bool expose_event(Gdk.EventExpose event) {
35                 Context ctx = Gdk.cairo_create(this.window);
36                 
37                 if(pixbuf != null) {
38                         if(!pixbuf.has_alpha) {
39                                 draw_rounded_path(ctx, allocation.x + 2, allocation.y + 2, allocation.width - 2,
40                                         allocation.height - 2, 4);
41                                 ctx.set_source_rgb(242 / 256.0, 242 / 256.0, 242 / 256.0);
42                                 ctx.fill_preserve();
43                                 ctx.clip();
44                                 
45                                 ctx.reset_clip();
46                                 
47                                 draw_rounded_path(ctx, allocation.x + 1, allocation.y + 1, allocation.width - 2,
48                                         allocation.height - 2, 4);
49                                 ctx.set_source_rgb(217 / 256.0, 217 / 256.0, 217 / 256.0);
50                                 ctx.fill_preserve();
51                                 ctx.clip();
52                                 
53                                 ctx.reset_clip();
54                         }
55                         
56                         draw_rounded_path(ctx, allocation.x, allocation.y, allocation.width - 2,
57                                 allocation.height - 2, 4);
58                         
59                         Gdk.cairo_set_source_pixbuf(ctx, pixbuf, allocation.x, allocation.y);
60                         ctx.clip();
61                         ctx.paint();
62                 }
63                 return false;
64         }
65         
66         private void draw_rounded_path(Context ctx, double x, double y,
67                 double width, double height, double radius) {
68                 
69                 double degrees = M_PI / 180.0;
70                 
71                 ctx.new_sub_path();
72                 ctx.arc(x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees);
73                 ctx.arc(x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees);
74                 ctx.arc(x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees);
75                 ctx.arc(x + radius, y + radius, radius, 180 * degrees, 270 * degrees);
76                 ctx.close_path();
77         }
78         
79         private void set_color(Context ctx, Gdk.Color color) {
80                 //get rgb
81                 double r = (double) color.red / MAX_RGB;
82                 double g = (double) color.green / MAX_RGB;
83                 double b = (double) color.blue / MAX_RGB;
84                 
85                 ctx.set_source_rgb(r, g, b);
86         }
87         
88         private void redraw() {
89                 if (null == this.window)
90                         return;
91
92                 unowned Gdk.Region region = this.window.get_clip_region();
93                 this.window.invalidate_region(region, true);
94                 this.window.process_updates(true);
95     }
96     
97     public void load_pic() {
98                 try {
99                         unowned Thread thread = Thread.create<void*>(load_pic_thread, true);
100                 } catch(GLib.Error e) {
101                         debug(e.message); //TODO
102                 }
103         }
104         
105         private void* load_pic_thread() {
106                 string? img_path = img_cache.download(url);
107                 
108                 if(img_path != null) {
109                         //debug("%s, %s", img_path, status.user.pic);
110                         Idle.add(() => {
111                                 try {
112                                         this.set_file_name(img_path);
113                                 } catch(GLib.Error e) {
114                                         debug(e.message); //TODO
115                                 }
116                                 return false;
117                         });
118                 }
119                 
120                 //debug("loading userpic");
121                 return null;
122         }
123 }