forked from 0x2620/oxjs
fix bugs in video editor; begin to implement new list map mode that allows for defining/clearing places
This commit is contained in:
parent
ae82696600
commit
3c94f44a99
15 changed files with 437 additions and 255 deletions
|
|
@ -396,9 +396,8 @@ Ox.AnnotationFolder = function(options, self) {
|
|||
}
|
||||
|
||||
function isDefined(item) {
|
||||
return self.options.type == 'event'
|
||||
? item.event.start !== ''
|
||||
: item.place.lat !== null;
|
||||
return !!item[self.options.type]
|
||||
&& !!item[self.options.type].type;
|
||||
}
|
||||
|
||||
function removeAnnotation(data) {
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ Ox.AnnotationPanel = function(options, self) {
|
|||
}
|
||||
|
||||
function selectAnnotation(data, index) {
|
||||
Ox.print('selectAnnotation', index)
|
||||
self.options.selected = data.id;
|
||||
if (data.id) {
|
||||
self.$folder.forEach(function($folder, i) {
|
||||
|
|
@ -288,25 +289,6 @@ Ox.AnnotationPanel = function(options, self) {
|
|||
});
|
||||
scrollToSelected(self.options.layers[index].type);
|
||||
}
|
||||
/*
|
||||
if (data.top) {
|
||||
data.bottom = data.top + data.height;
|
||||
height = self.$folders.height();
|
||||
top = self.$folders.offset().top;
|
||||
scrollTop = self.$folders.scrollTop();
|
||||
if (data.top < top || data.bottom > height) {
|
||||
if (data.top < top) {
|
||||
Ox.print('top scrollTop', data.top, scrollTop)
|
||||
scrollTop += data.top - top;
|
||||
} else {
|
||||
scrollTop += data.bottom - top - height;
|
||||
}
|
||||
self.$folders.animate({
|
||||
scrollTop: scrollTop + 'px'
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
*/
|
||||
that.triggerEvent('select', data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ Ox.VideoEditor = function(options, self) {
|
|||
},
|
||||
key_alt_shift_right: function() {
|
||||
},
|
||||
key_b: function() {
|
||||
selectAnnotation(getNextAnnotation('annotation', -1));
|
||||
},
|
||||
key_backslash: function() {
|
||||
selectAnnotation();
|
||||
},
|
||||
|
|
@ -112,7 +115,7 @@ Ox.VideoEditor = function(options, self) {
|
|||
});
|
||||
},
|
||||
key_g: function() {
|
||||
self.results.length && selectAnnotation(getNextResult(1));
|
||||
self.results.length && selectAnnotation(getNextAnnotation('result', 1));
|
||||
},
|
||||
key_i: function() {
|
||||
setPoint('in', self.options.position);
|
||||
|
|
@ -123,6 +126,9 @@ Ox.VideoEditor = function(options, self) {
|
|||
key_minus: function() {
|
||||
self.options.videoSize == 'large' && toggleSize();
|
||||
},
|
||||
key_n: function() {
|
||||
selectAnnotation(getNextAnnotation('annotation', 1));
|
||||
},
|
||||
key_o: function() {
|
||||
setPoint('out', self.options.position);
|
||||
},
|
||||
|
|
@ -146,7 +152,7 @@ Ox.VideoEditor = function(options, self) {
|
|||
movePositionBy(self.options.duration);
|
||||
},
|
||||
key_shift_g: function() {
|
||||
self.results.length && selectAnnotation(getNextResult(-1));
|
||||
self.results.length && selectAnnotation(getNextAnnotation('result', -1));
|
||||
},
|
||||
key_shift_left: function() {
|
||||
movePositionBy(-1);
|
||||
|
|
@ -183,9 +189,12 @@ Ox.VideoEditor = function(options, self) {
|
|||
|
||||
self.$player = [];
|
||||
self.$timeline = [];
|
||||
self.annotations = getAnnotations();
|
||||
self.controlsHeight = 16;
|
||||
self.editing = false;
|
||||
self.margin = 8;
|
||||
self.positions = getPositions();
|
||||
self.results = [];
|
||||
self.words = getWords();
|
||||
|
||||
Ox.print('VIDEO EDITOR OPTIONS', self.options)
|
||||
|
|
@ -354,7 +363,7 @@ Ox.VideoEditor = function(options, self) {
|
|||
});
|
||||
|
||||
self.$keyboardShortcuts = $('<div>').css({margin: '16px'});
|
||||
[
|
||||
Ox.merge([
|
||||
{key: Ox.UI.symbols.space, action: 'Play/Pause'},
|
||||
{key: 'P', action: 'Play In to Out'},
|
||||
{key: '0', action: 'Mute/Unmute'},
|
||||
|
|
@ -375,17 +384,19 @@ Ox.VideoEditor = function(options, self) {
|
|||
{key: '[', action: 'Go to Previous Annotation'},
|
||||
{key: ']', action: 'Go to Next Annotation'},
|
||||
{key: '\\', action: 'Select Current Annotation'},
|
||||
{key: 'B', action: 'Select Previous Annotation'},
|
||||
{key: 'N', action: 'Select Next Annotation'},
|
||||
{key: '<', action: 'Go to Previous Cut'},
|
||||
{key: '>', action: 'Go to Next Cut'},
|
||||
{key: '/', action: 'Select Current Cut'},
|
||||
{key: 'F', action: 'Find'},
|
||||
{key: Ox.UI.symbols.shift + 'G', action: 'Go to Previous Result'},
|
||||
{key: 'G', action: 'Go to Next Result'},
|
||||
{key: 'S', action: 'Select Current Annotation'},
|
||||
{key: 'E', action: 'Edit Selected Annotation'},
|
||||
{key: Ox.UI.symbols['return'], action: 'Submit'},
|
||||
{key: Ox.UI.symbols.escape, action: 'Cancel'}
|
||||
].forEach(function(shortcut) {
|
||||
{key: Ox.UI.symbols['return'], action: 'Edit/Submit'},
|
||||
{key: Ox.UI.symbols.escape, action: 'Cancel/Deselect'}
|
||||
], self.options.layers.map(function(layer, i) {
|
||||
return {key: i + 1, action: 'Add ' + layer.item};
|
||||
})).forEach(function(shortcut) {
|
||||
self.$keyboardShortcuts.append(
|
||||
$('<div>').css({display: 'table-row'})
|
||||
.append(
|
||||
|
|
@ -532,7 +543,7 @@ Ox.VideoEditor = function(options, self) {
|
|||
.css({float: 'right'})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
selectAnnotation(getNextResult(1));
|
||||
selectAnnotation(getNextAnnotation('result', 1));
|
||||
}
|
||||
})
|
||||
.appendTo(self.$menubar);
|
||||
|
|
@ -547,7 +558,7 @@ Ox.VideoEditor = function(options, self) {
|
|||
.css({float: 'right'})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
selectAnnotation(getNextResult(-1));
|
||||
selectAnnotation(getNextAnnotation('result', -1));
|
||||
}
|
||||
})
|
||||
.appendTo(self.$menubar);
|
||||
|
|
@ -614,17 +625,7 @@ Ox.VideoEditor = function(options, self) {
|
|||
that.triggerEvent('info', data);
|
||||
},
|
||||
paused: togglePaused,
|
||||
remove: function(data) {
|
||||
Ox.print('REMOVE EVENT REACHED EDITOR', data)
|
||||
var layer = Ox.getObjectById(self.options.layers, data.layer),
|
||||
index = Ox.getIndexById(layer.items, data.id);
|
||||
updateWords('remove');
|
||||
layer.items.splice(index, 1);
|
||||
self.editing = false;
|
||||
self.options.selected = '';
|
||||
setTimelineState();
|
||||
that.triggerEvent('removeannotation', data);
|
||||
},
|
||||
remove: removeAnnotation,
|
||||
resize: resizeAnnotations,
|
||||
resizeend: resizeendAnnotations,
|
||||
resizecalendar: function(data) {
|
||||
|
|
@ -736,37 +737,17 @@ Ox.VideoEditor = function(options, self) {
|
|||
out: item.out
|
||||
} : null;
|
||||
});
|
||||
}))).sort(function(a, b) {
|
||||
var ret = 0;
|
||||
if (a['in'] < b['in']) {
|
||||
ret = -1;
|
||||
} else if (a['in'] > b['in']) {
|
||||
ret = 1;
|
||||
} else if (a.out < b.out) {
|
||||
ret = -1;
|
||||
} else if (a.out > b.out) {
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
});
|
||||
}))).sort(sortAnnotations);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
function getAnnotation() {
|
||||
// Get annotation at current position
|
||||
var annotations = [];
|
||||
self.options.layers.forEach(function(layer) {
|
||||
layer.items.forEach(function(item) {
|
||||
if (
|
||||
item['in'] <= self.options.position
|
||||
&& item.out >= self.options.position
|
||||
) {
|
||||
annotations.push(item);
|
||||
}
|
||||
});
|
||||
});
|
||||
annotations.sort(function(a, b) {
|
||||
var annotations = self.annotations.filter(function(annotation) {
|
||||
return annotation['in'] <= self.options.position
|
||||
&& annotation.out >= self.options.position
|
||||
}).sort(function(a, b) {
|
||||
var aValue = self.options.position - a['in'],
|
||||
bValue = self.options.position - b['in'],
|
||||
ret = 0;
|
||||
|
|
@ -788,6 +769,12 @@ Ox.VideoEditor = function(options, self) {
|
|||
return annotations.length ? annotations[0] : {id: ''};
|
||||
}
|
||||
|
||||
function getAnnotations() {
|
||||
return Ox.flatten(Ox.merge(self.options.layers.map(function(layer) {
|
||||
return layer.items;
|
||||
}))).sort(sortAnnotations);
|
||||
}
|
||||
|
||||
function getAnnotationValue(annotationId) {
|
||||
var found = false, value;
|
||||
Ox.forEach(self.options.layers, function(layer, i) {
|
||||
|
|
@ -803,26 +790,43 @@ Ox.VideoEditor = function(options, self) {
|
|||
return value;
|
||||
}
|
||||
|
||||
function getNextAnnotation(type, direction) {
|
||||
// type can be 'annotation' or 'result
|
||||
var annotation,
|
||||
annotations = type == 'annotation' ? self.annotations : self.results,
|
||||
index,
|
||||
position;
|
||||
if (self.options.selected) {
|
||||
index = Ox.getIndexById(annotations, self.options.selected);
|
||||
if (index > -1 && self.options.position == annotations[index]['in']) {
|
||||
annotation = annotations[Ox.mod(index + direction, annotations.length)];
|
||||
}
|
||||
}
|
||||
if (!annotation) {
|
||||
position = getNextPosition(type, direction);
|
||||
annotations = annotations.filter(function(annotation) {
|
||||
return annotation['in'] == position;
|
||||
});
|
||||
annotation = annotations[direction == 1 ? 0 : annotations.length - 1];
|
||||
}
|
||||
return annotation;
|
||||
}
|
||||
|
||||
// fixme: why not goToNextPosition()?
|
||||
function getNextPosition(type, direction) {
|
||||
// type can be 'annotation', 'cut' or 'result'
|
||||
var found = false,
|
||||
position = 0,
|
||||
positions;
|
||||
if (type == 'annotation') {
|
||||
positions = Ox.sort(Ox.unique(Ox.flatten(
|
||||
self.options.layers.map(function(layer) {
|
||||
return layer.items.map(function(item) {
|
||||
return item['in'];
|
||||
});
|
||||
})
|
||||
)));
|
||||
positions = self.positions;
|
||||
} else if (type == 'cut') {
|
||||
positions = Ox.merge(0, self.options.cuts, self.options.duration);
|
||||
}/* else if (type == 'result') {
|
||||
positions = self.results.map(function(v) {
|
||||
return v['in'];
|
||||
});
|
||||
}*/
|
||||
} else if (type == 'result') {
|
||||
positions = Ox.unique(self.results.map(function(result) {
|
||||
return result['in'];
|
||||
}));
|
||||
}
|
||||
direction == -1 && positions.reverse();
|
||||
Ox.forEach(positions, function(v) {
|
||||
if (
|
||||
|
|
@ -842,69 +846,12 @@ Ox.VideoEditor = function(options, self) {
|
|||
return position;
|
||||
}
|
||||
|
||||
function getNextResult(direction) {
|
||||
var found = false, index, result;
|
||||
if (
|
||||
self.currentResult
|
||||
&& self.options.position == Ox.getObjectById(self.results, self.currentResult)['in']
|
||||
) {
|
||||
index = Ox.getIndexById(self.results, self.currentResult);
|
||||
result = self.results[Ox.mod(index + direction, self.results.length)];
|
||||
} else {
|
||||
direction == -1 && self.results.reverse();
|
||||
Ox.forEach(self.results, function(v) {
|
||||
if (
|
||||
direction == 1
|
||||
? v['in'] > self.options.position
|
||||
: v['in'] < self.options.position
|
||||
) {
|
||||
result = v;
|
||||
found = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
direction == -1 && self.results.reverse();
|
||||
if (!found) {
|
||||
Ox.print('!found', direction, self.results[direction == 1 ? 0 : results.length - 1])
|
||||
result = self.results[direction == 1 ? 0 : self.results.length - 1];
|
||||
}
|
||||
}
|
||||
self.currentResult = result.id;
|
||||
return result;
|
||||
function getPositions() {
|
||||
return Ox.unique(self.annotations.map(function(annotation) {
|
||||
return annotation['in'];
|
||||
}));
|
||||
}
|
||||
|
||||
/*
|
||||
function getPoints(type) {
|
||||
var found = false,
|
||||
points,
|
||||
positions = [];
|
||||
if (type == 'annotation') {
|
||||
|
||||
} else if (type == 'cut') {
|
||||
positions = self.options.cuts;
|
||||
} else if (type == 'result') {
|
||||
// ...
|
||||
} else if (type == 'subtitle') {
|
||||
// FIXME: remove? annotation?
|
||||
self.options.subtitles.forEach(function(v, i) {
|
||||
positions.push(v['in']);
|
||||
positions.push(v.out);
|
||||
});
|
||||
}
|
||||
positions.indexOf(0) == -1 && positions.unshift(0);
|
||||
positions.indexOf(self.options.duration) == -1
|
||||
&& positions.push(self.options.duration);
|
||||
Ox.forEach(positions, function(v, i) {
|
||||
if (v > self.options.position) {
|
||||
points = [positions[i - 1], positions[i]];
|
||||
found = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return points;
|
||||
}
|
||||
*/
|
||||
|
||||
function getSizes(scrollbarIsVisible) {
|
||||
var scrollbarWidth = Ox.UI.SCROLLBAR_SIZE,
|
||||
contentWidth = self.options.width
|
||||
|
|
@ -1005,6 +952,20 @@ Ox.VideoEditor = function(options, self) {
|
|||
self.$player[0].playInToOut();
|
||||
}
|
||||
|
||||
function removeAnnotation(data) {
|
||||
Ox.print('REMOVE EVENT REACHED EDITOR', data)
|
||||
var layer = Ox.getObjectById(self.options.layers, data.layer),
|
||||
index = Ox.getIndexById(layer.items, data.id);
|
||||
updateWords('remove');
|
||||
layer.items.splice(index, 1);
|
||||
self.annotations = getAnnotations();
|
||||
self.positions = getPositions();
|
||||
self.editing = false;
|
||||
self.options.selected = '';
|
||||
setTimelineState();
|
||||
that.triggerEvent('removeannotation', data);
|
||||
}
|
||||
|
||||
function resizeAnnotations(data) {
|
||||
self.options.annotationsSize = data.size;
|
||||
setSizes();
|
||||
|
|
@ -1137,18 +1098,35 @@ Ox.VideoEditor = function(options, self) {
|
|||
: self.options.selected ? 'selected'
|
||||
: 'default'
|
||||
});
|
||||
//Ox.print('SET STATE', self.$timeline[1].options('state'))
|
||||
}
|
||||
|
||||
function sortAnnotations(a, b) {
|
||||
var ret = 0;
|
||||
if (a['in'] < b['in']) {
|
||||
ret = -1;
|
||||
} else if (a['in'] > b['in']) {
|
||||
ret = 1;
|
||||
} else if (a.out < b.out) {
|
||||
ret = -1;
|
||||
} else if (a.out > b.out) {
|
||||
ret = 1;
|
||||
} else if (a.value < b.value) {
|
||||
ret = -1;
|
||||
} else if (a.value > b.value) {
|
||||
ret = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function submitAnnotation(data) {
|
||||
self.annotations = getAnnotations();
|
||||
self.positions = getPositions();
|
||||
updateWords('add');
|
||||
self.editing = false;
|
||||
setTimelineState();
|
||||
Ox.print('....', self.options.annotationsRange == 'position',
|
||||
self.options.position < self.options['in'],
|
||||
self.options.position > self.options.out)
|
||||
if (
|
||||
self.options.annotationsRange == 'position' && (
|
||||
self.options.annotationsRange == 'position'
|
||||
&& (
|
||||
self.options.position < self.options['in']
|
||||
|| self.options.position > self.options.out
|
||||
)
|
||||
|
|
@ -1185,7 +1163,7 @@ Ox.VideoEditor = function(options, self) {
|
|||
if (hasPressedEnter) {
|
||||
that.triggerEvent('find', {find: self.options.find});
|
||||
if (self.results.length) {
|
||||
selectAnnotation(getNextResult(1));
|
||||
selectAnnotation(getNextAnnotation('result', 1));
|
||||
} else {
|
||||
self.$findInput.focusInput(true);
|
||||
}
|
||||
|
|
@ -1235,7 +1213,9 @@ Ox.VideoEditor = function(options, self) {
|
|||
} else {
|
||||
self.words[index].count++;
|
||||
}
|
||||
} else {
|
||||
} else if (index > -1) {
|
||||
// index is -1 when removing an annotation by editing
|
||||
// (which removes the words) and clearing its value
|
||||
if (self.words[index].count == 1) {
|
||||
self.words.splice(index, 1);
|
||||
} else {
|
||||
|
|
@ -1276,7 +1256,7 @@ Ox.VideoEditor = function(options, self) {
|
|||
|
||||
that.updateAnnotation = function(id, annotation) {
|
||||
// called from editannotation callback
|
||||
self.options.selected = annotation.id;
|
||||
self.options.selected = annotation.id; // fixme: needed?
|
||||
self.$annotationPanel.updateItem(id, annotation);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -692,6 +692,10 @@ Ox.VideoPlayer = function(options, self) {
|
|||
blur: function() {
|
||||
self.inputHasFocus = false;
|
||||
submitPositionInput();
|
||||
},
|
||||
submit: function() {
|
||||
self.inputHasFocus = false;
|
||||
submitPositionInput();
|
||||
}
|
||||
})
|
||||
.appendTo(self['$controls' + titleCase].$element);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue