0.10.7: fire scripts at play-start + right-click duplicate script frame

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.7 committed 2026-04-22 19:39:26 +02:00
1 parent 0bbef66192
commit 34d1a89d56
6 files changed
+313 -15

No files matched your search

+62 -2
View File
@@ -1124,6 +1124,36 @@ function onScriptFramePointerUp(e: PointerEvent) {
sfDrag.value = null
}
interface ScriptFrameMenuState {
frameId: string
x: number
y: number
}
const scriptFrameMenu = ref<ScriptFrameMenuState | null>(null)
const scriptFrameMenuRef = ref<HTMLDivElement | null>(null)
function onScriptFrameContextMenu(e: MouseEvent, frameId: string) {
e.preventDefault()
e.stopPropagation()
scriptFrameMenu.value = { frameId, x: e.clientX, y: e.clientY }
}
function duplicateScriptFrameFromMenu() {
const m = scriptFrameMenu.value
if (!m) return
const newId = store.duplicateScriptFrame(m.frameId)
scriptFrameMenu.value = null
if (newId) openScriptFrame(newId)
}
function deleteScriptFrameFromMenu() {
const m = scriptFrameMenu.value
if (!m) return
store.removeScriptFrame(m.frameId)
scriptFrameMenu.value = null
}
// ---------------------------------------------------------------------------
interface KfSegment {
@@ -2486,12 +2516,18 @@ function onDocumentPointerDown(e: PointerEvent) {
} else if (trackMenu.value) {
trackMenu.value = null
}
if (scriptFrameMenu.value && scriptFrameMenuRef.value && e.target instanceof Node) {
if (!scriptFrameMenuRef.value.contains(e.target)) scriptFrameMenu.value = null
} else if (scriptFrameMenu.value) {
scriptFrameMenu.value = null
}
}
function onKeyDown(e: KeyboardEvent) {
if (e.key === 'Escape') {
menu.value = null
trackMenu.value = null
scriptFrameMenu.value = null
}
}
@@ -2557,8 +2593,8 @@ function onDocumentKeyDown(e: KeyboardEvent) {
}
}
watch([menu, trackMenu], ([m, tm]) => {
if (m || tm) {
watch([menu, trackMenu, scriptFrameMenu], ([m, tm, sm]) => {
if (m || tm || sm) {
document.addEventListener('pointerdown', onDocumentPointerDown, true)
document.addEventListener('keydown', onKeyDown)
} else {
@@ -2597,6 +2633,11 @@ watch(trackMenu, (tm) => {
clampMenuIntoViewport(() => trackMenuRef.value, tm.x, tm.y)
})
watch(scriptFrameMenu, (sm) => {
if (!sm) return
clampMenuIntoViewport(() => scriptFrameMenuRef.value, sm.x, sm.y)
})
function onWheel(e: WheelEvent) {
if (!scrollEl.value) return
if (e.ctrlKey || e.metaKey) {
@@ -3220,6 +3261,7 @@ onBeforeUnmount(() => {
@pointermove="onScriptFramePointerMove"
@pointerup="onScriptFramePointerUp"
@pointercancel="onScriptFramePointerUp"
@contextmenu="!track.locked ? onScriptFrameContextMenu($event, frame.id) : null"
>
<span class="script-frame-dot"></span>
<span v-if="frame.actions.length > 1" class="script-frame-count">{{ frame.actions.length }}</span>
@@ -3611,6 +3653,24 @@ onBeforeUnmount(() => {
}}
</button>
</div>
<div
v-if="scriptFrameMenu"
ref="scriptFrameMenuRef"
class="kf-menu"
:style="{ left: scriptFrameMenu.x + 'px', top: scriptFrameMenu.y + 'px' }"
>
<button class="kf-menu-item" @click="duplicateScriptFrameFromMenu">
<PhCopy :size="12" class="kf-menu-icon" />
{{ t('timeline.duplicate') }}
</button>
<div class="kf-menu-divider"></div>
<button class="kf-menu-item danger" @click="deleteScriptFrameFromMenu">
<PhTrash :size="12" class="kf-menu-icon" />
{{ t('timeline.delete') }}
</button>
</div>
<ScriptFrameDialog
v-model="scriptDialogOpen"
:frame-id="scriptDialogFrameId"