Skip to content

Commit ad642b1

Browse files
Allow toggling layout areas from player controls
1 parent e06d942 commit ad642b1

5 files changed

Lines changed: 346 additions & 14 deletions

File tree

src/_shared/modules/Localization/locale/de.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ window.FrameTrail_L10n['de'] = {
124124
"GenericJumpBackward": "Springe zurück",
125125
"GenericJumpForward": "Springe vorwärts",
126126
"GenericLanguage": "Sprache",
127+
"GenericLayoutAreas": "Layoutbereiche",
127128
"GenericLastChanged": "Zuletzt geändert",
128129
"GenericName": "Name",
129130
"GenericNoDiscard": "Verwerfen",

src/_shared/modules/Localization/locale/en.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ window.FrameTrail_L10n['en'] = {
124124
"GenericJumpBackward": "Jump backward",
125125
"GenericJumpForward": "Jump forward",
126126
"GenericLanguage": "Language",
127+
"GenericLayoutAreas": "Layout Areas",
127128
"GenericLastChanged": "Last changed",
128129
"GenericName": "Title",
129130
"GenericNoDiscard": "Discard",

src/_shared/modules/Localization/locale/fr.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ window.FrameTrail_L10n['fr'] = {
124124
"GenericJumpBackward": "Reculer",
125125
"GenericJumpForward": "Avancer",
126126
"GenericLanguage": "Langue",
127+
"GenericLayoutAreas": "Zones de mise en page",
127128
"GenericLastChanged": "Dernière modification",
128129
"GenericName": "Titre",
129130
"GenericNoDiscard": "Ignorer",

src/player/modules/ViewVideo/module.js

Lines changed: 154 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ FrameTrail.defineModule('ViewVideo', function(FrameTrail){
9393
+ ' <div class="annotationSearchContainer contextButtonContainer">'
9494
+ ' </div>'
9595
+ ' </div>'
96+
+ ' <div class="layoutAreasButton playerControl">'
97+
+ ' <span class="icon-th-large-1"></span>'
98+
+ ' <div class="layoutAreasPanel"></div>'
99+
+ ' </div>'
96100
+ ' <div class="captionsButton playerControl">'
97101
+ ' <span class="icon-captions-off"></span>'
98102
+ ' <div class="captionSelectContainer">'
@@ -339,23 +343,161 @@ FrameTrail.defineModule('ViewVideo', function(FrameTrail){
339343
}
340344
}
341345

342-
Controls.querySelector('.captionsButton').addEventListener('click', function() {
346+
var layoutAreasButton = Controls.querySelector('.layoutAreasButton');
347+
var layoutAreasPanel = layoutAreasButton.querySelector('.layoutAreasPanel');
348+
layoutAreasButton.style.display = 'none';
349+
350+
layoutAreasButton.addEventListener('click', function(evt) {
351+
evt.stopPropagation();
352+
353+
Controls.querySelectorAll('.rightControlPanel .active:not([data-config]):not(.layoutAreasButton):not(.layoutAreasPanel)').forEach(function(el) { el.classList.remove('active'); });
354+
closeCaptionPanel();
355+
356+
if (!layoutAreasPanel.classList.contains('active')) {
357+
updateLayoutAreasPanel();
358+
layoutAreasPanel.classList.add('active');
359+
addOutsideClickHandler();
360+
} else {
361+
layoutAreasPanel.classList.remove('active');
362+
}
363+
364+
});
365+
366+
layoutAreasPanel.addEventListener('click', function(evt) {
367+
evt.stopPropagation();
368+
});
369+
370+
function updateLayoutAreasPanel() {
371+
layoutAreasPanel.innerHTML = '';
372+
373+
var schematic = document.createElement('div');
374+
schematic.className = 'layoutAreasSchematic';
375+
376+
var hasTop = FrameTrail.getState('hv_config_areaTopVisible');
377+
var hasBottom = FrameTrail.getState('hv_config_areaBottomVisible');
378+
var hasLeft = FrameTrail.getState('hv_config_areaLeftVisible');
379+
var hasRight = FrameTrail.getState('hv_config_areaRightVisible');
380+
381+
if (hasTop) {
382+
var topEl = document.createElement('div');
383+
topEl.className = 'schematicArea schematicAreaTop';
384+
topEl.setAttribute('data-size', AreaTopContainer.getAttribute('data-size') || 'small');
385+
if (!AreaTopContainer.classList.contains('closed')) topEl.classList.add('active');
386+
topEl.addEventListener('click', function() {
387+
AreaTopContainer.classList.toggle('closed');
388+
this.classList.toggle('active');
389+
FrameTrail.changeState('slidePosition', 'middle');
390+
window.setTimeout(function() { adjustHypervideo(); }, 250);
391+
});
392+
schematic.appendChild(topEl);
393+
}
394+
395+
var middleRow = document.createElement('div');
396+
middleRow.className = 'schematicMiddleRow';
397+
398+
if (hasLeft) {
399+
var leftEl = document.createElement('div');
400+
leftEl.className = 'schematicArea schematicAreaLeft';
401+
leftEl.setAttribute('data-size', AreaLeftContainer.getAttribute('data-size') || 'small');
402+
if (!AreaLeftContainer.classList.contains('closed')) leftEl.classList.add('active');
403+
leftEl.addEventListener('click', function() {
404+
AreaLeftContainer.classList.toggle('closed');
405+
this.classList.toggle('active');
406+
FrameTrail.changeState('slidePosition', 'middle');
407+
window.setTimeout(function() { adjustHypervideo(); }, 250);
408+
});
409+
middleRow.appendChild(leftEl);
410+
}
411+
412+
var centerEl = document.createElement('div');
413+
centerEl.className = 'schematicCenter';
414+
centerEl.innerHTML = '<span class="icon-play-1"></span>';
415+
middleRow.appendChild(centerEl);
416+
417+
if (hasRight) {
418+
var rightEl = document.createElement('div');
419+
rightEl.className = 'schematicArea schematicAreaRight';
420+
rightEl.setAttribute('data-size', AreaRightContainer.getAttribute('data-size') || 'small');
421+
if (!AreaRightContainer.classList.contains('closed')) rightEl.classList.add('active');
422+
rightEl.addEventListener('click', function() {
423+
AreaRightContainer.classList.toggle('closed');
424+
this.classList.toggle('active');
425+
FrameTrail.changeState('slidePosition', 'middle');
426+
window.setTimeout(function() { adjustHypervideo(); }, 250);
427+
});
428+
middleRow.appendChild(rightEl);
429+
}
430+
431+
schematic.appendChild(middleRow);
432+
433+
if (hasBottom) {
434+
var bottomEl = document.createElement('div');
435+
bottomEl.className = 'schematicArea schematicAreaBottom';
436+
bottomEl.setAttribute('data-size', AreaBottomContainer.getAttribute('data-size') || 'small');
437+
if (!AreaBottomContainer.classList.contains('closed')) bottomEl.classList.add('active');
438+
bottomEl.addEventListener('click', function() {
439+
AreaBottomContainer.classList.toggle('closed');
440+
this.classList.toggle('active');
441+
FrameTrail.changeState('slidePosition', 'middle');
442+
window.setTimeout(function() { adjustHypervideo(); }, 250);
443+
});
444+
schematic.appendChild(bottomEl);
445+
}
446+
447+
layoutAreasPanel.appendChild(schematic);
448+
}
449+
450+
function updateLayoutAreasButtonVisibility() {
451+
var hasAny = FrameTrail.getState('hv_config_areaTopVisible')
452+
|| FrameTrail.getState('hv_config_areaBottomVisible')
453+
|| FrameTrail.getState('hv_config_areaLeftVisible')
454+
|| FrameTrail.getState('hv_config_areaRightVisible');
455+
layoutAreasButton.style.display = hasAny ? '' : 'none';
456+
}
457+
458+
var captionsButton = Controls.querySelector('.captionsButton');
459+
var captionContainer = captionsButton.querySelector('.captionSelectContainer');
460+
461+
captionsButton.addEventListener('click', function(evt) {
462+
evt.stopPropagation();
343463

344464
Controls.querySelectorAll('.rightControlPanel .active:not([data-config]):not(.captionsButton):not(.captionSelectContainer):not(.annotationSetButton)').forEach(function(el) { el.classList.remove('active'); });
465+
layoutAreasPanel.classList.remove('active');
345466

346-
var captionContainer = this.querySelector('.captionSelectContainer');
347467
if ( !captionContainer.classList.contains('active') ) {
348468
captionContainer.classList.add('active');
349469
VideoContainer.style.opacity = '0.3';
350470
domElement.querySelectorAll('.areaLeftContainer, .areaRightContainer').forEach(function(el) { el.style.opacity = '0.3'; });
471+
addOutsideClickHandler();
351472
} else {
352-
captionContainer.classList.remove('active');
353-
VideoContainer.style.opacity = '1';
354-
domElement.querySelectorAll('.areaLeftContainer, .areaRightContainer').forEach(function(el) { el.style.opacity = '1'; });
473+
closeCaptionPanel();
355474
}
356475

357476
});
358477

478+
captionContainer.addEventListener('click', function(evt) {
479+
evt.stopPropagation();
480+
});
481+
482+
function closeCaptionPanel() {
483+
captionContainer.classList.remove('active');
484+
VideoContainer.style.opacity = '1';
485+
domElement.querySelectorAll('.areaLeftContainer, .areaRightContainer').forEach(function(el) { el.style.opacity = '1'; });
486+
}
487+
488+
function closeAllPanels() {
489+
layoutAreasPanel.classList.remove('active');
490+
closeCaptionPanel();
491+
}
492+
493+
function addOutsideClickHandler() {
494+
var handler = function() {
495+
closeAllPanels();
496+
document.removeEventListener('click', handler);
497+
};
498+
document.addEventListener('click', handler);
499+
}
500+
359501
Controls.querySelector('.captionSelect.none').addEventListener('click', function() {
360502
FrameTrail.changeState('hv_config_captionsVisible', false);
361503
});
@@ -944,6 +1086,9 @@ FrameTrail.defineModule('ViewVideo', function(FrameTrail){
9441086
AreaLeftContainer.style.display = 'none';
9451087
AreaRightContainer.style.display = 'none';
9461088

1089+
layoutAreasButton.style.display = 'none';
1090+
layoutAreasPanel.classList.remove('active');
1091+
9471092
// Timeline visibility is handled by CSS rules based on .editActive[data-edit-mode]
9481093
// Don't use .show() here as it sets inline display:block that persists after leaving edit mode
9491094

@@ -1080,6 +1225,7 @@ FrameTrail.defineModule('ViewVideo', function(FrameTrail){
10801225
if ( FrameTrail.getState('slidePosition') != 'middle' ) {
10811226
FrameTrail.changeState('slidePosition', 'middle');
10821227
}
1228+
updateLayoutAreasButtonVisibility();
10831229
};
10841230

10851231
/**
@@ -1100,6 +1246,7 @@ FrameTrail.defineModule('ViewVideo', function(FrameTrail){
11001246
if ( FrameTrail.getState('slidePosition') != 'middle' ) {
11011247
FrameTrail.changeState('slidePosition', 'middle');
11021248
}
1249+
updateLayoutAreasButtonVisibility();
11031250
};
11041251

11051252
/**
@@ -1117,6 +1264,7 @@ FrameTrail.defineModule('ViewVideo', function(FrameTrail){
11171264
} else {
11181265
AreaLeftContainer.style.display = 'none';
11191266
}
1267+
updateLayoutAreasButtonVisibility();
11201268
};
11211269

11221270
/**
@@ -1134,6 +1282,7 @@ FrameTrail.defineModule('ViewVideo', function(FrameTrail){
11341282
} else {
11351283
AreaRightContainer.style.display = 'none';
11361284
}
1285+
updateLayoutAreasButtonVisibility();
11371286
};
11381287

11391288
/**

0 commit comments

Comments
 (0)