refactor/fix usePopover: dragging and closing when distant

This commit is contained in:
Cole Lawrence 2022-05-30 09:45:44 -04:00
parent 1862625433
commit 243e77efe8
3 changed files with 11 additions and 10 deletions

View file

@ -40,6 +40,7 @@ function _usePointerCapturingContext(): PointerCapturingFn {
debugReason: string debugReason: string
} }
let currentCaptureRef = React.useRef<null | CaptureInfo>(null) let currentCaptureRef = React.useRef<null | CaptureInfo>(null)
const isPointerBeingCaptured = () => currentCaptureRef.current != null
return (forDebugName) => { return (forDebugName) => {
/** keep track of the captures being made by this user of {@link usePointerCapturing} */ /** keep track of the captures being made by this user of {@link usePointerCapturing} */
@ -80,15 +81,13 @@ function _usePointerCapturingContext(): PointerCapturingFn {
}, },
} }
}, },
isPointerBeingCaptured() { isPointerBeingCaptured,
return currentCaptureRef.current != null
},
} }
return { return {
capturing, capturing,
forceRelease() { forceRelease() {
if (currentCaptureRef.current === localCapture) { if (localCapture && currentCaptureRef.current === localCapture) {
logger._debug('Force releasing pointer', {localCapture}) logger._debug('Force releasing pointer', {localCapture})
updateCapture(null) updateCapture(null)
} }

View file

@ -14,7 +14,6 @@ import CurveEditorPopover, {
import selectedKeyframeIdsIfInSingleTrack from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/selectedKeyframeIdsIfInSingleTrack' import selectedKeyframeIdsIfInSingleTrack from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/selectedKeyframeIdsIfInSingleTrack'
import type {OpenFn} from '@theatre/studio/src/uiComponents/Popover/usePopover' import type {OpenFn} from '@theatre/studio/src/uiComponents/Popover/usePopover'
import type {Keyframe} from '@theatre/core/projects/store/types/SheetState_Historic' import type {Keyframe} from '@theatre/core/projects/store/types/SheetState_Historic'
import {usePointerCapturing} from '@theatre/studio/UIRoot/PointerCapturing'
import type {ISingleKeyframeEditorProps} from './SingleKeyframeEditor' import type {ISingleKeyframeEditorProps} from './SingleKeyframeEditor'
import type {IConnectorThemeValues} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/keyframeRowUI/ConnectorLine' import type {IConnectorThemeValues} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/keyframeRowUI/ConnectorLine'
import {ConnectorLine} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/keyframeRowUI/ConnectorLine' import {ConnectorLine} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/keyframeRowUI/ConnectorLine'
@ -43,16 +42,11 @@ const BasicKeyframeConnector: React.VFC<IBasicKeyframeConnectorProps> = (
const [nodeRef, node] = useRefAndState<HTMLDivElement | null>(null) const [nodeRef, node] = useRefAndState<HTMLDivElement | null>(null)
const {isPointerBeingCaptured} = usePointerCapturing(
'KeyframeEditor Connector',
)
const [popoverNode, openPopover, closePopover, isPopoverOpen] = usePopover( const [popoverNode, openPopover, closePopover, isPopoverOpen] = usePopover(
() => { () => {
const rightDims = val(props.layoutP.rightDims) const rightDims = val(props.layoutP.rightDims)
return { return {
debugName: 'Connector', debugName: 'Connector',
closeWhenPointerIsDistant: !isPointerBeingCaptured(),
constraints: { constraints: {
minX: rightDims.screenX + POPOVER_MARGIN, minX: rightDims.screenX + POPOVER_MARGIN,
maxX: rightDims.screenX + rightDims.width - POPOVER_MARGIN, maxX: rightDims.screenX + rightDims.width - POPOVER_MARGIN,

View file

@ -1,3 +1,4 @@
import {usePointerCapturing} from '@theatre/studio/UIRoot/PointerCapturing'
import useRefAndState from '@theatre/studio/utils/useRefAndState' import useRefAndState from '@theatre/studio/utils/useRefAndState'
import React, {useCallback, useContext, useEffect, useRef} from 'react' import React, {useCallback, useContext, useEffect, useRef} from 'react'
import {createPortal} from 'react-dom' import {createPortal} from 'react-dom'
@ -51,6 +52,10 @@ export default function usePopover(
): [node: React.ReactNode, open: OpenFn, close: CloseFn, isOpen: boolean] { ): [node: React.ReactNode, open: OpenFn, close: CloseFn, isOpen: boolean] {
const _debug = (...args: any) => {} const _debug = (...args: any) => {}
// want to make sure that we don't close a popover when dragging something (like a curve editor handle)
// I think this could be improved to handle closing after done dragging, better.
const {isPointerBeingCaptured} = usePointerCapturing(`usePopover`)
const [stateRef, state] = useRefAndState<State>({ const [stateRef, state] = useRefAndState<State>({
isOpen: false, isOpen: false,
}) })
@ -88,6 +93,9 @@ export default function usePopover(
threshold: opts.pointerDistanceThreshold ?? 100, threshold: opts.pointerDistanceThreshold ?? 100,
callback: () => { callback: () => {
if (lock.childHasFocusRef.current) return if (lock.childHasFocusRef.current) return
// this is a bit weird, because when you stop capturing, then the popover can close on you...
// TODO: Better fixes?
if (isPointerBeingCaptured()) return
close('pointer outside') close('pointer outside')
}, },
}, },