allow for grouped highlights in video annotations

This commit is contained in:
rolux 2018-10-09 18:29:13 +02:00
parent 56cbb3b90c
commit a5f7dd720a
5 changed files with 107 additions and 46 deletions

View file

@ -61,19 +61,19 @@ body.$themeClass:-webkit-full-screen {
.$themeClass .OxGrid { .$themeClass .OxGrid {
background-color: $gridGradient[0]; background-color: $gridGradient[0];
background-image: background-image:
-moz-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]), -moz-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]),
-moz-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]); -moz-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]);
background: background:
-ms-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]), -ms-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]),
-ms-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]); -ms-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]);
background-image: background-image:
-o-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]), -o-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]),
-o-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]); -o-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]);
background-image: background-image:
-webkit-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]), -webkit-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]),
-webkit-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]); -webkit-linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]);
background-image: background-image:
linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]), linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]),
linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]); linear-gradient(45deg, $gridGradient[1] 25%, transparent 25%, transparent 75%, $gridGradient[1] 75%, $gridGradient[1]);
} }
.$themeClass .OxReflection > div { .$themeClass .OxReflection > div {
@ -122,7 +122,7 @@ Bars
$progressbarBackground 25%, $progressbarBackground 50%, $progressbarBackground 25%, $progressbarBackground 50%,
transparent 50%, transparent 75%, transparent 50%, transparent 75%,
$progressbarBackground 75%, $progressbarBackground 100% $progressbarBackground 75%, $progressbarBackground 100%
), ),
-moz-linear-gradient(top, $buttonGradient); -moz-linear-gradient(top, $buttonGradient);
background: background:
-ms-repeating-linear-gradient( -ms-repeating-linear-gradient(
@ -130,7 +130,7 @@ Bars
$progressbarBackground 25%, $progressbarBackground 50%, $progressbarBackground 25%, $progressbarBackground 50%,
transparent 50%, transparent 75%, transparent 50%, transparent 75%,
$progressbarBackground 75%, $progressbarBackground 100% $progressbarBackground 75%, $progressbarBackground 100%
), ),
-ms-linear-gradient(top, $buttonGradient); -ms-linear-gradient(top, $buttonGradient);
background-image: background-image:
-o-repeating-linear-gradient( -o-repeating-linear-gradient(
@ -138,7 +138,7 @@ Bars
$progressbarBackground 25%, $progressbarBackground 50%, $progressbarBackground 25%, $progressbarBackground 50%,
transparent 50%, transparent 75%, transparent 50%, transparent 75%,
$progressbarBackground 75%, $progressbarBackground 100% $progressbarBackground 75%, $progressbarBackground 100%
), ),
-o-linear-gradient(top, $buttonGradient); -o-linear-gradient(top, $buttonGradient);
background-image: background-image:
-webkit-repeating-linear-gradient( -webkit-repeating-linear-gradient(
@ -146,7 +146,7 @@ Bars
$progressbarBackground 25%, $progressbarBackground 50%, $progressbarBackground 25%, $progressbarBackground 50%,
transparent 50%, transparent 75%, transparent 50%, transparent 75%,
$progressbarBackground 75%, $progressbarBackground 100% $progressbarBackground 75%, $progressbarBackground 100%
), ),
-webkit-linear-gradient(top, $buttonGradient); -webkit-linear-gradient(top, $buttonGradient);
background-image: background-image:
repeating-linear-gradient( repeating-linear-gradient(
@ -154,9 +154,9 @@ Bars
$progressbarBackground 25%, $progressbarBackground 50%, $progressbarBackground 25%, $progressbarBackground 50%,
transparent 50%, transparent 75%, transparent 50%, transparent 75%,
$progressbarBackground 75%, $progressbarBackground 100% $progressbarBackground 75%, $progressbarBackground 100%
), ),
linear-gradient(top, $buttonGradient); linear-gradient(top, $buttonGradient);
background-size: 32px 32px, 16px 16px; background-size: 32px 32px, 16px 16px;
} }
.$themeClass .OxProgressbar .OxProgress.OxAnimate { .$themeClass .OxProgressbar .OxProgress.OxAnimate {
background-image: background-image:
@ -422,7 +422,7 @@ Forms
background-image: -o-linear-gradient(top, $buttonDisabledGradient); background-image: -o-linear-gradient(top, $buttonDisabledGradient);
background-image: -webkit-linear-gradient(top, $buttonDisabledGradient); background-image: -webkit-linear-gradient(top, $buttonDisabledGradient);
background-image: linear-gradient(top, $buttonDisabledGradient); background-image: linear-gradient(top, $buttonDisabledGradient);
color: $buttonDisabledColor; color: $buttonDisabledColor;
} }
.$themeClass .OxButton.OxSymbol, .$themeClass .OxButton.OxSymbol,
@ -524,7 +524,7 @@ Forms
background-image: linear-gradient(top, $buttonDisabledGradient); background-image: linear-gradient(top, $buttonDisabledGradient);
} }
.$themeClass .OxFileInput.OxDisabled > .OxBar > div { .$themeClass .OxFileInput.OxDisabled > .OxBar > div {
color: $buttonDisabledColor color: $buttonDisabledColor
} }
.$themeClass .OxFormMessage { .$themeClass .OxFormMessage {
@ -1386,6 +1386,9 @@ Video
.$themeClass .OxAnnotationFolder .OxEditableElement.OxWarning .OxValue { .$themeClass .OxAnnotationFolder .OxEditableElement.OxWarning .OxValue {
border-bottom: 2px dotted $bodyWarningBorder; border-bottom: 2px dotted $bodyWarningBorder;
} }
.$themeClass .OxAnnotationFolder .OxArrayEditable .OxEditableElement.OxEditable.OxGroup {
background-color: $videoAnnotationSelectedBackground;
}
.$themeClass .OxAnnotationFolder .OxArrayEditable .OxEditableElement.OxEditable.OxSelected { .$themeClass .OxAnnotationFolder .OxArrayEditable .OxEditableElement.OxEditable.OxSelected {
background-color: $videoAnnotationEditableSelectedBackground; background-color: $videoAnnotationEditableSelectedBackground;
} }

View file

@ -30,6 +30,7 @@ Ox.ArrayEditable = function(options, self) {
getSortValue: null, getSortValue: null,
globalAttributes: [], globalAttributes: [],
highlight: '', highlight: '',
highlightGroup: false,
itemName: 'item', itemName: 'item',
items: [], items: [],
maxHeight: void 0, maxHeight: void 0,
@ -160,6 +161,9 @@ Ox.ArrayEditable = function(options, self) {
.appendTo(that)]; .appendTo(that)];
} else { } else {
sortItems(); sortItems();
if (self.options.highlightGroup) {
var selectedItem = Ox.getObjectById(self.options.items, self.options.selected) || {};
}
self.$items = self.options.items.map(function appendItem(item, i) { self.$items = self.options.items.map(function appendItem(item, i) {
if (i && self.options.type == 'input') { if (i && self.options.type == 'input') {
$('<span>') $('<span>')
@ -192,6 +196,7 @@ Ox.ArrayEditable = function(options, self) {
width: self.options.type == 'input' ? 0 : self.options.width - 9 width: self.options.type == 'input' ? 0 : self.options.width - 9
}) })
.addClass(item.id == self.options.selected ? 'OxSelected' : '') .addClass(item.id == self.options.selected ? 'OxSelected' : '')
.addClass(self.options.highlightGroup && item.group == selectedItem.group ? 'OxGroup' : '')
.data({id: item.id, position: i}) .data({id: item.id, position: i})
.bindEvent({ .bindEvent({
blur: function(data) { blur: function(data) {
@ -265,7 +270,11 @@ Ox.ArrayEditable = function(options, self) {
that.blurItem(); that.blurItem();
} }
that.find('.OxSelected').removeClass('OxSelected'); that.find('.OxSelected').removeClass('OxSelected');
self.selected > -1 && self.$items[self.selected].addClass('OxSelected'); that.find('.OxGroup').removeClass('OxGroup')
if (self.selected > -1) {
self.$items[self.selected].addClass('OxSelected');
self.options.highlightGroup && that.updateItemGroup()
}
triggerSelectEvent(); triggerSelectEvent();
} }
@ -473,6 +482,15 @@ Ox.ArrayEditable = function(options, self) {
} }
}; };
that.updateItemGroup = function() {
var group = self.options.items[self.selected].group;
self.$items.forEach(function($item, index) {
$item[
self.options.items[index].group == group ? 'addClass' : 'removeClass'
]('OxGroup');
})
}
return that; return that;
}; };

View file

@ -38,6 +38,7 @@ Ox.AnnotationFolder = function(options, self) {
collapsed: false, collapsed: false,
editable: false, editable: false,
highlight: '', highlight: '',
highlightAnnotations: false,
id: '', id: '',
'in': 0, 'in': 0,
item: '', item: '',
@ -64,6 +65,10 @@ Ox.AnnotationFolder = function(options, self) {
if (key == 'highlight') { if (key == 'highlight') {
self.$annotations.options({highlight: value}); self.$annotations.options({highlight: value});
} }
if (key == 'highlightAnnotations') {
self.$annotations.options({highlightGroup: value});
updateAnnotations();
}
if (['in', 'out'].indexOf(key) > -1 && self.editing) { if (['in', 'out'].indexOf(key) > -1 && self.editing) {
var item = Ox.getObjectById(self.options.items, self.options.selected); var item = Ox.getObjectById(self.options.items, self.options.selected);
item[key] = value; item[key] = value;
@ -282,6 +287,7 @@ Ox.AnnotationFolder = function(options, self) {
: null, : null,
globalAttributes: ['data', 'lang'], globalAttributes: ['data', 'lang'],
highlight: self.options.translate ? Ox._(self.options.highlight) : self.options.highlight, highlight: self.options.translate ? Ox._(self.options.highlight) : self.options.highlight,
highlightGroup: self.options.highlightAnnotations,
placeholder: Ox._('Loading...'), placeholder: Ox._('Loading...'),
separator: self.options.separator, separator: self.options.separator,
sort: self.sort, sort: self.sort,
@ -400,7 +406,6 @@ Ox.AnnotationFolder = function(options, self) {
}); });
}); });
showWarnings(); showWarnings();
function changeAnnotation(data) { function changeAnnotation(data) {
@ -472,6 +477,10 @@ Ox.AnnotationFolder = function(options, self) {
|| self.options.users.indexOf(item.user) > -1 || self.options.users.indexOf(item.user) > -1
) )
); );
}).map(function(item) {
return Ox.extend(item, {
group: item['in'] + '-' + item.out
});
}); });
return annotations; return annotations;
} }
@ -658,7 +667,9 @@ Ox.AnnotationFolder = function(options, self) {
self.options.items.splice(pos, 0, item); self.options.items.splice(pos, 0, item);
self.$panel.options({collapsed: false}); self.$panel.options({collapsed: false});
self.$annotations self.$annotations
.addItem(pos, item) .addItem(pos, Ox.extend(item, {
group: item['in'] + '-' + item.out
}))
.options({selected: item.id}) .options({selected: item.id})
.editItem(); .editItem();
showWarnings(); showWarnings();
@ -735,6 +746,10 @@ Ox.AnnotationFolder = function(options, self) {
Ox.forEach(data, function(value, key) { Ox.forEach(data, function(value, key) {
item[key] = value; item[key] = value;
}); });
item.group = item['in'] + '-' + item.out;
if (self.options.highlightAnnotations) {
self.$annotations.updateItemGroup();
}
if (id != item.id) { if (id != item.id) {
self.$annotations.find('.OxEditableElement').each(function() { self.$annotations.find('.OxEditableElement').each(function() {
var $element = $(this); var $element = $(this);

View file

@ -5,21 +5,22 @@
/*@ /*@
Ox.AnnotationPanel <f> Video Annotation Panel Ox.AnnotationPanel <f> Video Annotation Panel
options <o> Options object options <o> Options object
calendarSize <n|256> calendar size calendarSize <n|256> calendar size
clickLink <f|null> click link callback clickLink <f|null> click link callback
editable <b|false> if true, annotations can be edited editable <b|false> if true, annotations can be edited
highlight <s|''> highlight given string in annotations highlight <s|''> highlight given string in annotations
highlightLayer <s|'*'> limit highlight to specific layer highlightAnnotations <b|false> highlight annotations that match selection
layers <a|[]> array with annotation objects highlightLayer <s|'*'> l limit highlight to specific layer
mapSize <n|256> map size layers <a|[]> array with annotation objects
range <s|'all'> all, position, selection mapSize <n|256> map size
selected <s|''> selected annotation range <s|'all'> all, position, selection
showCalendar <b|false> if true, calendar is shown selected <s|''> selected annotation
showLayers <o|{}> object with layers to show showCalendar <b|false> if true, calendar is shown
showMap <b|false> if true, show map showLayers <o|{}> object with layers to show
showUsers <b|false> if true show user showMap <b|false> if true, show map
sort <s|'position'> position, start, text showUsers <b|false> if true show user
width <n|256> panel width sort <s|'position'> position, start, text
width <n|256> panel width
self <o> Shared private variable self <o> Shared private variable
([options[, self]]) -> <o:Ox.SplitPanel> AnnotationPanel Object ([options[, self]]) -> <o:Ox.SplitPanel> AnnotationPanel Object
add <!> add add <!> add
@ -51,6 +52,7 @@ Ox.AnnotationPanel = function(options, self) {
enableExport: false, enableExport: false,
enableImport: false, enableImport: false,
highlight: '', highlight: '',
highlightAnnotations: false,
highlightLayer: '*', highlightLayer: '*',
itemName: {singular: 'video', plural: 'videos'}, itemName: {singular: 'video', plural: 'videos'},
layers: [], layers: [],
@ -73,6 +75,12 @@ Ox.AnnotationPanel = function(options, self) {
highlight: getHighlight($folder.options('id')) highlight: getHighlight($folder.options('id'))
}); });
}); });
} else if (key == 'highlightAnnotations') {
self.$folder.forEach(function($folder) {
$folder.options({
highlightAnnotations: self.options.highlightAnnotations
});
});
} else if (['in', 'out', 'position'].indexOf(key) > -1) { } else if (['in', 'out', 'position'].indexOf(key) > -1) {
self.$folder.forEach(function($folder) { self.$folder.forEach(function($folder) {
$folder.options(key, value); $folder.options(key, value);
@ -365,6 +373,7 @@ Ox.AnnotationPanel = function(options, self) {
collapsed: !self.options.showLayers[layer.id], collapsed: !self.options.showLayers[layer.id],
editable: self.options.editable, editable: self.options.editable,
highlight: getHighlight(layer.id), highlight: getHighlight(layer.id),
highlightAnnotations: self.options.highlightAnnotations,
id: layer.id, id: layer.id,
'in': self.options['in'], 'in': self.options['in'],
keyboard: index < 9 ? index + 1 + '' : '', keyboard: index < 9 ? index + 1 + '' : '',
@ -481,20 +490,7 @@ Ox.AnnotationPanel = function(options, self) {
{id: 'duration', title: Ox._('By Duration'), checked: self.options.sort == 'duration'}, {id: 'duration', title: Ox._('By Duration'), checked: self.options.sort == 'duration'},
{id: 'text', title: Ox._('By Text'), checked: self.options.sort == 'text'}, {id: 'text', title: Ox._('By Text'), checked: self.options.sort == 'text'},
{id: 'created', title: Ox._('By Creation Time'), checked: self.options.sort == 'created'} {id: 'created', title: Ox._('By Creation Time'), checked: self.options.sort == 'created'}
]} ]},
],
self.languages.length > 1 ? [
{},
{id: 'languages', title: Ox._('Show Languages'), disabled: true},
{group: 'languages', min: 1, max: -1, items: self.languages.map(function(language) {
return {
id: language.code,
title: Ox._(language.name),
checked: Ox.contains(self.enabledLanguages, language.code)
};
})}
] : [],
[
{}, {},
{id: 'results', title: Ox._('Find Annotations'), disabled: true}, {id: 'results', title: Ox._('Find Annotations'), disabled: true},
{group: 'results', max: 1, items: [ {group: 'results', max: 1, items: [
@ -511,6 +507,25 @@ Ox.AnnotationPanel = function(options, self) {
}; };
}))} }))}
], ],
self.options.editable ? [
{},
{id: 'highlightannotations', title: Ox._('Highlight Annotations'), disabled: true},
{group: 'highlight', max: 1, items: [
{id: 'none', title: Ox._('None'), checked: !self.options.highlightAnnotations},
{id: 'selection', title: Ox._('Matching Current Selection'), checked: self.options.highlightAnnotations}
]}
] : [],
self.languages.length > 1 ? [
{},
{id: 'languages', title: Ox._('Show Languages'), disabled: true},
{group: 'languages', min: 1, max: -1, items: self.languages.map(function(language) {
return {
id: language.code,
title: Ox._(language.name),
checked: Ox.contains(self.enabledLanguages, language.code)
};
})}
] : [],
self.options.showUsers && self.users.length ? [ self.options.showUsers && self.users.length ? [
{}, {},
{id: 'users', title: Ox._('Show Users'), disabled: true}, {id: 'users', title: Ox._('Show Users'), disabled: true},
@ -553,8 +568,12 @@ Ox.AnnotationPanel = function(options, self) {
}); });
} else if (data.id == 'results') { } else if (data.id == 'results') {
var layer = data.checked[0].id.split('_').pop() var layer = data.checked[0].id.split('_').pop()
that.options('highlightLayer', layer); that.options({highlightLayer: layer});
that.triggerEvent('highlightlayer', self.options.highlightLayer); that.triggerEvent('highlightlayer', self.options.highlightLayer);
} else if (data.id == 'highlight') {
var value = data.checked[0].id == 'selection'
that.options({highlightAnnotations: value});
that.triggerEvent('highlightannotations', self.options.highlightAnnotations);
} else { } else {
self.options[data.id] = data.checked[0].id; self.options[data.id] = data.checked[0].id;
set[data.id] = self.options[data.id]; set[data.id] = self.options[data.id];

View file

@ -49,6 +49,7 @@ Ox.VideoAnnotationPanel = function(options, self) {
var that = Ox.Element({}, self) var that = Ox.Element({}, self)
.defaults({ .defaults({
annotationsCalendarSize: 256, annotationsCalendarSize: 256,
annotationsHighlight: false,
annotationsMapSize: 256, annotationsMapSize: 256,
annotationsRange: 'all', annotationsRange: 'all',
annotationsSeparator: ';', annotationsSeparator: ';',
@ -841,6 +842,7 @@ Ox.VideoAnnotationPanel = function(options, self) {
enableExport: self.options.enableExport, enableExport: self.options.enableExport,
enableImport: self.options.enableImport, enableImport: self.options.enableImport,
highlight: self.options.find, highlight: self.options.find,
highlightAnnotations: self.options.annotationsHighlight,
highlightLayer: self.options.findLayer, highlightLayer: self.options.findLayer,
'in': self.options['in'], 'in': self.options['in'],
itemName: self.options.itemName, itemName: self.options.itemName,
@ -906,6 +908,10 @@ Ox.VideoAnnotationPanel = function(options, self) {
that.triggerEvent('findannotations', data); that.triggerEvent('findannotations', data);
}, },
focus: that.gainFocus, focus: that.gainFocus,
highlightannotations: function(data) {
self.options.annotationsHighlight = data;
that.triggerEvent('annotationshighlight', data);
},
highlightlayer: function(data) { highlightlayer: function(data) {
self.options.findLayer = data; self.options.findLayer = data;
submitFindInput(self.$findInput.value(), false); submitFindInput(self.$findInput.value(), false);