[gnome-games/wip/exalm/gtk4: 237/238] game-thumbnail: Port to textures and render nodes
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/wip/exalm/gtk4: 237/238] game-thumbnail: Port to textures and render nodes
- Date: Mon, 19 Aug 2019 20:36:21 +0000 (UTC)
commit 2048f8221dc40484128f6328a14c714949c761b1
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date: Tue Aug 20 01:15:14 2019 +0500
game-thumbnail: Port to textures and render nodes
This allows them to be drawn on GPU together with other widgets.
src/ui/game-thumbnail.vala | 153 +++++++++++++++++++++------------------------
1 file changed, 73 insertions(+), 80 deletions(-)
---
diff --git a/src/ui/game-thumbnail.vala b/src/ui/game-thumbnail.vala
index 2c1bb335..7ce41d24 100644
--- a/src/ui/game-thumbnail.vala
+++ b/src/ui/game-thumbnail.vala
@@ -1,6 +1,6 @@
// This file is part of GNOME Games. License: GPL-3.0+.
-private class Games.GameThumbnail : Gtk.DrawingArea {
+private class Games.GameThumbnail : Gtk.Widget {
private const Gtk.CornerType[] right_corners = { Gtk.CornerType.TOP_RIGHT,
Gtk.CornerType.BOTTOM_RIGHT };
private const Gtk.CornerType[] bottom_corners = { Gtk.CornerType.BOTTOM_LEFT,
Gtk.CornerType.BOTTOM_RIGHT };
@@ -54,12 +54,12 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
}
private bool tried_loading_cover;
- private Gdk.Pixbuf? cover_cache;
+ private Gdk.Texture? cover_cache;
private int previous_cover_width;
private int previous_cover_height;
public struct DrawingContext {
- Cairo.Context cr;
+ Gtk.Snapshot snapshot;
Gtk.StyleContext style;
int width;
int height;
@@ -78,15 +78,13 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
minimum_baseline = natural_baseline = -1;
}
- construct {
- set_draw_func (draw);
- }
-
- public void draw (Gtk.DrawingArea area, Cairo.Context cr, int width, int height) {
+ public override void snapshot (Gtk.Snapshot snapshot) {
var style = get_style_context ();
+ var width = get_width ();
+ var height = get_height ();
DrawingContext context = {
- cr, style, width, height
+ snapshot, style, width, height
};
if (icon == null)
@@ -97,6 +95,9 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
var drawn = false;
+ var mask = get_mask (context);
+ context.snapshot.push_rounded_clip (mask);
+
drawn = draw_cover (context);
if (!drawn)
@@ -105,6 +106,8 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
// Draw the default thumbnail if no thumbnail have been drawn
if (!drawn)
draw_default (context);
+
+ context.snapshot.pop ();
}
public bool draw_icon (DrawingContext context) {
@@ -112,36 +115,35 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
if (g_icon == null)
return false;
- var pixbuf = get_scaled_icon (context, g_icon, ICON_SCALE);
- if (pixbuf == null)
+ var texture = get_scaled_icon (context, g_icon, ICON_SCALE);
+ if (texture == null)
return false;
- draw_pixbuf (context, pixbuf);
+ draw_texture (context, texture);
return true;
}
public bool draw_cover (DrawingContext context) {
- var pixbuf = get_scaled_cover (context);
- if (pixbuf == null)
+ var texture = get_scaled_cover (context);
+ if (texture == null)
return false;
- var border_radius = (int) context.style.get_property (Gtk.STYLE_PROPERTY_BORDER_RADIUS);
- border_radius = border_radius.clamp (0, int.max (context.width / 2, context.height / 2));
-
- context.cr.set_source_rgb (0, 0, 0);
- rounded_rectangle (context.cr, 0.5, 0.5, context.width - 1, context.height - 1,
border_radius);
- context.cr.fill ();
- draw_pixbuf (context, pixbuf);
+ draw_background (context);
+ draw_texture (context, texture);
return true;
}
public void draw_default (DrawingContext context) {
- draw_emblem_icon (context, Config.APPLICATION_ID + "-symbolic", EMBLEM_SCALE);
+ var texture = get_emblem_icon (context, Config.APPLICATION_ID + "-symbolic", EMBLEM_SCALE);
+ if (texture == null)
+ return;
+
+ draw_texture (context, texture);
}
- private void draw_emblem_icon (DrawingContext context, string icon_name, double scale) {
+ private Gdk.Texture? get_emblem_icon (DrawingContext context, string icon_name, double scale) {
Gdk.Pixbuf? emblem = null;
var color = context.style.get_color ();
@@ -153,25 +155,16 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
emblem = icon_info.load_symbolic (color);
} catch (GLib.Error error) {
warning (@"Unable to get icon “$icon_name”: $(error.message)");
- return;
+ return null;
}
if (emblem == null)
- return;
-
- double offset_x = context.width * scale_factor / 2.0 - emblem.width / 2.0;
- double offset_y = context.height * scale_factor / 2.0 - emblem.height / 2.0;
-
- context.cr.save ();
- context.cr.scale (1.0 / scale_factor, 1.0 / scale_factor);
-
- Gdk.cairo_set_source_pixbuf (context.cr, emblem, offset_x, offset_y);
- context.cr.paint ();
+ return null;
- context.cr.restore ();
+ return Gdk.Texture.for_pixbuf (emblem);
}
- private Gdk.Pixbuf? get_scaled_icon (DrawingContext context, GLib.Icon? icon, double scale) {
+ private Gdk.Texture? get_scaled_icon (DrawingContext context, GLib.Icon? icon, double scale) {
if (icon == null)
return null;
@@ -183,16 +176,22 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
if (icon_info == null)
return null;
+ Gdk.Pixbuf? pixbuf = null;
try {
- return icon_info.load_icon ();
+ pixbuf = icon_info.load_icon ();
}
catch (Error e) {
warning (@"Couldn’t load the icon: $(e.message)\n");
return null;
}
+
+ if (pixbuf == null)
+ return null;
+
+ return Gdk.Texture.for_pixbuf (pixbuf);
}
- private Gdk.Pixbuf? get_scaled_cover (DrawingContext context) {
+ private Gdk.Texture? get_scaled_cover (DrawingContext context) {
if (previous_cover_width != context.width * scale_factor) {
previous_cover_width = context.width * scale_factor;
cover_cache = null;
@@ -222,14 +221,20 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
var lookup_flags = Gtk.IconLookupFlags.FORCE_SIZE | Gtk.IconLookupFlags.FORCE_REGULAR;
var icon_info = theme.lookup_by_gicon (g_icon, (int) size, lookup_flags);
+ Gdk.Pixbuf? pixbuf = null;
try {
- cover_cache = icon_info.load_icon ();
- save_cover_cache_to_disk (size);
+ pixbuf = icon_info.load_icon ();
+ save_cover_cache_to_disk (pixbuf, size);
}
catch (Error e) {
warning (@"Couldn’t load the icon: $(e.message)\n");
}
+ if (pixbuf == null)
+ return null;
+
+ cover_cache = Gdk.Texture.for_pixbuf (pixbuf);
+
return cover_cache;
}
@@ -250,17 +255,15 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
}
try {
- cover_cache = new Gdk.Pixbuf.from_file_at_scale (cover_cache_path,
- context.width * scale_factor,
- context.height * scale_factor,
- true);
+ var file = File.new_for_path (cover_cache_path);
+ cover_cache = Gdk.Texture.from_file (file);
}
catch (Error e) {
debug (e.message);
}
}
- private void save_cover_cache_to_disk (int size) {
+ private void save_cover_cache_to_disk (Gdk.Pixbuf? pixbuf, int size) {
if (cover_cache == null)
return;
@@ -270,10 +273,10 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
try {
var cover_cache_path = get_cover_cache_path (size);
- cover_cache.save (cover_cache_path, "png",
- "tEXt::Software", "GNOME Games",
- "tEXt::Creation Time", creation_time.to_string (),
- null);
+ pixbuf.save (cover_cache_path, "png",
+ "tEXt::Software", "GNOME Games",
+ "tEXt::Creation Time", creation_time.to_string (),
+ null);
}
catch (Error e) {
critical (e.message);
@@ -296,47 +299,37 @@ private class Games.GameThumbnail : Gtk.DrawingArea {
queue_draw ();
}
- private void draw_pixbuf (DrawingContext context, Gdk.Pixbuf pixbuf) {
- context.cr.save ();
- context.cr.scale (1.0 / scale_factor, 1.0 / scale_factor);
-
- var mask = get_mask (context);
-
- var x_offset = (context.width * scale_factor - pixbuf.width) / 2;
- var y_offset = (context.height * scale_factor - pixbuf.height) / 2;
+ private void draw_texture (DrawingContext context, Gdk.Texture texture) {
+ var x_offset = (context.width * scale_factor - texture.width) / 2;
+ var y_offset = (context.height * scale_factor - texture.height) / 2;
- Gdk.cairo_set_source_pixbuf (context.cr, pixbuf, x_offset, y_offset);
- context.cr.mask_surface (mask, 0, 0);
+ Graphene.Rect bounds = {};
+ bounds.init (x_offset, y_offset, texture.width, texture.height);
- context.cr.restore ();
+ context.snapshot.scale (1.0f / scale_factor, 1.0f / scale_factor);
+ context.snapshot.append_texture (texture, bounds);
+ context.snapshot.scale (scale_factor, scale_factor);
}
- private Cairo.Surface get_mask (DrawingContext context) {
- var mask = new Cairo.ImageSurface (Cairo.Format.A8, context.width * scale_factor,
context.height * scale_factor);
+ private Gsk.RoundedRect get_mask (DrawingContext context) {
+ Graphene.Rect bounds = {};
+ bounds.init (0, 0, context.width, context.height);
var border_radius = (int) context.style.get_property (Gtk.STYLE_PROPERTY_BORDER_RADIUS);
border_radius = border_radius.clamp (0, int.max (context.width / 2, context.height / 2));
- var cr = new Cairo.Context (mask);
- cr.scale (scale_factor, scale_factor);
- cr.set_source_rgb (0, 0, 0);
- rounded_rectangle (cr, 0.5, 0.5, context.width - 1, context.height - 1, border_radius);
- cr.fill ();
+ Gsk.RoundedRect rect = {};
+ rect.init_from_rect (bounds, border_radius);
- return mask;
+ return rect;
}
- private void rounded_rectangle (Cairo.Context cr, double x, double y, double width, double height,
double radius) {
- const double ARC_0 = 0;
- const double ARC_1 = Math.PI * 0.5;
- const double ARC_2 = Math.PI;
- const double ARC_3 = Math.PI * 1.5;
-
- cr.new_sub_path ();
- cr.arc (x + width - radius, y + radius, radius, ARC_3, ARC_0);
- cr.arc (x + width - radius, y + height - radius, radius, ARC_0, ARC_1);
- cr.arc (x + radius, y + height - radius, radius, ARC_1, ARC_2);
- cr.arc (x + radius, y + radius, radius, ARC_2, ARC_3);
- cr.close_path ();
+ private void draw_background (DrawingContext context) {
+ Graphene.Rect bounds = {};
+ bounds.init (0, 0, context.width, context.height);
+
+ Gdk.RGBA rgba = {0, 0, 0, 1};
+
+ context.snapshot.append_color (rgba, bounds);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]