/** * [class@Gtk.Image] 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, }