Commit 0448dad1 authored by Andreas Brauchli's avatar Andreas Brauchli Committed by Jens Georg

map: Add lock to avoid accidental repositioning

The map now features a new padlock icon which must be unlocked before
pictures can be drag-n-dropped on the map to set their position.

Padlock icon source: https://openclipart.org/detail/68533/padlock-icon
Kudos to user "jaschon"
parent 25f98eeb
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2394"
viewBox="0 0 500 500"
version="1.0"
inkscape:version="0.91 r13725"
sodipodi:docname="map-edit-lock.svg">
<defs
id="defs3618" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="836"
id="namedview3616"
showgrid="false"
inkscape:zoom="1.3350176"
inkscape:cx="245.59921"
inkscape:cy="225.03259"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg2394">
<inkscape:grid
type="xygrid"
id="grid4324" />
</sodipodi:namedview>
<path
style="fill:#2c2c2c;fill-rule:evenodd"
d="M 138.14453 235.48047 C 138.14734 235.54209 138.1495 235.84106 138.15234 235.88086 L 122.5625 235.88086 L 122.56055 235.88086 C 108.43055 235.88086 97.001953 247.31922 97.001953 261.44922 L 97.001953 416.94922 L 409.43164 416.94922 L 409.43164 261.44922 C 409.43164 247.31922 398.00109 235.88086 383.87109 235.88086 L 368.28125 235.88086 C 368.28423 235.84106 368.28613 235.54209 368.28906 235.48047 L 298.55273 235.48047 C 298.54126 235.58953 298.53125 235.82185 298.51953 235.88086 L 207.91016 235.88086 C 207.89864 235.82184 207.88824 235.58955 207.87695 235.48047 L 138.14453 235.48047 z M 97.357422 434.69922 C 99.381422 446.80922 109.89055 456.00977 122.56055 456.00977 L 383.86914 456.00977 C 396.53914 456.00977 407.05008 446.80922 409.08008 434.69922 L 97.359375 434.69922 L 97.357422 434.69922 z "
id="path14" />
<metadata
id="metadata3614">
<rdf:RDF>
<cc:Work>
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
<dc:publisher>
<cc:Agent
rdf:about="http://openclipart.org/">
<dc:title>Openclipart</dc:title>
</cc:Agent>
</dc:publisher>
<dc:title>Padlock Icon</dc:title>
<dc:date>2010-06-25T17:53:36</dc:date>
<dc:description>a simple padlock icon</dc:description>
<dc:source>https://openclipart.org/detail/68533/padlock-icon-by-jaschon</dc:source>
<dc:creator>
<cc:Agent>
<dc:title>jaschon</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>black</rdf:li>
<rdf:li>black and white</rdf:li>
<rdf:li>key</rdf:li>
<rdf:li>keyhole</rdf:li>
<rdf:li>lock</rdf:li>
<rdf:li>padlock</rdf:li>
<rdf:li>security</rdf:li>
<rdf:li>silhouette</rdf:li>
<rdf:li>symbol</rdf:li>
<rdf:li>tool</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<path
inkscape:connector-curvature="0"
style="fill:#2c2c2c;fill-rule:evenodd"
d="m 253.22266,81.94726 c -63.73,-0.002 -115.39063,51.66086 -115.39063,115.38086 0,2.99 0.11031,66.29047 0.32031,69.23047 l 230.12891,0 c 0.22,-2.94 0.32031,-66.24047 0.32031,-69.23047 0,-63.72 -51.6589,-115.38086 -115.3789,-115.38086 z m -0.002,69.23047 c 25.49,0 46.14844,20.66039 46.14844,46.15039 0,3.06 -0.27961,66.36047 -0.84961,69.23047 l -90.60937,0 c -0.56,-2.87 -0.84961,-66.17047 -0.84961,-69.23047 0,-25.49 20.67015,-46.15039 46.16015,-46.15039 z"
id="path14-5"
sodipodi:nodetypes="csccscssccss" />
</svg>
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2394"
viewBox="0 0 500 500"
version="1.0"
inkscape:version="0.91 r13725"
sodipodi:docname="map-edit-lock.svg">
<defs
id="defs3618" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="836"
id="namedview3616"
showgrid="false"
inkscape:zoom="1.3350176"
inkscape:cx="245.59921"
inkscape:cy="225.03259"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg2394">
<inkscape:grid
type="xygrid"
id="grid4324" />
</sodipodi:namedview>
<path
style="fill:#2c2c2c;fill-rule:evenodd"
d="m 122.5625,235.88086 -0.002,0 c -14.13,0 -25.558597,11.43836 -25.558597,25.56836 l 0,155.5 312.429687,0 0,-155.5 c 0,-14.13 -11.43055,-25.56836 -25.56055,-25.56836 l -15.58984,0 c 0.003,-0.0398 0.005,-0.33877 0.008,-0.40039 l -69.73633,0 c -0.0115,0.10906 -0.0215,0.34138 -0.0332,0.40039 -65.89132,-0.43686 -117.23022,0 -175.95703,0 z M 97.357422,434.69922 c 2.024,12.11 12.533128,21.31055 25.203128,21.31055 l 261.30859,0 c 12.67,0 23.18094,-9.20055 25.21094,-21.31055 l -311.720705,0 z"
id="path14"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssccssccccccssccc" />
<metadata
id="metadata3614">
<rdf:RDF>
<cc:Work>
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
<dc:publisher>
<cc:Agent
rdf:about="http://openclipart.org/">
<dc:title>Openclipart</dc:title>
</cc:Agent>
</dc:publisher>
<dc:title></dc:title>
<dc:date>2010-06-25T17:53:36</dc:date>
<dc:description>a simple padlock icon</dc:description>
<dc:source>https://openclipart.org/detail/68533/padlock-icon-by-jaschon</dc:source>
<dc:creator>
<cc:Agent>
<dc:title>jaschon</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>black</rdf:li>
<rdf:li>black and white</rdf:li>
<rdf:li>key</rdf:li>
<rdf:li>keyhole</rdf:li>
<rdf:li>lock</rdf:li>
<rdf:li>padlock</rdf:li>
<rdf:li>security</rdf:li>
<rdf:li>silhouette</rdf:li>
<rdf:li>symbol</rdf:li>
<rdf:li>tool</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<path
style="fill:#2c2c2c;fill-rule:evenodd"
d="m 253.22266,51.947266 c -63.73,-0.002 -115.39063,51.660864 -115.39063,115.380854 0,1.75668 0.0432,23.75144 0.11719,42.67188 l 69.41797,0 c -0.1957,-18.90322 -0.30664,-40.87563 -0.30664,-42.67188 0,-25.49 20.67015,-46.15039 46.16015,-46.15039 25.49,0 46.14844,20.66039 46.14844,46.15039 0,3.06001 -0.27961,66.36047 -0.84961,69.23047 l 69.76172,0 c 0.22,-2.94 0.32031,-66.24046 0.32031,-69.23047 0,-63.71999 -51.6589,-115.380854 -115.3789,-115.380854 z"
id="path14-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccsssccsc" />
</svg>
......@@ -76,15 +76,21 @@ private class MapWidget : Gtk.Bin {
private uint last_zoom_level = DEFAULT_ZOOM_LEVEL;
private Champlain.Scale map_scale = new Champlain.Scale();
private Champlain.MarkerLayer marker_layer = new Champlain.MarkerLayer();
public bool map_edit_lock { get; set; }
private Gee.Map<DataView, PositionMarker> position_markers =
new Gee.HashMap<DataView, PositionMarker>();
private Gee.TreeMap<long, Gee.TreeMap<long, MarkerGroup>> marker_groups_tree =
new Gee.TreeMap<long, Gee.TreeMap<long, MarkerGroup>>();
private Gee.Collection<MarkerGroup> marker_groups = new Gee.LinkedList<MarkerGroup>();
private unowned Page page = null;
private Clutter.Image? map_edit_locked_image;
private Clutter.Image? map_edit_unlocked_image;
private Clutter.Actor map_edit_lock_button = new Clutter.Actor();
public float marker_image_width { get; private set; }
public float marker_image_height { get; private set; }
public float map_edit_lock_image_width { get; private set; }
public float map_edit_lock_image_height { get; private set; }
public Clutter.Image? marker_image { get; private set; }
public Clutter.Image? marker_selected_image { get; private set; }
public const Clutter.Color marker_point_color = { 10, 10, 255, 192 };
......@@ -239,6 +245,33 @@ private class MapWidget : Gtk.Bin {
map_view = gtk_champlain_widget.get_view();
map_view.add_layer(marker_layer);
// add lock/unlock button to top left corner of map
map_edit_lock_button.content_gravity = Clutter.ContentGravity.TOP_RIGHT;
map_edit_lock_button.reactive = true;
map_edit_lock_button.button_release_event.connect((a, e) => {
if (e.button != 1 /* CLUTTER_BUTTON_PRIMARY */)
return false;
map_edit_lock = !map_edit_lock;
map_edit_lock_button.set_content(map_edit_lock ?
map_edit_locked_image : map_edit_unlocked_image);
return true;
});
map_view.bin_layout_add(map_edit_lock_button, Clutter.BinAlignment.END, Clutter.BinAlignment.START);
gtk_champlain_widget.has_tooltip = true;
gtk_champlain_widget.query_tooltip.connect((x, y, keyboard_tooltip, tooltip) => {
Gdk.Rectangle lock_rect = {
(int) map_edit_lock_button.x,
(int) map_edit_lock_button.y,
(int) map_edit_lock_button.width,
(int) map_edit_lock_button.height,
};
Gdk.Rectangle mouse_pos = { x, y, 1, 1 };
if (!lock_rect.intersect(mouse_pos, null))
return false;
tooltip.set_text(_("Lock or unlock map for geotagging by dragging pictures onto the map"));
return true;
});
// add scale to bottom left corner of the map
map_scale.content_gravity = Clutter.ContentGravity.BOTTOM_LEFT;
map_scale.connect_view(map_view);
......@@ -264,6 +297,18 @@ private class MapWidget : Gtk.Bin {
marker_image_height = h;
marker_selected_image = Resources.get_icon_as_clutter_image(
Resources.ICON_GPS_MARKER_SELECTED, out w, out h);
map_edit_locked_image = Resources.get_icon_as_clutter_image(
Resources.ICON_MAP_EDIT_LOCKED, out w, out h);
map_edit_unlocked_image = Resources.get_icon_as_clutter_image(
Resources.ICON_MAP_EDIT_UNLOCKED, out w, out h);
map_edit_lock_image_width = w;
map_edit_lock_image_height = h;
if (map_edit_locked_image == null) {
warning("Couldn't load map edit lock image");
} else {
map_edit_lock_button.set_content(map_edit_locked_image);
map_edit_lock_button.set_size(map_edit_lock_image_width, map_edit_lock_image_height);
map_edit_lock = true;
}
}
......@@ -357,6 +402,9 @@ private class MapWidget : Gtk.Bin {
}
private bool internal_drop_received(Gee.List<MediaSource> media, double lat, double lon) {
if (map_edit_lock) {
return false;
}
int i = 0;
bool success = false;
while (i < media.size) {
......
......@@ -84,6 +84,8 @@ along with Shotwell; if not, write to the Free Software Foundation, Inc.,
public const int ICON_ZOOM_SCALE = 16;
public const string ICON_GPS_MARKER = "gps-marker.svg";
public const string ICON_GPS_MARKER_SELECTED = "gps-marker-selected.svg";
public const string ICON_MAP_EDIT_LOCKED = "map-edit-locked.svg";
public const string ICON_MAP_EDIT_UNLOCKED = "map-edit-unlocked.svg";
public const string ICON_CAMERAS = "camera-photo-symbolic";
public const string ICON_EVENTS = "multiple-events-symbolic";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment