--- a/src/iconolab/fixtures/dev_initial_data.json Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/fixtures/dev_initial_data.json Thu Jun 23 17:27:44 2016 +0200
@@ -68,7 +68,30 @@
"author": 1,
"created": "2016-03-24 14:13:44.913765+01"
}
- },{
+ },
+ {
+ "model": "iconolab.Annotation",
+ "pk": 2,
+ "fields": {
+ "annotation_guid": "34ae39ae-a9a2-4736-bc59-ba6f00e37f51",
+ "image": 1,
+ "current_revision" : 2,
+ "author": 1,
+ "created": "2016-03-24 14:13:44.913765+01"
+ }
+ },
+ {
+ "model": "iconolab.Annotation",
+ "pk": 3,
+ "fields": {
+ "annotation_guid": "34ae39ae-a9a2-4736-bc59-ba6f00e37f53",
+ "image": 1,
+ "current_revision" : 3,
+ "author": 1,
+ "created": "2016-03-24 14:13:44.913765+01"
+ }
+ },
+ {
"model": "iconolab.AnnotationStats",
"pk": 1,
"fields": {
@@ -93,6 +116,35 @@
"state": 1,
"created": "2016-03-25 14:13:44.913765+01"
}
+ },
+ {
+ "model": "iconolab.AnnotationRevision",
+ "pk": 2,
+ "fields": {
+ "annotation": 2,
+ "revision_guid": "b14c8382-b136-42d0-abe1-b0a94f60d9d1",
+ "author": 1,
+ "title": "Une autre annotation sur Napoléon!",
+ "description": "ma nouvelle description",
+ "fragment": "M41.49797570850203,17.375C41.49797570850203,17.375,46.35627530364373,14.25,46.35627530364373,14.25C46.35627530364373,14.25,55.87044534412955,13.625,55.87044534412955,13.625C55.87044534412955,13.625,61.94331983805668,21.375,61.94331983805668,21.375C61.94331983805668,21.375,59.10931174089069,26.875,59.10931174089069,26.875C59.10931174089069,26.875,44.534412955465584,27.375,44.534412955465584,27.375C44.534412955465584,27.375,40.48582995951418,23.875,40.48582995951418,23.875C40.48582995951418,23.875,41.49797570850203,17.375,41.49797570850203,17.375 Z;FREE",
+ "state": 1,
+ "created": "2016-03-25 14:13:44.913765+01"
+ }
+ },
+ {
+ "model": "iconolab.AnnotationRevision",
+ "pk": 3,
+ "fields": {
+ "annotation": 3,
+ "revision_guid": "b14c8382-b136-42d0-abe1-b0a94f60d9d2",
+ "author": 1,
+ "title": "Ceci est ma nouvelle annotation",
+ "description": "C'est une autre description",
+ "fragment": "M12.955465587044534,23.625C12.955465587044534,23.625,9.7165991902834,17.75,9.7165991902834,17.75C9.7165991902834,17.75,4.65587044534413,12.125,4.65587044534413,12.125C4.65587044534413,12.125,5.870445344129554,4.25,5.870445344129554,4.25C5.870445344129554,4.25,6.680161943319838,1.125,6.680161943319838,1.125C6.680161943319838,1.125,12.753036437246964,1.625,12.753036437246964,1.625C12.753036437246964,1.625,13.157894736842104,9.375,13.157894736842104,9.375C13.157894736842104,9.375,16.194331983805668,13.625,16.194331983805668,13.625C16.194331983805668,13.625,22.267206477732792,17.125,22.267206477732792,17.125C22.267206477732792,17.125,28.74493927125506,22,28.74493927125506,22C28.74493927125506,22,24.493927125506072,25.75,24.493927125506072,25.75C24.493927125506072,25.75,12.955465587044534,23.625,12.955465587044534,23.625 Z;FREE",
+ "state": 1,
+ "created": "2016-03-25 14:13:44.913765+01"
+ }
}
+
]
\ No newline at end of file
--- a/src/iconolab/migrations/0001_initial.py Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/migrations/0001_initial.py Thu Jun 23 17:27:44 2016 +0200
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Generated by Django 1.9.7 on 2016-06-21 12:07
+# Generated by Django 1.9.7 on 2016-06-22 10:22
from __future__ import unicode_literals
from django.conf import settings
--- a/src/iconolab/models.py Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/models.py Thu Jun 23 17:27:44 2016 +0200
@@ -36,6 +36,9 @@
return self.name
+class Item(models.Model):
+ collection = models.ForeignKey(Collection, related_name="items")
+
class ItemMetadata(models.Model):
item = models.OneToOneField('Item', related_name='metadatas')
joconde_ref = models.CharField(max_length=20, null=False, blank=False, unique=True)
@@ -43,8 +46,7 @@
title = models.CharField(max_length=255)
description = models.CharField(max_length=255)
-class Item(models.Model):
- collection = models.ForeignKey(Collection, related_name="items")
+
class ImageStats(models.Model):
image = models.OneToOneField('Image', related_name='stats', blank=False, null=False)
--- a/src/iconolab/static/iconolab/js/components/cutout/index.js Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/static/iconolab/js/components/cutout/index.js Thu Jun 23 17:27:44 2016 +0200
@@ -253,7 +253,6 @@
updatePath(paper);
};
-
var attachRectEvents = function (paper) {
if (readOnly) { return false; }
@@ -344,8 +343,11 @@
}
this.setDrawingMode(pathInfos[1]);
- var pathData =pathInfos[0];
-
+ var pathData = pathInfos[0];
+
+ if(!pathData.length) {
+ return;
+ }
/* deal with path nomalization x = ImageWith/MaxXBound*/
var xRatio = mainImage.width() / viewBoxBounds.X;
var yRatio = mainImage.height() / viewBoxBounds.Y;
@@ -361,7 +363,6 @@
if (path.search(/[z|Z]/gi) === -1 ) {
path += "Z";
}
-
if (pathInfos.length >= 2) {
if (pathInfos[1] === RECT_MODE) {
handleRectPath(path);
@@ -413,7 +414,14 @@
var path = "";
if (drawing_path) {
if (drawingMode === RECT_MODE) {
- path = Snap.path.toAbsolute(drawing_path.getBBox().path).toString();
+ path = Snap.path.toAbsolute(drawing_path.realPath).toString();
+ var parentMatrix = drawing_path.transform();
+ console.log("local Matrix", drawing_path.transform());
+ console.log("drawing_path", drawing_path.getBBox());
+ console.log("chemin...", path);
+
+ paper.path(path);
+ console.log("...radical blaze...", drawing_path);
}
else {
path = drawing_path.attr('d');
@@ -426,10 +434,14 @@
new Error('ratio should be a number.');
}
+ if (!path.length) {
+ path = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
+ return path;
+ }
+
var normalizeMatrix = Snap.matrix(xRatio, 0, 0, yRatio, 0, 0);
path = Snap.path.map(path, normalizeMatrix).toString();
-
- /* save the type */
+ /* save the type */
var type = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
if (path.search(/[z|Z]/gi) === -1) {
path += " Z";
@@ -454,7 +466,6 @@
onChangeCallback = config.onDrawingModeChange;
}
- onChangeCallback
if (!cutCanvas.length) {
var cutCanvas = jQuery('<svg version="1.1"></svg>').addClass('cut-canvas');
jQuery(config.wrapperId).append(cutCanvas);
--- a/src/iconolab/static/iconolab/js/dist/bundle.js Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/static/iconolab/js/dist/bundle.js Thu Jun 23 17:27:44 2016 +0200
@@ -320,7 +320,6 @@
updatePath(paper);
};
-
var attachRectEvents = function (paper) {
if (readOnly) { return false; }
@@ -411,8 +410,11 @@
}
this.setDrawingMode(pathInfos[1]);
- var pathData =pathInfos[0];
-
+ var pathData = pathInfos[0];
+
+ if(!pathData.length) {
+ return;
+ }
/* deal with path nomalization x = ImageWith/MaxXBound*/
var xRatio = mainImage.width() / viewBoxBounds.X;
var yRatio = mainImage.height() / viewBoxBounds.Y;
@@ -428,7 +430,6 @@
if (path.search(/[z|Z]/gi) === -1 ) {
path += "Z";
}
-
if (pathInfos.length >= 2) {
if (pathInfos[1] === RECT_MODE) {
handleRectPath(path);
@@ -480,7 +481,14 @@
var path = "";
if (drawing_path) {
if (drawingMode === RECT_MODE) {
- path = Snap.path.toAbsolute(drawing_path.getBBox().path).toString();
+ path = Snap.path.toAbsolute(drawing_path.realPath).toString();
+ var parentMatrix = drawing_path.transform();
+ console.log("local Matrix", drawing_path.transform());
+ console.log("drawing_path", drawing_path.getBBox());
+ console.log("chemin...", path);
+
+ paper.path(path);
+ console.log("...radical blaze...", drawing_path);
}
else {
path = drawing_path.attr('d');
@@ -493,10 +501,14 @@
new Error('ratio should be a number.');
}
+ if (!path.length) {
+ path = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
+ return path;
+ }
+
var normalizeMatrix = Snap.matrix(xRatio, 0, 0, yRatio, 0, 0);
path = Snap.path.map(path, normalizeMatrix).toString();
-
- /* save the type */
+ /* save the type */
var type = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
if (path.search(/[z|Z]/gi) === -1) {
path += " Z";
@@ -521,7 +533,6 @@
onChangeCallback = config.onDrawingModeChange;
}
- onChangeCallback
if (!cutCanvas.length) {
var cutCanvas = jQuery('<svg version="1.1"></svg>').addClass('cut-canvas');
jQuery(config.wrapperId).append(cutCanvas);
@@ -564,7 +575,7 @@
/* 2 */
/***/ function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_LOCAL_MODULE_0__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*** IMPORTS FROM imports-loader ***/
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_LOCAL_MODULE_0__;/*** IMPORTS FROM imports-loader ***/
(function() {
var fix = module.exports=0;
--- a/src/iconolab/templates/iconolab/change_annotation.html Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/templates/iconolab/change_annotation.html Thu Jun 23 17:27:44 2016 +0200
@@ -8,7 +8,7 @@
<div id="drawing-zone" class="row" style="padding-top: 10px; border:1px solid orange">
- <div v-show='!formView' class="editor-wrapper col-md-12">
+ <div v-show='!formView' style="display:none" class="editor-wrapper col-md-12">
<div class='col-md-2'>
<ul class="form-drawing-wrapper list-inline">
<p class='form-drawing pullright'><strong>Type de dessin</strong></p>
@@ -21,7 +21,7 @@
<li @click="clear" class='pull-md-right drawingModeBtn'><i class='fa fa-trash'></i> Effacer</li>
- <li @click="save" class='pull-md-right drawingModeBtn'><i class='fa fa-plus'></i> Créer le fragment</li>
+ <li @click="showForm" class='pull-md-right drawingModeBtn infos info'><i class='fa fa-plus'></i> Valider</li>
</ul>
</div>
@@ -33,6 +33,10 @@
{% endthumbnail %}
</div>
</div>
+
+ <div class="col-md-2">
+ <a @click="cancel"><i class="fa fa-close"></i> Annuler</a>
+ </div>
</div>
@@ -49,7 +53,7 @@
<mask xmlns="http://www.w3.org/2000/svg" id="smallImage">
<rect x="0" y="0" width="{{ im.width }}", height="{{ im.height }}" fill="white"/>
<g v-bind:transform="transformMatrix">
- <path v-bind:d="fragmentPath"></path>
+ <path v-el:current-path v-bind:d="fragmentPath"></path>
</g>
</mask>
</defs>
@@ -89,8 +93,9 @@
<button type="submit" class="save btn btn-default">Enregister</button>
</form>
</div>
+
+ </div>
- </div>
</div>
{% endblock %}
@@ -107,7 +112,7 @@
isRect: true,
normalizePath: "",
readOnly: false,
- formView: false,
+ formView: true,
useClipPath: false,
transformMatrix: "",
fragmentPath: "",
@@ -117,6 +122,7 @@
init: function () {
var self = this;
+ this.initialDrawingMode = null;
this.drawingComponent = iconolab.initCutoutComponent({
wrapperId: '#iconolab-image-wrapper',
actionWrapper: '#action-wrapper',
@@ -127,11 +133,18 @@
});
}
});
+
+ this.$nextTick(function () {
+ this.showForm();
+ });
},
methods: {
setDrawingMode: function (mode, updateComponent) {
+ if (!this.initialDrawingMode) {
+ this.initialDrawingMode = mode;//useful for cancel
+ }
var updateComponent = (typeof updateComponent === "boolean") ? updateComponent: true;
this.mode = this.$options['MODE_' + mode];
this.isRect = (this.mode === this.$options.MODE_RECT) ? true: false;
@@ -139,10 +152,18 @@
this.drawingComponent.setDrawingMode(this.mode);
}
},
+
+ cancel: function () {
+ this.formView = true;
+ var currentPath = this.$els.currentPath.getAttribute("d");
+ if (!currentPath.length || !this.initialDrawingMode) { return; } {
+ currentPath += ";" + this.initialDrawingMode;
+ this.drawingComponent.setPath(currentPath);
+ }
+ },
showEditor: function () {
this.formView = false;
- console.log(this.$els.smallImage);
},
highLightZone: function () {
@@ -161,18 +182,15 @@
var normalizePath = this.drawingComponent.getPath();
},
- save: function () {
+ showForm: function () {
this.normalizePath = this.drawingComponent.getPath();
var smallImage = this.$els.smallImage;
this.formView = true;
- /* 100x = smallImageHeight && 100x=smallImageWidth | 100 = ViewBoxBound */
var xRatio = smallImage.width / 100;
var yRatio = smallImage.height / 100;
var transformMatrix = [xRatio, 0, 0, yRatio, 0, 0].join(',');
this.transformMatrix ="matrix(" + transformMatrix + ")";
this.fragmentPath = this.normalizePath.split(';')[0];
- console.log(this.fragmentPath);
- console.log(this.transformMatrix);
},
clear: function () {
--- a/src/iconolab/templates/iconolab/detail_annotation.html Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/templates/iconolab/detail_annotation.html Thu Jun 23 17:27:44 2016 +0200
@@ -7,6 +7,8 @@
{% load iconolab_tags %}
{% block content %}
+
+ <a href="{% url 'image_detail' collection_name image_ref %}"><i class="fa fa-list"></i> Revoir l'image </a>
<div id="annotation-wrapper" class="row" style="border: 1px solid gray">
<div v-show="formView" class="col-md-12">
@@ -18,7 +20,7 @@
<svg width="{{ im.width }}" height="{{ im.height }}" version="1.1" style="position:absolute; top:0px; left: 0px">
<g transform="matrix({% transform_matrix im_width=im.width im_height=im.height max_x=100 max_y=100 %})">
- <path d="{{ annotation.current_revision.fragment }}" opacity="0.7" fill="orange"></path>
+ <path d="{{ annotation.current_revision.fragment|clean_path }}" opacity="0.7" fill="orange"></path>
</g>
</svg>
@@ -38,5 +40,4 @@
</div>
</div>
</div>
-
{% endblock %}
--- a/src/iconolab/templates/iconolab/detail_image.html Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/templates/iconolab/detail_image.html Thu Jun 23 17:27:44 2016 +0200
@@ -7,7 +7,17 @@
{% load iconolab_tags %}
{% block content %}
-<p>detail_image for {{image_ref}} in the collection {{collection_name}}</p>
-<a href="{% url 'annotation_create' collection_name image_ref %}">Create Annotation</a>
+
+<div class="row">
+ <div class="col-md-6 col-md-offset-3">
+ <a class="btn btn-link" href="{% url 'image_detail' collection_name image_ref %}"><i class="fa fa-plus"></i> Créer une nouvelle annotation</a>
+
+ {% thumbnail image.media "x800" crop="center" as im %}
+ <img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
+ {% endthumbnail %}
+ </div>
+</div>
+
+{% include "partials/image_annotations_list.html" with annotation_list=annotation_list %}
{% endblock %}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab/templates/partials/image_annotations_list.html Thu Jun 23 17:27:44 2016 +0200
@@ -0,0 +1,30 @@
+{% load thumbnail %}
+{% load iconolab_tags %}
+
+<ul class="annotation-list-wrapper list-inline">
+
+ <p><strong>Annotations de l'image</strong></p>
+
+ {% for annotation in annotation_list %}
+ <li class="small-image-wrapper">
+
+ <div class="fragment-container" style="position: relative">
+ {% thumbnail annotation.image.media "x300" crop="center" as im %}
+ <img v-el:small-image src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />
+ <svg width="{{ im.width }}" height="{{ im.height }}" version="1.1" style="position:absolute; top:0px; left: 0px">
+ <g transform="matrix({% transform_matrix im_width=im.width im_height=im.height max_x=100 max_y=100 %})">
+ <path d="{{ annotation.current_revision.fragment|clean_path }}" opacity="0.7" fill="orange"></path>
+ </g>
+ </svg>
+ </div>
+ {% endthumbnail %}
+ <div class="fragment-infos">
+ <a class="fa fa-eye" href="{% url 'annotation_edit' collection_name image_ref annotation.annotation_guid %}">Voir</a>
+ <p class="small">Créer par <strong>{{ annotation.author }}</strong></strong><p>
+ <p class="small">Révisée par <strong>{{ annotation.current_revision.author }}</strong>
+ le {{ annotation.current_revision.created|date:'d-m-Y' }}
+ </p>
+ </div>
+ </li>
+{% endfor %}
+</ul>
\ No newline at end of file
--- a/src/iconolab/templatetags/iconolab_tags.py Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/templatetags/iconolab_tags.py Thu Jun 23 17:27:44 2016 +0200
@@ -16,6 +16,7 @@
return matrix
+@register.filter
def clean_path(path):
if not len(path):
return ""
--- a/src/iconolab/views.py Wed Jun 22 17:53:40 2016 +0200
+++ b/src/iconolab/views.py Thu Jun 23 17:27:44 2016 +0200
@@ -27,6 +27,15 @@
context = super(ShowImageView, self).get_context_data(**kwargs)
context["collection_name"] = self.kwargs.get("collection_name", "")
context["image_ref"] = self.kwargs.get("image_ref", "")
+ context["annotation_list"] = []
+ try:
+ image = Image.objects.get(image_ref=context["image_ref"])
+ annotation_list = Annotation.objects.filter(image_id=image.id)
+ context["image"] = image
+ context["annotation_list"] = annotation_list
+ except Image.DoesNotExist:
+ return RedirectView.as_view(url=reverse("404error"))
+
return render(request, 'iconolab/detail_image.html', context);