chapter tangle
authorAnthony Ly <anthonyly.com@gmail.com>
Wed, 22 May 2013 17:09:59 +0200
changeset 28 a0a048ff33a1
parent 25 ab966883a458
child 29 ec6a5592c617
chapter tangle
integration/css/style.css
integration/edition.html
integration/js/edition.js
integration/js/tangle.js
integration/template.html
--- a/integration/css/style.css	Tue May 21 17:41:57 2013 +0200
+++ b/integration/css/style.css	Wed May 22 17:09:59 2013 +0200
@@ -83,4 +83,29 @@
 .timeline-annotation-widget .annotation{width: 10px; height: 10px; background-color: #c0392b; position: absolute; top:15px;}
 ul.tagit{margin-left: 10px;-webkit-border-radius: 0px;
 -moz-border-radius: 0px;
-border-radius: 0px;}
\ No newline at end of file
+border-radius: 0px;}
+
+/* Tangle */
+.time-tangle {
+	color: #2c3e50; cursor: w-resize; position: relative;
+}
+.time-tangle:hover, 
+.time-tangle.active {
+    color: #c0392b; border-bottom: 1px dashed #2c3e50;
+}
+.time-tangle:hover:after, 
+.time-tangle.active:after {
+	position: absolute;
+	display: inline-block;
+    color: #2c3e50;  top: 18px; left: 50%; width: 160px;
+    margin-left: -80px; font-size: 10px; text-align: center;
+    content: "glisser pour modifier";
+}
+
+.time-tangle.deactivate:hover {
+    border: none; color: #2c3e50;
+}
+
+.time-tangle.deactivate:hover:after {
+    display: none;
+}
--- a/integration/edition.html	Tue May 21 17:41:57 2013 +0200
+++ b/integration/edition.html	Wed May 22 17:09:59 2013 +0200
@@ -463,8 +463,8 @@
         myProject = myDir.remoteSource({
                 url: "data/empty-project.json",
                 serializer: IriSP.serializers.ldt
-            }),
-        myMedia = null;
+            });
+        
 
     </script>
 </body>
--- a/integration/js/edition.js	Tue May 21 17:41:57 2013 +0200
+++ b/integration/js/edition.js	Wed May 22 17:09:59 2013 +0200
@@ -1,16 +1,23 @@
+var myMedia = null,
+    currentChapter = null,
+    chapters = [],
+    annotations = [];
+
 $(function(){
 
 var global = {
     diaporama : null,
     idAnnotation : null,
-    colors : ['#f39c12', '#2ecc71', '#3498db', '#9b59b6',  
-    '#f1c40f', '#e67e22', '#e74c3c', '#ecf0f1', 
-    '#16a085', '#27ae60', '#2980b9', '#8e44ad', '#2c3e50',
-    '#f39c12', '#d35400', '#c0392b', '#bdc3c7', '#7f8c8d']
-},
-currentChapter = null,
-chapters = [],
-annotations = [];
+    colorsIndex : 0,
+    colors : 
+        ['#f39c12', '#2ecc71', '#3498db', '#9b59b6',  
+        '#f1c40f', '#e67e22', '#e74c3c', '#ecf0f1', 
+        '#16a085', '#27ae60', '#2980b9', '#8e44ad', 
+        '#f39c12', '#d35400', '#c0392b', '#bdc3c7']
+};
+
+
+
 
 myProject.onLoad(function() {
 
@@ -18,7 +25,7 @@
     
     myMedia = myProject.getCurrentMedia();
     
-    loadChapters();
+    loadInitChapters();
 
     IriSP.htmlPlayer(
         myMedia,
@@ -45,27 +52,6 @@
         }else{
             btnCutChapter.css("left",pos);
         }
-
-        /*
-        //chapitre edit
-        var formChapter = $('.form-chapter-edit'),
-            inputBeginChapter = formChapter.find('input[name=begin]'),
-            inputDurationChapter = formChapter.find('input[name=duration]'),
-            inputEndChapter = formChapter.find('input[name=end]'),
-            viewBeginChapter = formChapter.find('.begin'),
-            viewDurationChapter = formChapter.find('.duration'),
-            viewEndChapter = formChapter.find('.end'),
-            timeBegin = 0,
-            timeEnd = t.milliseconds,
-            timeDuration = timeEnd - timeBegin;
-
-        inputBeginChapter.val(timeBegin);
-        inputEndChapter.val(timeEnd);
-        inputDurationChapter.val(timeDuration);
-        viewBeginChapter.html(millisecondsToString(timeBegin));
-        viewDurationChapter.html(millisecondsToString(timeDuration));
-        viewEndChapter.html(millisecondsToString(timeEnd));
-        */
     });//timeupdate
     
 });//myProject.onLoad
