mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
feat: clipboard with keyframe paste
Made-with: Cursor
This commit is contained in:
@@ -8,6 +8,7 @@ import { CommandManager } from "./managers/commands";
|
||||
import { SaveManager } from "./managers/save-manager";
|
||||
import { AudioManager } from "./managers/audio-manager";
|
||||
import { SelectionManager } from "./managers/selection-manager";
|
||||
import { ClipboardManager } from "./managers/clipboard-manager";
|
||||
import { registerDefaultEffects } from "@/lib/effects";
|
||||
import { registerDefaultMasks } from "@/lib/masks";
|
||||
|
||||
@@ -23,6 +24,7 @@ export class EditorCore {
|
||||
public readonly save: SaveManager;
|
||||
public readonly audio: AudioManager;
|
||||
public readonly selection: SelectionManager;
|
||||
public readonly clipboard: ClipboardManager;
|
||||
|
||||
private constructor() {
|
||||
registerDefaultEffects();
|
||||
@@ -37,6 +39,8 @@ export class EditorCore {
|
||||
this.save = new SaveManager(this);
|
||||
this.audio = new AudioManager(this);
|
||||
this.selection = new SelectionManager(this);
|
||||
this.clipboard = new ClipboardManager(this);
|
||||
this.playback.bindTimelineScope();
|
||||
this.command.registerReactor(() => {
|
||||
const activeScene = this.scenes.getActiveSceneOrNull();
|
||||
if (!activeScene) {
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import type { EditorCore } from "@/core";
|
||||
import {
|
||||
buildPasteClipboardCommand,
|
||||
copyClipboardEntry,
|
||||
type ClipboardEntry,
|
||||
type CopyContext,
|
||||
type PasteContext,
|
||||
} from "@/lib/clipboard";
|
||||
|
||||
export class ClipboardManager {
|
||||
private entry: ClipboardEntry | null = null;
|
||||
private listeners = new Set<() => void>();
|
||||
|
||||
constructor(private editor: EditorCore) {}
|
||||
|
||||
getEntry(): ClipboardEntry | null {
|
||||
return this.entry;
|
||||
}
|
||||
|
||||
hasEntry(): boolean {
|
||||
return this.entry !== null;
|
||||
}
|
||||
|
||||
copy(): boolean {
|
||||
const entry = copyClipboardEntry({
|
||||
context: this.getCopyContext(),
|
||||
});
|
||||
if (!entry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.entry = entry;
|
||||
this.notify();
|
||||
return true;
|
||||
}
|
||||
|
||||
paste({ time }: { time?: number } = {}): boolean {
|
||||
if (!this.entry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const command = buildPasteClipboardCommand({
|
||||
entry: this.entry,
|
||||
context: this.getPasteContext({ time }),
|
||||
});
|
||||
if (!command) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.editor.command.execute({ command });
|
||||
return true;
|
||||
}
|
||||
|
||||
subscribe(listener: () => void): () => void {
|
||||
this.listeners.add(listener);
|
||||
return () => this.listeners.delete(listener);
|
||||
}
|
||||
|
||||
private getCopyContext(): CopyContext {
|
||||
return {
|
||||
editor: this.editor,
|
||||
selectedElements: this.editor.selection.getSelectedElements(),
|
||||
selectedKeyframes: this.editor.selection.getSelectedKeyframes(),
|
||||
};
|
||||
}
|
||||
|
||||
private getPasteContext({ time }: { time?: number }): PasteContext {
|
||||
return {
|
||||
editor: this.editor,
|
||||
selectedElements: this.editor.selection.getSelectedElements(),
|
||||
selectedKeyframes: this.editor.selection.getSelectedKeyframes(),
|
||||
time: time ?? this.editor.playback.getCurrentTime(),
|
||||
};
|
||||
}
|
||||
|
||||
private notify(): void {
|
||||
this.listeners.forEach((listener) => {
|
||||
listener();
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user