1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/**
* [[email protected]] subclass meant to be used only for icons.
*
* It's size is calculated from `font-size` css property.
* Its css selector is `icon`.
*/
public class Astal.Icon : Gtk.Image {
private IconType type = IconType.NAMED;
private double size { get; set; default = 14; }
public new Gdk.Pixbuf pixbuf { get; set; }
private static bool gicon_warned = false;
[Version (deprecated = true, deprecated_since = "0.1.0", replacement = "gicon")]
public GLib.Icon g_icon {
owned get {
return this.gicon;
}
set {
if( !gicon_warned ) {
GLib.warning("g-icon is deprecated. Use gicon instead.");
gicon_warned = true;
}
this.gicon = value;
}
}
/**
* Either a named icon or a path to a file.
*/
public string icon { get; set; default = ""; }
public static Gtk.IconInfo? lookup_icon(string icon) {
var theme = Gtk.IconTheme.get_default();
return theme.lookup_icon(icon, 16, Gtk.IconLookupFlags.USE_BUILTIN);
}
private async void display_icon() {
switch(type) {
case IconType.NAMED:
icon_name = icon;
pixel_size = (int)size;
break;
case IconType.FILE:
try {
var file = File.new_for_path(icon);
var stream = yield file.read_async();
var pb = yield new Gdk.Pixbuf.from_stream_at_scale_async(
stream,
(int)size * scale_factor,
(int)size * scale_factor,
true,
null
);
var cs = Gdk.cairo_surface_create_from_pixbuf(pb, 0, this.get_window());
set_from_surface(cs);
} catch (Error err) {
printerr(err.message);
}
break;
case IconType.PIXBUF:
var pb_scaled = pixbuf.scale_simple(
(int)size * scale_factor,
(int)size * scale_factor,
Gdk.InterpType.BILINEAR
);
if (pb_scaled != null) {
var cs = Gdk.cairo_surface_create_from_pixbuf(pb_scaled, 0, this.get_window());
set_from_surface(cs);
}
break;
case IconType.GICON:
pixel_size = (int)size;
break;
}
}
static construct {
set_css_name("icon");
}
construct {
notify["icon"].connect(() => {
if(FileUtils.test(icon, GLib.FileTest.EXISTS))
type = IconType.FILE;
else if (lookup_icon(icon) != null)
type = IconType.NAMED;
else {
type = IconType.NAMED;
warning("cannot assign %s as icon, "+
"it is not a file nor a named icon", icon);
}
display_icon.begin();
});
notify["pixbuf"].connect(() => {
type = IconType.PIXBUF;
display_icon.begin();
});
notify["gicon"].connect(() => {
type = IconType.GICON;
display_icon.begin();
});
size_allocate.connect(() => {
size = get_style_context()
.get_property("font-size", Gtk.StateFlags.NORMAL).get_double();
display_icon.begin();
});
get_style_context().changed.connect(() => {
size = get_style_context()
.get_property("font-size", Gtk.StateFlags.NORMAL).get_double();
display_icon.begin();
});
}
}
private enum Astal.IconType {
NAMED,
FILE,
PIXBUF,
GICON,
}
|