@@ -166,7 +152,6 @@
         e.preventDefault();
         var idChapter = $(this).attr('data-chapter-id');
         loadFormChapter(idChapter);
-        currentChapter = _.find(chapters, function(c){ return c.id == idChapter; });
     });
 
     $('.chapter-segments').on('click', 'li', function(){
@@ -187,8 +172,8 @@
 
     function onTagItChange(e, ui) {
         var idChapter = $(this).parents('form').attr('data-chapter-id'),
-            value = $('input[name=tags]').val();
-        currentChapter.tags = value;
+            value = $('input[name=keywords]').val();
+        currentChapter.keywords = value;
         $('#row-list-chapter-'+idChapter).find('.list-chapter-tags').text(value);
     }
 
@@ -198,14 +183,18 @@
     }
 
     function loadFormChapter(idChapter){
-        var chapterData = _.find(chapters, function(c){ return c.id == idChapter; }),
-            chapterWrap = $('.chapter-widget-info');
+        currentChapter = _.find(chapters, function(c){ return c.id == idChapter; });
+        var chapterWrap = $('.chapter-widget-info'),
+            indexChapter = _.indexOf(chapters, currentChapter),
+            beginTangle = (indexChapter>0) ? true : false,
+            endTangle = (indexChapter<(chapters.length-1)) ? true : false;
 
-        currentChapter = chapterData;
+        currentChapter.beginTangle = beginTangle;
+        currentChapter.endTangle = endTangle;
 
         $.get('template.html', function(templates){
             var tpl = $(templates).filter('#tpl-chapter-edit').html();
-            tpl = Mustache.render(tpl, chapterData);
+            tpl = Mustache.render(tpl, currentChapter);
             chapterWrap.empty().append(tpl);
             chapterWrap.find('.tag-it').tagit(tagitParam);
         });
@@ -217,18 +206,18 @@
     e.preventDefault();
 
     if(chapters.length == 1){alert('Le projet doit contenir au moins un chapitre.'); return;}
+
     var idChapter = $(this).attr('data-chapter-id'),
         chapter = _.find(chapters, function(c){ return c.id == idChapter; }),
         indexChapter = _.indexOf(chapters, chapter),
         chapterModify;
     if(indexChapter == 0){
         chapterModify = chapters[1];
-        chapterModify.begin = 0;
-        chapterModify.duration = chapterModify.end;
+        chapterModify.setBegin(0);
     }else{
         chapterModify = chapters[indexChapter-1];
-        chapterModify.end = chapter.end;
-        chapterModify.duration = chapterModify.end - chapterModify.begin;
+        //var newEnd = new IriSP.Model.Time(chapter.end)
+        chapterModify.setEnd(chapter.end);
     }
     chapters = _(chapters).reject(function(c) { return c.id == idChapter; });
     renderChapter();
@@ -239,33 +228,34 @@
 });
 
 //nouveau chapitre
+    function newChapter(dataChapter){
+        var chapter = new IriSP.Model.Annotation(false, myProject);
+            chapter.setMedia(myMedia.id);
+            chapter.setBegin(dataChapter.begin);
+            chapter.setEnd(dataChapter.end);
+            chapter.title = dataChapter.title;
+            chapter.description = dataChapter.description;
+            chapter.keywords = dataChapter.keywords;
+            chapter.color = global.colors[(global.colorsIndex<global.colors.length) ? global.colorsIndex++ : (global.colorsIndex=0)];
+    
+        chapters.push(chapter);
+        renderChapter();
+        loadFormChapter(chapter.id);
+    }
+
     $('.chapter-widget').on('click', '.btn-cut-chapter', function(e){
         e.preventDefault();
 
-        var uniqId = 'id' + (new Date()).getTime();
-
-        var title = 'New',
-            tags = 'tag',
-            begin = myMedia.currentTime.milliseconds,
-            end = organizeNewChapter(begin),
-            duration = end - begin,
-            description = '',
-            id = uniqId;
+        var dataChapter = {
+                title : 'New',
+                begin : myMedia.currentTime,
+                end : organizeNewChapter(myMedia.currentTime),
+                description : 'description',
+                keywords : 'tag1,tag2'
+            };
 
-        var dataChapter = {
-            title : title,
-            tags : tags,
-            begin : begin,
-            duration : duration,
-            end : end,
-            description : description,
-            color : global.colors[chapters.length],
-            id : uniqId
-        };
-      
-        chapters.push(dataChapter);
-        renderChapter();
-        loadFormChapter(id);
+        newChapter(dataChapter);
+
     });
     
     function organizeNewChapter(beginNew){
@@ -275,11 +265,11 @@
             var begin = v.begin,
                 end = v.end;
             if(beginNew>=begin && beginNew<=end){
-                v.end = beginNew;
-                v.duration = v.end - v.begin;
-                returnEnd = end;
+                returnEnd = new IriSP.Model.Time(end);
+                v.setEnd(beginNew); 
             }
         });
