implement 'view annotations at position / in selection / all'

This commit is contained in:
j 2012-01-03 00:36:36 +05:30
parent 0c6541363d
commit 39f9e9bb4d
6 changed files with 152 additions and 80 deletions

View file

@ -26,7 +26,7 @@ Ox.List <f:Ox.Element> List Element
selected <a|[]> ids of the selected elements selected <a|[]> ids of the selected elements
sort <a|[]> sort order sort <a|[]> sort order
sortable <b|false> If true, items can be re-ordered sortable <b|false> If true, items can be re-ordered
type <s|text> type <s|'text'>
unique <s|''> name of the key that acts as unique id unique <s|''> name of the key that acts as unique id
self <o> shared private variable self <o> shared private variable
add <!> item added add <!> item added
@ -442,8 +442,8 @@ Ox.List = function(options, self) {
if (self.listLength < visibleItems) { if (self.listLength < visibleItems) {
Ox.range(self.listLength, visibleItems).forEach(function(i) { Ox.range(self.listLength, visibleItems).forEach(function(i) {
var $item = Ox.ListItem({ var $item = Ox.ListItem({
construct: self.options.construct, construct: self.options.construct,
}); });
$item.addClass('OxEmpty').removeClass('OxTarget'); $item.addClass('OxEmpty').removeClass('OxTarget');
if (i == visibleItems - 1) { if (i == visibleItems - 1) {
$item.$element.css({ $item.$element.css({
@ -1507,7 +1507,7 @@ Ox.List = function(options, self) {
}); });
self.options.items.splice.apply(self.options.items, Ox.merge([pos, 0], items)); self.options.items.splice.apply(self.options.items, Ox.merge([pos, 0], items));
self.$items.splice.apply(self.$items, Ox.merge([pos, 0], $items)); self.$items.splice.apply(self.$items, Ox.merge([pos, 0], $items));
self.listLength += length; self.listLength = self.options.items.length;
//loadItems(); //loadItems();
updatePositions(); updatePositions();
} }
@ -1657,10 +1657,10 @@ Ox.List = function(options, self) {
self.selected[i] -= length; self.selected[i] -= length;
} }
}); });
self.listLength -= length; self.listLength = self.options.items.length;
updatePositions(); updatePositions();
} }
} }
/*@ /*@
scrollToSelection <f> scroll list to current selection scrollToSelection <f> scroll list to current selection
() -> <f> returns List Element () -> <f> returns List Element

View file

@ -118,7 +118,9 @@ Ox.Menu = function(options, self) {
function clickItem(position) { function clickItem(position) {
var item = that.items[position], var item = that.items[position],
group = item.options('group'),
menu = self.options.mainmenu || self.options.parent || that, menu = self.options.mainmenu || self.options.parent || that,
offset,
toggled; toggled;
that.hideMenu(); that.hideMenu();
if (!item.options('items').length) { if (!item.options('items').length) {
@ -126,19 +128,20 @@ Ox.Menu = function(options, self) {
self.options.parent.hideMenu(true).triggerEvent('click'); self.options.parent.hideMenu(true).triggerEvent('click');
} }
if (item.options('checked') !== null) { if (item.options('checked') !== null) {
if (item.options('group')) { if (group) {
toggled = self.optionGroups[item.options('group')].toggle(position); offset = self.optionGroupOffset[group];
toggled = self.optionGroup[group].toggle(position - offset);
if (toggled.length) { if (toggled.length) {
toggled.forEach(function(pos) { toggled.forEach(function(pos) {
that.items[pos].toggleChecked(); that.items[pos + offset].toggleChecked();
}); });
menu.triggerEvent('change', { menu.triggerEvent('change', {
id: item.options('group'), id: item.options('group'),
checked: self.optionGroups[item.options('group')].checked().map(function(v) { checked: self.optionGroup[group].checked().map(function(pos) {
return { return {
id: that.items[v].options('id'), id: that.items[pos + offset].options('id'),
title: Ox.isString(that.items[v].options('title')[0]) title: Ox.isString(that.items[pos + offset].options('title')[0])
? Ox.stripTags(that.items[v].options('title')[0]) : '' ? Ox.stripTags(that.items[pos + offset].options('title')[0]) : ''
}; };
}) })
}); });
@ -263,10 +266,13 @@ Ox.Menu = function(options, self) {
function renderItems(items) { function renderItems(items) {
var offset = 0;
that.$content.empty(); that.$content.empty();
scrollMenuUp(); scrollMenuUp();
self.optionGroups = {}; self.optionGroup = {};
self.optionGroupOffset = {};
items.forEach(function(item, i) { items.forEach(function(item, i) {
if (item.group) { if (item.group) {
items[i] = item.items.map(function(v) { items[i] = item.items.map(function(v) {
@ -274,13 +280,15 @@ Ox.Menu = function(options, self) {
group: item.group group: item.group
}); });
}); });
self.optionGroups[item.group] = new Ox.OptionGroup( self.optionGroup[item.group] = new Ox.OptionGroup(
items[i].filter(function(v) { items[i].filter(function(v) {
return 'id' in v; return 'id' in v;
}), }),
'min' in item ? item.min : 1, 'min' in item ? item.min : 1,
'max' in item ? item.max : 1 'max' in item ? item.max : 1
); );
self.optionGroupOffset[item.group] = i + offset;
offset += items[i].length - 1;
} }
}); });
items = Ox.flatten(items); items = Ox.flatten(items);
@ -581,17 +589,23 @@ Ox.Menu = function(options, self) {
@*/ @*/
that.checkItem = function(id) { that.checkItem = function(id) {
Ox.Log('Menu', 'checkItem id', id) Ox.Log('Menu', 'checkItem id', id)
var ids = id.split('_'), var group,
item; ids = id.split('_'),
item,
offset,
position,
toggled;
if (ids.length == 1) { if (ids.length == 1) {
item = that.getItem(id); item = that.getItem(id);
group = item.options('group');
Ox.Log('Menu', 'checkItem', id, item, that.submenus) Ox.Log('Menu', 'checkItem', id, item, that.submenus)
if (item.options('group')) { if (group) {
var position = getItemPositionById(id), offset = self.optionGroupOffset[group];
toggled = self.optionGroups[item.options('group')].toggle(position); position = getItemPositionById(id);
toggled = self.optionGroup[item.options('group')].toggle(position - offset);
if (toggled.length) { if (toggled.length) {
toggled.forEach(function(pos) { toggled.forEach(function(pos) {
that.items[pos].toggleChecked(); that.items[pos + offset].toggleChecked();
}); });
} }
} else { } else {

View file

@ -85,7 +85,7 @@ Ox.MenuButton = function(options, self) {
} }
function changeMenu(data) { function changeMenu(data) {
that.triggerEvent('click', data); that.triggerEvent('change', data);
} }
function hideMenu(data) { function hideMenu(data) {

View file

@ -8,6 +8,7 @@ Ox.AnnotationPanel <f:Ox.Element> AnnotationPanel Object
(options) -> <f> AnnotationPanel Object (options) -> <f> AnnotationPanel Object
(options, self) -> <f> AnnotationPanel Object (options, self) -> <f> AnnotationPanel Object
options <o> Options object options <o> Options object
editable <b|false> If true, annotations can be added
id <s> id id <s> id
items <a|[]> items items <a|[]> items
title <s> title title <s> title
@ -21,8 +22,10 @@ Ox.AnnotationPanel = function(options, self) {
self = self || {}; self = self || {};
var that = Ox.Element({}, self) var that = Ox.Element({}, self)
.defaults({ .defaults({
editable: false,
id: '', id: '',
items: [], items: [],
range: 'all',
title: '', title: '',
type: 'text', type: 'text',
width: 0 width: 0
@ -31,7 +34,8 @@ Ox.AnnotationPanel = function(options, self) {
self.selected = -1; self.selected = -1;
that.$element = Ox.CollapsePanel({ that.setElement(
Ox.CollapsePanel({
collapsed: false, collapsed: false,
extras: self.options.editable ? [ extras: self.options.editable ? [
Ox.Button({ Ox.Button({
@ -52,7 +56,8 @@ Ox.AnnotationPanel = function(options, self) {
.addClass('OxAnnotationPanel') .addClass('OxAnnotationPanel')
.bindEvent({ .bindEvent({
toggle: togglePanel toggle: togglePanel
}); })
);
that.$content = that.$element.$content; that.$content = that.$element.$content;
self.$annotations = Ox.List({ self.$annotations = Ox.List({
@ -78,8 +83,11 @@ Ox.AnnotationPanel = function(options, self) {
.append($('<div>').css({height: '4px'})); .append($('<div>').css({height: '4px'}));
return $item; return $item;
}, },
items: self.options.items, items: getAnnotations(),
max: 1, max: 1,
min: 0,
sort: [{key: 'in', operator: '+'}],
type: 'none', // fixme
unique: 'id' unique: 'id'
}) })
.bindEvent({ .bindEvent({
@ -116,6 +124,21 @@ Ox.AnnotationPanel = function(options, self) {
.appendTo(self.$annotations); .appendTo(self.$annotations);
}); });
*/ */
function getAnnotations() {
return self.options.items.filter(function(item) {
return self.options.range == 'all' || (
self.options.range == 'selection'
&& item['in'] < self.options.out
&& item.out > self.options['in']
) || (
self.options.range == 'position'
&& item['in'] <= self.options.position
&& item.out > self.options.position
);
});
}
function selectAnnotation(data) { function selectAnnotation(data) {
var item = Ox.getObjectById(self.options.items, data.ids[0]); var item = Ox.getObjectById(self.options.items, data.ids[0]);
item && that.triggerEvent('select', { item && that.triggerEvent('select', {
@ -124,6 +147,7 @@ Ox.AnnotationPanel = function(options, self) {
'layer': self.options.id 'layer': self.options.id
}); });
} }
function updateAnnotation(data) { function updateAnnotation(data) {
var item = Ox.getObjectById(self.options.items, data.id); var item = Ox.getObjectById(self.options.items, data.id);
item.value = data.value; item.value = data.value;
@ -134,6 +158,26 @@ Ox.AnnotationPanel = function(options, self) {
} }
self.setOption = function(key, value) {
if (key == 'in') {
self.options.range == 'selection' && self.$annotations.options({
items: getAnnotations()
});
} else if (key == 'out') {
self.options.range == 'selection' && self.$annotations.options({
items: getAnnotations()
});
} else if (key == 'position') {
self.options.range == 'position' && self.$annotations.options({
items: getAnnotations()
});
} else if (key == 'range') {
self.$annotations.options({
items: getAnnotations()
});
}
};
/*@ /*@
addItem <f> addItem addItem <f> addItem
@*/ @*/

View file

@ -18,6 +18,8 @@ Ox.VideoEditor = function(options, self) {
self = self || {}; self = self || {};
var that = Ox.Element({}, self) var that = Ox.Element({}, self)
.defaults({ .defaults({
annotationsFont: 'small',
annotationsRange: 'all',
annotationsSize: 0, annotationsSize: 0,
censored: [], censored: [],
cuts: [], cuts: [],
@ -214,10 +216,11 @@ Ox.VideoEditor = function(options, self) {
paused: function(data) { paused: function(data) {
that.triggerEvent('paused', data); that.triggerEvent('paused', data);
}, },
playing: changePlayer, playing: function(data) {
setPosition(data.position, true);
},
position: function(data) { position: function(data) {
changePlayer(data); setPosition(data.position);
that.triggerEvent('position', data);
}, },
resolution: function(data) { resolution: function(data) {
that.triggerEvent('resolution', data); that.triggerEvent('resolution', data);
@ -262,7 +265,9 @@ Ox.VideoEditor = function(options, self) {
top: self.sizes.timeline[0].top + 'px' top: self.sizes.timeline[0].top + 'px'
}) })
.bindEvent({ .bindEvent({
position: changeTimelineLarge position: function(data) {
setPosition(data.position);
}
}) })
.appendTo(self.$editor); .appendTo(self.$editor);
@ -287,7 +292,9 @@ Ox.VideoEditor = function(options, self) {
top: self.sizes.timeline[1].top + 'px', top: self.sizes.timeline[1].top + 'px',
}) })
.bindEvent({ .bindEvent({
position: changeTimelineSmall position: function(data) {
setPosition(data.position);
}
}) })
.appendTo(self.$editor); .appendTo(self.$editor);
@ -300,6 +307,11 @@ Ox.VideoEditor = function(options, self) {
self.options.layers.forEach(function(layer, i) { self.options.layers.forEach(function(layer, i) {
self.$annotationPanel[i] = Ox.AnnotationPanel( self.$annotationPanel[i] = Ox.AnnotationPanel(
Ox.extend({ Ox.extend({
font: self.options.annotationsFont,
'in': self.options['in'],
out: self.options.out,
position: self.options.position,
range: self.options.annotationsRange,
width: self.options.annotationsSize - Ox.UI.SCROLLBAR_SIZE width: self.options.annotationsSize - Ox.UI.SCROLLBAR_SIZE
}, layer) }, layer)
) )
@ -419,6 +431,7 @@ Ox.VideoEditor = function(options, self) {
{id: 'keyboard', title: 'Keyboard Shortcuts...', keyboard: 'h'} {id: 'keyboard', title: 'Keyboard Shortcuts...', keyboard: 'h'}
] ]
), ),
style: 'square',
title: 'set', title: 'set',
tooltip: 'Actions and Settings', tooltip: 'Actions and Settings',
type: 'image' type: 'image'
@ -621,22 +634,36 @@ Ox.VideoEditor = function(options, self) {
self.$annotationsMenuButton = Ox.MenuButton({ self.$annotationsMenuButton = Ox.MenuButton({
items: [ items: [
{id: 'annotations', title: 'Show Annotations', disabled: true}, {id: 'showannotations', title: 'Show Annotations', disabled: true},
{id: 'showAnnotationsAtPosition', title: 'At Current Position', checked: true}, {group: 'range', min: 1, max: 1, items: [
{id: 'showAnnotationsInSelection', title: 'In Current Selection'}, {id: 'position', title: 'At Current Position', checked: self.options.annotationsRange == 'position'},
{id: 'showAllAnnotations', title: 'All'}, {id: 'selection', title: 'In Current Selection', checked: self.options.annotationsRange == 'selection'},
{id: 'all', title: 'All', checked: self.options.annotationsRange == 'all'}
]},
{}, {},
{id: 'textSize', title: 'Font Size', disabled: true}, {id: 'fontsize', title: 'Font Size', disabled: true},
{id: 'smallText', title: 'Small', checked: true}, {group: 'font', min: 1, max: 1, items: [
{id: 'mediumText', title: 'Medium'}, {id: 'small', title: 'Small', checked: self.options.annotationsFont == 'small'},
{id: 'largeText', title: 'Large'} {id: 'medium', title: 'Medium', checked: self.options.annotationsFont == 'medium'},
{id: 'large', title: 'Large', checked: self.options.annotationsFont == 'large'}
]}
], ],
max: 2, style: 'square',
title: 'set', title: 'set',
tooltip: 'Actions and Settings', tooltip: 'Actions and Settings',
type: 'image' type: 'image'
}) })
.css({float: 'left'}) .css({float: 'left'})
.bindEvent({
change: function(data) {
var set = {};
set[data.id] = data.checked[0].id;
self.$annotationPanel.forEach(function($panel) {
$panel.options(set);
});
that.triggerEvent('annotations' + Ox.toTitleCase(data.id), set);
}
})
.appendTo(self.$annotationsbar); .appendTo(self.$annotationsbar);
that.$element = Ox.SplitPanel({ that.$element = Ox.SplitPanel({
@ -672,6 +699,7 @@ Ox.VideoEditor = function(options, self) {
}) })
.bindEvent({ .bindEvent({
resize: resizeAnnotations, resize: resizeAnnotations,
resizeend: resizeendAnnotations,
toggle: toggleAnnotations toggle: toggleAnnotations
}), }),
resizable: true, resizable: true,
@ -689,42 +717,6 @@ Ox.VideoEditor = function(options, self) {
submitFindInput(self.options.find, true); submitFindInput(self.options.find, true);
}, 0); }, 0);
function changePlayer(data) {
self.options.position = data.position;
self.$timeline[0].options({
position: data.position
});
self.$timeline[1].options({
position: data.position
});
}
function changeTimelineLarge(data) {
self.options.position = data.position;
self.$player[0].options({
position: data.position
});
self.$timeline[1].options({
position: data.position
});
that.triggerEvent('position', {
position: self.options.position
});
}
function changeTimelineSmall(data) {
self.options.position = data.position;
self.$player[0].options({
position: data.position
});
self.$timeline[0].options({
position: data.position
});
that.triggerEvent('position', {
position: self.options.position
});
}
function find(query) { function find(query) {
var results = []; var results = [];
if (query.length) { if (query.length) {
@ -888,6 +880,10 @@ Ox.VideoEditor = function(options, self) {
setSizes(); setSizes();
} }
function resizeendAnnotations(data) {
that.triggerEvent('annotationsSize', {size: data.size});
}
function resizeEditor(data) { function resizeEditor(data) {
var width = data.size - 2 * margin + 100; var width = data.size - 2 * margin + 100;
resizeVideoPlayers(width); resizeVideoPlayers(width);
@ -943,23 +939,34 @@ Ox.VideoEditor = function(options, self) {
if (self.options['in'] > self.options.out) { if (self.options['in'] > self.options.out) {
setPoint(point == 'in' ? 'out' : 'in', position); setPoint(point == 'in' ? 'out' : 'in', position);
} }
self.$annotationPanel.forEach(function($panel) {
$panel.options({
'in': self.options['in'],
out: self.options.out
});
});
that.triggerEvent('points', { that.triggerEvent('points', {
'in': self.options['in'], 'in': self.options['in'],
out: self.options.out out: self.options.out
}); });
} }
function setPosition(position) { function setPosition(position, playing) {
self.options.position = position; self.options.position = position;
self.$player[0].options({ !playing && self.$player[0].options({
position: self.options.position position: self.options.position
}); });
self.$timeline.forEach(function(v) { self.$timeline.forEach(function($timeline) {
v.options({ $timeline.options({
position: self.options.position position: self.options.position
}); });
}); });
that.triggerEvent('position', { self.$annotationPanel.forEach(function($panel) {
$panel.options({
position: self.options.position
});
});
!playing && that.triggerEvent('position', {
position: self.options.position position: self.options.position
}); });
} }

View file

@ -668,6 +668,13 @@ Video
================================================================================ ================================================================================
*/ */
.OxThemeClassic .OxAnnotation {
border-color: rgb(208, 208, 208);
}
.OxThemeClassic .OxAnnotation.OxSelected {
background: rgb(208, 208, 208);
}
.OxThemeClassic .OxSmallVideoTimeline .OxMarkerPlay { .OxThemeClassic .OxSmallVideoTimeline .OxMarkerPlay {
border-color: rgba(0, 0, 0, 0.5); border-color: rgba(0, 0, 0, 0.5);
} }