[gnome-maps] placeBubble: Large Wikipedia thumbnails
- From: Marcus Lundblad <mlundblad src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps] placeBubble: Large Wikipedia thumbnails
- Date: Sun, 15 Nov 2020 21:43:12 +0000 (UTC)
commit da8f112acaed84194dd6a932bf75de250df463f1
Author: James Westman <james flyingpimonster net>
Date: Thu Aug 6 13:35:14 2020 -0500
placeBubble: Large Wikipedia thumbnails
The Wikipedia thumbnail, if available, is now shown much larger and at the top
of the popover, rather than in place of the icon.
data/gnome-maps.css | 10 +++
data/ui/map-bubble.ui | 15 +++++
src/mapBubble.js | 18 ++++++
src/org.gnome.Maps.src.gresource.xml | 1 +
src/placeBubble.js | 29 +--------
src/placeBubbleImage.js | 118 +++++++++++++++++++++++++++++++++++
6 files changed, 165 insertions(+), 26 deletions(-)
---
diff --git a/data/gnome-maps.css b/data/gnome-maps.css
index ea4977fe..55e60fb9 100644
--- a/data/gnome-maps.css
+++ b/data/gnome-maps.css
@@ -61,6 +61,16 @@
padding-left: 6px;
}
+.map-bubble {
+ /* This is so the Wikipedia image is flush against the borders of the popover */
+ padding: 0;
+}
+
+.no-margin-separator {
+ /* A separator with no margin, so it's flush with the widgets/borders around it */
+ margin: 0;
+}
+
.bubble-title {
font-size: large;
font-weight: bold;
diff --git a/data/ui/map-bubble.ui b/data/ui/map-bubble.ui
index d94fc41a..d64d00b1 100644
--- a/data/ui/map-bubble.ui
+++ b/data/ui/map-bubble.ui
@@ -9,6 +9,21 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
+ <child>
+ <object class="Gjs_PlaceBubbleImage" id="bubble-thumbnail">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparator" id="thumbnail-separator">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ <style>
+ <class name="no-margin-separator"/>
+ </style>
+ </object>
+ </child>
<child>
<object class="GtkGrid" id="bubble-content-area">
<property name="visible">True</property>
diff --git a/src/mapBubble.js b/src/mapBubble.js
index 5f4c82a5..f99bf9fb 100644
--- a/src/mapBubble.js
+++ b/src/mapBubble.js
@@ -71,6 +71,8 @@ class MapBubble extends Gtk.Popover {
super._init(params);
let ui = Utils.getUIObject('map-bubble', [ 'bubble-main-box',
'bubble-spinner',
+ 'bubble-thumbnail',
+ 'thumbnail-separator',
'bubble-main-stack',
'bubble-content-area',
'bubble-button-area',
@@ -80,6 +82,8 @@ class MapBubble extends Gtk.Popover {
'bubble-check-in-button',
'bubble-edit-button',
'bubble-favorite-button-image']);
+ this._thumbnail = ui.bubbleThumbnail;
+ this._thumbnailSeparator = ui.thumbnailSeparator;
this._content = ui.bubbleContentArea;
this._mainStack = ui.bubbleMainStack;
this._spinner = ui.bubbleSpinner;
@@ -101,6 +105,8 @@ class MapBubble extends Gtk.Popover {
}
this.add(this._mainStack);
+
+ this.get_style_context().add_class("map-bubble");
}
get place() {
@@ -111,6 +117,18 @@ class MapBubble extends Gtk.Popover {
return this._content;
}
+ get thumbnail() {
+ return this._thumbnail.pixbuf;
+ }
+
+ set thumbnail(val) {
+ if (val) {
+ this._thumbnail.pixbuf = val;
+ this._thumbnail.visible = true;
+ this._thumbnailSeparator.visible = true;
+ }
+ }
+
get loading() {
return this._spinner.active;
}
diff --git a/src/org.gnome.Maps.src.gresource.xml b/src/org.gnome.Maps.src.gresource.xml
index ab2e12f0..80f852ee 100644
--- a/src/org.gnome.Maps.src.gresource.xml
+++ b/src/org.gnome.Maps.src.gresource.xml
@@ -55,6 +55,7 @@
<file>photonParser.js</file>
<file>place.js</file>
<file>placeBubble.js</file>
+ <file>placeBubbleImage.js</file>
<file>placeEntry.js</file>
<file>placeFormatter.js</file>
<file>placeListRow.js</file>
diff --git a/src/placeBubble.js b/src/placeBubble.js
index 846a3d15..5d44139c 100644
--- a/src/placeBubble.js
+++ b/src/placeBubble.js
@@ -31,15 +31,14 @@ const ContactPlace = imports.contactPlace;
const MapBubble = imports.mapBubble;
const Overpass = imports.overpass;
const Place = imports.place;
+const PlaceBubbleImage = imports.placeBubbleImage;
const PlaceFormatter = imports.placeFormatter;
const PlaceStore = imports.placeStore;
const Utils = imports.utils;
const Wikipedia = imports.wikipedia;
// maximum dimension of thumbnails to fetch from Wikipedia
-const THUMBNAIL_FETCH_SIZE = 128;
-// final scaled size of cropped thumnail
-const THUMBNAIL_FINAL_SIZE = 70;
+const THUMBNAIL_FETCH_SIZE = 360;
var PlaceBubble = GObject.registerClass({
Properties: {
@@ -75,7 +74,6 @@ var PlaceBubble = GObject.registerClass({
this._title = ui.labelTitle;
this._boxContent = ui.boxContent;
- this._gridContent = ui.gridContent;
this._expandButton = ui.expandButton;
this._expandedContent = ui.expandedContent;
this._revealer = ui.contentRevealer;
@@ -284,28 +282,7 @@ var PlaceBubble = GObject.registerClass({
}
_onThumbnailComplete(thumbnail) {
- if (thumbnail) {
- // TODO: Add thumbnails back
- }
- }
-
- // returns a cropped square-shaped thumbnail
- _cropAndScaleThumbnail(thumbnail) {
- let width = thumbnail.get_width();
- let height = thumbnail.get_height();
- let croppedThumbnail;
-
- if (width > height) {
- let x = (width - height) / 2;
- croppedThumbnail = thumbnail.new_subpixbuf(x, 0, height, height);
- } else {
- let y = (height - width) / 2;
- croppedThumbnail = thumbnail.new_subpixbuf(0, y, width, width);
- }
-
- return croppedThumbnail.scale_simple(THUMBNAIL_FINAL_SIZE,
- THUMBNAIL_FINAL_SIZE,
- GdkPixbuf.InterpType.BILINEAR);
+ this.thumbnail = thumbnail;
}
// clear the view widgets to be able to re-populate an updated place
diff --git a/src/placeBubbleImage.js b/src/placeBubbleImage.js
new file mode 100644
index 00000000..1745df26
--- /dev/null
+++ b/src/placeBubbleImage.js
@@ -0,0 +1,118 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2020 James Westman
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: James Westman <james flyingpimonster net>
+ */
+
+const Cairo = imports.cairo;
+const Gdk = imports.gi.Gdk;
+const GObject = imports.gi.GObject;
+const Gtk = imports.gi.Gtk;
+
+/* The maximum aspect ratio, after which the image will be cropped vertically */
+const MAX_ASPECT_RATIO = 1;
+
+var PlaceBubbleImage = GObject.registerClass(
+class PlaceBubbleImage extends Gtk.DrawingArea {
+ _init(params) {
+ super._init(params);
+
+ this._pixbuf = null;
+ this._cached = null;
+ }
+
+ get pixbuf() {
+ return this._pixbuf;
+ }
+
+ set pixbuf(val) {
+ /* crop the pixbuf to the max aspect ratio, if necessary */
+ if (val.height / val.width > MAX_ASPECT_RATIO) {
+ let y = (val.height - val.width * MAX_ASPECT_RATIO) / 2;
+ val = val.new_subpixbuf(0, y, val.width, val.width * MAX_ASPECT_RATIO);
+ }
+
+ this._pixbuf = val;
+ this.queue_resize();
+ }
+
+ vfunc_draw(cr) {
+ let [{x, y, width, height}, baseline] = this.get_allocated_size();
+
+ if (this._pixbuf === null || width === 0 || height === 0) {
+ return;
+ }
+
+ width *= this.scale_factor;
+ height *= this.scale_factor;
+
+ /* Cache surfaces so we don't have to do as much scaling */
+ if (this._cached === null || width !== this._cached.getWidth() || height !==
this._cached.getHeight()) {
+ // create a new, scaled image
+ this._cached = new Cairo.ImageSurface(Cairo.Format.ARGB32, width, height);
+
+ let cr_scaled = new Cairo.Context(this._cached);
+ cr_scaled.scale(width / this._pixbuf.width, height / this._pixbuf.height);
+ Gdk.cairo_set_source_pixbuf(cr_scaled, this._pixbuf, 0, 0);
+ cr_scaled.paint();
+ }
+
+ cr.save();
+
+ if (this.scale_factor !== 1) {
+ cr.scale(1 / this.scale_factor, 1 / this.scale_factor);
+ }
+
+ let popover = this.get_ancestor(Gtk.Popover);
+ if (popover) {
+ // clip the top corners to the rounded corner
+ let radius = popover.get_style_context()
+ .get_property(Gtk.STYLE_PROPERTY_BORDER_RADIUS, popover.get_state_flags())
+ * this.scale_factor;
+
+ // bottom left
+ cr.moveTo(x, y + height);
+ //cr.lineTo(x, y + radius);
+ cr.arc(x + radius, y + radius, radius, Math.PI, -Math.PI / 2.0);
+ cr.arc(x + width - radius, y + radius, radius, -Math.PI / 2.0, 0);
+ cr.lineTo(x + width, y + height);
+
+ cr.clip();
+ }
+
+ cr.setSourceSurface(this._cached, 0, 0);
+
+ cr.paint();
+ cr.restore();
+
+ return false;
+ }
+
+ vfunc_get_request_mode() {
+ return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH;
+ }
+
+ vfunc_get_preferred_height_for_width(width) {
+ if (this._pixbuf) {
+ let height = (this._pixbuf.height / this._pixbuf.width) * width;
+ return [height, height];
+ } else {
+ return [0, 0];
+ }
+ }
+});
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]