+ 
         return returnEnd;
     }
     
@@ -296,24 +286,21 @@
         chapterList.empty();
 
         $.each(chapters, function(k, v){
-
+            //form
+            if($('#form-chapter-edit-'+v.id).length){
+                loadFormChapter(v.id);
+            }
             //segments
-                color = global.colors[k],
-                width = Math.floor(v.duration * wChapterSegmentWrap / myMedia.duration.milliseconds),
+            var width = Math.floor(v.getDuration() * wChapterSegmentWrap / myMedia.duration),
                 segment = $('<li>'+v.title+'</li>').css({
                     width : width,
                     backgroundColor : v.color
                 }).attr('id', v.id);
     
             chapterSegmentWrap.append(segment);
- 
+
             //liste
             $.get('template.html', function(templates){
-
-                v.beginString = millisecondsToString(v.begin);
-                v.durationString = millisecondsToString(v.duration);
-                v.endString = millisecondsToString(v.end);
-             
                 var tplChapterRow = $(templates).filter('#tpl-chapter-row').html();
                 tplChapterRow = Mustache.render(tplChapterRow, v);
                 chapterList.append(tplChapterRow);
@@ -323,37 +310,21 @@
     }
 
 //init
-    function loadChapters(){//nouveau projet, 1 chapitre
-
-        var uniqId = 'id' + (new Date()).getTime();
-
-        var title = 'chapitre 1',
-            tags = 'tag1,tag2',
-            begin = 0,
-            duration = myMedia.duration.milliseconds,
-            end = myMedia.duration.milliseconds,
-            description = 'description du chapitre 1',
-            id = uniqId;
-
+    function loadInitChapters(){//nouveau projet, 1 chapitre
         var dataChapter = {
-            title : title,
-            tags : tags,
-            begin : begin,
-            duration : duration,
-            end : end,
-            description : description,
-            color : global.colors[chapters.length],
-            id : id
-        };
+                title : 'New',
+                begin : 0,
+                end : myMedia.duration,
+                description : 'description',
+                keywords : 'tag1,tag2'
+            };
 
-        chapters.push(dataChapter);
-        renderChapter();
+        newChapter(dataChapter);
     }
 
 
 
 
-
     //edit annotation
     $('#list-annotations').on('click', 'a.btn-edit-annotation', function(e){
         e.preventDefault();
--- a/integration/js/tangle.js	Tue May 21 17:41:57 2013 +0200
+++ b/integration/js/tangle.js	Wed May 22 17:09:59 2013 +0200
@@ -6,16 +6,15 @@
         tangleHasMoved;
     
     $('.chapter-widget-info').on('mousedown', '.time-tangle', function(evt){
-   // $(".time-tangle").mousedown(function(evt) {
-
         activeTangle = $(this);
         activeTangle.addClass("active");
         tangleStartVal = +activeTangle.attr("data-milliseconds");
         tangleStartX = evt.pageX;
         tangleHasMoved = false;
-        $(this).siblings(".time-tangle").addClass("deactivate");
+        $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
         return false;
     });
+
     $(document)
         .mousemove(function(evt) {
             if (activeTangle) {
@@ -27,23 +26,77 @@
         })
         .mouseup(function() {
             if (activeTangle) {
-                activeTangle.text(activeTangle.text().replace(/\.\d+$/,''));
                 $(".time-tangle").removeClass("active deactivate");
                 activeTangle = undefined;
             }
         });
+
+    function updateRenderChapter(chapterData){
+        var segment = $('.chapter-segments li#'+chapterData.id),
+            wChapterSegmentWrap = $('.chapter-segments').width(),
+            wSegmentNew = Math.floor(chapterData.getDuration() * wChapterSegmentWrap / myMedia.duration),
+            row = $('#row-list-chapter-'+chapterData.id),
+            form = ($('#form-chapter-edit-'+chapterData.id).length) ? $('#form-chapter-edit-'+chapterData.id) : false;
+
+        segment.width(wSegmentNew);
+
+        row.find('.begin').text(chapterData.begin);
+        row.find('.duration').text(chapterData.getDuration());
+        row.find('.end').text(chapterData.end);
+
+        if(form){
+            form.find('.begin').text(chapterData.begin);
+            form.find('.begin').attr('data-milliseconds',chapterData.begin);
+            form.find('.duration').text(chapterData.getDuration());
+            form.find('.end').text(chapterData.end);
+            form.find('.end').attr('data-milliseconds',chapterData.end);
+        }
+    }
+
+    function updateChapterDuration(val, chapterBefore, chapterAfter){
+        if (val<chapterAfter.end && val>chapterBefore.begin) {
+            chapterAfter.setBegin(val);
+            chapterBefore.setEnd(val);
+
+            updateRenderChapter(chapterAfter);
+            updateRenderChapter(chapterBefore);
+        }
+    }
+
+    $('.chapter-widget-info').on('valuechange', '.tangle-start', function(evt, val){
+        var indexChapter = _.indexOf(chapters, currentChapter);
+        if(indexChapter == 0 || chapters.length<=1) return;
         
+        var chapterBefore = chapters[indexChapter-1],
+            chapterAfter = currentChapter;
+
+        updateChapterDuration(val, chapterBefore, chapterAfter);
+    });
+
+    $('.chapter-widget-info').on('valuechange', '.tangle-end', function(evt, val){
+        var indexChapter = _.indexOf(chapters, currentChapter);
+        if(indexChapter == chapters.length-1 || chapters.length<=1) return;
+        
+        var chapterAfter = chapters[indexChapter+1],
+            chapterBefore = currentChapter;
+        
+        updateChapterDuration(val, chapterBefore, chapterAfter);
+    });
+    /*
     $(".tangle-start")
         .mouseup(function(evt) {
+
             if (!tangleHasMoved && currentMedia && currentSegment) {
                 currentMedia.setCurrentTime(currentSegment.begin);
             }
         })
         .on("valuechange", function(evt, val) {
+
             if (currentMedia && currentSegment) {
                 currentSegment.setBegin(val);
             }
         });
+
     $(".tangle-end")
         .mouseup(function(evt) {
             if (!tangleHasMoved && currentMedia && currentSegment) {
@@ -59,4 +112,5 @@
         if (currentMedia && currentSegment) {
             currentSegment.setDuration(val);
         }
-    });
\ No newline at end of file
+       
+    }); */
\ No newline at end of file
--- a/integration/template.html	Tue May 21 17:41:57 2013 +0200
+++ b/integration/template.html	Wed May 22 17:09:59 2013 +0200
@@ -185,10 +185,10 @@
 <script id="tpl-chapter-row" type="text/html">
 <tr id="row-list-chapter-{{id}}" style="background-color : {{color}};">
 	<td class="list-chapter-title">{{title}}</td>
-	<td class="list-chapter-tags">{{tags}}</td>
-	<td>{{beginString}}</td>
-	<td>{{durationString}}</td>
-	<td>{{endString}}</td>
+	<td class="list-chapter-tags">{{keywords}}</td>
+	<td class="begin">{{begin}}</td>
+	<td class="duration">{{getDuration}}</td>
+	<td class="end">{{end}}</td>
 	<td>
 		<table>
 			<tr>
@@ -209,14 +209,9 @@
 	<div class="row">
 		<div class="span3 text-right">
 			<input name="title" type="text" value="{{title}}">
-			<input name="tags" type="text" class="tag-it" value="{{tags}}">
+			<input name="keywords" type="text" class="tag-it" value="{{keywords}}">
 		</div>
 		<div class="span3">
-		<!--
-			<input type="hidden" name="begin" value="{{begin}}">
-			<input type="hidden" name="duration" value="{{duration}}">
-			<input type="hidden" name="end" value="{{end}}">
-		-->
 			<table class="table text-right">
 				<thead>
 					<tr>
@@ -227,9 +222,9 @@
 				</thead>
 				<tbody>
 					<tr>
-						<td class="span1 begin time-tangle">{{beginString}}</td>
-						<td class="span1 duration">{{durationString}}</td>
-						<td class="span1 end">{{endString}}</td>
+						<td class="span1"><span {{#beginTangle}}class="time-tangle tangle-start begin" data-milliseconds="{{begin.milliseconds}}"{{/beginTangle}}>{{begin}}</span></td>
+						<td class="span1"><span>{{getDuration}}</span></td>
+						<td class="span1"><span {{#endTangle}}class="time-tangle tangle-end end" data-milliseconds="{{end.milliseconds}}"{{/endTangle}}>{{end}}</span></td>
 					</tr>
 				</tbody>
 			</table>