wip
This commit is contained in:
parent
ea66a89ce1
commit
bd85d39af5
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
data/www/js/lib/jquery-ui-rotatable.min.js
vendored
Normal file
1
data/www/js/lib/jquery-ui-rotatable.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
271
data/www/js/slideshow/content-composition.js
Normal file
271
data/www/js/slideshow/content-composition.js
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
const getPayload = function() {
|
||||||
|
let screen = $('#screen');
|
||||||
|
let screenWidth = screen.width();
|
||||||
|
let screenHeight = screen.height();
|
||||||
|
|
||||||
|
$('.element').each(function () {
|
||||||
|
let offset = $(this).position();
|
||||||
|
let x = offset.left;
|
||||||
|
let y = offset.top;
|
||||||
|
let width = $(this).width();
|
||||||
|
let height = $(this).height();
|
||||||
|
|
||||||
|
let xPercent = (x / screenWidth) * 100;
|
||||||
|
let yPercent = (y / screenHeight) * 100;
|
||||||
|
let widthPercent = (width / screenWidth) * 100;
|
||||||
|
let heightPercent = (height / screenHeight) * 100;
|
||||||
|
|
||||||
|
console.log(JSON.stringify({
|
||||||
|
xPercent: xPercent,
|
||||||
|
yPercent: yPercent,
|
||||||
|
widthPercent: widthPercent,
|
||||||
|
heightPercent: heightPercent
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
jQuery(document).ready(function ($) {
|
||||||
|
let currentElement = null;
|
||||||
|
let elementCounter = 0;
|
||||||
|
|
||||||
|
$('.screen').css({
|
||||||
|
width: $('.screen').width(),
|
||||||
|
height: $('.screen').height(),
|
||||||
|
position: 'relative',
|
||||||
|
}).parents('.screen-holder:eq(0)').css({
|
||||||
|
width: 'auto',
|
||||||
|
'padding-top': '0px'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function createElement() {
|
||||||
|
let screen = $('#screen');
|
||||||
|
let screenWidth = screen.width();
|
||||||
|
let screenHeight = screen.height();
|
||||||
|
|
||||||
|
// Dimensions de l'élément
|
||||||
|
let elementWidth = 100;
|
||||||
|
let elementHeight = 50;
|
||||||
|
|
||||||
|
// Générer des positions aléatoires
|
||||||
|
let x = Math.round(Math.random() * (screenWidth - elementWidth));
|
||||||
|
let y = Math.round(Math.random() * (screenHeight - elementHeight));
|
||||||
|
|
||||||
|
// Constrain x and y
|
||||||
|
x = Math.round(Math.max(0, Math.min(x, screenWidth - elementWidth)));
|
||||||
|
y = Math.round(Math.max(0, Math.min(y, screenHeight - elementHeight)));
|
||||||
|
|
||||||
|
let elementId = elementCounter++;
|
||||||
|
let element = $('<div class="element" id="element-' + elementId + '" data-id="' + elementId + '"><button>Button</button></div>');
|
||||||
|
// let element = $('<div class="element" id="' + elementId + '"><button>Button</button><div class="rotate-handle"></div></div>');
|
||||||
|
|
||||||
|
element.css({
|
||||||
|
left: x,
|
||||||
|
top: y,
|
||||||
|
width: elementWidth,
|
||||||
|
height: elementHeight,
|
||||||
|
transform: `rotate(0deg)`
|
||||||
|
});
|
||||||
|
|
||||||
|
element.draggable({
|
||||||
|
containment: "#screen",
|
||||||
|
start: function (event, ui) {
|
||||||
|
focusElement(ui.helper);
|
||||||
|
},
|
||||||
|
drag: function (event, ui) {
|
||||||
|
updateForm(ui.helper);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
element.resizable({
|
||||||
|
containment: "#screen",
|
||||||
|
handles: 'nw, ne, sw, se',
|
||||||
|
start: function (event, ui) {
|
||||||
|
focusElement(ui.element);
|
||||||
|
},
|
||||||
|
resize: function (event, ui) {
|
||||||
|
updateForm(ui.element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
element.rotatable({
|
||||||
|
handle: element.find('.rotate-handle'),
|
||||||
|
rotate: function(event, ui) {
|
||||||
|
updateForm(ui.element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
element.click(function () {
|
||||||
|
focusElement($(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#screen').append(element);
|
||||||
|
addElementToList(elementId);
|
||||||
|
setTimeout(function() {
|
||||||
|
focusElement(element);
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on('click', '.element-list-item', function(){
|
||||||
|
focusElement($('#element-' + $(this).attr('data-id')));
|
||||||
|
})
|
||||||
|
|
||||||
|
$(document).on('click', '.remove-element', function(){
|
||||||
|
removeElementById($(this).attr('data-id'));
|
||||||
|
})
|
||||||
|
|
||||||
|
function removeElementById(elementId) {
|
||||||
|
$('.element[data-id='+elementId+'], .element-list-item[data-id='+elementId+']').remove();
|
||||||
|
updateZIndexes();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addElementToList(elementId) {
|
||||||
|
let listItem = $('<div class="element-list-item" data-id="' + elementId + '">Element ' + elementId + ' <button type="button" class="remove-element" data-id="' + elementId + '">remove</button></div>');
|
||||||
|
$('#elementList').append(listItem);
|
||||||
|
updateZIndexes();
|
||||||
|
}
|
||||||
|
|
||||||
|
function unfocusElements() {
|
||||||
|
$('.element, .element-list-item').removeClass('focused');
|
||||||
|
currentElement = null;
|
||||||
|
updateForm(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function focusElement(element) {
|
||||||
|
unfocusElements();
|
||||||
|
currentElement = element;
|
||||||
|
currentElement.addClass('focused');
|
||||||
|
const listElement = $('.element-list-item[data-id="' + currentElement.attr('data-id') + '"]');
|
||||||
|
listElement.addClass('focused');
|
||||||
|
updateForm(currentElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateForm(element) {
|
||||||
|
if (!element) {
|
||||||
|
$('form#elementForm input').val('').prop('disabled', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('form#elementForm input').prop('disabled', false);
|
||||||
|
|
||||||
|
let offset = element.position();
|
||||||
|
|
||||||
|
if (offset !== undefined) {
|
||||||
|
$('#elem-x').val(offset.left);
|
||||||
|
$('#elem-y').val(offset.top);
|
||||||
|
$('#elem-width').val(element.width());
|
||||||
|
$('#elem-height').val(element.height());
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
let rotation = element.css('transform');
|
||||||
|
let values = rotation.split('(')[1].split(')')[0].split(',');
|
||||||
|
let angle = Math.round(Math.atan2(values[1], values[0]) * (180/Math.PI));
|
||||||
|
$('#elem-rotate').val(angle);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).on('input', '#elementForm input', function () {
|
||||||
|
if (currentElement) {
|
||||||
|
let screenWidth = $('#screen').width();
|
||||||
|
let screenHeight = $('#screen').height();
|
||||||
|
|
||||||
|
let x = Math.round(parseInt($('#elem-x').val()));
|
||||||
|
let y = Math.round(parseInt($('#elem-y').val()));
|
||||||
|
let width = Math.round(parseInt($('#elem-width').val()));
|
||||||
|
let height = Math.round(parseInt($('#elem-height').val()));
|
||||||
|
// let rotation = parseInt($('#elem-rotate').val());
|
||||||
|
|
||||||
|
// Constrain x and y
|
||||||
|
x = Math.max(0, Math.min(x, screenWidth - width));
|
||||||
|
y = Math.max(0, Math.min(y, screenHeight - height));
|
||||||
|
|
||||||
|
// Constrain width and height
|
||||||
|
width = Math.min(width, screenWidth - x);
|
||||||
|
height = Math.min(height, screenHeight - y);
|
||||||
|
|
||||||
|
currentElement.css({
|
||||||
|
left: x,
|
||||||
|
top: y,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
// transform: `rotate(${rotation}deg)`
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update form values to reflect clamped values
|
||||||
|
$('#elem-x').val(x);
|
||||||
|
$('#elem-y').val(y);
|
||||||
|
$('#elem-width').val(width);
|
||||||
|
$('#elem-height').val(height);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#addElement', function () {
|
||||||
|
createElement();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#removeAllElements', function () {
|
||||||
|
$('.element, .element-list-item').remove();
|
||||||
|
updateZIndexes();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('mousedown', function (e) {
|
||||||
|
const keepFocusedElement = $(e.target).hasClass('element')
|
||||||
|
|| $(e.target).hasClass('element-list-item')
|
||||||
|
|| $(e.target).parents('.element:eq(0)').length !== 0
|
||||||
|
|| $(e.target).parents('.element-list-item:eq(0)').length !== 0
|
||||||
|
|| $(e.target).is('input,select,textarea')
|
||||||
|
|
||||||
|
if (!keepFocusedElement) {
|
||||||
|
unfocusElements();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#presetGrid2x2', function () {
|
||||||
|
let screenWidth = $('#screen').width();
|
||||||
|
let screenHeight = $('#screen').height();
|
||||||
|
let elements = $('.element');
|
||||||
|
if (elements.length < 4) {
|
||||||
|
while (elements.length < 4) {
|
||||||
|
createElement();
|
||||||
|
elements = $('.element');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gridPositions = [
|
||||||
|
{x: 0, y: 0},
|
||||||
|
{x: screenWidth / 2, y: 0},
|
||||||
|
{x: 0, y: screenHeight / 2},
|
||||||
|
{x: screenWidth / 2, y: screenHeight / 2}
|
||||||
|
];
|
||||||
|
|
||||||
|
elements.each(function (index) {
|
||||||
|
let position = gridPositions[index];
|
||||||
|
$(this).css({
|
||||||
|
left: position.x,
|
||||||
|
top: position.y,
|
||||||
|
width: screenWidth / 2,
|
||||||
|
height: screenHeight / 2
|
||||||
|
});
|
||||||
|
updateForm($(this));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateZIndexes() {
|
||||||
|
const zindex = $('.element-list-item').length + 1;
|
||||||
|
$('.element-list-item').each(function(index) {
|
||||||
|
let id = $(this).attr('data-id');
|
||||||
|
$('#element-' + id).css('z-index', zindex - index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#elementList').sortable({
|
||||||
|
update: function(event, ui) {
|
||||||
|
updateZIndexes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
createElement();
|
||||||
|
updateForm(null);
|
||||||
|
});
|
||||||
@ -23,6 +23,29 @@
|
|||||||
|
|
||||||
.view-content-edit main .main-container {
|
.view-content-edit main .main-container {
|
||||||
|
|
||||||
|
.top-content {
|
||||||
|
h3 {
|
||||||
|
color: $gscaleF;
|
||||||
|
padding: 10px 10px 10px 0;
|
||||||
|
font-size: 16px;
|
||||||
|
align-self: stretch;
|
||||||
|
flex: 1;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
span {
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-radius: $baseRadius;
|
||||||
|
padding: 4px 10px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bottom-content {
|
.bottom-content {
|
||||||
.page-content {
|
.page-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -43,27 +66,6 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
|
||||||
h3 {
|
|
||||||
color: $gscaleF;
|
|
||||||
padding: 10px 10px 10px 0;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
font-size: 16px;
|
|
||||||
align-self: stretch;
|
|
||||||
margin-left: -8px;
|
|
||||||
|
|
||||||
span {
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: $baseRadius;
|
|
||||||
padding: 4px 10px;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.iframe-wrapper {
|
.iframe-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -88,6 +90,179 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.view-content-edit.view-content-edit-composition main .main-container {
|
||||||
|
|
||||||
|
.page-panel.left-panel {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.form-holder {
|
||||||
|
margin: 20px 20px 20px 10px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content {
|
||||||
|
flex: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-panel.right-panel {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen-holder {
|
||||||
|
//display: flex;
|
||||||
|
//flex-direction: row;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
padding-top: 56.25%; /* 16:9 aspect ratio */
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: $baseRadius;
|
||||||
|
outline: 4px solid rgba($gscaleF, .1);
|
||||||
|
|
||||||
|
|
||||||
|
.screen {
|
||||||
|
background-color: #ddd;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
.element {
|
||||||
|
position: absolute !important;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
outline: 1px solid rgba($black, .5);
|
||||||
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&.focused {
|
||||||
|
border: none;
|
||||||
|
outline: 2px solid blue;
|
||||||
|
z-index: 89 !important;
|
||||||
|
|
||||||
|
.ui-resizable-handle {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate-handle {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background-color: red;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: -15px;
|
||||||
|
cursor: pointer;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-resizable-handle {
|
||||||
|
background: black;
|
||||||
|
border: 1px solid #000;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
z-index: 90;
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&.ui-resizable-nw {
|
||||||
|
cursor: nw-resize;
|
||||||
|
top: -5px;
|
||||||
|
left: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ui-resizable-ne {
|
||||||
|
cursor: ne-resize;
|
||||||
|
top: -5px;
|
||||||
|
right: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ui-resizable-sw {
|
||||||
|
cursor: sw-resize;
|
||||||
|
bottom: -5px;
|
||||||
|
left: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ui-resizable-se {
|
||||||
|
cursor: se-resize;
|
||||||
|
bottom: -5px;
|
||||||
|
right: -5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.elements-holder {
|
||||||
|
align-self: stretch;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: $gscaleD;
|
||||||
|
text-decoration: none;
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
|
||||||
|
&.divide {
|
||||||
|
border-top: 1px solid $gscale2;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-elements-list {
|
||||||
|
background: $gscale2;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: $baseRadius;
|
||||||
|
|
||||||
|
.element-list-item {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
|
||||||
|
&.focused {
|
||||||
|
background-color: #d0ebff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.form-element-properties {
|
||||||
|
margin-left: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
label,
|
||||||
|
input {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#elementList {
|
||||||
|
h3 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@ $layoutBorder: 1px solid $gscale2;
|
|||||||
// Packs
|
// Packs
|
||||||
$colors: (
|
$colors: (
|
||||||
warning: $warning,
|
warning: $warning,
|
||||||
|
orange: $orange,
|
||||||
info: $info,
|
info: $info,
|
||||||
info-alt: $bitterBlue,
|
info-alt: $bitterBlue,
|
||||||
success: $success,
|
success: $success,
|
||||||
|
|||||||
@ -290,6 +290,7 @@
|
|||||||
"enum_content_type_external_storage": "External Storage",
|
"enum_content_type_external_storage": "External Storage",
|
||||||
"enum_content_type_external_storage_object_label": "Specify an existing directory relative to the following path",
|
"enum_content_type_external_storage_object_label": "Specify an existing directory relative to the following path",
|
||||||
"enum_content_type_external_storage_flashdrive_label": "Path relative to a removeable device",
|
"enum_content_type_external_storage_flashdrive_label": "Path relative to a removeable device",
|
||||||
|
"enum_content_type_composition": "Composition",
|
||||||
"enum_content_type_url": "URL",
|
"enum_content_type_url": "URL",
|
||||||
"enum_content_type_video": "Video",
|
"enum_content_type_video": "Video",
|
||||||
"enum_content_type_picture": "Picture",
|
"enum_content_type_picture": "Picture",
|
||||||
|
|||||||
@ -291,6 +291,7 @@
|
|||||||
"enum_content_type_external_storage": "Almacenamiento externo",
|
"enum_content_type_external_storage": "Almacenamiento externo",
|
||||||
"enum_content_type_external_storage_object_label": "Especifique un directorio existente relativo a la siguiente ruta",
|
"enum_content_type_external_storage_object_label": "Especifique un directorio existente relativo a la siguiente ruta",
|
||||||
"enum_content_type_external_storage_flashdrive_label": "Ruta relativa a un dispositivo extraíble",
|
"enum_content_type_external_storage_flashdrive_label": "Ruta relativa a un dispositivo extraíble",
|
||||||
|
"enum_content_type_composition": "Composición",
|
||||||
"enum_content_type_url": "URL",
|
"enum_content_type_url": "URL",
|
||||||
"enum_content_type_video": "Video",
|
"enum_content_type_video": "Video",
|
||||||
"enum_content_type_picture": "Imagen",
|
"enum_content_type_picture": "Imagen",
|
||||||
|
|||||||
@ -292,6 +292,7 @@
|
|||||||
"enum_content_type_external_storage": "Stockage externe",
|
"enum_content_type_external_storage": "Stockage externe",
|
||||||
"enum_content_type_external_storage_object_label": "Spécifiez un répertoire existant par rapport au chemin suivant",
|
"enum_content_type_external_storage_object_label": "Spécifiez un répertoire existant par rapport au chemin suivant",
|
||||||
"enum_content_type_external_storage_flashdrive_label": "Chemin relatif à un périphérique amovible",
|
"enum_content_type_external_storage_flashdrive_label": "Chemin relatif à un périphérique amovible",
|
||||||
|
"enum_content_type_composition": "Composition",
|
||||||
"enum_content_type_url": "URL",
|
"enum_content_type_url": "URL",
|
||||||
"enum_content_type_video": "Vidéo",
|
"enum_content_type_video": "Vidéo",
|
||||||
"enum_content_type_picture": "Image",
|
"enum_content_type_picture": "Image",
|
||||||
|
|||||||
@ -291,6 +291,7 @@
|
|||||||
"enum_content_type_external_storage": "Archiviazione esterna",
|
"enum_content_type_external_storage": "Archiviazione esterna",
|
||||||
"enum_content_type_external_storage_object_label": "Specificare una directory esistente relativi al seguente percorso",
|
"enum_content_type_external_storage_object_label": "Specificare una directory esistente relativi al seguente percorso",
|
||||||
"enum_content_type_external_storage_flashdrive_label": "Percorso relativo ad un dispositivo rimovibile",
|
"enum_content_type_external_storage_flashdrive_label": "Percorso relativo ad un dispositivo rimovibile",
|
||||||
|
"enum_content_type_composition": "Composizione",
|
||||||
"enum_content_type_url": "URL",
|
"enum_content_type_url": "URL",
|
||||||
"enum_content_type_video": "Video",
|
"enum_content_type_video": "Video",
|
||||||
"enum_content_type_picture": "Immagine",
|
"enum_content_type_picture": "Immagine",
|
||||||
|
|||||||
@ -112,9 +112,13 @@ class ContentController(ObController):
|
|||||||
return abort(404)
|
return abort(404)
|
||||||
|
|
||||||
working_folder_path, working_folder = self.get_working_folder()
|
working_folder_path, working_folder = self.get_working_folder()
|
||||||
|
edit_view = 'slideshow/contents/edit.jinja.html'
|
||||||
|
|
||||||
|
if content.type == ContentType.COMPOSITION:
|
||||||
|
edit_view = 'slideshow/contents/edit-composition.jinja.html'
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'slideshow/contents/edit.jinja.html',
|
edit_view,
|
||||||
content=content,
|
content=content,
|
||||||
working_folder_path=working_folder_path,
|
working_folder_path=working_folder_path,
|
||||||
working_folder=working_folder,
|
working_folder=working_folder,
|
||||||
|
|||||||
@ -11,6 +11,7 @@ class ContentInputType(Enum):
|
|||||||
UPLOAD = 'upload'
|
UPLOAD = 'upload'
|
||||||
TEXT = 'text'
|
TEXT = 'text'
|
||||||
STORAGE = 'storage'
|
STORAGE = 'storage'
|
||||||
|
HIDDEN = 'hidden'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_editable(value: Enum) -> bool:
|
def is_editable(value: Enum) -> bool:
|
||||||
@ -29,6 +30,7 @@ class ContentType(Enum):
|
|||||||
YOUTUBE = 'youtube'
|
YOUTUBE = 'youtube'
|
||||||
VIDEO = 'video'
|
VIDEO = 'video'
|
||||||
EXTERNAL_STORAGE = 'external_storage'
|
EXTERNAL_STORAGE = 'external_storage'
|
||||||
|
COMPOSITION = 'composition'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def guess_content_type_file(filename: str):
|
def guess_content_type_file(filename: str):
|
||||||
@ -61,6 +63,8 @@ class ContentType(Enum):
|
|||||||
return ContentInputType.TEXT
|
return ContentInputType.TEXT
|
||||||
elif value == ContentType.EXTERNAL_STORAGE:
|
elif value == ContentType.EXTERNAL_STORAGE:
|
||||||
return ContentInputType.STORAGE
|
return ContentInputType.STORAGE
|
||||||
|
elif value == ContentType.COMPOSITION:
|
||||||
|
return ContentInputType.HIDDEN
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_fa_icon(value: Union[Enum, str]) -> str:
|
def get_fa_icon(value: Union[Enum, str]) -> str:
|
||||||
@ -77,6 +81,8 @@ class ContentType(Enum):
|
|||||||
return 'fa-link'
|
return 'fa-link'
|
||||||
elif value == ContentType.EXTERNAL_STORAGE:
|
elif value == ContentType.EXTERNAL_STORAGE:
|
||||||
return 'fa-brands fa-usb'
|
return 'fa-brands fa-usb'
|
||||||
|
elif value == ContentType.COMPOSITION:
|
||||||
|
return 'fa-solid fa-clone'
|
||||||
|
|
||||||
return 'fa-file'
|
return 'fa-file'
|
||||||
|
|
||||||
@ -95,5 +101,7 @@ class ContentType(Enum):
|
|||||||
return 'danger'
|
return 'danger'
|
||||||
elif value == ContentType.EXTERNAL_STORAGE:
|
elif value == ContentType.EXTERNAL_STORAGE:
|
||||||
return 'other'
|
return 'other'
|
||||||
|
elif value == ContentType.COMPOSITION:
|
||||||
|
return 'warning'
|
||||||
|
|
||||||
return 'neutral'
|
return 'neutral'
|
||||||
|
|||||||
@ -36,6 +36,7 @@ class TemplateRenderer:
|
|||||||
AUTH_ENABLED=self._model_store.variable().map().get('auth_enabled').as_bool(),
|
AUTH_ENABLED=self._model_store.variable().map().get('auth_enabled').as_bool(),
|
||||||
last_pillmenu_slideshow=self._model_store.variable().map().get('last_pillmenu_slideshow').as_string(),
|
last_pillmenu_slideshow=self._model_store.variable().map().get('last_pillmenu_slideshow').as_string(),
|
||||||
last_pillmenu_configuration=self._model_store.variable().map().get('last_pillmenu_configuration').as_string(),
|
last_pillmenu_configuration=self._model_store.variable().map().get('last_pillmenu_configuration').as_string(),
|
||||||
|
external_url=self._model_store.variable().map().get('external_url').as_string().strip('/'),
|
||||||
last_pillmenu_fleet=self._model_store.variable().map().get('last_pillmenu_fleet').as_string(),
|
last_pillmenu_fleet=self._model_store.variable().map().get('last_pillmenu_fleet').as_string(),
|
||||||
last_pillmenu_security=self._model_store.variable().map().get('last_pillmenu_security').as_string(),
|
last_pillmenu_security=self._model_store.variable().map().get('last_pillmenu_security').as_string(),
|
||||||
track_created=self._model_store.user().track_user_created,
|
track_created=self._model_store.user().track_user_created,
|
||||||
|
|||||||
@ -64,7 +64,8 @@
|
|||||||
|
|
||||||
{% if current_player_group.playlist_id %}
|
{% if current_player_group.playlist_id %}
|
||||||
<div class="preview-holder">
|
<div class="preview-holder">
|
||||||
{% set preview_url = request.scheme ~ '://' ~ request.headers.get('host') ~ url_for('player_use', playlist_slug_or_id=current_player_group.playlist_id) %}
|
{% set base_url = external_url if external_url else request.scheme ~ '://' ~ request.headers.get('host') %}
|
||||||
|
{% set preview_url = base_url~ url_for('player_use', playlist_slug_or_id=current_player_group.playlist_id) %}
|
||||||
|
|
||||||
<h4 class="divide">
|
<h4 class="divide">
|
||||||
Iframe
|
Iframe
|
||||||
|
|||||||
@ -82,7 +82,8 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-holder">
|
<div class="preview-holder">
|
||||||
{% set preview_url = request.scheme ~ '://' ~ request.headers.get('host') ~ url_for('player_use', playlist_slug_or_id=current_playlist.slug) %}
|
{% set base_url = external_url if external_url else request.scheme ~ '://' ~ request.headers.get('host') %}
|
||||||
|
{% set preview_url = base_url ~ url_for('player_use', playlist_slug_or_id=current_playlist.slug) %}
|
||||||
<h4 class="divide">
|
<h4 class="divide">
|
||||||
URL
|
URL
|
||||||
</h4>
|
</h4>
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
<i class="fa fa-play"></i>
|
<i class="fa fa-play"></i>
|
||||||
</sub>
|
</sub>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{% if use_href %}{{ url_for('slideshow_content_edit', content_id=content.id) }}{% else %}javascript:void(0);{% endif %}"
|
<a href="{% if use_href %}{{ url_for('slideshow_content_edit', content_id=content.id, path=folder.path) }}{% else %}javascript:void(0);{% endif %}"
|
||||||
class="{{ 'explr-pick-element' if not use_href }}">
|
class="{{ 'explr-pick-element' if not use_href }}">
|
||||||
{{ content.name }}
|
{{ content.name }}
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
145
views/slideshow/contents/edit-composition.jinja.html
Normal file
145
views/slideshow/contents/edit-composition.jinja.html
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
{% set active_pill_route='slideshow_content_list' %}
|
||||||
|
{% extends 'base.jinja.html' %}
|
||||||
|
|
||||||
|
{% block page_title %}
|
||||||
|
{{ l.slideshow_content_page_title }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block add_css %}
|
||||||
|
<link rel="stylesheet" href="{{ STATIC_PREFIX }}css/lib/flatpickr.min.css"/>
|
||||||
|
<link rel="stylesheet" href="{{ STATIC_PREFIX }}css/lib/jquery-explr-1.4.css"/>
|
||||||
|
{{ HOOK(H_SLIDESHOW_CONTENT_CSS) }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block add_js %}
|
||||||
|
<script src="{{ STATIC_PREFIX }}js/lib/jquery-explr-1.4.js"></script>
|
||||||
|
<script src="{{ STATIC_PREFIX }}js/slideshow/contents.js"></script>
|
||||||
|
<script src="{{ STATIC_PREFIX }}js/lib/jquery-ui.min.js"></script>
|
||||||
|
{# <script src="{{ STATIC_PREFIX }}js/lib/jquery-ui-rotatable.min.js"></script> #}
|
||||||
|
<script src="{{ STATIC_PREFIX }}js/slideshow/content-composition.js"></script>
|
||||||
|
{{ HOOK(H_SLIDESHOW_CONTENT_JAVASCRIPT) }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body_class %}view-content-edit view-content-edit-composition edit-page{% endblock %}
|
||||||
|
|
||||||
|
{% block page %}
|
||||||
|
<div class="top-content">
|
||||||
|
<h1>
|
||||||
|
{{ l.slideshow_content_form_edit_title }}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
{% set icon = enum_content_type.get_fa_icon(content.type) %}
|
||||||
|
{% set color = enum_content_type.get_color_icon(content.type) %}
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
<span class="{{ color }} border-{{ color }}">
|
||||||
|
<i class="fa {{ icon }} {{ color }}"></i> {{ t(content.type) }}
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if request.args.get('saved') %}
|
||||||
|
<div class="alert alert-success alert-timeout">
|
||||||
|
<i class="fa fa-check icon-left"></i>
|
||||||
|
{{ l.common_saved }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="bottom-content">
|
||||||
|
<div class="page-panel left-panel">
|
||||||
|
<div class="inner dirview">
|
||||||
|
<div class="breadcrumb-container">
|
||||||
|
<ul class="breadcrumb">
|
||||||
|
{% set ns = namespace(breadpath='') %}
|
||||||
|
{% for dir in working_folder_path[1:].split('/') %}
|
||||||
|
{% set ns.breadpath = ns.breadpath ~ '/' ~ dir %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ url_for('slideshow_content_cd', path=ns.breadpath) }}">
|
||||||
|
<i class="explr-icon explr-icon-folder"></i>
|
||||||
|
{{ truncate(dir, 25, '...') }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% if not loop.last %}
|
||||||
|
<li class="divider">
|
||||||
|
<i class="fa fa-chevron-right"></i>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="horizontal">
|
||||||
|
<div class="form-holder">
|
||||||
|
<form class="form"
|
||||||
|
action="{{ url_for('slideshow_content_save', content_id=content.id) }}?path={{ working_folder_path }}"
|
||||||
|
method="POST">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="content-edit-name">{{ l.slideshow_content_form_label_name }}</label>
|
||||||
|
<div class="widget">
|
||||||
|
<input type="text" name="name" id="content-edit-name" required="required"
|
||||||
|
value="{{ content.name }}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="elements-holder">
|
||||||
|
<h3 class="divide">Elements</h3>
|
||||||
|
<div class="form-elements-list" id="elementList">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions actions-right">
|
||||||
|
<button type="submit" class="btn btn-info">
|
||||||
|
<i class="fa fa-save icon-left"></i>
|
||||||
|
{{ l.common_save }}
|
||||||
|
</button>
|
||||||
|
<a href="{{ url_for('slideshow_content_list') }}" class="btn btn-naked">
|
||||||
|
<i class="fa fa-rectangle-xmark icon-left"></i>
|
||||||
|
{{ l.common_cancel }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="inner">
|
||||||
|
<div class="toolbar">
|
||||||
|
<button id="presetGrid2x2">Grid 2x2</button>
|
||||||
|
<button id="addElement">Add Element</button>
|
||||||
|
<button id="removeAllElements">Remove All Elements</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="screen-holder">
|
||||||
|
<div class="screen" id="screen">
|
||||||
|
<!-- Elements will be dynamically added here -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="page-panel right-panel">
|
||||||
|
<div class="form-element-properties">
|
||||||
|
<form id="elementForm">
|
||||||
|
<h3>Element Properties</h3>
|
||||||
|
<label for="elem-x">X:</label>
|
||||||
|
<input type="number" id="elem-x" name="elem-x"><br>
|
||||||
|
<label for="elem-y">Y:</label>
|
||||||
|
<input type="number" id="elem-y" name="elem-y"><br>
|
||||||
|
<label for="elem-width">Width:</label>
|
||||||
|
<input type="number" id="elem-width" name="elem-width"><br>
|
||||||
|
<label for="elem-height">Height:</label>
|
||||||
|
<input type="number" id="elem-height" name="elem-height"><br>
|
||||||
|
<!--<label for="elem-rotate">Rotate (deg):</label>-->
|
||||||
|
<!--<input type="number" id="elem-rotate" name="elem-rotate"><br>-->
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@ -25,6 +25,15 @@
|
|||||||
<h1>
|
<h1>
|
||||||
{{ l.slideshow_content_form_edit_title }}
|
{{ l.slideshow_content_form_edit_title }}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
{% set icon = enum_content_type.get_fa_icon(content.type) %}
|
||||||
|
{% set color = enum_content_type.get_color_icon(content.type) %}
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
<span class="{{ color }} border-{{ color }}">
|
||||||
|
<i class="fa {{ icon }} {{ color }}"></i> {{ t(content.type) }}
|
||||||
|
</span>
|
||||||
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if request.args.get('saved') %}
|
{% if request.args.get('saved') %}
|
||||||
@ -89,7 +98,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="actions actions-left">
|
<div class="actions actions-right">
|
||||||
<button type="submit" class="btn btn-info">
|
<button type="submit" class="btn btn-info">
|
||||||
<i class="fa fa-save icon-left"></i>
|
<i class="fa fa-save icon-left"></i>
|
||||||
{{ l.common_save }}
|
{{ l.common_save }}
|
||||||
@ -107,14 +116,6 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="page-panel right-panel">
|
<div class="page-panel right-panel">
|
||||||
{% set icon = enum_content_type.get_fa_icon(content.type) %}
|
|
||||||
{% set color = enum_content_type.get_color_icon(content.type) %}
|
|
||||||
|
|
||||||
<h3>
|
|
||||||
<span class="{{ color }} border-{{ color }}">
|
|
||||||
<i class="fa {{ icon }} {{ color }}"></i> {{ t(content.type) }}
|
|
||||||
</span>
|
|
||||||
</h3>
|
|
||||||
<div class="iframe-wrapper">
|
<div class="iframe-wrapper">
|
||||||
<iframe src="{{ url_for('player', preview_content_id=content.id) }}"></iframe>
|
<iframe src="{{ url_for('player', preview_content_id=content.id) }}"></iframe>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user