[gnome-games] ui: Introduce SnapshotThumbnail
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] ui: Introduce SnapshotThumbnail
- Date: Wed, 24 Jun 2020 15:31:15 +0000 (UTC)
commit ffcaa55ad8ca844c9460e5b42a838b93fcee0152
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Wed Jun 24 15:36:03 2020 +0500
ui: Introduce SnapshotThumbnail
Split it from SnapshotRow, it will make things easier.
Clip shadow correctly, so that we can switch to box-shadow later.
src/meson.build | 1 +
src/ui/snapshot-thumbnail.vala | 130 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 131 insertions(+)
---
diff --git a/src/meson.build b/src/meson.build
index 8c55610d..4cb22389 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -150,6 +150,7 @@ vala_sources = [
'ui/search-bar.vala',
'ui/shortcuts-window.vala',
'ui/snapshot-row.vala',
+ 'ui/snapshot-thumbnail.vala',
'ui/snapshots-list.vala',
'ui/titlebar-box.vala',
'ui/ui-view.vala',
diff --git a/src/ui/snapshot-thumbnail.vala b/src/ui/snapshot-thumbnail.vala
new file mode 100644
index 00000000..6894d4b5
--- /dev/null
+++ b/src/ui/snapshot-thumbnail.vala
@@ -0,0 +1,130 @@
+// This file is part of GNOME Games. License: GPL-3.0+.
+
+private class Games.SnapshotThumbnail : Gtk.DrawingArea {
+ public const int THUMBNAIL_SIZE = 64;
+
+ private Snapshot _snapshot;
+ public Snapshot snapshot {
+ get { return _snapshot; }
+ set {
+ _snapshot = value;
+
+ load_thumbnail ();
+ }
+ }
+
+ private Gdk.Pixbuf pixbuf;
+
+ construct {
+ width_request = THUMBNAIL_SIZE;
+ height_request = THUMBNAIL_SIZE;
+
+ get_style_context ().add_class ("snapshot-thumbnail");
+
+ notify["scale-factor"].connect (load_thumbnail);
+ }
+
+ private void load_thumbnail () {
+ if (snapshot == null)
+ return;
+
+ var screenshot_path = snapshot.get_screenshot_path ();
+ var screenshot_width = 0;
+ var screenshot_height = 0;
+
+ Gdk.Pixbuf.get_file_info (screenshot_path, out screenshot_width, out screenshot_height);
+
+ var aspect_ratio = snapshot.screenshot_aspect_ratio;
+
+ // A fallback for migrated snapshots
+ if (aspect_ratio == 0)
+ aspect_ratio = (double) screenshot_width / screenshot_height;
+
+ var thumbnail_width = screenshot_width;
+ var thumbnail_height = (int) (screenshot_width / aspect_ratio);
+
+ if (thumbnail_width > thumbnail_height) {
+ thumbnail_width = THUMBNAIL_SIZE;
+ thumbnail_height = (int) (THUMBNAIL_SIZE / aspect_ratio);
+ }
+ else {
+ thumbnail_height = THUMBNAIL_SIZE;
+ thumbnail_width = (int) (THUMBNAIL_SIZE * aspect_ratio);
+ }
+
+ thumbnail_width *= scale_factor;
+ thumbnail_height *= scale_factor;
+
+ try {
+ pixbuf = new Gdk.Pixbuf.from_file_at_scale (screenshot_path,
+ thumbnail_width,
+ thumbnail_height,
+ false);
+ }
+ catch (Error e) {
+ warning ("Failed to load snapshot thumbnail: %s", e.message);
+ }
+ }
+
+ public override void size_allocate (Gtk.Allocation alloc) {
+ var context = get_style_context ();
+ var clip = context.render_background_get_clip (
+ alloc.x,
+ alloc.y,
+ alloc.width,
+ alloc.height
+ );
+
+ base.size_allocate (alloc);
+
+ set_clip (clip);
+ }
+
+ public override bool draw (Cairo.Context cr) {
+ var width = get_allocated_width ();
+ var height = get_allocated_height ();
+
+ var style = get_style_context ();
+ style.render_background (cr, 0.0, 0.0, width, height);
+ style.render_frame (cr, 0.0, 0.0, width, height);
+
+ if (pixbuf == null)
+ return Gdk.EVENT_PROPAGATE;
+
+ cr.save ();
+
+ var flags = get_state_flags ();
+ var border_radius = (int) style.get_property (Gtk.STYLE_PROPERTY_BORDER_RADIUS, flags);
+ border_radius = border_radius.clamp (0, int.max (width / 2, height / 2));
+
+ rounded_rectangle (cr, 0, 0, width, height, border_radius);
+ cr.clip ();
+
+ cr.scale (1.0 / scale_factor, 1.0 / scale_factor);
+
+ var x_offset = (width * scale_factor - pixbuf.width) / 2;
+ var y_offset = (height * scale_factor - pixbuf.height) / 2;
+
+ Gdk.cairo_set_source_pixbuf (cr, pixbuf, x_offset, y_offset);
+ cr.paint ();
+
+ cr.restore ();
+
+ return Gdk.EVENT_PROPAGATE;
+ }
+
+ // TODO: Share this with GameThumbnail
+ 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 ();
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]