Consolidate the properties panel: Position & taille, no more Taille/Survol/duplicate Disposition

- Merge "Taille dans le conteneur" into "Position & taille": a child
  element (posé dans un conteneur/répéteur/groupe de champs) now shows
  greyed-out X/Y (not applicable, it follows its parent's layout) and
  a single Largeur/Hauteur field per axis with a unit selector (%/px)
  instead of the old fixed-px-only sliders capped at 1000 — which was
  the root cause of a landscape-mode bug where a child couldn't be
  made wider than 1000px even though the actual screen was wider.
  New c_size control type (one style key per axis, not two competing
  sliders — an earlier px+% two-slider attempt let the untouched
  slider silently clobber the other's value on every autosave).
- Merge the two "Disposition" groups (visibility + scale, previously
  split apart in UNIVERSAL_CONTROLS by unrelated groups) into one.
- Remove the "Survol" panel: hovering is conceptually a flow trigger,
  not a static element property — to be reintroduced there. The
  underlying data-hover-text/bindHoverTexts runtime is untouched.
This commit is contained in:
william
2026-08-23 12:14:00 +02:00
parent d86b1a60c7
commit 4a593d07e4
9 changed files with 120 additions and 33 deletions
+37 -5
View File
@@ -188,21 +188,49 @@
</details>
{% endif %}
{% set size_ctrl_keys = ['child-width', 'child-height'] %}
{% set size_ctrls = {} %}
{% for c in selected_controls if c.key in size_ctrl_keys %}{% set _ = size_ctrls.update({c.key: c}) %}{% endfor %}
<form method="post" action="{{ url_for('element_save', slug=game.slug, element_id=el.id) }}" id="propsForm" onsubmit="event.preventDefault(); return false;">
<details class="propGroup" open>
<summary>Position &amp; taille</summary>
<div class="propGroupBody">
<div class="posGrid">
<label>X (%)<input type="number" id="pos-x" min="0" max="100" value="{{ el.x }}"></label>
<label>Y (%)<input type="number" id="pos-y" min="0" max="100" value="{{ el.y }}"></label>
<label>X (%)<input type="number" id="pos-x" min="0" max="100" value="{{ el.x }}" {{ 'disabled' if el.parent_id else '' }}></label>
<label>Y (%)<input type="number" id="pos-y" min="0" max="100" value="{{ el.y }}" {{ 'disabled' if el.parent_id else '' }}></label>
{% if el.parent_id %}
<label>Largeur
<div class="sizeField">
<input type="number" name="ctrl_child-width_value" min="0" value="{{ size_ctrls['child-width'].value.value or '' }}" placeholder="auto">
<select name="ctrl_child-width_unit">
<option value="%" {{ 'selected' if size_ctrls['child-width'].value.unit == '%' else '' }}>%</option>
<option value="px" {{ 'selected' if size_ctrls['child-width'].value.unit == 'px' else '' }}>px</option>
</select>
</div>
</label>
<label>Hauteur
<div class="sizeField">
<input type="number" name="ctrl_child-height_value" min="0" value="{{ size_ctrls['child-height'].value.value or '' }}" placeholder="auto">
<select name="ctrl_child-height_unit">
<option value="%" {{ 'selected' if size_ctrls['child-height'].value.unit == '%' else '' }}>%</option>
<option value="px" {{ 'selected' if size_ctrls['child-height'].value.unit == 'px' else '' }}>px</option>
</select>
</div>
</label>
{% else %}
<label>Largeur (%)<input type="number" id="pos-w" min="1" max="100" value="{{ el.width }}"></label>
<label>Hauteur (%)<input type="number" id="pos-h" min="1" max="100" value="{{ el.height }}"></label>
{% endif %}
</div>
{% if el.parent_id %}
<p class="hint">X/Y ne s'appliquent qu'à un élément posé directement sur l'écran — celui-ci suit la disposition de son conteneur. Largeur/Hauteur : laisser vide garde la taille automatique ; "%" (relatif au conteneur) convient à la plupart des cas, "px" pour une taille précise.</p>
{% endif %}
</div>
</details>
<form method="post" action="{{ url_for('element_save', slug=game.slug, element_id=el.id) }}" id="propsForm" onsubmit="event.preventDefault(); return false;">
{% set ns = namespace(last_group=None, started=False) %}
{% for c in selected_controls %}
{% for c in selected_controls if c.key not in size_ctrl_keys %}
{% if c.group != ns.last_group %}
{% if ns.started %}
</div>
@@ -767,7 +795,11 @@ function initBuilderPanel() {
(function () {
var xEl = document.getElementById('pos-x'), yEl = document.getElementById('pos-y');
var wEl = document.getElementById('pos-w'), hEl = document.getElementById('pos-h');
if (!xEl) return;
// pos-w/pos-h n'existent pas pour un élément posé dans un conteneur (sa
// taille se règle via les champs "Largeur/Hauteur (%)"/"fixe (px)" du
// formulaire général à la place, voir size_ctrls plus haut) — X/Y non
// plus, mais ils restent dans le DOM (juste désactivés) pour cet élément.
if (!xEl || !wEl) return;
function apply() {
var canvasEl = document.getElementById('el-' + CURRENT_SELECTED_ID);
var x = parseFloat(xEl.value) || 0, y = parseFloat(yEl.value) || 0;