[shotwell/wip/716987-basic-map: 1/2] Basic implementation, from ritchiew. A bit more cleanup needed
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell/wip/716987-basic-map: 1/2] Basic implementation, from ritchiew. A bit more cleanup needed
- Date: Thu, 15 Jan 2015 23:42:22 +0000 (UTC)
commit 6669fa8231a8a43b633649b12d940e7b2dfbd0ee
Author: Jim Nelson <jim yorba org>
Date: Thu Jan 15 14:39:29 2015 -0800
Basic implementation, from ritchiew. A bit more cleanup needed
Makefile | 9 +
icons/gps-marker.svg | 370 ++++++++++++++++++++++++++++++++++++++
src/MapWidget.vala | 120 ++++++++++++
src/Page.vala | 8 +
src/Photo.vala | 8 +-
src/Properties.vala | 58 +++++--
src/Resources.vala | 1 +
src/core/SourceInterfaces.vala | 4 +
src/library/ImportQueuePage.vala | 4 +
src/library/LibraryWindow.vala | 6 +-
src/main.vala | 2 +-
src/photos/PhotoMetadata.vala | 30 +++
12 files changed, 603 insertions(+), 17 deletions(-)
---
diff --git a/Makefile b/Makefile
index 7f8a1b1..e66d7d3 100644
--- a/Makefile
+++ b/Makefile
@@ -78,6 +78,7 @@ UNUNITIZED_SRC_FILES = \
Debug.vala \
ColorTransformation.vala \
Properties.vala \
+ MapWidget.vala \
CustomComponents.vala \
Event.vala \
International.vala \
@@ -253,6 +254,10 @@ LOCAL_PKGS = \
EXT_PKGS = \
atk \
+ champlain-0.12 \
+ champlain-gtk-0.12 \
+ clutter-1.0 \
+ clutter-gtk-1.0 \
gdk-3.0 \
gee-0.8 \
gexiv2 \
@@ -285,6 +290,10 @@ THUMBNAILER_PKGS = \
DIRECT_LIBS =
EXT_PKG_VERSIONS = \
+ champlain-0.12 >= 0.12.3 \
+ champlain-gtk-0.12 >= 0.12.3 \
+ clutter-1.0 >= 1.12.0 \
+ clutter-gtk-1.0 >= 1.0.0 \
gee-0.8 >= 0.8.5 \
gexiv2 >= 0.4.90 \
gio-unix-2.0 >= 2.20 \
diff --git a/icons/gps-marker.svg b/icons/gps-marker.svg
new file mode 100644
index 0000000..564a38a
--- /dev/null
+++ b/icons/gps-marker.svg
@@ -0,0 +1,370 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="28.74"
+ height="38.98"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="marker.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3887">
+ <stop
+ id="stop3889"
+ offset="0"
+ style="stop-color:#ff573f;stop-opacity:1;" />
+ <stop
+ id="stop3891"
+ offset="1"
+ style="stop-color:#b71111;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3857">
+ <stop
+ style="stop-color:#87b5f5;stop-opacity:1;"
+ offset="0"
+ id="stop3859" />
+ <stop
+ style="stop-color:#87b5f5;stop-opacity:0;"
+ offset="1"
+ id="stop3861" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3849">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3851" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3853" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3827">
+ <stop
+ id="stop3829"
+ offset="0"
+ style="stop-color:#50a9ff;stop-opacity:1;" />
+ <stop
+ id="stop3831"
+ offset="1"
+ style="stop-color:#0034a9;stop-opacity:0.92490119;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3821">
+ <stop
+ id="stop3823"
+ offset="0"
+ style="stop-color:#60aaf1;stop-opacity:1;" />
+ <stop
+ id="stop3825"
+ offset="1"
+ style="stop-color:#124cd1;stop-opacity:0.92490119;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3787">
+ <stop
+ style="stop-color:#535353;stop-opacity:1;"
+ offset="0"
+ id="stop3789" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3791" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3765">
+ <stop
+ style="stop-color:#23b3ff;stop-opacity:1;"
+ offset="0"
+ id="stop3767" />
+ <stop
+ style="stop-color:#124cd1;stop-opacity:0.92490119;"
+ offset="1"
+ id="stop3769" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3765"
+ id="linearGradient3771"
+ x1="381.42856"
+ y1="335.09586"
+ x2="381.42856"
+ y2="567.15851"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.13306152,0,0,0.13306152,324.43662,388.73998)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3787"
+ id="radialGradient3793"
+ cx="374.25"
+ cy="464.11218"
+ fx="374.25"
+ fy="464.11218"
+ r="8.25"
+ gradientTransform="matrix(1,0,0,0.33333333,0,309.40812)"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ inkscape:collect="always"
+ id="filter3803"
+ x="-0.096096098"
+ width="1.1921922"
+ y="-0.2882883"
+ height="1.5765766"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.66066066"
+ id="feGaussianBlur3805" />
+ </filter>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3787"
+ id="radialGradient3843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.33333333,0,309.40812)"
+ cx="374.25"
+ cy="464.11218"
+ fx="374.25"
+ fy="464.11218"
+ r="8.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3765"
+ id="linearGradient3845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.13306152,0,0,0.13306152,394.43662,388.73998)"
+ x1="381.42856"
+ y1="335.09586"
+ x2="381.42856"
+ y2="567.15851" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3849"
+ id="linearGradient3855"
+ x1="461.5"
+ y1="477.36218"
+ x2="462.5"
+ y2="434.36218"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3857"
+ id="linearGradient3863"
+ x1="444.95898"
+ y1="433.89029"
+ x2="444.95898"
+ y2="454.77341"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3849"
+ id="linearGradient3871"
+ x1="382.17749"
+ y1="377.47879"
+ x2="382.17749"
+ y2="414.47479"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3787"
+ id="radialGradient3883"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.33333333,0,309.40812)"
+ cx="374.25"
+ cy="464.11218"
+ fx="374.25"
+ fy="464.11218"
+ r="8.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3887"
+ id="linearGradient3885"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.13306152,0,0,0.13306152,270.34295,388.73998)"
+ x1="381.42856"
+ y1="335.09586"
+ x2="381.42856"
+ y2="567.15851" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3787"
+ id="radialGradient3925"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.33333333,0,309.40812)"
+ cx="374.25"
+ cy="464.11218"
+ fx="374.25"
+ fy="464.11218"
+ r="8.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3765"
+ id="linearGradient3927"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.13306152,0,0,0.13306152,324.43662,388.73998)"
+ x1="381.42856"
+ y1="335.09586"
+ x2="381.42856"
+ y2="567.15851" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3787"
+ id="radialGradient3941"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.33333333,0,309.40812)"
+ cx="374.25"
+ cy="464.11218"
+ fx="374.25"
+ fy="464.11218"
+ r="8.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3765"
+ id="linearGradient3943"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.13306152,0,0,0.13306152,324.43662,388.73998)"
+ x1="381.42856"
+ y1="335.09586"
+ x2="381.42856"
+ y2="567.15851" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3787"
+ id="radialGradient3945"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.33333333,0,309.40812)"
+ cx="374.25"
+ cy="464.11218"
+ fx="374.25"
+ fy="464.11218"
+ r="8.25" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3887"
+ id="linearGradient3947"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.13306152,0,0,0.13306152,270.34295,388.73998)"
+ x1="381.42856"
+ y1="335.09586"
+ x2="381.42856"
+ y2="567.15851" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="-23.119863"
+ inkscape:cy="10.735606"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:snap-global="false"
+ fit-margin-left="1"
+ units="px"
+ fit-margin-top="1"
+ fit-margin-right="1"
+ fit-margin-bottom="1"
+ inkscape:window-width="1440"
+ inkscape:window-height="844"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2987"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true"
+ originx="-306.53522px"
+ originy="-506.68905px" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <cc:license
+ rdf:resource="" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-306.53522,-506.69183)">
+ <g
+ id="g3902"
+ transform="translate(0,75.224057)">
+ <g
+ id="g3035">
+ <path
+ transform="matrix(1.3594635,0,0,1,-187.87288,1)"
+ d="m 382.5,464.11218 c 0,1.51879 -3.69365,2.75 -8.25,2.75 -4.55635,0 -8.25,-1.23121 -8.25,-2.75
0,-1.51878 3.69365,-2.75 8.25,-2.75 4.55635,0 8.25,1.23122 8.25,2.75 z"
+ sodipodi:ry="2.75"
+ sodipodi:rx="8.25"
+ sodipodi:cy="464.11218"
+ sodipodi:cx="374.25"
+ id="path3873"
+
style="opacity:0.58662612;fill:url(#radialGradient3945);fill-opacity:1;stroke:none;filter:url(#filter3803)"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="sszczss"
+ inkscape:connector-curvature="0"
+ id="path3875"
+ d="m 320.90633,432.9663 c -5.14414,0 -9.3143,4.17016 -9.3143,9.31432 0,1.76829 0.91939,4.12348
1.34724,4.82763 0.42786,0.70414 7.79657,17.16494 7.79657,17.16494 0,0 7.58026,-16.29039 8.03775,-17.01109
0.45749,-0.7207 1.44704,-3.14782 1.44704,-4.98148 0,-5.14416 -4.17016,-9.31432 -9.3143,-9.31432 z"
+
style="fill:url(#linearGradient3947);fill-opacity:1;stroke:#982f26;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
/>
+ <path
+
style="fill:none;stroke:#e19089;stroke-width:1.03512061;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 320.90633,434.00353 c -4.50028,0 -8.14847,3.69949 -8.14847,8.26307 0,1.56873 0.80432,3.6581
1.17861,4.28277 0.3743,0.62468 6.82071,15.22767 6.82071,15.22767 0,0 6.63148,-14.45182 7.03171,-15.09118
0.40022,-0.63936 1.26591,-2.79256 1.26591,-4.41926 0,-4.56358 -3.64819,-8.26307 -8.14847,-8.26307 z"
+ id="path3877"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sszczss" />
+ <path
+ sodipodi:type="arc"
+
style="fill:#ffffff;fill-opacity:1;stroke:#e19089;stroke-width:4.32061148;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.7"
+ id="path3879"
+ sodipodi:cx="381.25"
+ sodipodi:cy="396.11218"
+ sodipodi:rx="18.75"
+ sodipodi:ry="18.75"
+ d="m 400,396.11218 c 0,10.35534 -8.39466,18.75 -18.75,18.75 -10.35534,0 -18.75,-8.39466
-18.75,-18.75 0,-10.35534 8.39466,-18.75 18.75,-18.75 10.35534,0 18.75,8.39466 18.75,18.75 z"
+ transform="matrix(0.23144871,0,0,0.23144871,232.66651,350.69905)" />
+ <path
+ transform="matrix(0.17705667,0,0,0.17705667,253.40348,372.2444)"
+ d="m 400,396.11218 c 0,10.35534 -8.39466,18.75 -18.75,18.75 -10.35534,0 -18.75,-8.39466
-18.75,-18.75 0,-10.35534 8.39466,-18.75 18.75,-18.75 10.35534,0 18.75,8.39466 18.75,18.75 z"
+ sodipodi:ry="18.75"
+ sodipodi:rx="18.75"
+ sodipodi:cy="396.11218"
+ sodipodi:cx="381.25"
+ id="path3881"
+
style="fill:#ffffff;fill-opacity:1;stroke:#982f26;stroke-width:6.2157526;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0.7"
+ sodipodi:type="arc" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/src/MapWidget.vala b/src/MapWidget.vala
new file mode 100644
index 0000000..c4d761e
--- /dev/null
+++ b/src/MapWidget.vala
@@ -0,0 +1,120 @@
+ /* Copyright 2015 Yorba Foundation
+ *
+ * This software is licensed under the GNU LGPL (version 2.1 or later).
+ * See the COPYING file in this distribution.
+ */
+
+private class MapWidget : GtkChamplain.Embed {
+ private const uint DEFAULT_ZOOM_LEVEL = 8;
+
+ private static MapWidget? instance = null;
+
+ public Cogl.Handle marker_cogl_texture { get; private set; }
+
+ private Champlain.View? map_view = null;
+ private Champlain.Scale map_scale = new Champlain.Scale();
+ private Champlain.MarkerLayer marker_layer = new Champlain.MarkerLayer();
+
+ public static MapWidget get_instance() {
+ if (instance == null)
+ instance = new MapWidget();
+
+ return instance;
+ }
+
+ public void setup_map() {
+ // add scale to bottom left corner of the map
+ map_view = get_view();
+ map_view.add_layer(marker_layer);
+ map_scale.x_align = Clutter.ActorAlign.START;
+ map_scale.y_align = Clutter.ActorAlign.END;
+ map_scale.connect_view(map_view);
+ map_view.add(map_scale);
+
+ map_view.set_zoom_on_double_click(false);
+
+ button_press_event.connect(map_zoom_handler);
+ set_size_request(200, 200);
+
+ // Load gdk pixbuf via Resources class
+ Gdk.Pixbuf gdk_marker = Resources.get_icon(Resources.ICON_GPS_MARKER);
+ try {
+ // this is what GtkClutter.Texture.set_from_pixmap does
+ Clutter.Texture tex = new Clutter.Texture();
+ tex.set_from_rgb_data(gdk_marker.get_pixels(),
+ gdk_marker.get_has_alpha(),
+ gdk_marker.get_width(),
+ gdk_marker.get_height(),
+ gdk_marker.get_rowstride(),
+ gdk_marker.get_has_alpha() ? 4 : 3,
+ Clutter.TextureFlags.NONE);
+ marker_cogl_texture = tex.get_cogl_texture();
+ } catch (GLib.Error e) {
+ // Fall back to the generic champlain marker
+ marker_cogl_texture = null;
+ }
+ }
+
+ public void clear() {
+ marker_layer.remove_all();
+ }
+
+ public void add_position_marker(DataView view) {
+ clear();
+
+ Positionable? positionable = view.get_source() as Positionable;
+ if (positionable == null)
+ return;
+
+ GpsCoords? gps_coords = positionable.get_gps_coords();
+ if (gps_coords == null)
+ return;
+
+ Champlain.Marker marker = create_champlain_marker(gps_coords);
+ marker_layer.add_marker(marker);
+ }
+
+ public void show_position_markers() {
+ if (marker_layer.get_markers().length() != 0) {
+ if (map_view.get_zoom_level() < DEFAULT_ZOOM_LEVEL) {
+ map_view.set_zoom_level(DEFAULT_ZOOM_LEVEL);
+ }
+ Champlain.BoundingBox bbox = marker_layer.get_bounding_box();
+ map_view.ensure_visible(bbox, true);
+ }
+ }
+
+ private Champlain.Marker create_champlain_marker(GpsCoords gps_coords) {
+ Champlain.Marker champlain_marker;
+ if (marker_cogl_texture == null) {
+ // Fall back to the generic champlain marker
+ champlain_marker = new Champlain.Point.full(12, { red:10, green:10, blue:255, alpha:255 });
+ } else {
+ champlain_marker = new Champlain.CustomMarker(); // TODO: deprecated, switch to Champlain.Marker
once libchamplain-0.12.4 is used
+ Clutter.Texture t = new Clutter.Texture();
+ t.set_cogl_texture(marker_cogl_texture);
+ champlain_marker.add(t);
+ }
+ champlain_marker.set_pivot_point(0.5f, 0.5f); // set center of marker
+ champlain_marker.set_location(gps_coords.latitude, gps_coords.longitude);
+
+ return champlain_marker;
+ }
+
+ private bool map_zoom_handler(Gdk.EventButton event) {
+ if (event.type == Gdk.EventType.2BUTTON_PRESS) {
+ if (event.button == 1 || event.button == 3) {
+ double lat = map_view.y_to_latitude(event.y);
+ double lon = map_view.x_to_longitude(event.x);
+ if (event.button == 1) {
+ map_view.zoom_in();
+ } else {
+ map_view.zoom_out();
+ }
+ map_view.center_on(lat, lon);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/Page.vala b/src/Page.vala
index 1e6d706..aa87b18 100644
--- a/src/Page.vala
+++ b/src/Page.vala
@@ -1159,6 +1159,10 @@ public abstract class Page : Gtk.ScrolledWindow {
return false;
}
+
+ public virtual bool is_map_display_enabled(){
+ return false;
+ }
}
public abstract class CheckerboardPage : Page {
@@ -2401,6 +2405,10 @@ public abstract class SinglePhotoPage : Page {
return (base.key_press_event != null) ? base.key_press_event(event) : true;
}
+
+ public override bool is_map_display_enabled(){
+ return true;
+ }
}
//
diff --git a/src/Photo.vala b/src/Photo.vala
index 98a3175..8b5d49e 100644
--- a/src/Photo.vala
+++ b/src/Photo.vala
@@ -158,7 +158,7 @@ public enum Rating {
// particular photo without modifying the backing image file. The interface allows for
// transformations to be stored persistently elsewhere or in memory until they're committed en
// masse to an image file.
-public abstract class Photo : PhotoSource, Dateable {
+public abstract class Photo : PhotoSource, Dateable, Positionable {
// Need to use "thumb" rather than "photo" for historical reasons -- this name is used
// directly to load thumbnails from disk by already-existing filenames
public const string TYPENAME = "thumb";
@@ -2345,6 +2345,12 @@ public abstract class Photo : PhotoSource, Dateable {
notify_altered(new Alteration("metadata", "name"));
}
+ public GpsCoords? get_gps_coords() {
+ PhotoMetadata? metadata = get_metadata();
+
+ return (metadata != null) ? metadata.get_gps_coords() : null;
+ }
+
public override bool set_comment(string? comment) {
string? new_comment = prep_comment(comment);
diff --git a/src/Properties.vala b/src/Properties.vala
index 4a86308..1e77ece 100644
--- a/src/Properties.vala
+++ b/src/Properties.vala
@@ -4,12 +4,15 @@
* See the COPYING file in this distribution.
*/
-private abstract class Properties : Gtk.Grid {
- uint line_count = 0;
+private abstract class Properties : Gtk.VBox {
+ protected Gtk.Grid grid = new Gtk.Grid();
+ protected uint line_count = 0;
public Properties() {
- row_spacing = 0;
- column_spacing = 6;
+ grid.column_spacing = 6;
+ set_homogeneous(false);
+ set_spacing(0);
+ pack_start(grid, false, true, 0);
}
protected void add_line(string label_text, string info_text, bool multi_line = false) {
@@ -48,12 +51,12 @@ private abstract class Properties : Gtk.Grid {
info = (Gtk.Widget) info_label;
}
- attach(label, 0, (int) line_count, 1, 1);
+ grid.attach(label, 0, (int) line_count, 1, 1);
if (multi_line) {
- attach(info, 1, (int) line_count, 1, 2);
+ grid.attach(info, 1, (int) line_count, 2, 1);
} else {
- attach(info, 1, (int) line_count, 1, 1);
+ grid.attach(info, 1, (int) line_count, 1, 1);
}
line_count++;
@@ -126,9 +129,9 @@ private abstract class Properties : Gtk.Grid {
}
protected virtual void clear_properties() {
- foreach (Gtk.Widget child in get_children())
- remove(child);
-
+ foreach (Gtk.Widget child in grid.get_children())
+ grid.remove(child);
+
line_count = 0;
}
@@ -143,7 +146,7 @@ private abstract class Properties : Gtk.Grid {
}
public void unselect_text() {
- foreach (Gtk.Widget child in get_children()) {
+ foreach (Gtk.Widget child in grid.get_children()) {
if (child is Gtk.Label)
((Gtk.Label) child).select_region(0, 0);
}
@@ -164,8 +167,14 @@ private class BasicProperties : Properties {
private double clip_duration;
private string raw_developer;
private string raw_assoc;
+ private GpsCoords? gps_coords;
+ private MapWidget map_widget;
+ private bool map_widget_displayed;
public BasicProperties() {
+ map_widget = MapWidget.get_instance();
+ map_widget.setup_map();
+ this.pack_end(map_widget);
}
protected override void clear_properties() {
@@ -183,6 +192,8 @@ private class BasicProperties : Properties {
clip_duration = 0.0;
raw_developer = "";
raw_assoc = "";
+ map_widget.clear();
+ gps_coords = null;
}
protected override void get_single_properties(DataView view) {
@@ -192,7 +203,7 @@ private class BasicProperties : Properties {
title = source.get_name();
- if (source is PhotoSource || source is PhotoImportSource) {
+ if (source is PhotoSource || source is PhotoImportSource) {
start_time = (source is PhotoSource) ? ((PhotoSource) source).get_exposure_time() :
((PhotoImportSource) source).get_exposure_time();
end_time = start_time;
@@ -216,6 +227,9 @@ private class BasicProperties : Properties {
dimensions = (metadata.get_pixel_dimensions() != null) ?
metadata.get_orientation().rotate_dimensions(metadata.get_pixel_dimensions()) :
Dimensions(0, 0);
+
+ gps_coords = metadata.get_gps_coords();
+ map_widget.add_position_marker(view);
}
if (source is PhotoSource)
@@ -262,8 +276,8 @@ private class BasicProperties : Properties {
video_count = 0;
foreach (DataView view in iter) {
DataSource source = view.get_source();
-
- if (source is PhotoSource || source is PhotoImportSource) {
+
+ if (source is PhotoSource || source is PhotoImportSource) {
time_t exposure_time = (source is PhotoSource) ?
((PhotoSource) source).get_exposure_time() :
((PhotoImportSource) source).get_exposure_time();
@@ -448,6 +462,22 @@ private class BasicProperties : Properties {
}
}
}
+
+ if (gps_coords != null && page.is_map_display_enabled()){
+ map_widget_displayed = true;
+ map_widget.show_position_markers();
+ }
+ else
+ map_widget_displayed = false;
+ }
+
+ public override void show_all() {
+ base.show_all();
+ map_widget.set_visible(map_widget_displayed);
+ }
+
+ public bool get_map_widget_displayed(){
+ return map_widget_displayed;
}
}
diff --git a/src/Resources.vala b/src/Resources.vala
index 61bd518..74f3321 100644
--- a/src/Resources.vala
+++ b/src/Resources.vala
@@ -110,6 +110,7 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc.,
public const string ICON_ZOOM_IN = "zoom-in.png";
public const string ICON_ZOOM_OUT = "zoom-out.png";
public const int ICON_ZOOM_SCALE = 16;
+ public const string ICON_GPS_MARKER = "gps-marker.svg";
public const string ICON_CAMERAS = "camera-photo";
public const string ICON_EVENTS = "multiple-events";
diff --git a/src/core/SourceInterfaces.vala b/src/core/SourceInterfaces.vala
index 59956d3..d49955b 100644
--- a/src/core/SourceInterfaces.vala
+++ b/src/core/SourceInterfaces.vala
@@ -42,3 +42,7 @@ public interface Indexable : DataSource {
}
}
+// Positionable DataSources provide a globally locatable point in longitude and latitude degrees
+public interface Positionable : DataSource {
+ public abstract GpsCoords? get_gps_coords();
+}
diff --git a/src/library/ImportQueuePage.vala b/src/library/ImportQueuePage.vala
index 5ace1d8..931065b 100644
--- a/src/library/ImportQueuePage.vala
+++ b/src/library/ImportQueuePage.vala
@@ -204,5 +204,9 @@ public class ImportQueuePage : SinglePhotoPage {
private void on_fatal_error(ImportResult result, string message) {
AppWindow.error_message(message);
}
+
+ public override bool is_map_display_enabled(){
+ return false;
+ }
}
diff --git a/src/library/LibraryWindow.vala b/src/library/LibraryWindow.vala
index 908a892..7229c9a 100644
--- a/src/library/LibraryWindow.vala
+++ b/src/library/LibraryWindow.vala
@@ -1507,8 +1507,12 @@ public class LibraryWindow : AppWindow {
}
private void on_update_properties_now() {
- if (bottom_frame.visible)
+ if (bottom_frame.visible){
+ bool map_was_displayed = basic_properties.get_map_widget_displayed();
basic_properties.update_properties(get_current_page());
+ if (map_was_displayed && !basic_properties.get_map_widget_displayed())
+ sidebar_paned.set_position(1000);
+ }
if (extended_properties.visible)
extended_properties.update_properties(get_current_page());
diff --git a/src/main.vala b/src/main.vala
index 8c045fd..aa3125b 100644
--- a/src/main.vala
+++ b/src/main.vala
@@ -335,7 +335,7 @@ void main(string[] args) {
// init GTK (valac has already called g_threads_init())
try {
- Gtk.init_with_args(ref args, _("[FILE]"), CommandlineOptions.get_options(),
+ GtkClutter.init_with_args(ref args, _("[FILE]"), CommandlineOptions.get_options(),
Resources.APP_GETTEXT_PACKAGE);
} catch (Error e) {
print(e.message + "\n");
diff --git a/src/photos/PhotoMetadata.vala b/src/photos/PhotoMetadata.vala
index 37804bf..102a456 100644
--- a/src/photos/PhotoMetadata.vala
+++ b/src/photos/PhotoMetadata.vala
@@ -96,6 +96,22 @@ public abstract class PhotoPreview {
}
}
+public class GpsCoords {
+ public double latitude { get; private set; }
+ public double longitude { get; private set; }
+ public double altitude { get; private set; }
+
+ public GpsCoords(double latitude, double longitude, double altitude) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.altitude = altitude;
+ }
+
+ public bool equal_to(GpsCoords other) {
+ return latitude == other.latitude && longitude == other.longitude && altitude == other.altitude;
+ }
+}
+
public class PhotoMetadata : MediaMetadata {
public enum SetOption {
ALL_DOMAINS,
@@ -1009,6 +1025,20 @@ public class PhotoMetadata : MediaMetadata {
return true;
}
+ public GpsCoords? get_gps_coords() {
+ double latitude, longitude, altitude;
+ if (!exiv2.get_gps_info(out longitude, out latitude, out altitude))
+ return null;
+
+ if (get_string("Exif.GPSInfo.GPSLongitudeRef") == "W" && longitude > 0)
+ longitude = -longitude;
+
+ if (get_string("Exif.GPSInfo.GPSLatitudeRef") == "S" && latitude > 0)
+ latitude = -latitude;
+
+ return new GpsCoords(latitude, longitude, altitude);
+ }
+
public bool get_exposure(out MetadataRational exposure) {
return get_rational("Exif.Photo.ExposureTime", out exposure);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]