Skip to content

Commit 7d28eb3

Browse files
Update interface
1 parent e758c2e commit 7d28eb3

3 files changed

Lines changed: 254 additions & 51 deletions

File tree

public/app.mjs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -248,18 +248,18 @@ function summarizeTransition(config) {
248248
function setSyncState(kind, text) {
249249
syncIndicatorDot.dataset.state = kind;
250250
syncIndicatorText.textContent = text;
251-
livePreviewBadge.textContent = kind === "error" ? "Validation" : kind === "pending" ? "Projection..." : "Apercu live";
252-
liveModeText.textContent = kind === "error" ? "Correction requise" : kind === "pending" ? "Recomposition en cours" : "Apercu temps reel actif";
251+
if (livePreviewBadge) livePreviewBadge.textContent = kind === "error" ? "Validation" : kind === "pending" ? "Projection..." : "Apercu live";
252+
if (liveModeText) liveModeText.textContent = kind === "error" ? "Correction requise" : kind === "pending" ? "Recomposition en cours" : "Apercu temps reel actif";
253253
}
254254

255255
function updateLiveNarrative(config, source, live) {
256256
const sourceLabel = source || "Configuration";
257257
const liveLabel = live ? "Projection immediate" : "Synchronisation";
258-
livePreviewOrigin.textContent = `${liveLabel} depuis ${sourceLabel}`;
259-
livePreviewSummary.textContent = `${summarizeConfig(config)}. ${summarizeTransition(config)}`;
260-
liveImpactText.textContent = `Impact direct: ${config.mode_regle} sur ${config.largeur} x ${config.hauteur}`;
261-
universeLiveSummary.innerHTML = `<span class="live-summary-label">Projection</span><strong>${summarizeConfig(config)}</strong>`;
262-
transitionLiveSummary.innerHTML = `<span class="live-summary-label">Reponse</span><strong>${summarizeTransition(config)}</strong>`;
258+
if (livePreviewOrigin) livePreviewOrigin.textContent = `${liveLabel} depuis ${sourceLabel}`;
259+
if (livePreviewSummary) livePreviewSummary.textContent = `${summarizeConfig(config)}. ${summarizeTransition(config)}`;
260+
if (liveImpactText) liveImpactText.textContent = `Impact direct: ${config.mode_regle} sur ${config.largeur} x ${config.hauteur}`;
261+
if (universeLiveSummary) universeLiveSummary.innerHTML = `<span class="live-summary-label">Projection</span><strong>${summarizeConfig(config)}</strong>`;
262+
if (transitionLiveSummary) transitionLiveSummary.innerHTML = `<span class="live-summary-label">Reponse</span><strong>${summarizeTransition(config)}</strong>`;
263263
}
264264

265265
function renderTransitionSignals(config) {
@@ -373,8 +373,8 @@ function applyConfig(config, { updateJson = true, updateControls = true, source
373373
showStatus(validation);
374374
if (!validation.valid) {
375375
setSyncState("error", `Correction requise: ${validation.errors[0] || "configuration invalide"}`);
376-
livePreviewOrigin.textContent = `Validation depuis ${source}`;
377-
livePreviewSummary.textContent = validation.errors.join(" ");
376+
if (livePreviewOrigin) livePreviewOrigin.textContent = `Validation depuis ${source}`;
377+
if (livePreviewSummary) livePreviewSummary.textContent = validation.errors.join(" ");
378378
return false;
379379
}
380380
state.config = normalized;

public/index.html

Lines changed: 100 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,36 +22,17 @@ <h1 id="app-title">Automaginarium</h1>
2222
</header>
2323

2424
<main class="app-shell">
25-
<section class="hero-band" aria-labelledby="app-title">
26-
<div class="hero-copy">
27-
<p class="eyebrow">Laboratoire interactif</p>
28-
<p class="lede">Un laboratoire de r&egrave;gles, d'alphabets et de voisinages pour faire appara&icirc;tre des univers configurables.</p>
29-
</div>
30-
<div class="hero-signals" aria-label="Signaux du laboratoire">
31-
<div class="hero-signal-card">
32-
<span class="hero-signal-label">Flux</span>
33-
<strong>Param&egrave;tres -&gt; R&egrave;gles -&gt; Univers</strong>
34-
</div>
35-
<div class="hero-signal-card">
36-
<span class="hero-signal-label">Mode</span>
37-
<strong id="live-mode-text">Aper&ccedil;u temps r&eacute;el actif</strong>
38-
</div>
39-
<div class="hero-signal-card">
40-
<span class="hero-signal-label">Impact</span>
41-
<strong id="live-impact-text">Chaque ajustement recompose l'univers</strong>
42-
</div>
25+
<section class="hero-band minimal" aria-labelledby="app-title">
26+
<div class="hero-indicator">
27+
<span class="sync-pulse" id="hero-sync-dot"></span>
28+
<span id="hero-status-text">Synchronisation live</span>
4329
</div>
4430
</section>
4531

4632
<section id="main-panel" class="workspace" aria-label="Univers g&eacute;n&eacute;r&eacute;">
4733
<div class="canvas-wrap">
4834
<div class="canvas-aura" aria-hidden="true"></div>
4935
<canvas id="universe" width="805" height="500"></canvas>
50-
<div class="canvas-story glass-panel" aria-live="polite">
51-
<span class="live-badge" id="live-preview-badge">Aper&ccedil;u live</span>
52-
<strong id="live-preview-origin">Univers synchronis&eacute;</strong>
53-
<p id="live-preview-summary">Les param&egrave;tres et les r&egrave;gles se projettent ici en temps r&eacute;el.</p>
54-
</div>
5536
<div class="canvas-hud">
5637
<div class="hud-metric">
5738
<strong id="hud-rule">90</strong>
@@ -85,14 +66,37 @@ <h1 id="app-title">Automaginarium</h1>
8566

8667
<aside class="inspector">
8768
<div class="inspector-tabs">
88-
<button type="button" class="inspector-tab-btn active" data-panel="info">Infos</button>
69+
<button type="button" class="inspector-tab-btn active" data-panel="univers">Univers</button>
70+
<button type="button" class="inspector-tab-btn" data-panel="transition">Transition</button>
71+
<button type="button" class="inspector-tab-btn" data-panel="info">Infos</button>
8972
<button type="button" class="inspector-tab-btn" data-panel="display">Affichage</button>
9073
<button type="button" class="inspector-tab-btn" data-panel="rules">R&egrave;gles</button>
9174
<button type="button" class="inspector-tab-btn" data-panel="analytics">Analyse</button>
9275
<button type="button" class="inspector-tab-btn" data-panel="advanced">Avanc&eacute;</button>
9376
</div>
9477

95-
<div id="info-panel" class="inspector-panel active">
78+
<div id="univers-panel" class="inspector-panel active">
79+
<p class="eyebrow">Param&egrave;tres</p>
80+
<h3>Univers</h3>
81+
<div class="field-grid compact-fields">
82+
<label>Alphabet<input id="alphabet-input-quick" type="text" placeholder="0,1,2" /></label>
83+
<label>Voisinage<input id="neighborhood-size-quick" type="number" min="1" max="9" step="1" /></label>
84+
<label>Largeur<input id="grid-width-quick" type="number" min="21" max="401" step="2" value="805" /></label>
85+
<label>Hauteur<input id="grid-height-quick" type="number" min="20" max="240" step="5" value="500" /></label>
86+
</div>
87+
</div>
88+
89+
<div id="transition-panel" class="inspector-panel">
90+
<p class="eyebrow">R&egrave;gles</p>
91+
<h3>Espace de transition</h3>
92+
<div class="field-grid compact-fields">
93+
<label>Mode<select id="rule-mode-quick"><option value="table">Table</option><option value="totalistique">Totalistique</option><option value="aleatoire">Al&eacute;atoire</option></select></label>
94+
<label>Wolfram<input id="wolfram-rule-quick" type="number" min="0" max="255" step="1" value="90" /></label>
95+
<button id="generate-rule-quick" type="button">G&eacute;n&eacute;rer</button>
96+
</div>
97+
</div>
98+
99+
<div id="info-panel" class="inspector-panel">
96100
<p class="eyebrow">Configuration active</p>
97101
<h2 id="config-title">Chargement...</h2>
98102
<p id="config-meta" class="meta"></p>
@@ -257,7 +261,7 @@ <h2>Univers</h2>
257261
<label>Nom<input id="config-name" type="text" /></label>
258262
<label>Alphabet entr&eacute;e<input id="alphabet-input" type="text" placeholder="0,1,2 ou air,feu,eau" /></label>
259263
<label>Alphabet sortie<input id="alphabet-output" type="text" placeholder="0,1" /></label>
260-
<label>Voisinage<input id="neighborhood-size" type="number" min="1" max="9" step="2" /></label>
264+
<label>Voisinage<input id="neighborhood-size" type="number" min="1" max="9" step="1" /></label>
261265
<label>Canaux sortie<input id="channel-count" type="number" min="1" max="4" step="1" /></label>
262266
<label>Largeur<input id="grid-width" type="number" min="21" max="401" step="2" /></label>
263267
<label>Hauteur<input id="grid-height" type="number" min="20" max="240" step="5" /></label>
@@ -344,6 +348,12 @@ <h2>Configuration brute</h2>
344348
btn.classList.add('active');
345349
document.documentElement.setAttribute('data-palette', btn.dataset.palette);
346350
localStorage.setItem('palette-preference', btn.dataset.palette);
351+
setTimeout(() => {
352+
if (typeof window.updatePaletteEditor === 'function') {
353+
window.updatePaletteEditor();
354+
}
355+
window.AutomaginariumApp?.render?.();
356+
}, 0);
347357
});
348358
});
349359

