Merge pull request #127 from theatre-js/dev/cl-2022-04/refactors-docs
Dev/cl 2022 04/refactors docs
This commit is contained in:
commit
9f46a0b78f
23 changed files with 76 additions and 49 deletions
|
@ -1,6 +1,8 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Playground – Theatre.js</title>
|
<title>Playground – Theatre.js</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
|
|
|
@ -14,8 +14,7 @@ import type {
|
||||||
IValidCompoundProps,
|
IValidCompoundProps,
|
||||||
ShorthandCompoundPropsToLonghandCompoundProps,
|
ShorthandCompoundPropsToLonghandCompoundProps,
|
||||||
} from './internals'
|
} from './internals'
|
||||||
import {sanitizeCompoundProps} from './internals'
|
import {propTypeSymbol, sanitizeCompoundProps} from './internals'
|
||||||
import {propTypeSymbol} from './internals'
|
|
||||||
// eslint-disable-next-line unused-imports/no-unused-imports
|
// eslint-disable-next-line unused-imports/no-unused-imports
|
||||||
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
|
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
|
||||||
|
|
||||||
|
@ -91,9 +90,7 @@ const validateCommonOpts = (fnCallSignature: string, opts?: CommonOpts) => {
|
||||||
*/
|
*/
|
||||||
export const compound = <Props extends IShorthandCompoundProps>(
|
export const compound = <Props extends IShorthandCompoundProps>(
|
||||||
props: Props,
|
props: Props,
|
||||||
opts: {
|
opts: CommonOpts = {},
|
||||||
label?: string
|
|
||||||
} = {},
|
|
||||||
): PropTypeConfig_Compound<
|
): PropTypeConfig_Compound<
|
||||||
ShorthandCompoundPropsToLonghandCompoundProps<Props>
|
ShorthandCompoundPropsToLonghandCompoundProps<Props>
|
||||||
> => {
|
> => {
|
||||||
|
@ -287,9 +284,7 @@ const _interpolateNumber = (
|
||||||
|
|
||||||
export const rgba = (
|
export const rgba = (
|
||||||
defaultValue: Rgba = {r: 0, g: 0, b: 0, a: 1},
|
defaultValue: Rgba = {r: 0, g: 0, b: 0, a: 1},
|
||||||
opts: {
|
opts: CommonOpts = {},
|
||||||
label?: string
|
|
||||||
} = {},
|
|
||||||
): PropTypeConfig_Rgba => {
|
): PropTypeConfig_Rgba => {
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
validateCommonOpts('t.rgba(defaultValue, opts)', opts)
|
validateCommonOpts('t.rgba(defaultValue, opts)', opts)
|
||||||
|
@ -337,6 +332,7 @@ export const rgba = (
|
||||||
}
|
}
|
||||||
|
|
||||||
const _sanitizeRgba = (val: unknown): Rgba | undefined => {
|
const _sanitizeRgba = (val: unknown): Rgba | undefined => {
|
||||||
|
if (!val) return undefined
|
||||||
let valid = true
|
let valid = true
|
||||||
for (const c of ['r', 'g', 'b', 'a']) {
|
for (const c of ['r', 'g', 'b', 'a']) {
|
||||||
if (
|
if (
|
||||||
|
@ -555,8 +551,6 @@ export function stringLiteral<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Sanitizer<T> = (value: unknown) => T | undefined
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A linear interpolator for a certain value type.
|
* A linear interpolator for a certain value type.
|
||||||
*
|
*
|
||||||
|
@ -669,7 +663,7 @@ const defaultNumberNudgeFn: NumberNudgeFn = ({
|
||||||
export interface PropTypeConfig_Boolean
|
export interface PropTypeConfig_Boolean
|
||||||
extends ISimplePropType<'boolean', boolean> {}
|
extends ISimplePropType<'boolean', boolean> {}
|
||||||
|
|
||||||
interface CommonOpts {
|
type CommonOpts = {
|
||||||
/**
|
/**
|
||||||
* Each prop type may be given a custom label instead of the name of the sub-prop
|
* Each prop type may be given a custom label instead of the name of the sub-prop
|
||||||
* it is in.
|
* it is in.
|
||||||
|
|
|
@ -17,6 +17,16 @@ export type IValidCompoundProps = {
|
||||||
[K in string]: PropTypeConfig
|
[K in string]: PropTypeConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This does not include Rgba since Rgba does not have a predictable
|
||||||
|
* object shape. We prefer to infer that compound props are described as
|
||||||
|
* `Record<string, IShorthandProp>` for now.
|
||||||
|
*
|
||||||
|
* In the future, it might be reasonable to wrap these types up into something
|
||||||
|
* which would allow us to differentiate between values at runtime
|
||||||
|
* (e.g. `val.type = "Rgba"` vs `val.type = "Compound"` etc)
|
||||||
|
*/
|
||||||
type IShorthandProp =
|
type IShorthandProp =
|
||||||
| string
|
| string
|
||||||
| number
|
| number
|
||||||
|
|
|
@ -23,7 +23,7 @@ const BooleanPropEditor: React.FC<{
|
||||||
|
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(el: React.ChangeEvent<HTMLInputElement>) => {
|
(el: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
stuff.permenantlySetValue(Boolean(el.target.checked))
|
stuff.permanentlySetValue(Boolean(el.target.checked))
|
||||||
},
|
},
|
||||||
[propConfig, pointerToProp, obj],
|
[propConfig, pointerToProp, obj],
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,7 +29,7 @@ const NumberPropEditor: React.FC<{
|
||||||
value={stuff.value}
|
value={stuff.value}
|
||||||
temporarilySetValue={stuff.temporarilySetValue}
|
temporarilySetValue={stuff.temporarilySetValue}
|
||||||
discardTemporaryValue={stuff.discardTemporaryValue}
|
discardTemporaryValue={stuff.discardTemporaryValue}
|
||||||
permenantlySetValue={stuff.permenantlySetValue}
|
permanentlySetValue={stuff.permanentlySetValue}
|
||||||
range={propConfig.range}
|
range={propConfig.range}
|
||||||
nudge={nudge}
|
nudge={nudge}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -76,7 +76,7 @@ const RgbaPropEditor: React.FC<{
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(color: string) => {
|
(color: string) => {
|
||||||
const rgba = decorateRgba(parseRgbaFromHex(color))
|
const rgba = decorateRgba(parseRgbaFromHex(color))
|
||||||
stuff.permenantlySetValue(rgba)
|
stuff.permanentlySetValue(rgba)
|
||||||
},
|
},
|
||||||
[stuff],
|
[stuff],
|
||||||
)
|
)
|
||||||
|
@ -98,7 +98,7 @@ const RgbaPropEditor: React.FC<{
|
||||||
permanentlySetValue={(color) => {
|
permanentlySetValue={(color) => {
|
||||||
// console.log('perm')
|
// console.log('perm')
|
||||||
const rgba = decorateRgba(color)
|
const rgba = decorateRgba(color)
|
||||||
stuff.permenantlySetValue(rgba)
|
stuff.permanentlySetValue(rgba)
|
||||||
}}
|
}}
|
||||||
discardTemporaryValue={stuff.discardTemporaryValue}
|
discardTemporaryValue={stuff.discardTemporaryValue}
|
||||||
/>
|
/>
|
||||||
|
@ -120,7 +120,7 @@ const RgbaPropEditor: React.FC<{
|
||||||
value={rgba2hex(stuff.value)}
|
value={rgba2hex(stuff.value)}
|
||||||
temporarilySetValue={noop}
|
temporarilySetValue={noop}
|
||||||
discardTemporaryValue={noop}
|
discardTemporaryValue={noop}
|
||||||
permenantlySetValue={onChange}
|
permanentlySetValue={onChange}
|
||||||
isValid={(v) => !!v.match(/^#?([0-9a-f]{8})$/i)}
|
isValid={(v) => !!v.match(/^#?([0-9a-f]{8})$/i)}
|
||||||
/>
|
/>
|
||||||
</RowContainer>
|
</RowContainer>
|
||||||
|
|
|
@ -20,7 +20,7 @@ const StringLiteralPropEditor: React.FC<{
|
||||||
|
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(val: string) => {
|
(val: string) => {
|
||||||
stuff.permenantlySetValue(val)
|
stuff.permanentlySetValue(val)
|
||||||
},
|
},
|
||||||
[propConfig, pointerToProp, obj],
|
[propConfig, pointerToProp, obj],
|
||||||
)
|
)
|
||||||
|
|
|
@ -22,7 +22,7 @@ const StringPropEditor: React.FC<{
|
||||||
value={stuff.value}
|
value={stuff.value}
|
||||||
temporarilySetValue={stuff.temporarilySetValue}
|
temporarilySetValue={stuff.temporarilySetValue}
|
||||||
discardTemporaryValue={stuff.discardTemporaryValue}
|
discardTemporaryValue={stuff.discardTemporaryValue}
|
||||||
permenantlySetValue={stuff.permenantlySetValue}
|
permanentlySetValue={stuff.permanentlySetValue}
|
||||||
/>
|
/>
|
||||||
</SingleRowPropEditor>
|
</SingleRowPropEditor>
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,7 +23,7 @@ interface CommonStuff<T> {
|
||||||
|
|
||||||
temporarilySetValue(v: T): void
|
temporarilySetValue(v: T): void
|
||||||
discardTemporaryValue(): void
|
discardTemporaryValue(): void
|
||||||
permenantlySetValue(v: T): void
|
permanentlySetValue(v: T): void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Default<T> extends CommonStuff<T> {
|
interface Default<T> extends CommonStuff<T> {
|
||||||
|
@ -76,7 +76,7 @@ export function useEditingToolsForPrimitiveProp<
|
||||||
currentScrub = null
|
currentScrub = null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
permenantlySetValue(v: T): void {
|
permanentlySetValue(v: T): void {
|
||||||
if (currentScrub) {
|
if (currentScrub) {
|
||||||
currentScrub.capture((api) => {
|
currentScrub.capture((api) => {
|
||||||
api.set(pointerToProp, v)
|
api.set(pointerToProp, v)
|
||||||
|
|
|
@ -192,7 +192,7 @@ const CurveEditorPopover: React.FC<
|
||||||
tempTransaction = undefined
|
tempTransaction = undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
permenantlySetValue(newCurve: string): void {
|
permanentlySetValue(newCurve: string): void {
|
||||||
if (tempTransaction) {
|
if (tempTransaction) {
|
||||||
tempTransaction.discard()
|
tempTransaction.discard()
|
||||||
tempTransaction = undefined
|
tempTransaction = undefined
|
||||||
|
@ -282,7 +282,7 @@ const CurveEditorPopover: React.FC<
|
||||||
props.onRequestClose()
|
props.onRequestClose()
|
||||||
}
|
}
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
fns.permenantlySetValue(filter)
|
fns.permanentlySetValue(filter)
|
||||||
props.onRequestClose()
|
props.onRequestClose()
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@ -302,7 +302,7 @@ const CurveEditorPopover: React.FC<
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
props.onRequestClose()
|
props.onRequestClose()
|
||||||
} else if (e.key === 'Enter') {
|
} else if (e.key === 'Enter') {
|
||||||
fns.permenantlySetValue(preset.value)
|
fns.permanentlySetValue(preset.value)
|
||||||
props.onRequestClose()
|
props.onRequestClose()
|
||||||
}
|
}
|
||||||
if (e.key === 'ArrowRight') {
|
if (e.key === 'ArrowRight') {
|
||||||
|
@ -358,7 +358,7 @@ const CurveEditorPopover: React.FC<
|
||||||
ref={optionsRef.current[preset.label]}
|
ref={optionsRef.current[preset.label]}
|
||||||
key={preset.label}
|
key={preset.label}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
fns.permenantlySetValue(preset.value)
|
fns.permanentlySetValue(preset.value)
|
||||||
props.onRequestClose()
|
props.onRequestClose()
|
||||||
}}
|
}}
|
||||||
// Temporarily apply on hover
|
// Temporarily apply on hover
|
||||||
|
|
|
@ -14,7 +14,7 @@ import styled from 'styled-components'
|
||||||
import type KeyframeEditor from './KeyframeEditor'
|
import type KeyframeEditor from './KeyframeEditor'
|
||||||
import {useLockFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
import {useLockFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||||
import {attributeNameThatLocksFramestamp} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
import {attributeNameThatLocksFramestamp} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||||
import {useCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
import {useCssCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
||||||
import SnapCursor from './SnapCursor.svg'
|
import SnapCursor from './SnapCursor.svg'
|
||||||
import selectedKeyframeIdsIfInSingleTrack from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/selectedKeyframeIdsIfInSingleTrack'
|
import selectedKeyframeIdsIfInSingleTrack from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/selectedKeyframeIdsIfInSingleTrack'
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ function useDragKeyframe(
|
||||||
|
|
||||||
useDrag(node, gestureHandlers)
|
useDrag(node, gestureHandlers)
|
||||||
|
|
||||||
useCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'ew-resize')
|
useCssCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'ew-resize')
|
||||||
|
|
||||||
return [isDragging]
|
return [isDragging]
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import React, {useLayoutEffect, useMemo} from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import {useReceiveVerticalWheelEvent} from '@theatre/studio/panels/SequenceEditorPanel/VerticalScrollContainer'
|
import {useReceiveVerticalWheelEvent} from '@theatre/studio/panels/SequenceEditorPanel/VerticalScrollContainer'
|
||||||
import {pointerEventsAutoInNormalMode} from '@theatre/studio/css'
|
import {pointerEventsAutoInNormalMode} from '@theatre/studio/css'
|
||||||
import {useCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
import {useCssCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
||||||
import type {IRange} from '@theatre/shared/utils/types'
|
import type {IRange} from '@theatre/shared/utils/types'
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
|
@ -80,7 +80,7 @@ function useDragHandlers(
|
||||||
const setIsSeeking = val(layoutP.seeker.setIsSeeking)
|
const setIsSeeking = val(layoutP.seeker.setIsSeeking)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onDrag(dx: number, _, event) {
|
onDrag(dx, _, event) {
|
||||||
const deltaPos = scaledSpaceToUnitSpace(dx)
|
const deltaPos = scaledSpaceToUnitSpace(dx)
|
||||||
const unsnappedPos = clamp(posBeforeSeek + deltaPos, 0, sequence.length)
|
const unsnappedPos = clamp(posBeforeSeek + deltaPos, 0, sequence.length)
|
||||||
|
|
||||||
|
@ -104,8 +104,12 @@ function useDragHandlers(
|
||||||
sequence.position = newPosition
|
sequence.position = newPosition
|
||||||
},
|
},
|
||||||
onDragStart(event) {
|
onDragStart(event) {
|
||||||
if (event.target instanceof HTMLInputElement) return false
|
if (event.target instanceof HTMLInputElement) {
|
||||||
|
// editing some value
|
||||||
|
return false
|
||||||
|
}
|
||||||
if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) {
|
if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) {
|
||||||
|
// e.g. marquee selection has shiftKey
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
@ -113,6 +117,9 @@ function useDragHandlers(
|
||||||
.composedPath()
|
.composedPath()
|
||||||
.some((el) => el instanceof HTMLElement && el.draggable === true)
|
.some((el) => el instanceof HTMLElement && el.draggable === true)
|
||||||
) {
|
) {
|
||||||
|
// Question: I think to check if we want another descendent element
|
||||||
|
// to be able to take control of this drag event.
|
||||||
|
// Question: e.g. for `useDragKeyframe`?
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,9 +146,9 @@ function useDragHandlers(
|
||||||
}
|
}
|
||||||
}, [layoutP, containerEl])
|
}, [layoutP, containerEl])
|
||||||
|
|
||||||
const [isDragigng] = useDrag(containerEl, handlers)
|
const [isDragging] = useDrag(containerEl, handlers)
|
||||||
|
|
||||||
useCursorLock(isDragigng, 'draggingPositionInSequenceEditor', 'ew-resize')
|
useCssCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'ew-resize')
|
||||||
}
|
}
|
||||||
|
|
||||||
function useHandlePanAndZoom(
|
function useHandlePanAndZoom(
|
||||||
|
|
|
@ -57,7 +57,7 @@ const LengthEditorPopover: React.FC<{
|
||||||
tempTransaction = undefined
|
tempTransaction = undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
permenantlySetValue(newLength: number): void {
|
permanentlySetValue(newLength: number): void {
|
||||||
if (tempTransaction) {
|
if (tempTransaction) {
|
||||||
tempTransaction.discard()
|
tempTransaction.discard()
|
||||||
tempTransaction = undefined
|
tempTransaction = undefined
|
||||||
|
|
|
@ -13,7 +13,7 @@ import type {Keyframe} from '@theatre/core/projects/store/types/SheetState_Histo
|
||||||
import {useLockFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
import {useLockFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||||
import {attributeNameThatLocksFramestamp} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
import {attributeNameThatLocksFramestamp} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||||
import {pointerEventsAutoInNormalMode} from '@theatre/studio/css'
|
import {pointerEventsAutoInNormalMode} from '@theatre/studio/css'
|
||||||
import {useCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
import {useCssCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
||||||
|
|
||||||
export const dotSize = 6
|
export const dotSize = 6
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ function useDragKeyframe(
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useDrag(node, gestureHandlers)
|
useDrag(node, gestureHandlers)
|
||||||
useCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'ew-resize')
|
useCssCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'ew-resize')
|
||||||
return isDragging
|
return isDragging
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import type {Keyframe} from '@theatre/core/projects/store/types/SheetState_Histo
|
||||||
import {useLockFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
import {useLockFrameStampPosition} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||||
import {attributeNameThatLocksFramestamp} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
import {attributeNameThatLocksFramestamp} from '@theatre/studio/panels/SequenceEditorPanel/FrameStampPositionProvider'
|
||||||
import {pointerEventsAutoInNormalMode} from '@theatre/studio/css'
|
import {pointerEventsAutoInNormalMode} from '@theatre/studio/css'
|
||||||
import {useCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
import {useCssCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
||||||
|
|
||||||
export const dotSize = 6
|
export const dotSize = 6
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ function useDragKeyframe(
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useDrag(node, gestureHandlers)
|
useDrag(node, gestureHandlers)
|
||||||
useCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'move')
|
useCssCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'move')
|
||||||
return isDragging
|
return isDragging
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import getStudio from '@theatre/studio/getStudio'
|
||||||
import type {SequenceEditorPanelLayout} from '@theatre/studio/panels/SequenceEditorPanel/layout/layout'
|
import type {SequenceEditorPanelLayout} from '@theatre/studio/panels/SequenceEditorPanel/layout/layout'
|
||||||
import {topStripHeight} from '@theatre/studio/panels/SequenceEditorPanel/RightOverlay/TopStrip'
|
import {topStripHeight} from '@theatre/studio/panels/SequenceEditorPanel/RightOverlay/TopStrip'
|
||||||
import type {CommitOrDiscard} from '@theatre/studio/StudioStore/StudioStore'
|
import type {CommitOrDiscard} from '@theatre/studio/StudioStore/StudioStore'
|
||||||
import {useCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
import {useCssCursorLock} from '@theatre/studio/uiComponents/PointerEventsHandler'
|
||||||
import useDrag from '@theatre/studio/uiComponents/useDrag'
|
import useDrag from '@theatre/studio/uiComponents/useDrag'
|
||||||
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
||||||
import React, {useMemo, useRef, useState} from 'react'
|
import React, {useMemo, useRef, useState} from 'react'
|
||||||
|
@ -211,7 +211,7 @@ const FocusRangeThumb: React.FC<{
|
||||||
|
|
||||||
useDrag(hitZoneNode, gestureHandlers)
|
useDrag(hitZoneNode, gestureHandlers)
|
||||||
|
|
||||||
useCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'ew-resize')
|
useCssCursorLock(isDragging, 'draggingPositionInSequenceEditor', 'ew-resize')
|
||||||
|
|
||||||
return usePrism(() => {
|
return usePrism(() => {
|
||||||
const existingRange = existingRangeD.getValue()
|
const existingRange = existingRangeD.getValue()
|
||||||
|
|
|
@ -133,6 +133,8 @@ const Playhead: React.FC<{layoutP: Pointer<SequenceEditorPanelLayout>}> = ({
|
||||||
|
|
||||||
const scaledSpaceToUnitSpace = val(layoutP.scaledSpace.toUnitSpace)
|
const scaledSpaceToUnitSpace = val(layoutP.scaledSpace.toUnitSpace)
|
||||||
|
|
||||||
|
// This may not currently snap correctly like it does when grabbing the "Rod".
|
||||||
|
// See https://www.notion.so/theatrejs/dragging-from-playhead-does-not-snap-dadac4fa755149cebbcb70a655c3a0d5
|
||||||
const gestureHandlers = useMemo((): Parameters<typeof useDrag>[1] => {
|
const gestureHandlers = useMemo((): Parameters<typeof useDrag>[1] => {
|
||||||
const setIsSeeking = val(layoutP.seeker.setIsSeeking)
|
const setIsSeeking = val(layoutP.seeker.setIsSeeking)
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ const PlayheadPositionPopover: React.FC<{
|
||||||
sequence.position = originalPosition
|
sequence.position = originalPosition
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
permenantlySetValue(newPosition: number): void {
|
permanentlySetValue(newPosition: number): void {
|
||||||
if (tempPosition) {
|
if (tempPosition) {
|
||||||
tempPosition = undefined
|
tempPosition = undefined
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
// export const
|
|
||||||
export {}
|
|
|
@ -68,9 +68,23 @@ const PointerEventsHandler: React.FC<{
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useCursorLock = (
|
/**
|
||||||
|
* A "locking" mechanism for managing style.cursor values.
|
||||||
|
*
|
||||||
|
* Putting this behind a lock is important so we can properly manage
|
||||||
|
* multiple features all coordinating to style the cursor.
|
||||||
|
*
|
||||||
|
* This will also track a stack of different cursor styles so that
|
||||||
|
* adding a style to be the "foremost" cursor can override a previous style,
|
||||||
|
* but then "unlocking" that style will again reveal the existing styles.
|
||||||
|
*
|
||||||
|
* It behaves a bit like a stack.
|
||||||
|
*/
|
||||||
|
export const useCssCursorLock = (
|
||||||
|
/** Whether to enable the provided cursor style */
|
||||||
enabled: boolean,
|
enabled: boolean,
|
||||||
className: string,
|
className: string,
|
||||||
|
/** e.g. `"ew"`, `"help"`, `"pointer"`, `"text"`, etc */
|
||||||
cursor: string,
|
cursor: string,
|
||||||
) => {
|
) => {
|
||||||
const ctx = useContext(context)
|
const ctx = useContext(context)
|
||||||
|
|
|
@ -105,7 +105,7 @@ const BasicNumberInput: React.FC<{
|
||||||
value: number
|
value: number
|
||||||
temporarilySetValue: (v: number) => void
|
temporarilySetValue: (v: number) => void
|
||||||
discardTemporaryValue: () => void
|
discardTemporaryValue: () => void
|
||||||
permenantlySetValue: (v: number) => void
|
permanentlySetValue: (v: number) => void
|
||||||
className?: string
|
className?: string
|
||||||
range?: [min: number, max: number]
|
range?: [min: number, max: number]
|
||||||
isValid?: (v: number) => boolean
|
isValid?: (v: number) => boolean
|
||||||
|
@ -167,7 +167,7 @@ const BasicNumberInput: React.FC<{
|
||||||
if (curState.valueBeforeEditing === value) {
|
if (curState.valueBeforeEditing === value) {
|
||||||
propsRef.current.discardTemporaryValue()
|
propsRef.current.discardTemporaryValue()
|
||||||
} else {
|
} else {
|
||||||
propsRef.current.permenantlySetValue(value)
|
propsRef.current.permanentlySetValue(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,7 +243,7 @@ const BasicNumberInput: React.FC<{
|
||||||
if (curState.valueBeforeDragging === value) {
|
if (curState.valueBeforeDragging === value) {
|
||||||
propsRef.current.discardTemporaryValue()
|
propsRef.current.discardTemporaryValue()
|
||||||
} else {
|
} else {
|
||||||
propsRef.current.permenantlySetValue(value)
|
propsRef.current.permanentlySetValue(value)
|
||||||
}
|
}
|
||||||
stateRef.current = {mode: 'noFocus'}
|
stateRef.current = {mode: 'noFocus'}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ const BasicStringInput: React.FC<{
|
||||||
value: string
|
value: string
|
||||||
temporarilySetValue: (v: string) => void
|
temporarilySetValue: (v: string) => void
|
||||||
discardTemporaryValue: () => void
|
discardTemporaryValue: () => void
|
||||||
permenantlySetValue: (v: string) => void
|
permanentlySetValue: (v: string) => void
|
||||||
className?: string
|
className?: string
|
||||||
isValid?: (v: string) => boolean
|
isValid?: (v: string) => boolean
|
||||||
inputRef?: MutableRefObject<HTMLInputElement | null>
|
inputRef?: MutableRefObject<HTMLInputElement | null>
|
||||||
|
@ -112,7 +112,7 @@ const BasicStringInput: React.FC<{
|
||||||
if (curState.valueBeforeEditing === value) {
|
if (curState.valueBeforeEditing === value) {
|
||||||
propsRef.current.discardTemporaryValue()
|
propsRef.current.discardTemporaryValue()
|
||||||
} else {
|
} else {
|
||||||
propsRef.current.permenantlySetValue(value)
|
propsRef.current.permanentlySetValue(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type {$FixMe} from '@theatre/shared/utils/types'
|
import type {$FixMe} from '@theatre/shared/utils/types'
|
||||||
import {useLayoutEffect, useRef} from 'react'
|
import {useLayoutEffect, useRef} from 'react'
|
||||||
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
import useRefAndState from '@theatre/studio/utils/useRefAndState'
|
||||||
import {useCursorLock} from './PointerEventsHandler'
|
import {useCssCursorLock} from './PointerEventsHandler'
|
||||||
|
|
||||||
export type UseDragOpts = {
|
export type UseDragOpts = {
|
||||||
/**
|
/**
|
||||||
|
@ -52,7 +52,7 @@ export default function useDrag(
|
||||||
'dragStartCalled' | 'dragging' | 'notDragging'
|
'dragStartCalled' | 'dragging' | 'notDragging'
|
||||||
>('notDragging')
|
>('notDragging')
|
||||||
|
|
||||||
useCursorLock(
|
useCssCursorLock(
|
||||||
mode === 'dragging' && typeof opts.lockCursorTo === 'string',
|
mode === 'dragging' && typeof opts.lockCursorTo === 'string',
|
||||||
'dragging',
|
'dragging',
|
||||||
opts.lockCursorTo!,
|
opts.lockCursorTo!,
|
||||||
|
|
Loading…
Reference in a new issue