From a5f7dd720ab369acab3ca37c226118b57374f97a Mon Sep 17 00:00:00 2001 From: rolux Date: Tue, 9 Oct 2018 18:29:13 +0200 Subject: [PATCH] allow for grouped highlights in video annotations --- source/UI/css/theme.css | 29 ++++---- source/UI/js/Form/ArrayEditable.js | 20 +++++- source/UI/js/Video/AnnotationFolder.js | 19 +++++- source/UI/js/Video/AnnotationPanel.js | 79 ++++++++++++++-------- source/UI/js/Video/VideoAnnotationPanel.js | 6 ++ 5 files changed, 107 insertions(+), 46 deletions(-) diff --git a/source/UI/css/theme.css b/source/UI/css/theme.css index 1536b780..91427838 100644 --- a/source/UI/css/theme.css +++ b/source/UI/css/theme.css @@ -61,19 +61,19 @@ body.$themeClass:-webkit-full-screen { .$themeClass .OxGrid { background-color: $gridGradient[0]; 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]); 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]); 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]); 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]); 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]); } .$themeClass .OxReflection > div { @@ -122,7 +122,7 @@ Bars $progressbarBackground 25%, $progressbarBackground 50%, transparent 50%, transparent 75%, $progressbarBackground 75%, $progressbarBackground 100% - ), + ), -moz-linear-gradient(top, $buttonGradient); background: -ms-repeating-linear-gradient( @@ -130,7 +130,7 @@ Bars $progressbarBackground 25%, $progressbarBackground 50%, transparent 50%, transparent 75%, $progressbarBackground 75%, $progressbarBackground 100% - ), + ), -ms-linear-gradient(top, $buttonGradient); background-image: -o-repeating-linear-gradient( @@ -138,7 +138,7 @@ Bars $progressbarBackground 25%, $progressbarBackground 50%, transparent 50%, transparent 75%, $progressbarBackground 75%, $progressbarBackground 100% - ), + ), -o-linear-gradient(top, $buttonGradient); background-image: -webkit-repeating-linear-gradient( @@ -146,7 +146,7 @@ Bars $progressbarBackground 25%, $progressbarBackground 50%, transparent 50%, transparent 75%, $progressbarBackground 75%, $progressbarBackground 100% - ), + ), -webkit-linear-gradient(top, $buttonGradient); background-image: repeating-linear-gradient( @@ -154,9 +154,9 @@ Bars $progressbarBackground 25%, $progressbarBackground 50%, transparent 50%, transparent 75%, $progressbarBackground 75%, $progressbarBackground 100% - ), + ), linear-gradient(top, $buttonGradient); - background-size: 32px 32px, 16px 16px; + background-size: 32px 32px, 16px 16px; } .$themeClass .OxProgressbar .OxProgress.OxAnimate { background-image: @@ -422,7 +422,7 @@ Forms background-image: -o-linear-gradient(top, $buttonDisabledGradient); background-image: -webkit-linear-gradient(top, $buttonDisabledGradient); background-image: linear-gradient(top, $buttonDisabledGradient); - color: $buttonDisabledColor; + color: $buttonDisabledColor; } .$themeClass .OxButton.OxSymbol, @@ -524,7 +524,7 @@ Forms background-image: linear-gradient(top, $buttonDisabledGradient); } .$themeClass .OxFileInput.OxDisabled > .OxBar > div { - color: $buttonDisabledColor + color: $buttonDisabledColor } .$themeClass .OxFormMessage { @@ -1386,6 +1386,9 @@ Video .$themeClass .OxAnnotationFolder .OxEditableElement.OxWarning .OxValue { border-bottom: 2px dotted $bodyWarningBorder; } +.$themeClass .OxAnnotationFolder .OxArrayEditable .OxEditableElement.OxEditable.OxGroup { + background-color: $videoAnnotationSelectedBackground; +} .$themeClass .OxAnnotationFolder .OxArrayEditable .OxEditableElement.OxEditable.OxSelected { background-color: $videoAnnotationEditableSelectedBackground; } diff --git a/source/UI/js/Form/ArrayEditable.js b/source/UI/js/Form/ArrayEditable.js index c7be65be..d6157c6e 100644 --- a/source/UI/js/Form/ArrayEditable.js +++ b/source/UI/js/Form/ArrayEditable.js @@ -30,6 +30,7 @@ Ox.ArrayEditable = function(options, self) { getSortValue: null, globalAttributes: [], highlight: '', + highlightGroup: false, itemName: 'item', items: [], maxHeight: void 0, @@ -160,6 +161,9 @@ Ox.ArrayEditable = function(options, self) { .appendTo(that)]; } else { 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) { if (i && self.options.type == 'input') { $('') @@ -192,6 +196,7 @@ Ox.ArrayEditable = function(options, self) { width: self.options.type == 'input' ? 0 : self.options.width - 9 }) .addClass(item.id == self.options.selected ? 'OxSelected' : '') + .addClass(self.options.highlightGroup && item.group == selectedItem.group ? 'OxGroup' : '') .data({id: item.id, position: i}) .bindEvent({ blur: function(data) { @@ -265,7 +270,11 @@ Ox.ArrayEditable = function(options, self) { that.blurItem(); } 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(); } @@ -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; }; diff --git a/source/UI/js/Video/AnnotationFolder.js b/source/UI/js/Video/AnnotationFolder.js index b889c46f..c313b217 100644 --- a/source/UI/js/Video/AnnotationFolder.js +++ b/source/UI/js/Video/AnnotationFolder.js @@ -38,6 +38,7 @@ Ox.AnnotationFolder = function(options, self) { collapsed: false, editable: false, highlight: '', + highlightAnnotations: false, id: '', 'in': 0, item: '', @@ -64,6 +65,10 @@ Ox.AnnotationFolder = function(options, self) { if (key == 'highlight') { self.$annotations.options({highlight: value}); } + if (key == 'highlightAnnotations') { + self.$annotations.options({highlightGroup: value}); + updateAnnotations(); + } if (['in', 'out'].indexOf(key) > -1 && self.editing) { var item = Ox.getObjectById(self.options.items, self.options.selected); item[key] = value; @@ -282,6 +287,7 @@ Ox.AnnotationFolder = function(options, self) { : null, globalAttributes: ['data', 'lang'], highlight: self.options.translate ? Ox._(self.options.highlight) : self.options.highlight, + highlightGroup: self.options.highlightAnnotations, placeholder: Ox._('Loading...'), separator: self.options.separator, sort: self.sort, @@ -400,7 +406,6 @@ Ox.AnnotationFolder = function(options, self) { }); }); - showWarnings(); function changeAnnotation(data) { @@ -472,6 +477,10 @@ Ox.AnnotationFolder = function(options, self) { || self.options.users.indexOf(item.user) > -1 ) ); + }).map(function(item) { + return Ox.extend(item, { + group: item['in'] + '-' + item.out + }); }); return annotations; } @@ -658,7 +667,9 @@ Ox.AnnotationFolder = function(options, self) { self.options.items.splice(pos, 0, item); self.$panel.options({collapsed: false}); self.$annotations - .addItem(pos, item) + .addItem(pos, Ox.extend(item, { + group: item['in'] + '-' + item.out + })) .options({selected: item.id}) .editItem(); showWarnings(); @@ -735,6 +746,10 @@ Ox.AnnotationFolder = function(options, self) { Ox.forEach(data, function(value, key) { item[key] = value; }); + item.group = item['in'] + '-' + item.out; + if (self.options.highlightAnnotations) { + self.$annotations.updateItemGroup(); + } if (id != item.id) { self.$annotations.find('.OxEditableElement').each(function() { var $element = $(this); diff --git a/source/UI/js/Video/AnnotationPanel.js b/source/UI/js/Video/AnnotationPanel.js index 84d478cc..7b5eedcb 100644 --- a/source/UI/js/Video/AnnotationPanel.js +++ b/source/UI/js/Video/AnnotationPanel.js @@ -5,21 +5,22 @@ /*@ Ox.AnnotationPanel Video Annotation Panel options Options object - calendarSize calendar size - clickLink click link callback - editable if true, annotations can be edited - highlight highlight given string in annotations - highlightLayer limit highlight to specific layer - layers array with annotation objects - mapSize map size - range all, position, selection - selected selected annotation - showCalendar if true, calendar is shown - showLayers object with layers to show - showMap if true, show map - showUsers if true show user - sort position, start, text - width panel width + calendarSize calendar size + clickLink click link callback + editable if true, annotations can be edited + highlight highlight given string in annotations + highlightAnnotations highlight annotations that match selection + highlightLayer l limit highlight to specific layer + layers array with annotation objects + mapSize map size + range all, position, selection + selected selected annotation + showCalendar if true, calendar is shown + showLayers object with layers to show + showMap if true, show map + showUsers if true show user + sort position, start, text + width panel width self Shared private variable ([options[, self]]) -> AnnotationPanel Object add add @@ -51,6 +52,7 @@ Ox.AnnotationPanel = function(options, self) { enableExport: false, enableImport: false, highlight: '', + highlightAnnotations: false, highlightLayer: '*', itemName: {singular: 'video', plural: 'videos'}, layers: [], @@ -73,6 +75,12 @@ Ox.AnnotationPanel = function(options, self) { 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) { self.$folder.forEach(function($folder) { $folder.options(key, value); @@ -365,6 +373,7 @@ Ox.AnnotationPanel = function(options, self) { collapsed: !self.options.showLayers[layer.id], editable: self.options.editable, highlight: getHighlight(layer.id), + highlightAnnotations: self.options.highlightAnnotations, id: layer.id, 'in': self.options['in'], 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: 'text', title: Ox._('By Text'), checked: self.options.sort == 'text'}, {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}, {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 ? [ {}, {id: 'users', title: Ox._('Show Users'), disabled: true}, @@ -553,8 +568,12 @@ Ox.AnnotationPanel = function(options, self) { }); } else if (data.id == 'results') { var layer = data.checked[0].id.split('_').pop() - that.options('highlightLayer', layer); + that.options({highlightLayer: layer}); 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 { self.options[data.id] = data.checked[0].id; set[data.id] = self.options[data.id]; diff --git a/source/UI/js/Video/VideoAnnotationPanel.js b/source/UI/js/Video/VideoAnnotationPanel.js index 4c93c621..0f46a9f8 100644 --- a/source/UI/js/Video/VideoAnnotationPanel.js +++ b/source/UI/js/Video/VideoAnnotationPanel.js @@ -49,6 +49,7 @@ Ox.VideoAnnotationPanel = function(options, self) { var that = Ox.Element({}, self) .defaults({ annotationsCalendarSize: 256, + annotationsHighlight: false, annotationsMapSize: 256, annotationsRange: 'all', annotationsSeparator: ';', @@ -841,6 +842,7 @@ Ox.VideoAnnotationPanel = function(options, self) { enableExport: self.options.enableExport, enableImport: self.options.enableImport, highlight: self.options.find, + highlightAnnotations: self.options.annotationsHighlight, highlightLayer: self.options.findLayer, 'in': self.options['in'], itemName: self.options.itemName, @@ -906,6 +908,10 @@ Ox.VideoAnnotationPanel = function(options, self) { that.triggerEvent('findannotations', data); }, focus: that.gainFocus, + highlightannotations: function(data) { + self.options.annotationsHighlight = data; + that.triggerEvent('annotationshighlight', data); + }, highlightlayer: function(data) { self.options.findLayer = data; submitFindInput(self.$findInput.value(), false);