@@ -433,11 +443,19 @@ <h2>Configuration brute</h2>
433443
document.getElementById('canvas-reset').addEventListener('click', () => {
434444
zoomLevel = 100;
435445
document.getElementById('canvas-zoom-display').textContent = '100%';
446+
if (window.AutomaginariumApp?.render) {
447+
window.AutomaginariumApp.render();
448+
}
436449
});
437450

438-
setInterval(() => {
439-
document.getElementById('hud-rule').textContent = document.getElementById('wolfram-rule').value;
440-
}, 500);
451+
function updateHUDRule() {
452+
const ruleValue = document.getElementById('wolfram-rule')?.value || document.getElementById('wolfram-rule-quick')?.value || '90';
453+
document.getElementById('hud-rule').textContent = ruleValue;
454+
}
455+
456+
updateHUDRule();
457+
document.getElementById('wolfram-rule')?.addEventListener('input', updateHUDRule);
458+
document.getElementById('wolfram-rule-quick')?.addEventListener('input', updateHUDRule);
441459

442460
let isPlaying = false;
443461
let simulationSpeed = 5;
@@ -451,6 +469,9 @@ <h2>Configuration brute</h2>
451469
playBtn.classList.add('hidden');
452470
pauseBtn.classList.remove('hidden');
453471
document.documentElement.setAttribute('data-playing', 'true');
472+
if (window.AutomaginariumApp?.render) {
473+
window.AutomaginariumApp.render();
474+
}
454475
});
455476

