mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-26 04:02:51 +01:00
improvements
allow precise setting value adjustments #1859 fix description of wheel shortcut #1883
This commit is contained in:
parent
951af6fedd
commit
ca7a9d3eeb
@ -7,9 +7,11 @@ import groupBy from 'lodash/groupBy';
|
|||||||
import orderBy from 'lodash/orderBy';
|
import orderBy from 'lodash/orderBy';
|
||||||
import uniq from 'lodash/uniq';
|
import uniq from 'lodash/uniq';
|
||||||
|
|
||||||
|
import useUserSettings from '../hooks/useUserSettings';
|
||||||
import Swal from '../swal';
|
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';
|
||||||
|
|
||||||
|
|
||||||
const renderKeys = (keys) => keys.map((key, i) => (
|
const renderKeys = (keys) => keys.map((key, i) => (
|
||||||
@ -105,13 +107,15 @@ const CreateBinding = memo(({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const rowStyle = { display: 'flex', alignItems: 'center', margin: '6px 0' };
|
const rowStyle = { display: 'flex', alignItems: 'center', margin: '.2em 0', borderBottom: '1px solid rgba(0,0,0,0.1)', paddingBottom: '.5em' };
|
||||||
|
|
||||||
const KeyboardShortcuts = memo(({
|
const KeyboardShortcuts = memo(({
|
||||||
keyBindings, setKeyBindings, resetKeyBindings, currentCutSeg, mainActions,
|
keyBindings, setKeyBindings, resetKeyBindings, currentCutSeg, mainActions,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { mouseWheelZoomModifierKey } = useUserSettings();
|
||||||
|
|
||||||
const { actionsMap, extraLinesPerCategory } = useMemo(() => {
|
const { actionsMap, extraLinesPerCategory } = useMemo(() => {
|
||||||
const playbackCategory = t('Playback');
|
const playbackCategory = t('Playback');
|
||||||
const selectivePlaybackCategory = t('Playback/preview segments only');
|
const selectivePlaybackCategory = t('Playback/preview segments only');
|
||||||
@ -136,8 +140,9 @@ const KeyboardShortcuts = memo(({
|
|||||||
<div key="2" style={{ ...rowStyle, alignItems: 'center' }}>
|
<div key="2" style={{ ...rowStyle, alignItems: 'center' }}>
|
||||||
<Text>{t('Pan timeline')}</Text>
|
<Text>{t('Pan timeline')}</Text>
|
||||||
<div style={{ flexGrow: 1 }} />
|
<div style={{ flexGrow: 1 }} />
|
||||||
|
{getModifier(mouseWheelZoomModifierKey).map((v) => <kbd key={v} style={{ marginRight: '.7em' }}>{v}</kbd>)}
|
||||||
<FaMouse style={{ marginRight: 3 }} />
|
<FaMouse style={{ marginRight: 3 }} />
|
||||||
<Text>{t('Mouse scroll/wheel left/right')}</Text>
|
<Text>{t('Mouse scroll/wheel up/down')}</Text>
|
||||||
</div>,
|
</div>,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -649,7 +654,7 @@ const KeyboardShortcuts = memo(({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ color: 'black' }}>
|
<div style={{ color: 'black', marginBottom: '1em' }}>
|
||||||
<div>
|
<div>
|
||||||
<SearchInput value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} placeholder="Search" width="100%" />
|
<SearchInput value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} placeholder="Search" width="100%" />
|
||||||
</div>
|
</div>
|
||||||
@ -691,7 +696,7 @@ const KeyboardShortcuts = memo(({
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
{extraLinesPerCategory[category]}
|
{extraLinesPerCategory[category] && <div style={{ marginTop: '.8em' }}>{extraLinesPerCategory[category]}</div>}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -321,8 +321,8 @@ const Settings = memo(({
|
|||||||
<KeyCell>{t('Mouse wheel zoom modifier key')}</KeyCell>
|
<KeyCell>{t('Mouse wheel zoom modifier key')}</KeyCell>
|
||||||
<td>
|
<td>
|
||||||
<Select value={mouseWheelZoomModifierKey} onChange={(e) => setMouseWheelZoomModifierKey(e.target.value)}>
|
<Select value={mouseWheelZoomModifierKey} onChange={(e) => setMouseWheelZoomModifierKey(e.target.value)}>
|
||||||
{Object.entries(getModifierKeyNames()).map(([key, value]) => (
|
{Object.entries(getModifierKeyNames()).map(([key, values]) => (
|
||||||
<option key={key} value={key}>{value}</option>
|
<option key={key} value={key}>{values.join(' / ')}</option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</td>
|
</td>
|
||||||
|
@ -1,27 +1,49 @@
|
|||||||
import React, { memo } from 'react';
|
import React, { memo, useState, useCallback } from 'react';
|
||||||
import { Button } from 'evergreen-ui';
|
import { Button } from 'evergreen-ui';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const ValueTuner = memo(({ style, title, value, setValue, onFinished, resolution = 1000, min = 0, max = 1, resetToDefault }) => {
|
import Switch from './Switch';
|
||||||
|
|
||||||
|
|
||||||
|
const ValueTuner = memo(({ style, title, value, setValue, onFinished, resolution = 1000, min: minIn = 0, max: maxIn = 1, resetToDefault }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [min, setMin] = useState(minIn);
|
||||||
|
const [max, setMax] = useState(maxIn);
|
||||||
|
|
||||||
function onChange(e) {
|
function onChange(e) {
|
||||||
e.target.blur();
|
e.target.blur();
|
||||||
setValue(Math.min(Math.max(min, ((e.target.value / resolution) * (max - min)) + min)), max);
|
setValue(Math.min(Math.max(min, ((e.target.value / resolution) * (max - min)) + min)), max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isZoomed = !(min === minIn && max === maxIn);
|
||||||
|
|
||||||
|
const toggleZoom = useCallback(() => {
|
||||||
|
if (isZoomed) {
|
||||||
|
setMin(minIn);
|
||||||
|
setMax(maxIn);
|
||||||
|
} else {
|
||||||
|
const zoomWindow = (maxIn - minIn) / 100;
|
||||||
|
setMin(Math.max(minIn, value - zoomWindow));
|
||||||
|
setMax(Math.min(maxIn, value + zoomWindow));
|
||||||
|
}
|
||||||
|
}, [isZoomed, maxIn, minIn, value]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ background: 'var(--gray1)', color: 'var(--gray12)', position: 'absolute', bottom: 0, padding: 10, margin: 10, borderRadius: 10, ...style }}>
|
<div style={{ background: 'var(--gray1)', color: 'var(--gray12)', position: 'absolute', bottom: 0, padding: 10, margin: 10, borderRadius: 10, ...style }}>
|
||||||
<div style={{ display: 'flex', alignItems: 'center', flexBasis: 400 }}>
|
<div style={{ display: 'flex', alignItems: 'center', flexBasis: 400, marginBottom: '.2em' }}>
|
||||||
<div style={{ marginBottom: '.5em' }}>{title}</div>
|
<div>{title}</div>
|
||||||
<div style={{ marginLeft: 10, fontWeight: 'bold' }}>{value.toFixed(2)}</div>
|
<div style={{ marginLeft: '.5em', fontWeight: 'bold', marginRight: '.5em', textDecoration: 'underline' }}>{value.toFixed(4)}</div>
|
||||||
<div style={{ flexGrow: 1, flexBasis: 10 }} />
|
<Switch checked={isZoomed} onCheckedChange={toggleZoom} style={{ flexShrink: 0 }} /><span style={{ marginLeft: '.3em' }}>{t('Precise')}</span>
|
||||||
<Button height={20} onClick={resetToDefault}>{t('Default')}</Button>
|
|
||||||
<Button height={20} intent="success" onClick={onFinished}>{t('Done')}</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ display: 'flex' }}>
|
<div style={{ marginBottom: '.3em' }}>
|
||||||
<input style={{ flexGrow: 1 }} type="range" min="0" max="1000" step="1" value={((value - min) / (max - min)) * resolution} onChange={onChange} />
|
<input style={{ width: '100%' }} type="range" min="0" max="1000" step="1" value={((value - min) / (max - min)) * resolution} onChange={onChange} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ textAlign: 'right' }}>
|
||||||
|
<Button height={20} onClick={resetToDefault}>{t('Default')}</Button>
|
||||||
|
<Button height={20} intent="success" onClick={onFinished}>{t('Done')}</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -14,6 +14,8 @@ const ValueTuners = memo(({ type, onFinished }) => {
|
|||||||
title: t('Timeline trackpad/wheel sensitivity'),
|
title: t('Timeline trackpad/wheel sensitivity'),
|
||||||
value: wheelSensitivity,
|
value: wheelSensitivity,
|
||||||
setValue: setWheelSensitivity,
|
setValue: setWheelSensitivity,
|
||||||
|
min: 0,
|
||||||
|
max: 4,
|
||||||
default: 0.2,
|
default: 0.2,
|
||||||
},
|
},
|
||||||
keyboardNormalSeekSpeed: {
|
keyboardNormalSeekSpeed: {
|
||||||
|
@ -11,12 +11,14 @@ export const keyMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getModifierKeyNames = () => ({
|
export const getModifierKeyNames = () => ({
|
||||||
ctrl: t('Ctrl'),
|
ctrl: [t('Ctrl')],
|
||||||
shift: t('Shift'),
|
shift: [t('Shift')],
|
||||||
alt: t('Alt'),
|
alt: [t('Alt')],
|
||||||
meta: t('⌘ Cmd / ⊞ Win'),
|
meta: [t('⌘ Cmd'), t('⊞ Win')],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const getModifier = (key) => getModifierKeyNames()[key];
|
||||||
|
|
||||||
function useTimelineScroll({ wheelSensitivity, mouseWheelZoomModifierKey, invertTimelineScroll, zoomRel, seekRel }) {
|
function useTimelineScroll({ wheelSensitivity, mouseWheelZoomModifierKey, invertTimelineScroll, zoomRel, seekRel }) {
|
||||||
const onWheel = useCallback((e) => {
|
const onWheel = useCallback((e) => {
|
||||||
const { pixelX, pixelY } = normalizeWheel(e);
|
const { pixelX, pixelY } = normalizeWheel(e);
|
||||||
|
Loading…
Reference in New Issue
Block a user