Skip to content

Commit 0389534

Browse files
committed
Introduce Gala.Icon
1 parent 4a8302b commit 0389534

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

lib/Icon.vala

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2025 elementary, Inc. (https://elementary.io)
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*
5+
* Authored by: Leonhard Kargl <[email protected]>
6+
*/
7+
8+
public class Gala.Icon : Clutter.Actor {
9+
private class ResourceIconSource : Object, IconSource {
10+
public string path { get; construct; }
11+
12+
public ResourceIconSource (string path) {
13+
Object (path: path);
14+
}
15+
16+
public string? get_cache_key (int size, float scale) {
17+
return "%s-%d".printf (path, get_texture_size (size, scale));
18+
}
19+
20+
public Gdk.Pixbuf create_pixbuf (int size, float scale) throws Error {
21+
return new Gdk.Pixbuf.from_resource_at_scale (path, -1, get_texture_size (size, scale), true);
22+
}
23+
}
24+
25+
private interface IconSource : Object {
26+
public abstract string? get_cache_key (int size, float scale);
27+
/**
28+
* Should look up the icon for the given size (e.g. if there are more detailed icons
29+
* for larger sizes) and return a texture of size * scale.
30+
*/
31+
public abstract Gdk.Pixbuf create_pixbuf (int size, float scale) throws Error;
32+
33+
protected static int get_texture_size (int size, float scale) {
34+
return (int) Math.ceilf (size * scale);
35+
}
36+
}
37+
38+
private static HashTable<string, Gdk.Pixbuf> icon_pixbufs = new HashTable<string, Gdk.Pixbuf> (str_hash, str_equal);
39+
40+
public int icon_size { get; construct set; }
41+
public float monitor_scale { get; construct set; }
42+
43+
public string resource_path { set { source = new ResourceIconSource (value); } }
44+
45+
private IconSource _source;
46+
private IconSource source {
47+
get { return _source; }
48+
set {
49+
_source = value;
50+
load_pixbuf ();
51+
}
52+
}
53+
54+
public Icon.from_resource (int icon_size, float monitor_scale, string resource_path) {
55+
Object (icon_size: icon_size, monitor_scale: monitor_scale, resource_path: resource_path);
56+
}
57+
58+
construct {
59+
notify["icon-size"].connect (load_pixbuf);
60+
notify["monitor-scale"].connect (load_pixbuf);
61+
resource_scale_changed.connect (load_pixbuf);
62+
}
63+
64+
private void load_pixbuf () {
65+
var actor_size = Utils.scale_to_int (icon_size, monitor_scale);
66+
set_size (actor_size, actor_size);
67+
68+
var scale = monitor_scale * get_resource_scale ();
69+
70+
try {
71+
var pixbuf = get_pixbuf (icon_size, scale);
72+
content = new Gala.Image.from_pixbuf_with_size (actor_size, actor_size, pixbuf);
73+
74+
set_background_color (null);
75+
} catch (Error e) {
76+
critical ("Could not load icon pixbuf: %s", e.message);
77+
background_color = { 255, 0, 0, 255 };
78+
}
79+
}
80+
81+
private Gdk.Pixbuf get_pixbuf (int size, float scale) throws Error {
82+
var cache_key = source.get_cache_key (size, scale);
83+
84+
if (cache_key == null) {
85+
return source.create_pixbuf (size, scale);
86+
}
87+
88+
if (!(cache_key in icon_pixbufs)) {
89+
icon_pixbufs[cache_key] = source.create_pixbuf (size, scale);
90+
}
91+
92+
return icon_pixbufs[cache_key];
93+
}
94+
}

lib/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ gala_lib_sources = files(
1717
'Drawing/Color.vala',
1818
'Drawing/StyleManager.vala',
1919
'Drawing/Utilities.vala',
20+
'Icon.vala',
2021
'Image.vala',
2122
'Plugin.vala',
2223
'RoundedCornersEffect.vala',

0 commit comments

Comments
 (0)