text content type wip

This commit is contained in:
jr-k 2024-08-26 14:16:08 +02:00
parent b1d11308d7
commit 83be75967c
13 changed files with 269 additions and 24 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,55 @@
jQuery(function () { jQuery(function () {
$(document).ready(function () { $(document).ready(function () {
function adjustValue(inputElement, delta) {
const currentValue = parseInt(inputElement.value) || 0;
const newValue = currentValue + delta;
inputElement.value = newValue >= 0 ? newValue : 0;
$(inputElement).trigger('input');
}
$('.numeric-input').on('input', function () { $('.numeric-input').on('input', function () {
this.value = this.value.replace(/[^0-9]/g, ''); this.value = this.value.replace(/[^0-9]/g, '');
}); });
$('.numeric-input').on('keydown', function (e) {
switch (e.key) {
case 'ArrowUp':
e.preventDefault();
adjustValue(this, e.shiftKey ? 10 : 1);
break;
case 'ArrowDown':
e.preventDefault();
adjustValue(this, e.shiftKey ? -10 : -1);
break;
}
});
function updateRadioActiveClass() {
$('.radio-group label').removeClass('active');
$('input[type="radio"]:checked').next('label').addClass('active');
}
updateRadioActiveClass();
$('.radio-group input[type="radio"]').change(function() {
updateRadioActiveClass();
});
function updateCheckboxActiveClass() {
$('.checkbox-group label').each(function() {
const checkbox = $(this).prev('input[type="checkbox"]');
if (checkbox.is(':checked')) {
$(this).addClass('active');
} else {
$(this).removeClass('active');
}
});
}
updateCheckboxActiveClass();
$('.checkbox-group input[type="checkbox"]').change(function() {
updateCheckboxActiveClass();
});
}); });
}) });

