diff options
Diffstat (limited to 'tools/timeline_editor')
| -rw-r--r-- | tools/timeline_editor/index.html | 98 |
1 files changed, 61 insertions, 37 deletions
diff --git a/tools/timeline_editor/index.html b/tools/timeline_editor/index.html index c6c54bd..5ab8ed0 100644 --- a/tools/timeline_editor/index.html +++ b/tools/timeline_editor/index.html @@ -663,28 +663,12 @@ seq._yPosition = cumulativeY; cumulativeY += seqHeight + sequenceGap; - // Format time display based on mode (show visual start, not seq.startTime) - let seqTimeDisplay; - if (showBeats) { - const beatDuration = 60.0 / bpm; - const startBeat = (seqVisualStart / beatDuration).toFixed(1); - seqTimeDisplay = `Start: ${startBeat}b`; - } else { - seqTimeDisplay = `Start: ${seqVisualStart.toFixed(2)}s`; - } - // Create sequence name overlay (large, centered, fades on hover) const seqNameDiv = document.createElement('div'); seqNameDiv.className = 'sequence-name'; seqNameDiv.textContent = seq.name || `Sequence ${seqIndex + 1}`; - // Create small info text in corner - const seqInfoDiv = document.createElement('div'); - seqInfoDiv.className = 'sequence-info'; - seqInfoDiv.innerHTML = `${seqTimeDisplay} | Priority: ${seq.priority}`; - seqDiv.appendChild(seqNameDiv); - seqDiv.appendChild(seqInfoDiv); if (selectedItem && selectedItem.type === 'sequence' && selectedItem.index === seqIndex) { seqDiv.classList.add('selected'); @@ -912,70 +896,110 @@ propertiesContent.innerHTML = ` <div class="property-group"> <label>Name</label> - <input type="text" id="propName" value="${seq.name || ''}" placeholder="Sequence name"> + <input type="text" id="propName" value="${seq.name || ''}" placeholder="Sequence name" oninput="autoApplyProperties()"> </div> <div class="property-group"> <label>Start Time (seconds)</label> - <input type="number" id="propStartTime" value="${seq.startTime}" step="0.1" min="0"> - </div> - <div class="property-group"> - <label>Priority</label> - <input type="number" id="propPriority" value="${seq.priority}" step="1"> + <input type="number" id="propStartTime" value="${seq.startTime}" step="0.1" min="0" oninput="autoApplyProperties()"> </div> - <button onclick="applyProperties()">Apply</button> `; } else if (selectedItem.type === 'effect') { const effect = sequences[selectedItem.seqIndex].effects[selectedItem.effectIndex]; + const effects = sequences[selectedItem.seqIndex].effects; + const canMoveUp = selectedItem.effectIndex < effects.length - 1; + const canMoveDown = selectedItem.effectIndex > 0; + const samePriority = effect.priorityModifier === '='; + propertiesContent.innerHTML = ` <div class="property-group"> <label>Effect Class</label> - <input type="text" id="propClassName" value="${effect.className}"> + <input type="text" id="propClassName" value="${effect.className}" oninput="autoApplyProperties()"> </div> <div class="property-group"> <label>Start Time (relative to sequence)</label> - <input type="number" id="propStartTime" value="${effect.startTime}" step="0.1" min="0"> + <input type="number" id="propStartTime" value="${effect.startTime}" step="0.1" oninput="autoApplyProperties()"> </div> <div class="property-group"> <label>End Time (relative to sequence)</label> - <input type="number" id="propEndTime" value="${effect.endTime}" step="0.1" min="0"> + <input type="number" id="propEndTime" value="${effect.endTime}" step="0.1" oninput="autoApplyProperties()"> </div> <div class="property-group"> - <label>Priority</label> - <input type="number" id="propPriority" value="${effect.priority}" step="1"> + <label>Constructor Arguments</label> + <input type="text" id="propArgs" value="${effect.args || ''}" oninput="autoApplyProperties()"> </div> <div class="property-group"> - <label>Constructor Arguments</label> - <input type="text" id="propArgs" value="${effect.args}"> + <label>Stack Position (determines priority)</label> + <div style="display: flex; gap: 5px; margin-bottom: 10px;"> + <button onclick="moveEffectUp()" ${!canMoveUp ? 'disabled' : ''} style="flex: 1;">↑ Up</button> + <button onclick="moveEffectDown()" ${!canMoveDown ? 'disabled' : ''} style="flex: 1;">↓ Down</button> + </div> + <button onclick="toggleSamePriority()" style="width: 100%;"> + ${samePriority ? '✓ Same as Above (=)' : 'Increment (+)'} + </button> </div> - <button onclick="applyProperties()">Apply</button> `; } } - function applyProperties() { + // Auto-apply properties on input change (no Apply button needed) + function autoApplyProperties() { if (!selectedItem) return; if (selectedItem.type === 'sequence') { const seq = sequences[selectedItem.index]; seq.name = document.getElementById('propName').value; seq.startTime = parseFloat(document.getElementById('propStartTime').value); - seq.priority = parseInt(document.getElementById('propPriority').value); } else if (selectedItem.type === 'effect') { const effect = sequences[selectedItem.seqIndex].effects[selectedItem.effectIndex]; effect.className = document.getElementById('propClassName').value; effect.startTime = parseFloat(document.getElementById('propStartTime').value); effect.endTime = parseFloat(document.getElementById('propEndTime').value); - effect.priority = parseInt(document.getElementById('propPriority').value); effect.args = document.getElementById('propArgs').value; } // Re-render timeline (recalculates sequence bounds) renderTimeline(); + } - // Update properties panel to reflect any calculated changes - updateProperties(); + // Move effect up in stack (higher priority) + function moveEffectUp() { + if (!selectedItem || selectedItem.type !== 'effect') return; - showMessage('Properties updated', 'success'); + const effects = sequences[selectedItem.seqIndex].effects; + const index = selectedItem.effectIndex; + + if (index < effects.length - 1) { + // Swap with effect above + [effects[index], effects[index + 1]] = [effects[index + 1], effects[index]]; + selectedItem.effectIndex = index + 1; + renderTimeline(); + updateProperties(); + } + } + + // Move effect down in stack (lower priority) + function moveEffectDown() { + if (!selectedItem || selectedItem.type !== 'effect') return; + + const effects = sequences[selectedItem.seqIndex].effects; + const index = selectedItem.effectIndex; + + if (index > 0) { + // Swap with effect below + [effects[index], effects[index - 1]] = [effects[index - 1], effects[index]]; + selectedItem.effectIndex = index - 1; + renderTimeline(); + updateProperties(); + } + } + + // Toggle same priority as previous effect (= modifier) + function toggleSamePriority() { + if (!selectedItem || selectedItem.type !== 'effect') return; + + const effect = sequences[selectedItem.seqIndex].effects[selectedItem.effectIndex]; + effect.priorityModifier = effect.priorityModifier === '=' ? '+' : '='; + updateProperties(); } // File operations |
