Dev #2
@@ -206,6 +206,11 @@ body.builderBody > main.content{ flex:1 1 auto; min-height:0; overflow:hidden; d
|
||||
.floatPanel--left{ left:24px; width:280px; }
|
||||
.floatPanel--right{ right:24px; width:340px; }
|
||||
.floatPanel--center{ left:50%; width:560px; max-width:calc(100vw - 48px); transform:translateX(-50%); }
|
||||
/* Plein écran (voir makeFloatPanelFullscreenable() dans game_dashboard.html)
|
||||
— juste un repère visuel (bordure accent) sur le panneau agrandi, tout le
|
||||
positionnement réel est posé directement en style inline par le JS (pour
|
||||
pouvoir revenir exactement à la position/taille d'avant en sortant). */
|
||||
.floatPanel--fullscreen{ border-color:var(--accent); }
|
||||
.floatPanelHeader{
|
||||
display:flex; align-items:center; justify-content:space-between; gap:8px;
|
||||
padding:8px 10px; border-bottom:1px solid var(--border); background:var(--panel2);
|
||||
|
||||
@@ -221,6 +221,7 @@
|
||||
<div class="floatPanel floatPanel--center hidden" id="newObjectPanel">
|
||||
<div class="floatPanelHeader" id="newObjectPanelHeader">
|
||||
<span class="floatPanelTitle">⋮⋮ Nouvel objet</span>
|
||||
<button type="button" class="button is-small floatPanelFullscreenBtn" title="Plein écran">⛶</button>
|
||||
<button type="button" class="button is-small" onclick="closeNewObjectPanel()">✕</button>
|
||||
</div>
|
||||
<div class="floatPanelBody">
|
||||
@@ -261,6 +262,7 @@
|
||||
<div class="floatPanel floatPanel--center hidden objectEditPanel" data-definition-id="{{ d.id }}" id="objectEditPanel-{{ d.id }}">
|
||||
<div class="floatPanelHeader">
|
||||
<span class="floatPanelTitle">⋮⋮ {{ definition.name }}</span>
|
||||
<button type="button" class="button is-small floatPanelFullscreenBtn" title="Plein écran">⛶</button>
|
||||
<button type="button" class="button is-small" onclick="closeObjectEditPanel({{ d.id }})">✕</button>
|
||||
</div>
|
||||
<div class="floatPanelBody">
|
||||
@@ -458,6 +460,7 @@
|
||||
<div class="floatPanel floatPanel--center hidden addFieldPanel" data-definition-id="{{ d.id }}" id="addFieldPanel-{{ d.id }}">
|
||||
<div class="floatPanelHeader">
|
||||
<span class="floatPanelTitle">⋮⋮ Ajouter un champ — {{ definition.name }}</span>
|
||||
<button type="button" class="button is-small floatPanelFullscreenBtn" title="Plein écran">⛶</button>
|
||||
<button type="button" class="button is-small" onclick="closeAddFieldPanel({{ d.id }})">✕</button>
|
||||
</div>
|
||||
<div class="floatPanelBody">
|
||||
@@ -509,6 +512,7 @@
|
||||
<div class="floatPanel floatPanel--center hidden addEntryPanel" data-definition-id="{{ d.id }}" id="addEntryPanel-{{ d.id }}">
|
||||
<div class="floatPanelHeader">
|
||||
<span class="floatPanelTitle">⋮⋮ Ajouter une entrée — {{ definition.name }}</span>
|
||||
<button type="button" class="button is-small floatPanelFullscreenBtn" title="Plein écran">⛶</button>
|
||||
<button type="button" class="button is-small" onclick="closeAddEntryPanel({{ d.id }})">✕</button>
|
||||
</div>
|
||||
<div class="floatPanelBody">
|
||||
@@ -628,10 +632,15 @@ function makeFloatPanelDraggable(panel, header) {
|
||||
header.addEventListener('mousedown', function (e) {
|
||||
if (e.target.closest('button')) return;
|
||||
dragging = true;
|
||||
// Glisser un panneau en plein écran doit d'abord l'en faire sortir —
|
||||
// sinon left/top posés juste en dessous seraient aussitôt repris en
|
||||
// main par bottom/right encore actifs (voir makeFloatPanelFullscreenable).
|
||||
if (panel.classList.contains('floatPanel--fullscreen')) panel._fsToggle.exit();
|
||||
var rect = panel.getBoundingClientRect();
|
||||
panel.style.left = rect.left + 'px';
|
||||
panel.style.top = rect.top + 'px';
|
||||
panel.style.right = 'auto';
|
||||
panel.style.bottom = 'auto';
|
||||
panel.style.transform = 'none';
|
||||
offsetX = e.clientX - rect.left;
|
||||
offsetY = e.clientY - rect.top;
|
||||
@@ -651,6 +660,10 @@ function makeFloatPanelResizable(panel, handle) {
|
||||
var resizing = false, startX = 0, startY = 0, startW = 0, startH = 0;
|
||||
handle.addEventListener('mousedown', function (e) {
|
||||
resizing = true;
|
||||
// Même remarque que pour le glisser-déposer : sortir du plein écran
|
||||
// d'abord, sinon bottom/right encore actifs reprendraient la main sur
|
||||
// la largeur/hauteur posées ci-dessous.
|
||||
if (panel.classList.contains('floatPanel--fullscreen')) panel._fsToggle.exit();
|
||||
var rect = panel.getBoundingClientRect();
|
||||
startX = e.clientX; startY = e.clientY;
|
||||
startW = rect.width; startH = rect.height;
|
||||
@@ -673,13 +686,50 @@ function makeFloatPanelResizable(panel, handle) {
|
||||
document.body.style.userSelect = '';
|
||||
});
|
||||
}
|
||||
// Plein écran (voir switchDashTab pour l'esprit général : chaque panneau
|
||||
// s'ouvre en plein écran par défaut — plus pratique dès qu'il y a plus de
|
||||
// quelques champs — avec un bouton pour revenir à sa taille/position
|
||||
// précédente, mémorisée le temps de la session (pas persistée). Renvoie un
|
||||
// objet {enter, exit} et pose panel._fsToggle dessus, pour que le code qui
|
||||
// OUVRE le panneau (openXxxPanel ci-dessous) puisse appeler enter() sans
|
||||
// avoir à re-chercher le bouton.
|
||||
function makeFloatPanelFullscreenable(panel, toggleBtn) {
|
||||
var saved = null;
|
||||
function enter() {
|
||||
saved = {
|
||||
left: panel.style.left, top: panel.style.top, right: panel.style.right,
|
||||
width: panel.style.width, height: panel.style.height,
|
||||
maxWidth: panel.style.maxWidth, transform: panel.style.transform,
|
||||
};
|
||||
panel.classList.add('floatPanel--fullscreen');
|
||||
panel.style.left = '12px'; panel.style.top = '12px'; panel.style.right = '12px'; panel.style.bottom = '12px';
|
||||
panel.style.width = 'auto'; panel.style.height = 'auto'; panel.style.maxWidth = 'none'; panel.style.transform = 'none';
|
||||
toggleBtn.title = 'Quitter le plein écran';
|
||||
}
|
||||
function exit() {
|
||||
panel.classList.remove('floatPanel--fullscreen');
|
||||
panel.style.bottom = '';
|
||||
if (saved) {
|
||||
panel.style.left = saved.left; panel.style.top = saved.top; panel.style.right = saved.right;
|
||||
panel.style.width = saved.width; panel.style.height = saved.height;
|
||||
panel.style.maxWidth = saved.maxWidth; panel.style.transform = saved.transform;
|
||||
}
|
||||
toggleBtn.title = 'Plein écran';
|
||||
}
|
||||
toggleBtn.addEventListener('click', function () {
|
||||
if (panel.classList.contains('floatPanel--fullscreen')) exit(); else enter();
|
||||
});
|
||||
panel._fsToggle = { enter: enter, exit: exit };
|
||||
return panel._fsToggle;
|
||||
}
|
||||
|
||||
// ---------- Panneau déplaçable "Nouvel objet" ----------
|
||||
(function () {
|
||||
var panel = document.getElementById('newObjectPanel');
|
||||
makeFloatPanelDraggable(panel, document.getElementById('newObjectPanelHeader'));
|
||||
makeFloatPanelResizable(panel, document.getElementById('newObjectPanelResizeHandle'));
|
||||
window.openNewObjectPanel = function () { panel.classList.remove('hidden'); };
|
||||
makeFloatPanelFullscreenable(panel, panel.querySelector('.floatPanelFullscreenBtn'));
|
||||
window.openNewObjectPanel = function () { panel.classList.remove('hidden'); panel._fsToggle.enter(); };
|
||||
window.closeNewObjectPanel = function () { panel.classList.add('hidden'); };
|
||||
})();
|
||||
|
||||
@@ -688,10 +738,13 @@ function makeFloatPanelResizable(panel, handle) {
|
||||
document.querySelectorAll('.objectEditPanel').forEach(function (panel) {
|
||||
makeFloatPanelDraggable(panel, panel.querySelector('.floatPanelHeader'));
|
||||
makeFloatPanelResizable(panel, panel.querySelector('.floatPanelResizeHandle'));
|
||||
makeFloatPanelFullscreenable(panel, panel.querySelector('.floatPanelFullscreenBtn'));
|
||||
});
|
||||
window.openObjectEditPanel = function (definitionId, subtab) {
|
||||
document.querySelectorAll('.objectEditPanel').forEach(function (panel) {
|
||||
panel.classList.toggle('hidden', panel.dataset.definitionId !== String(definitionId));
|
||||
var isTarget = panel.dataset.definitionId === String(definitionId);
|
||||
panel.classList.toggle('hidden', !isTarget);
|
||||
if (isTarget) panel._fsToggle.enter();
|
||||
});
|
||||
if (subtab) {
|
||||
var panel = document.querySelector('.objectEditPanel[data-definition-id="' + definitionId + '"]');
|
||||
@@ -725,6 +778,7 @@ function makeFloatPanelResizable(panel, handle) {
|
||||
document.querySelectorAll('.addFieldPanel').forEach(function (panel) {
|
||||
makeFloatPanelDraggable(panel, panel.querySelector('.floatPanelHeader'));
|
||||
makeFloatPanelResizable(panel, panel.querySelector('.floatPanelResizeHandle'));
|
||||
makeFloatPanelFullscreenable(panel, panel.querySelector('.floatPanelFullscreenBtn'));
|
||||
|
||||
var typeSelect = panel.querySelector('.fieldTypeSelect');
|
||||
var relationTarget = panel.querySelector('.relationTarget');
|
||||
@@ -739,11 +793,12 @@ function makeFloatPanelResizable(panel, handle) {
|
||||
document.querySelectorAll('.addEntryPanel').forEach(function (panel) {
|
||||
makeFloatPanelDraggable(panel, panel.querySelector('.floatPanelHeader'));
|
||||
makeFloatPanelResizable(panel, panel.querySelector('.floatPanelResizeHandle'));
|
||||
makeFloatPanelFullscreenable(panel, panel.querySelector('.floatPanelFullscreenBtn'));
|
||||
});
|
||||
|
||||
window.openAddFieldPanel = function (definitionId) {
|
||||
var panel = document.querySelector('.addFieldPanel[data-definition-id="' + definitionId + '"]');
|
||||
if (panel) panel.classList.remove('hidden');
|
||||
if (panel) { panel.classList.remove('hidden'); panel._fsToggle.enter(); }
|
||||
};
|
||||
window.closeAddFieldPanel = function (definitionId) {
|
||||
var panel = document.querySelector('.addFieldPanel[data-definition-id="' + definitionId + '"]');
|
||||
@@ -751,7 +806,7 @@ function makeFloatPanelResizable(panel, handle) {
|
||||
};
|
||||
window.openAddEntryPanel = function (definitionId) {
|
||||
var panel = document.querySelector('.addEntryPanel[data-definition-id="' + definitionId + '"]');
|
||||
if (panel) panel.classList.remove('hidden');
|
||||
if (panel) { panel.classList.remove('hidden'); panel._fsToggle.enter(); }
|
||||
};
|
||||
window.closeAddEntryPanel = function (definitionId) {
|
||||
var panel = document.querySelector('.addEntryPanel[data-definition-id="' + definitionId + '"]');
|
||||
|
||||
Reference in New Issue
Block a user