456477
pauseBtn.addEventListener('click', () => {
@@ -730,6 +751,56 @@ <h2>Configuration brute</h2>
730751
commandPalette.addEventListener('click', (e) => {
731752
if (e.target === commandPalette) closeCommandPalette();
732753
});
754+
755+
// Sync quick controls with main config fields
756+
const syncPairs = [
757+
{ quick: 'alphabet-input-quick', main: 'alphabet-input' },
758+
{ quick: 'neighborhood-size-quick', main: 'neighborhood-size' },
759+
{ quick: 'grid-width-quick', main: 'grid-width' },
760+
{ quick: 'grid-height-quick', main: 'grid-height' },
761+
{ quick: 'rule-mode-quick', main: 'rule-mode' },
762+
{ quick: 'wolfram-rule-quick', main: 'wolfram-rule' }
763+
];
764+
765+
syncPairs.forEach(pair => {
766+
const quickEl = document.getElementById(pair.quick);
767+
const mainEl = document.getElementById(pair.main);
768+
if (quickEl && mainEl) {
769+
quickEl.addEventListener('input', () => {
770+
const oldValue = mainEl.value;
771+
mainEl.value = quickEl.value;
772+
mainEl.dispatchEvent(new Event('input', { bubbles: true }));
773+
mainEl.dispatchEvent(new Event('change', { bubbles: true }));
774+
775+
// When neighborhood changes, regenerate the rule table to match new structure
776+
if (pair.quick === 'neighborhood-size-quick' && oldValue !== quickEl.value) {
777+
const ruleGen = document.getElementById('rule-generator');
778+
const newNeighborhood = Number(quickEl.value);
779+
780+
// If using Wolfram but neighborhood is not 3, switch to random generator
781+
if (ruleGen && ruleGen.value === 'wolfram' && newNeighborhood !== 3) {
782+
ruleGen.value = 'random';
783+
}
784+
785+
// Regenerate rules for the new neighborhood
786+
const generateBtnMain = document.getElementById('generate-rule');
787+
if (generateBtnMain) {
788+
setTimeout(() => generateBtnMain.click(), 100);
789+
}
790+
}
791+
});
792+
mainEl.addEventListener('input', () => {
793+
quickEl.value = mainEl.value;
794+
});
795+
}
796+
});
797+
798+
// Generate rule button sync
799+
const generateBtnQuick = document.getElementById('generate-rule-quick');
800+
const generateBtnMain = document.getElementById('generate-rule');
801+
if (generateBtnQuick && generateBtnMain) {
802+
generateBtnQuick.addEventListener('click', () => generateBtnMain.click());
803+
}
733804
</script>
734805
</body>
735806
</html>

0 commit comments

Comments
 (0)