mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-22 02:12:30 +01:00
implent customisable wheel modifiers #1884
- <kbd>alt</kbd> (customisable) + wheel: seek 1 frame - <kbd>shift</kbd> (customisable) + wheel: seek keyframe
This commit is contained in:
parent
2452de6de5
commit
b855e9e7d1
@ -132,6 +132,8 @@ const defaults: Config = {
|
|||||||
storeProjectInWorkingDir: true,
|
storeProjectInWorkingDir: true,
|
||||||
enableOverwriteOutput: true,
|
enableOverwriteOutput: true,
|
||||||
mouseWheelZoomModifierKey: 'ctrl',
|
mouseWheelZoomModifierKey: 'ctrl',
|
||||||
|
mouseWheelFrameSeekModifierKey: 'alt',
|
||||||
|
mouseWheelKeyframeSeekModifierKey: 'shift',
|
||||||
captureFrameMethod: 'videotag', // we don't default to ffmpeg because ffmpeg might choose a frame slightly off
|
captureFrameMethod: 'videotag', // we don't default to ffmpeg because ffmpeg might choose a frame slightly off
|
||||||
captureFrameQuality: 0.95,
|
captureFrameQuality: 0.95,
|
||||||
captureFrameFileNameFormat: 'timestamp',
|
captureFrameFileNameFormat: 'timestamp',
|
||||||
|
@ -171,7 +171,7 @@ function App() {
|
|||||||
const allUserSettings = useUserSettingsRoot();
|
const allUserSettings = useUserSettingsRoot();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, autoMerge, timecodeFormat, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, askBeforeClose, enableAskForImportChapters, enableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, wheelSensitivity, invertTimelineScroll, language, ffmpegExperimental, hideNotifications, hideOsNotifications, autoLoadTimecode, autoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, mergedFileTemplate, setMergedFileTemplate, keyboardSeekAccFactor, keyboardNormalSeekSpeed, keyboardSeekSpeed2, keyboardSeekSpeed3, treatInputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName, enableAutoHtml5ify, segmentsToChaptersOnly, keyBindings, setKeyBindings, resetKeyBindings, enableSmartCut, customFfPath, storeProjectInWorkingDir, setStoreProjectInWorkingDir, enableOverwriteOutput, mouseWheelZoomModifierKey, captureFrameMethod, captureFrameQuality, captureFrameFileNameFormat, enableNativeHevc, cleanupChoices, setCleanupChoices, darkMode, setDarkMode, preferStrongColors, outputFileNameMinZeroPadding, cutFromAdjustmentFrames,
|
captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, autoMerge, timecodeFormat, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, askBeforeClose, enableAskForImportChapters, enableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, wheelSensitivity, invertTimelineScroll, language, ffmpegExperimental, hideNotifications, hideOsNotifications, autoLoadTimecode, autoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, mergedFileTemplate, setMergedFileTemplate, keyboardSeekAccFactor, keyboardNormalSeekSpeed, keyboardSeekSpeed2, keyboardSeekSpeed3, treatInputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName, enableAutoHtml5ify, segmentsToChaptersOnly, keyBindings, setKeyBindings, resetKeyBindings, enableSmartCut, customFfPath, storeProjectInWorkingDir, setStoreProjectInWorkingDir, enableOverwriteOutput, mouseWheelZoomModifierKey, mouseWheelFrameSeekModifierKey, mouseWheelKeyframeSeekModifierKey, captureFrameMethod, captureFrameQuality, captureFrameFileNameFormat, enableNativeHevc, cleanupChoices, setCleanupChoices, darkMode, setDarkMode, preferStrongColors, outputFileNameMinZeroPadding, cutFromAdjustmentFrames,
|
||||||
} = allUserSettings;
|
} = allUserSettings;
|
||||||
|
|
||||||
const { working, setWorking, workingRef, abortWorking } = useLoading();
|
const { working, setWorking, workingRef, abortWorking } = useLoading();
|
||||||
@ -354,8 +354,6 @@ function App() {
|
|||||||
seekRel(val * zoomedDuration);
|
seekRel(val * zoomedDuration);
|
||||||
}, [seekRel, zoomedDuration]);
|
}, [seekRel, zoomedDuration]);
|
||||||
|
|
||||||
const onTimelineWheel = useTimelineScroll({ wheelSensitivity, mouseWheelZoomModifierKey, invertTimelineScroll, zoomRel, seekRel });
|
|
||||||
|
|
||||||
const shortStep = useCallback((direction: number) => {
|
const shortStep = useCallback((direction: number) => {
|
||||||
// If we don't know fps, just assume 30 (for example if unknown audio file)
|
// If we don't know fps, just assume 30 (for example if unknown audio file)
|
||||||
const fps = detectedFps || 30;
|
const fps = detectedFps || 30;
|
||||||
@ -1406,6 +1404,8 @@ function App() {
|
|||||||
seekAbs(time);
|
seekAbs(time);
|
||||||
}, [findNearestKeyFrameTime, getRelevantTime, seekAbs]);
|
}, [findNearestKeyFrameTime, getRelevantTime, seekAbs]);
|
||||||
|
|
||||||
|
const onTimelineWheel = useTimelineScroll({ wheelSensitivity, mouseWheelZoomModifierKey, mouseWheelFrameSeekModifierKey, mouseWheelKeyframeSeekModifierKey, invertTimelineScroll, zoomRel, seekRel, shortStep, seekClosestKeyframe });
|
||||||
|
|
||||||
const seekAccelerationRef = useRef(1);
|
const seekAccelerationRef = useRef(1);
|
||||||
|
|
||||||
const userOpenSingleFile = useCallback(async ({ path: pathIn, isLlcProject }: { path: string, isLlcProject?: boolean }) => {
|
const userOpenSingleFile = useCallback(async ({ path: pathIn, isLlcProject }: { path: string, isLlcProject?: boolean }) => {
|
||||||
|
@ -12,7 +12,7 @@ import Swal from '../swal';
|
|||||||
import SetCutpointButton from './SetCutpointButton';
|
import SetCutpointButton from './SetCutpointButton';
|
||||||
import SegmentCutpointButton from './SegmentCutpointButton';
|
import SegmentCutpointButton from './SegmentCutpointButton';
|
||||||
import { getModifier } from '../hooks/useTimelineScroll';
|
import { getModifier } from '../hooks/useTimelineScroll';
|
||||||
import { KeyBinding, KeyboardAction } from '../../../../types';
|
import { KeyBinding, KeyboardAction, ModifierKey } from '../../../../types';
|
||||||
import { StateSegment } from '../types';
|
import { StateSegment } from '../types';
|
||||||
import Sheet from './Sheet';
|
import Sheet from './Sheet';
|
||||||
|
|
||||||
@ -119,6 +119,18 @@ const CreateBinding = memo(({
|
|||||||
|
|
||||||
const rowStyle = { display: 'flex', alignItems: 'center', borderBottom: '1px solid rgba(0,0,0,0.1)', paddingBottom: '.2em' };
|
const rowStyle = { display: 'flex', alignItems: 'center', borderBottom: '1px solid rgba(0,0,0,0.1)', paddingBottom: '.2em' };
|
||||||
|
|
||||||
|
function WheelModifier({ text, wheelText, modifier }: { text: string, wheelText: string, modifier: ModifierKey }) {
|
||||||
|
return (
|
||||||
|
<div style={{ ...rowStyle, alignItems: 'center' }}>
|
||||||
|
<span>{text}</span>
|
||||||
|
<div style={{ flexGrow: 1 }} />
|
||||||
|
{getModifier(modifier).map((v) => <kbd key={v} style={{ marginRight: '.7em' }}>{v}</kbd>)}
|
||||||
|
<FaMouse style={{ marginRight: '.3em' }} />
|
||||||
|
<span>{wheelText}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line react/display-name
|
// eslint-disable-next-line react/display-name
|
||||||
const KeyboardShortcuts = memo(({
|
const KeyboardShortcuts = memo(({
|
||||||
keyBindings, setKeyBindings, resetKeyBindings, currentCutSeg,
|
keyBindings, setKeyBindings, resetKeyBindings, currentCutSeg,
|
||||||
@ -127,7 +139,7 @@ const KeyboardShortcuts = memo(({
|
|||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { mouseWheelZoomModifierKey } = useUserSettings();
|
const { mouseWheelZoomModifierKey, mouseWheelFrameSeekModifierKey, mouseWheelKeyframeSeekModifierKey } = useUserSettings();
|
||||||
|
|
||||||
const { actionsMap, extraLinesPerCategory } = useMemo(() => {
|
const { actionsMap, extraLinesPerCategory } = useMemo(() => {
|
||||||
const playbackCategory = t('Playback');
|
const playbackCategory = t('Playback');
|
||||||
@ -631,19 +643,17 @@ const KeyboardShortcuts = memo(({
|
|||||||
const extraLinesPerCategory: Record<Category, ReactNode> = {
|
const extraLinesPerCategory: Record<Category, ReactNode> = {
|
||||||
[zoomOperationsCategory]: [
|
[zoomOperationsCategory]: [
|
||||||
<div key="1" style={{ ...rowStyle, alignItems: 'center' }}>
|
<div key="1" style={{ ...rowStyle, alignItems: 'center' }}>
|
||||||
<span>{t('Zoom in/out timeline')}</span>
|
<span>{t('Pan timeline')}</span>
|
||||||
<div style={{ flexGrow: 1 }} />
|
<div style={{ flexGrow: 1 }} />
|
||||||
<FaMouse style={{ marginRight: '.3em' }} />
|
<FaMouse style={{ marginRight: '.3em' }} />
|
||||||
<span>{t('Mouse scroll/wheel up/down')}</span>
|
<span>{t('Mouse scroll/wheel up/down')}</span>
|
||||||
</div>,
|
</div>,
|
||||||
|
|
||||||
<div key="2" style={{ ...rowStyle, alignItems: 'center' }}>
|
<WheelModifier key="2" text={t('Seek one frame')} wheelText={t('Mouse scroll/wheel up/down')} modifier={mouseWheelFrameSeekModifierKey} />,
|
||||||
<span>{t('Pan timeline')}</span>
|
|
||||||
<div style={{ flexGrow: 1 }} />
|
<WheelModifier key="3" text={t('Seek one key frame')} wheelText={t('Mouse scroll/wheel up/down')} modifier={mouseWheelKeyframeSeekModifierKey} />,
|
||||||
{getModifier(mouseWheelZoomModifierKey).map((v) => <kbd key={v} style={{ marginRight: '.7em' }}>{v}</kbd>)}
|
|
||||||
<FaMouse style={{ marginRight: '.3em' }} />
|
<WheelModifier key="4" text={t('Zoom in/out timeline')} wheelText={t('Mouse scroll/wheel up/down')} modifier={mouseWheelZoomModifierKey} />,
|
||||||
<span>{t('Mouse scroll/wheel up/down')}</span>
|
|
||||||
</div>,
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -651,7 +661,7 @@ const KeyboardShortcuts = memo(({
|
|||||||
extraLinesPerCategory,
|
extraLinesPerCategory,
|
||||||
actionsMap,
|
actionsMap,
|
||||||
};
|
};
|
||||||
}, [currentCutSeg, mouseWheelZoomModifierKey, t]);
|
}, [currentCutSeg, mouseWheelFrameSeekModifierKey, mouseWheelKeyframeSeekModifierKey, mouseWheelZoomModifierKey, t]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// cleanup invalid bindings, to prevent renamed actions from blocking user to rebind
|
// cleanup invalid bindings, to prevent renamed actions from blocking user to rebind
|
||||||
|
@ -39,6 +39,20 @@ const Header = ({ title }: { title: string }) => (
|
|||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function ModifierKeySetting({ text, value, setValue }: { text: string, value: ModifierKey, setValue: (v: ModifierKey) => void }) {
|
||||||
|
return (
|
||||||
|
<Row>
|
||||||
|
<KeyCell>{text}</KeyCell>
|
||||||
|
<td>
|
||||||
|
<Select value={value} onChange={(e) => setValue(e.target.value as ModifierKey)}>
|
||||||
|
{Object.entries(getModifierKeyNames()).map(([key, values]) => (
|
||||||
|
<option key={key} value={key}>{values.join(' / ')}</option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</td>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
}
|
||||||
const detailsStyle: CSSProperties = { opacity: 0.75, fontSize: '.9em', marginTop: '.3em' };
|
const detailsStyle: CSSProperties = { opacity: 0.75, fontSize: '.9em', marginTop: '.3em' };
|
||||||
|
|
||||||
function Settings({
|
function Settings({
|
||||||
@ -59,7 +73,7 @@ function Settings({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [showAdvanced, setShowAdvanced] = useState(!simpleMode);
|
const [showAdvanced, setShowAdvanced] = useState(!simpleMode);
|
||||||
|
|
||||||
const { customOutDir, changeOutDir, keyframeCut, toggleKeyframeCut, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, autoSaveProjectFile, setAutoSaveProjectFile, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, hideNotifications, setHideNotifications, hideOsNotifications, setHideOsNotifications, autoLoadTimecode, setAutoLoadTimecode, enableAutoHtml5ify, setEnableAutoHtml5ify, customFfPath, setCustomFfPath, storeProjectInWorkingDir, mouseWheelZoomModifierKey, setMouseWheelZoomModifierKey, captureFrameMethod, setCaptureFrameMethod, captureFrameQuality, setCaptureFrameQuality, captureFrameFileNameFormat, setCaptureFrameFileNameFormat, enableNativeHevc, setEnableNativeHevc, enableUpdateCheck, setEnableUpdateCheck, allowMultipleInstances, setAllowMultipleInstances, preferStrongColors, setPreferStrongColors, treatInputFileModifiedTimeAsStart, setTreatInputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart, setTreatOutputFileModifiedTimeAsStart, exportConfirmEnabled, toggleExportConfirmEnabled } = useUserSettings();
|
const { customOutDir, changeOutDir, keyframeCut, toggleKeyframeCut, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, autoSaveProjectFile, setAutoSaveProjectFile, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, hideNotifications, setHideNotifications, hideOsNotifications, setHideOsNotifications, autoLoadTimecode, setAutoLoadTimecode, enableAutoHtml5ify, setEnableAutoHtml5ify, customFfPath, setCustomFfPath, storeProjectInWorkingDir, mouseWheelZoomModifierKey, setMouseWheelZoomModifierKey, mouseWheelFrameSeekModifierKey, setMouseWheelFrameSeekModifierKey, mouseWheelKeyframeSeekModifierKey, setMouseWheelKeyframeSeekModifierKey, captureFrameMethod, setCaptureFrameMethod, captureFrameQuality, setCaptureFrameQuality, captureFrameFileNameFormat, setCaptureFrameFileNameFormat, enableNativeHevc, setEnableNativeHevc, enableUpdateCheck, setEnableUpdateCheck, allowMultipleInstances, setAllowMultipleInstances, preferStrongColors, setPreferStrongColors, treatInputFileModifiedTimeAsStart, setTreatInputFileModifiedTimeAsStart, treatOutputFileModifiedTimeAsStart, setTreatOutputFileModifiedTimeAsStart, exportConfirmEnabled, toggleExportConfirmEnabled } = useUserSettings();
|
||||||
|
|
||||||
const onLangChange = useCallback<ChangeEventHandler<HTMLSelectElement>>((e) => {
|
const onLangChange = useCallback<ChangeEventHandler<HTMLSelectElement>>((e) => {
|
||||||
const { value } = e.target;
|
const { value } = e.target;
|
||||||
@ -362,16 +376,9 @@ function Settings({
|
|||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<Row>
|
<ModifierKeySetting text={t('Mouse wheel zoom modifier key')} value={mouseWheelZoomModifierKey} setValue={setMouseWheelZoomModifierKey} />
|
||||||
<KeyCell>{t('Mouse wheel zoom modifier key')}</KeyCell>
|
<ModifierKeySetting text={t('Mouse wheel frame seek modifier key')} value={mouseWheelFrameSeekModifierKey} setValue={setMouseWheelFrameSeekModifierKey} />
|
||||||
<td>
|
<ModifierKeySetting text={t('Mouse wheel keyframe seek modifier key')} value={mouseWheelKeyframeSeekModifierKey} setValue={setMouseWheelKeyframeSeekModifierKey} />
|
||||||
<Select value={mouseWheelZoomModifierKey} onChange={(e) => setMouseWheelZoomModifierKey(e.target.value as ModifierKey)}>
|
|
||||||
{Object.entries(getModifierKeyNames()).map(([key, values]) => (
|
|
||||||
<option key={key} value={key}>{values.join(' / ')}</option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</td>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Row>
|
<Row>
|
||||||
<KeyCell>{t('Timeline trackpad/wheel sensitivity')}</KeyCell>
|
<KeyCell>{t('Timeline trackpad/wheel sensitivity')}</KeyCell>
|
||||||
|
@ -9,7 +9,7 @@ export const keyMap = {
|
|||||||
shift: 'shiftKey',
|
shift: 'shiftKey',
|
||||||
alt: 'altKey',
|
alt: 'altKey',
|
||||||
meta: 'metaKey',
|
meta: 'metaKey',
|
||||||
};
|
} as const;
|
||||||
|
|
||||||
export const getModifierKeyNames = () => ({
|
export const getModifierKeyNames = () => ({
|
||||||
ctrl: [t('Ctrl')],
|
ctrl: [t('Ctrl')],
|
||||||
@ -20,22 +20,35 @@ export const getModifierKeyNames = () => ({
|
|||||||
|
|
||||||
export const getModifier = (key: ModifierKey) => getModifierKeyNames()[key];
|
export const getModifier = (key: ModifierKey) => getModifierKeyNames()[key];
|
||||||
|
|
||||||
function useTimelineScroll({ wheelSensitivity, mouseWheelZoomModifierKey, invertTimelineScroll, zoomRel, seekRel }: {
|
function useTimelineScroll({ wheelSensitivity, mouseWheelZoomModifierKey, mouseWheelFrameSeekModifierKey, mouseWheelKeyframeSeekModifierKey, invertTimelineScroll, zoomRel, seekRel, shortStep, seekClosestKeyframe }: {
|
||||||
wheelSensitivity: number, mouseWheelZoomModifierKey: ModifierKey, invertTimelineScroll?: boolean | undefined, zoomRel: (a: number) => void, seekRel: (a: number) => void,
|
wheelSensitivity: number,
|
||||||
|
mouseWheelZoomModifierKey: ModifierKey,
|
||||||
|
mouseWheelFrameSeekModifierKey: ModifierKey,
|
||||||
|
mouseWheelKeyframeSeekModifierKey: ModifierKey,
|
||||||
|
invertTimelineScroll?: boolean | undefined,
|
||||||
|
zoomRel: (a: number) => void,
|
||||||
|
seekRel: (a: number) => void,
|
||||||
|
shortStep: (a: number) => void,
|
||||||
|
seekClosestKeyframe: (a: number) => void,
|
||||||
}) {
|
}) {
|
||||||
const onWheel = useCallback<WheelEventHandler<Element>>((e) => {
|
const onWheel = useCallback<WheelEventHandler<Element>>((wheelEvent) => {
|
||||||
const { pixelX, pixelY } = normalizeWheel(e);
|
const { pixelX, pixelY } = normalizeWheel(wheelEvent);
|
||||||
// console.log({ spinX, spinY, pixelX, pixelY });
|
// console.log({ spinX, spinY, pixelX, pixelY });
|
||||||
|
|
||||||
const direction = invertTimelineScroll ? 1 : -1;
|
const direction = invertTimelineScroll ? 1 : -1;
|
||||||
|
|
||||||
const modifierKey = keyMap[mouseWheelZoomModifierKey];
|
const makeUnit = (v: number) => ((direction * v) > 0 ? 1 : -1);
|
||||||
if (e[modifierKey]) {
|
|
||||||
zoomRel(direction * (pixelY) * wheelSensitivity * 0.4);
|
if (wheelEvent[keyMap[mouseWheelZoomModifierKey]]) {
|
||||||
|
zoomRel(direction * pixelY * wheelSensitivity * 0.4);
|
||||||
|
} else if (wheelEvent[keyMap[mouseWheelFrameSeekModifierKey]]) {
|
||||||
|
shortStep(makeUnit(pixelX + pixelY));
|
||||||
|
} else if (wheelEvent[keyMap[mouseWheelKeyframeSeekModifierKey]]) {
|
||||||
|
seekClosestKeyframe(makeUnit(pixelX + pixelY));
|
||||||
} else {
|
} else {
|
||||||
seekRel(direction * (pixelX + pixelY) * wheelSensitivity * 0.2);
|
seekRel(direction * (pixelX + pixelY) * wheelSensitivity * 0.2);
|
||||||
}
|
}
|
||||||
}, [invertTimelineScroll, mouseWheelZoomModifierKey, zoomRel, wheelSensitivity, seekRel]);
|
}, [invertTimelineScroll, mouseWheelZoomModifierKey, mouseWheelFrameSeekModifierKey, mouseWheelKeyframeSeekModifierKey, zoomRel, wheelSensitivity, shortStep, seekClosestKeyframe, seekRel]);
|
||||||
|
|
||||||
return onWheel;
|
return onWheel;
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,10 @@ export default () => {
|
|||||||
useEffect(() => safeSetConfig({ enableOverwriteOutput }), [enableOverwriteOutput]);
|
useEffect(() => safeSetConfig({ enableOverwriteOutput }), [enableOverwriteOutput]);
|
||||||
const [mouseWheelZoomModifierKey, setMouseWheelZoomModifierKey] = useState(safeGetConfigInitial('mouseWheelZoomModifierKey'));
|
const [mouseWheelZoomModifierKey, setMouseWheelZoomModifierKey] = useState(safeGetConfigInitial('mouseWheelZoomModifierKey'));
|
||||||
useEffect(() => safeSetConfig({ mouseWheelZoomModifierKey }), [mouseWheelZoomModifierKey]);
|
useEffect(() => safeSetConfig({ mouseWheelZoomModifierKey }), [mouseWheelZoomModifierKey]);
|
||||||
|
const [mouseWheelFrameSeekModifierKey, setMouseWheelFrameSeekModifierKey] = useState(safeGetConfigInitial('mouseWheelFrameSeekModifierKey'));
|
||||||
|
useEffect(() => safeSetConfig({ mouseWheelFrameSeekModifierKey }), [mouseWheelFrameSeekModifierKey]);
|
||||||
|
const [mouseWheelKeyframeSeekModifierKey, setMouseWheelKeyframeSeekModifierKey] = useState(safeGetConfigInitial('mouseWheelKeyframeSeekModifierKey'));
|
||||||
|
useEffect(() => safeSetConfig({ mouseWheelKeyframeSeekModifierKey }), [mouseWheelKeyframeSeekModifierKey]);
|
||||||
const [captureFrameMethod, setCaptureFrameMethod] = useState(safeGetConfigInitial('captureFrameMethod'));
|
const [captureFrameMethod, setCaptureFrameMethod] = useState(safeGetConfigInitial('captureFrameMethod'));
|
||||||
useEffect(() => safeSetConfig({ captureFrameMethod }), [captureFrameMethod]);
|
useEffect(() => safeSetConfig({ captureFrameMethod }), [captureFrameMethod]);
|
||||||
const [captureFrameQuality, setCaptureFrameQuality] = useState(safeGetConfigInitial('captureFrameQuality'));
|
const [captureFrameQuality, setCaptureFrameQuality] = useState(safeGetConfigInitial('captureFrameQuality'));
|
||||||
@ -261,6 +265,10 @@ export default () => {
|
|||||||
setEnableOverwriteOutput,
|
setEnableOverwriteOutput,
|
||||||
mouseWheelZoomModifierKey,
|
mouseWheelZoomModifierKey,
|
||||||
setMouseWheelZoomModifierKey,
|
setMouseWheelZoomModifierKey,
|
||||||
|
mouseWheelFrameSeekModifierKey,
|
||||||
|
setMouseWheelFrameSeekModifierKey,
|
||||||
|
mouseWheelKeyframeSeekModifierKey,
|
||||||
|
setMouseWheelKeyframeSeekModifierKey,
|
||||||
captureFrameMethod,
|
captureFrameMethod,
|
||||||
setCaptureFrameMethod,
|
setCaptureFrameMethod,
|
||||||
captureFrameQuality,
|
captureFrameQuality,
|
||||||
|
2
types.ts
2
types.ts
@ -91,6 +91,8 @@ export interface Config {
|
|||||||
storeProjectInWorkingDir: boolean,
|
storeProjectInWorkingDir: boolean,
|
||||||
enableOverwriteOutput: boolean,
|
enableOverwriteOutput: boolean,
|
||||||
mouseWheelZoomModifierKey: ModifierKey,
|
mouseWheelZoomModifierKey: ModifierKey,
|
||||||
|
mouseWheelFrameSeekModifierKey: ModifierKey,
|
||||||
|
mouseWheelKeyframeSeekModifierKey: ModifierKey,
|
||||||
captureFrameMethod: 'videotag' | 'ffmpeg',
|
captureFrameMethod: 'videotag' | 'ffmpeg',
|
||||||
captureFrameQuality: number,
|
captureFrameQuality: number,
|
||||||
captureFrameFileNameFormat: 'timestamp' | 'index',
|
captureFrameFileNameFormat: 'timestamp' | 'index',
|
||||||
|
Loading…
Reference in New Issue
Block a user