Add option to trigger "selection changed" callback in realtime

This commit is contained in:
Rob Watson 2022-01-15 18:14:16 +01:00
parent bb3366ac9a
commit f386e12f72
4 changed files with 29 additions and 13 deletions

View File

@ -214,10 +214,18 @@ function App(): JSX.Element {
};
// handler called when the selection in the main waveform view is changed.
const handleWaveformSelectionChange = (newSelection: Frames) => {
const handleWaveformSelectionChange = (
newSelection: Frames,
final: boolean
) => {
if (mediaSet == null) {
return;
}
setSelection(newSelection);
if (mediaSet == null) {
// only update playback position when the selection is final.
if (!final) {
return;
}

View File

@ -14,7 +14,7 @@ interface Props {
styles: Styles;
position: number | null;
selection: Selection;
onSelectionChange: (selection: Selection) => void;
onSelectionChange: (selection: Selection, final: boolean) => void;
}
enum Mode {
@ -79,6 +79,10 @@ export const HudCanvas: React.FC<Props> = ({
};
}, [mode, newSelection]);
useEffect(() => {
onSelectionChange({ ...newSelection }, mode == Mode.Normal);
}, [mode, newSelection]);
// draw the overview HUD
useEffect(() => {
requestAnimationFrame(() => {
@ -279,8 +283,6 @@ export const HudCanvas: React.FC<Props> = ({
handleEmptySelectionAction();
return;
}
onSelectionChange({ ...newSelection });
};
const handleEmptySelectionAction = () => {
@ -289,7 +291,8 @@ export const HudCanvas: React.FC<Props> = ({
setNewSelection({ ...selection });
break;
case EmptySelectionAction.SelectNothing:
onSelectionChange({ start: 0, end: 0 });
setMode(Mode.Normal);
setNewSelection({ start: 0, end: 0 });
break;
}
};

View File

@ -56,7 +56,10 @@ export const Overview: React.FC<Props> = ({
// handlers
// convert selection change from canvas pixels to frames, and trigger callback.
const handleSelectionChange = ({ start, end }: Selection) => {
const handleSelectionChange = ({ start, end }: Selection, final: boolean) => {
if (!final) {
return;
}
onSelectionChange({
start: Math.round((start / CanvasLogicalWidth) * mediaSet.audioFrames),
end: Math.round((end / CanvasLogicalWidth) * mediaSet.audioFrames),

View File

@ -10,7 +10,7 @@ interface Props {
mediaSet: MediaSet;
position: VideoPosition;
viewport: Frames;
onSelectionChange: (selection: Selection) => void;
onSelectionChange: (selection: Selection, final: boolean) => void;
}
export const CanvasLogicalWidth = 2000;
@ -91,17 +91,19 @@ export const Waveform: React.FC<Props> = ({
// handlers
const handleSelectionChange = (selection: Selection) => {
setSelectedPixels(selection);
const handleSelectionChange = (selection: Selection, final: boolean) => {
const framesPerPixel = (viewport.end - viewport.start) / CanvasLogicalWidth;
const selectedFrames = {
start: Math.round(viewport.start + selection.start * framesPerPixel),
end: Math.round(viewport.start + selection.end * framesPerPixel),
};
if (final) {
setSelectedPixels(selection);
setSelectedFrames(selectedFrames);
onSelectionChange(selectedFrames);
}
onSelectionChange(selectedFrames, final);
};
// helpers