1
data/www/js/lib/jscolor.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
jQuery(document).ready(function ($) { jQuery(document).ready(function ($) {
const contentData = JSON.parse($('#content-edit-location').val()); const contentData = JSON.parse($('#content-edit-location').val() || '{"layers":{}}');
const screenRatio = 16/9; const screenRatio = 16/9;
let currentElement = null; let currentElement = null;

View File

@ -1,6 +1,6 @@
jQuery(document).ready(function ($) { jQuery(document).ready(function ($) {
const contentData = JSON.parse($('#content-edit-location').val()); const contentData = JSON.parse($('#content-edit-location').val() || '{}');
const screenRatio = 16/9; const screenRatio = 16/9;
$('.screen-holder').css({ $('.screen-holder').css({
@ -18,7 +18,41 @@ jQuery(document).ready(function ($) {
'padding-top': '0px' 'padding-top': '0px'
}); });
$(document).on('input', '#elementForm input', function () { const draw = function() {
const $screen = $('#screen');
const $text = $('<div class="text">');
$text.html($('#elem-text').val());
let justifyContent = 'center';
switch($('[name=elem-text-align]:checked').val()) {
case 'left': justifyContent = 'flex-start'; break;
case 'right': justifyContent = 'flex-end'; break;
}
$text.css({
padding: $('#elem-container-margin').val() + 'px',
backgroundColor: $('#elem-bg-color').val(),
color: $('#elem-fg-color').val(),
textAlign: $('[name=elem-text-align]:checked').val(),
textDecoration: $('#elem-text-underline').is(':checked') ? 'underline' : 'normal',
fontSize: $('#elem-font-size').val() + 'px',
fontWeight: $('#elem-font-bold').is(':checked') ? 'bold' : 'normal',
fontStyle: $('#elem-font-italic').is(':checked') ? 'italic' : 'normal',
fontFamily: $('#elem-font-family').val() + ", 'Arial', 'sans-serif'",
whiteSpace: $('#elem-single-line').is(':checked') ? 'nowrap' : 'normal',
justifyContent: justifyContent
});
$screen.html($text);
};
$(document).on('input', '#elementForm input, #elementForm select', function () {
draw();
}); });
draw();
}); });

View File

@ -57,6 +57,7 @@ button,
box-shadow: 0 $shadowOffset 0 0 darken($gscale5, 10%); box-shadow: 0 $shadowOffset 0 0 darken($gscale5, 10%);
border: 1px solid transparent; border: 1px solid transparent;
&.active,
&:hover { &:hover {
box-shadow: 0 $shadowOffset 0 1px $gkscale2 inset; box-shadow: 0 $shadowOffset 0 1px $gkscale2 inset;
background: darken($gscale5, 10%); background: darken($gscale5, 10%);

View File

@ -81,6 +81,24 @@ form {
} }
} }
.checkbox-group,
.radio-group {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
input {
display: none;
}
label {
margin: 0 5px 0 0 !important;
justify-content: center !important;
text-align: center;
}
}
.widget { .widget {
margin-top: 10px; margin-top: 10px;
align-self: stretch; align-self: stretch;
@ -105,7 +123,6 @@ form {
} }
&.widget-unit { &.widget-unit {
select, select,
input { input {
flex-grow: 0; flex-grow: 0;
@ -131,6 +148,33 @@ form {
} }
} }
select,
input {
&.size-m {
max-width: 150px;
}
&.color-picker {
max-width: 125px;
}
&.chars-4 {
max-width: 50px;
}
&.chars-3 {
max-width: 40px;
}
&.chars-2 {
max-width: 20px;
}
&.chars-1 {
max-width: 15px;
}
}
div { div {
color: rgba($gscaleF, .7); color: rgba($gscaleF, .7);
font-size: 14px; font-size: 14px;

View File

@ -54,6 +54,18 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
border: none; border: none;
display: flex;
.text {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
flex: 1;
align-self: stretch;
text-align: center;
max-width: 100%;
}
} }
} }
@ -77,11 +89,6 @@
} }
.form-group { .form-group {
flex-direction: row;
justify-content: flex-start;
align-items: center;
display: flex;
label { label {
flex-grow: 1; flex-grow: 1;
flex-direction: row; flex-direction: row;
@ -90,6 +97,7 @@
display: flex; display: flex;
font-weight: bold; font-weight: bold;
margin-right: 10px; margin-right: 10px;
margin-bottom: 5px;
} }
.widget { .widget {

View File

@ -61,7 +61,7 @@
align-self: stretch; align-self: stretch;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: auto;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
padding: 20px; padding: 20px;

View File

@ -212,7 +212,7 @@ class ContentManager(ModelManager):
content.location = object_path content.location = object_path
self.set_metadata(content) self.set_metadata(content)
else: else:
content.location = location if location else '' content.location = location if location else ContentType.get_empty_location(content.type)
self.add_form(content) self.add_form(content)
return self.get_one_by(query="uuid = '{}'".format(content.uuid)) return self.get_one_by(query="uuid = '{}'".format(content.uuid))

View File

@ -1,3 +1,4 @@
import json
import mimetypes import mimetypes
from enum import Enum from enum import Enum
@ -112,3 +113,23 @@ class ContentType(Enum):
return 'gscaleF' return 'gscaleF'
return 'neutral' return 'neutral'
@staticmethod
def get_empty_location(value: Enum) -> str:
if isinstance(value, str):
value = str_to_enum(value, ContentType)
if value == ContentType.COMPOSITION:
return json.dumps({
"ratio": '16/9',
"layers": {}
})
elif value == ContentType.TEXT:
return json.dumps({
"text": 'Hello',
"fontSize": 12,
"color": '#FFFFFF',
"backgroundColor": '#000000',
})
return ''

View File

@ -10,6 +10,7 @@
{% endblock %} {% endblock %}
{% block add_js %} {% block add_js %}
<script src="{{ STATIC_PREFIX }}js/lib/jscolor.min.js"></script>
<script src="{{ STATIC_PREFIX }}js/slideshow/contents.js"></script> <script src="{{ STATIC_PREFIX }}js/slideshow/contents.js"></script>
<script src="{{ STATIC_PREFIX }}js/slideshow/content-text.js"></script> <script src="{{ STATIC_PREFIX }}js/slideshow/content-text.js"></script>
{{ HOOK(H_SLIDESHOW_CONTENT_JAVASCRIPT) }} {{ HOOK(H_SLIDESHOW_CONTENT_JAVASCRIPT) }}
@ -116,9 +117,9 @@
</h3> </h3>
<div class="form-group"> <div class="form-group">
<label for="elem-x">Texte à afficher</label> <label for="elem-text">Text Label</label>
<div class="widget"> <div class="widget">
<input type="number" id="elem-x" name="elem-x"> <input type="text" id="elem-text" name="elem-text" value="Hello World !Hello World !Hello World !Hello World !Hello World !Hello World !Hello World !Hello World !Hello World !Hello World !Hello World !Hello World !Hello World !222">
</div> </div>
</div> </div>
@ -127,30 +128,117 @@
</h3> </h3>
<div class="form-group"> <div class="form-group">
<label for="elem-font-size">Font size</label> <label for="elem-font-size">Font Size</label>
<div class="widget widget-unit"> <div class="widget widget-unit">
<input type="text" id="elem-font-size" name="elem-font-size" maxlength="3" class="numeric-input"> <input type="text" id="elem-font-size" name="elem-font-size" maxlength="3" class="numeric-input chars-3" value="20">
<span>pt</span> <span>pt</span>
</div> </div>
</div> </div>
<div class="form-group">
<label for="elem-fg-color">Text Color</label>
<div class="widget">
<input type="text" id="elem-fg-color" name="elem-fg-color" class="color-picker" data-jscolor="{ value: '#FFFFFFFF', backgroundColor: '#333333', shadowColor: '#000000', width: 120, height: 120 }" />
</div>
</div>
<div class="form-group">
<label for="elem-fg-color">Text Alignment</label>
<div class="widget">
<div class="radio-group">
<input type="radio" id="elem-text-align-left" name="elem-text-align" value="left">
<label for="elem-text-align-left" class="btn btn-neutral">
<i class="fa fa-align-left"></i>
</label>
<input type="radio" id="elem-text-align-center" name="elem-text-align" value="center" checked="checked">
<label for="elem-text-align-center" class="btn btn-neutral">
<i class="fa fa-align-center"></i>
</label>
<input type="radio" id="elem-text-align-right" name="elem-text-align" value="right">
<label for="elem-text-align-right" class="btn btn-neutral">
<i class="fa fa-align-right"></i>
</label>
</div>
</div>
</div>
<div class="form-group">
<label for="elem-fg-color">Text Style</label>
<div class="widget">
<div class="checkbox-group">
<input type="checkbox" id="elem-font-bold" name="elem-font-bold" value="bold">
<label for="elem-font-bold" class="btn btn-neutral">
<i class="fa fa-bold"></i>
</label>
<input type="checkbox" id="elem-font-italic" name="elem-font-italic" value="italic">
<label for="elem-font-italic" class="btn btn-neutral">
<i class="fa fa-italic"></i>
</label>
<input type="checkbox" id="elem-text-underline" name="elem-text-underline" value="underline">
<label for="elem-text-underline" class="btn btn-neutral">
<i class="fa fa-underline"></i>
</label>
</div>
</div>
</div>
<div class="form-group">
<label for="elem-font-family">Text Font Type</label>
<div class="widget">
<select name="elem-font-family" id="elem-font-family" class="size-m">
<option value="Arial">Arial</option>
<option value="Arial Black">Arial Black</option>
<option value="Verdana">Verdana</option>
<option value="Trebuchet MS">Trebuchet MS</option>
<option value="Georgia">Georgia</option>
<option value="Times New Roman">Times New Roman</option>
<option value="Courier New">Courier New</option>
<option value="Comic Sans MS">Comic Sans MS</option>
<option value="Impact">Impact</option>
<option value="Tahoma">Tahoma</option>
<option value="Gill Sans">Gill Sans</option>
<option value="Helvetica">Helvetica</option>
<option value="Optima">Optima</option>
<option value="Garamond">Garamond</option>
<option value="Baskerville">Baskerville</option>
<option value="Copperplate">Copperplate</option>
<option value="Futura">Futura</option>
<option value="Monaco">Monaco</option>
<option value="Andale Mono">Andale Mono</option>
</select>
</div>
</div>
<h3 class="divide"> <h3 class="divide">
{{ l.common_size }} Layout
</h3> </h3>
<div class="form-group"> <div class="form-group">
<label for="elem-width">{{ l.common_width }}</label> <label for="elem-container-margin">Container Margin</label>
<div class="widget"> <div class="widget widget-unit">
<input type="number" id="elem-width" name="elem-width"> <input type="text" id="elem-container-margin" name="elem-container-margin" maxlength="3" class="numeric-input chars-3" value="20">
<span>pt</span>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="elem-height">{{ l.common_height }}</label> <label for="elem-bg-color">Background Color</label>
<div class="widget"> <div class="widget">
<input type="number" id="elem-height" name="elem-height"> <input type="text" id="elem-bg-color" name="elem-bg-color" class="color-picker" data-jscolor="{ value: '#000000FF', backgroundColor: '#333333', shadowColor: '#000000', width: 120, height: 120 }" />
</div> </div>
</div> </div>
<div class="form-group">
<label for="elem-single-line">Single Line Only</label>
<div class="widget">
<div class="toggle">
<input type="checkbox" name="elem-single-line" id="elem-single-line" value="1" />
<label for="elem-single-line"></label>
</div>
</div>
</div>
</form> </form>
</div> </div>