Refactor collapsing to be calculated in tree.
Co-authored-by: Fülöp <fulopkovacs@users.noreply.github.com>
This commit is contained in:
parent
bc5e687250
commit
b84f2eb106
14 changed files with 132 additions and 192 deletions
|
@ -5,8 +5,6 @@ import React from 'react'
|
||||||
import {HiOutlineChevronRight} from 'react-icons/all'
|
import {HiOutlineChevronRight} from 'react-icons/all'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import {propNameTextCSS} from '@theatre/studio/propEditors/utils/propNameTextCSS'
|
import {propNameTextCSS} from '@theatre/studio/propEditors/utils/propNameTextCSS'
|
||||||
import type {ICollapsableItem} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/useSequenceEditorCollapsable'
|
|
||||||
import {useVal} from '@theatre/react'
|
|
||||||
|
|
||||||
export const Container = styled.li<{depth: number}>`
|
export const Container = styled.li<{depth: number}>`
|
||||||
--depth: ${(props) => props.depth};
|
--depth: ${(props) => props.depth};
|
||||||
|
@ -71,9 +69,10 @@ const AnyCompositeRow: React.FC<{
|
||||||
leaf: SequenceEditorTree_Row<unknown>
|
leaf: SequenceEditorTree_Row<unknown>
|
||||||
label: React.ReactNode
|
label: React.ReactNode
|
||||||
toggleSelect?: VoidFn
|
toggleSelect?: VoidFn
|
||||||
|
toggleCollapsed: VoidFn
|
||||||
isSelected?: boolean
|
isSelected?: boolean
|
||||||
isSelectable?: boolean
|
isSelectable?: boolean
|
||||||
collapsable?: ICollapsableItem
|
isCollapsed: boolean
|
||||||
}> = ({
|
}> = ({
|
||||||
leaf,
|
leaf,
|
||||||
label,
|
label,
|
||||||
|
@ -81,10 +80,10 @@ const AnyCompositeRow: React.FC<{
|
||||||
isSelectable,
|
isSelectable,
|
||||||
isSelected,
|
isSelected,
|
||||||
toggleSelect,
|
toggleSelect,
|
||||||
collapsable,
|
toggleCollapsed,
|
||||||
|
isCollapsed,
|
||||||
}) => {
|
}) => {
|
||||||
const hasChildren = Array.isArray(children) && children.length > 0
|
const hasChildren = Array.isArray(children) && children.length > 0
|
||||||
const isCollapsed = useVal(collapsable?.isCollapsed) ?? false
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container depth={leaf.depth}>
|
<Container depth={leaf.depth}>
|
||||||
|
@ -97,15 +96,12 @@ const AnyCompositeRow: React.FC<{
|
||||||
onClick={toggleSelect}
|
onClick={toggleSelect}
|
||||||
isEven={leaf.n % 2 === 0}
|
isEven={leaf.n % 2 === 0}
|
||||||
>
|
>
|
||||||
<Head_Icon
|
<Head_Icon isCollapsed={isCollapsed} onClick={toggleCollapsed}>
|
||||||
isCollapsed={isCollapsed}
|
|
||||||
onClick={() => collapsable?.toggleCollapsed()}
|
|
||||||
>
|
|
||||||
<HiOutlineChevronRight />
|
<HiOutlineChevronRight />
|
||||||
</Head_Icon>
|
</Head_Icon>
|
||||||
<Head_Label>{label}</Head_Label>
|
<Head_Label>{label}</Head_Label>
|
||||||
</Header>
|
</Header>
|
||||||
{hasChildren && !isCollapsed && <Children>{children}</Children>}
|
{hasChildren && <Children>{children}</Children>}
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,7 @@ import {usePrism} from '@theatre/react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import AnyCompositeRow from './AnyCompositeRow'
|
import AnyCompositeRow from './AnyCompositeRow'
|
||||||
import PrimitivePropRow from './PrimitivePropRow'
|
import PrimitivePropRow from './PrimitivePropRow'
|
||||||
import {useSequenceEditorCollapsable} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/useSequenceEditorCollapsable'
|
import {setCollapsedSheetObjectOrCompoundProp} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/setCollapsedSheetObjectOrCompoundProp'
|
||||||
import {createStudioSheetItemKey} from '@theatre/shared/utils/ids'
|
|
||||||
|
|
||||||
export const decideRowByPropType = (
|
export const decideRowByPropType = (
|
||||||
leaf: SequenceEditorTree_PropWithChildren | SequenceEditorTree_PrimitiveProp,
|
leaf: SequenceEditorTree_PropWithChildren | SequenceEditorTree_PrimitiveProp,
|
||||||
): React.ReactElement =>
|
): React.ReactElement =>
|
||||||
|
@ -27,19 +25,15 @@ export const decideRowByPropType = (
|
||||||
const PropWithChildrenRow: React.VFC<{
|
const PropWithChildrenRow: React.VFC<{
|
||||||
leaf: SequenceEditorTree_PropWithChildren
|
leaf: SequenceEditorTree_PropWithChildren
|
||||||
}> = ({leaf}) => {
|
}> = ({leaf}) => {
|
||||||
const collapsable = useSequenceEditorCollapsable(
|
|
||||||
createStudioSheetItemKey.forSheetObjectProp(
|
|
||||||
leaf.sheetObject,
|
|
||||||
leaf.pathToProp,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
return usePrism(() => {
|
return usePrism(() => {
|
||||||
return (
|
return (
|
||||||
<AnyCompositeRow
|
<AnyCompositeRow
|
||||||
leaf={leaf}
|
leaf={leaf}
|
||||||
label={leaf.pathToProp[leaf.pathToProp.length - 1]}
|
label={leaf.pathToProp[leaf.pathToProp.length - 1]}
|
||||||
collapsable={collapsable}
|
isCollapsed={leaf.isCollapsed}
|
||||||
|
toggleCollapsed={() =>
|
||||||
|
setCollapsedSheetObjectOrCompoundProp(!leaf.isCollapsed, leaf)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{leaf.children.map((propLeaf) => decideRowByPropType(propLeaf))}
|
{leaf.children.map((propLeaf) => decideRowByPropType(propLeaf))}
|
||||||
</AnyCompositeRow>
|
</AnyCompositeRow>
|
||||||
|
|
|
@ -3,22 +3,20 @@ import {usePrism} from '@theatre/react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import AnyCompositeRow from './AnyCompositeRow'
|
import AnyCompositeRow from './AnyCompositeRow'
|
||||||
import {decideRowByPropType} from './PropWithChildrenRow'
|
import {decideRowByPropType} from './PropWithChildrenRow'
|
||||||
import {useSequenceEditorCollapsable} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/useSequenceEditorCollapsable'
|
import {setCollapsedSheetObjectOrCompoundProp} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/setCollapsedSheetObjectOrCompoundProp'
|
||||||
import {createStudioSheetItemKey} from '@theatre/shared/utils/ids'
|
|
||||||
|
|
||||||
const LeftSheetObjectRow: React.VFC<{
|
const LeftSheetObjectRow: React.VFC<{
|
||||||
leaf: SequenceEditorTree_SheetObject
|
leaf: SequenceEditorTree_SheetObject
|
||||||
}> = ({leaf}) => {
|
}> = ({leaf}) => {
|
||||||
const collapsable = useSequenceEditorCollapsable(
|
|
||||||
createStudioSheetItemKey.forSheetObject(leaf.sheetObject),
|
|
||||||
)
|
|
||||||
|
|
||||||
return usePrism(() => {
|
return usePrism(() => {
|
||||||
return (
|
return (
|
||||||
<AnyCompositeRow
|
<AnyCompositeRow
|
||||||
leaf={leaf}
|
leaf={leaf}
|
||||||
label={leaf.sheetObject.address.objectKey}
|
label={leaf.sheetObject.address.objectKey}
|
||||||
collapsable={collapsable}
|
isCollapsed={leaf.isCollapsed}
|
||||||
|
toggleCollapsed={() =>
|
||||||
|
setCollapsedSheetObjectOrCompoundProp(!leaf.isCollapsed, leaf)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{leaf.children.map((leaf) => decideRowByPropType(leaf))}
|
{leaf.children.map((leaf) => decideRowByPropType(leaf))}
|
||||||
</AnyCompositeRow>
|
</AnyCompositeRow>
|
||||||
|
|
|
@ -27,13 +27,15 @@ const PrimitivePropRow: React.FC<{
|
||||||
console.error(
|
console.error(
|
||||||
`trackData type ${trackData?.type} is not yet supported on the sequence editor`,
|
`trackData type ${trackData?.type} is not yet supported on the sequence editor`,
|
||||||
)
|
)
|
||||||
return <RightRow leaf={leaf} node={<div />}></RightRow>
|
return (
|
||||||
|
<RightRow leaf={leaf} isCollapsed={false} node={<div />}></RightRow>
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
const node = (
|
const node = (
|
||||||
<KeyframedTrack layoutP={layoutP} trackData={trackData} leaf={leaf} />
|
<KeyframedTrack layoutP={layoutP} trackData={trackData} leaf={leaf} />
|
||||||
)
|
)
|
||||||
|
|
||||||
return <RightRow leaf={leaf} node={node}></RightRow>
|
return <RightRow leaf={leaf} isCollapsed={false} node={node}></RightRow>
|
||||||
}
|
}
|
||||||
}, [leaf, layoutP])
|
}, [leaf, layoutP])
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,6 @@ import type {Pointer} from '@theatre/dataverse'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PrimitivePropRow from './PrimitivePropRow'
|
import PrimitivePropRow from './PrimitivePropRow'
|
||||||
import RightRow from './Row'
|
import RightRow from './Row'
|
||||||
import {useSequenceEditorCollapsable} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/useSequenceEditorCollapsable'
|
|
||||||
import {createStudioSheetItemKey} from '@theatre/shared/utils/ids'
|
|
||||||
|
|
||||||
export const decideRowByPropType = (
|
export const decideRowByPropType = (
|
||||||
leaf: SequenceEditorTree_PropWithChildren | SequenceEditorTree_PrimitiveProp,
|
leaf: SequenceEditorTree_PropWithChildren | SequenceEditorTree_PrimitiveProp,
|
||||||
|
@ -33,18 +31,11 @@ const PropWithChildrenRow: React.VFC<{
|
||||||
leaf: SequenceEditorTree_PropWithChildren
|
leaf: SequenceEditorTree_PropWithChildren
|
||||||
layoutP: Pointer<SequenceEditorPanelLayout>
|
layoutP: Pointer<SequenceEditorPanelLayout>
|
||||||
}> = ({leaf, layoutP}) => {
|
}> = ({leaf, layoutP}) => {
|
||||||
const collapsable = useSequenceEditorCollapsable(
|
|
||||||
createStudioSheetItemKey.forSheetObjectProp(
|
|
||||||
leaf.sheetObject,
|
|
||||||
leaf.pathToProp,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
return usePrism(() => {
|
return usePrism(() => {
|
||||||
const node = <div />
|
const node = <div />
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RightRow leaf={leaf} node={node} collapsable={collapsable}>
|
<RightRow leaf={leaf} node={node} isCollapsed={leaf.isCollapsed}>
|
||||||
{leaf.children.map((propLeaf) =>
|
{leaf.children.map((propLeaf) =>
|
||||||
decideRowByPropType(propLeaf, layoutP),
|
decideRowByPropType(propLeaf, layoutP),
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import type {SequenceEditorTree_Row} from '@theatre/studio/panels/SequenceEditorPanel/layout/tree'
|
import type {SequenceEditorTree_Row} from '@theatre/studio/panels/SequenceEditorPanel/layout/tree'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import type {ICollapsableItem} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/useSequenceEditorCollapsable'
|
|
||||||
import {useVal} from '@theatre/react'
|
|
||||||
|
|
||||||
const Container = styled.li<{}>`
|
const Container = styled.li<{}>`
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -40,10 +38,9 @@ const Children = styled.ul`
|
||||||
const RightRow: React.FC<{
|
const RightRow: React.FC<{
|
||||||
leaf: SequenceEditorTree_Row<unknown>
|
leaf: SequenceEditorTree_Row<unknown>
|
||||||
node: React.ReactElement
|
node: React.ReactElement
|
||||||
collapsable?: ICollapsableItem
|
isCollapsed: boolean
|
||||||
}> = ({leaf, children, node, collapsable}) => {
|
}> = ({leaf, children, node, isCollapsed}) => {
|
||||||
const hasChildren = Array.isArray(children) && children.length > 0
|
const hasChildren = Array.isArray(children) && children.length > 0
|
||||||
const isCollapsed = useVal(collapsable?.isCollapsed) ?? false
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
|
@ -53,7 +50,7 @@ const RightRow: React.FC<{
|
||||||
>
|
>
|
||||||
{node}
|
{node}
|
||||||
</NodeWrapper>
|
</NodeWrapper>
|
||||||
{hasChildren && !isCollapsed && <Children>{children}</Children>}
|
{hasChildren && <Children>{children}</Children>}
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,20 +5,15 @@ import type {Pointer} from '@theatre/dataverse'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {decideRowByPropType} from './PropWithChildrenRow'
|
import {decideRowByPropType} from './PropWithChildrenRow'
|
||||||
import RightRow from './Row'
|
import RightRow from './Row'
|
||||||
import {useSequenceEditorCollapsable} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/useSequenceEditorCollapsable'
|
|
||||||
import {createStudioSheetItemKey} from '@theatre/shared/utils/ids'
|
|
||||||
|
|
||||||
const RightSheetObjectRow: React.VFC<{
|
const RightSheetObjectRow: React.VFC<{
|
||||||
leaf: SequenceEditorTree_SheetObject
|
leaf: SequenceEditorTree_SheetObject
|
||||||
layoutP: Pointer<SequenceEditorPanelLayout>
|
layoutP: Pointer<SequenceEditorPanelLayout>
|
||||||
}> = ({leaf, layoutP}) => {
|
}> = ({leaf, layoutP}) => {
|
||||||
const collapsable = useSequenceEditorCollapsable(
|
|
||||||
createStudioSheetItemKey.forSheetObject(leaf.sheetObject),
|
|
||||||
)
|
|
||||||
return usePrism(() => {
|
return usePrism(() => {
|
||||||
const node = <div />
|
const node = <div />
|
||||||
return (
|
return (
|
||||||
<RightRow leaf={leaf} node={node} collapsable={collapsable}>
|
<RightRow leaf={leaf} node={node} isCollapsed={leaf.isCollapsed}>
|
||||||
{leaf.children.map((leaf) => decideRowByPropType(leaf, layoutP))}
|
{leaf.children.map((leaf) => decideRowByPropType(leaf, layoutP))}
|
||||||
</RightRow>
|
</RightRow>
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import type {StudioSheetItemKey} from '@theatre/shared/utils/ids'
|
||||||
|
import {createStudioSheetItemKey} from '@theatre/shared/utils/ids'
|
||||||
|
import getStudio from '@theatre/studio/getStudio'
|
||||||
|
import type {PathToProp} from '@theatre/shared/utils/addresses'
|
||||||
|
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
|
||||||
|
|
||||||
|
// discriminated union
|
||||||
|
export function setCollapsedSheetObjectOrCompoundProp(
|
||||||
|
isCollapsed: boolean,
|
||||||
|
toCollapse:
|
||||||
|
| {
|
||||||
|
sheetObject: SheetObject
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
sheetObject: SheetObject
|
||||||
|
pathToProp: PathToProp
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
const itemKey: StudioSheetItemKey =
|
||||||
|
'pathToProp' in toCollapse
|
||||||
|
? createStudioSheetItemKey.forSheetObjectProp(
|
||||||
|
toCollapse.sheetObject,
|
||||||
|
toCollapse.pathToProp,
|
||||||
|
)
|
||||||
|
: createStudioSheetItemKey.forSheetObject(toCollapse.sheetObject)
|
||||||
|
|
||||||
|
getStudio().transaction(({stateEditors}) => {
|
||||||
|
stateEditors.studio.ahistoric.projects.stateByProjectId.stateBySheetId.sequence.sequenceEditorCollapsableItems.set(
|
||||||
|
{
|
||||||
|
...toCollapse.sheetObject.address,
|
||||||
|
studioSheetItemKey: itemKey,
|
||||||
|
isCollapsed,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,91 +0,0 @@
|
||||||
import React, {useContext, useMemo} from 'react'
|
|
||||||
import type {IDerivation, Pointer} from '@theatre/dataverse'
|
|
||||||
import {prism, val, valueDerivation} from '@theatre/dataverse'
|
|
||||||
import type {StudioSheetItemKey, SheetId} from '@theatre/shared/utils/ids'
|
|
||||||
import type {SequenceEditorPanelLayout} from '@theatre/studio/panels/SequenceEditorPanel/layout/layout'
|
|
||||||
import {usePrism} from '@theatre/react'
|
|
||||||
import getStudio from '@theatre/studio/getStudio'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provided via context provided by {@link ProvideCollapsable}.
|
|
||||||
*/
|
|
||||||
export function useSequenceEditorCollapsable(
|
|
||||||
sheetItemKey: StudioSheetItemKey,
|
|
||||||
): ICollapsableItem {
|
|
||||||
const collapsableContext = useContext(CollapsableContext)
|
|
||||||
return useMemo(
|
|
||||||
() => collapsableContext.getCollapsable(sheetItemKey),
|
|
||||||
[sheetItemKey, collapsableContext],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get this via {@link useSequenceEditorCollapsable}
|
|
||||||
*/
|
|
||||||
export type ICollapsableItem = {
|
|
||||||
isCollapsed: IDerivation<boolean>
|
|
||||||
toggleCollapsed(): void
|
|
||||||
}
|
|
||||||
type ICollapsableContext = {
|
|
||||||
getCollapsable(sheetItemKey: StudioSheetItemKey): ICollapsableItem
|
|
||||||
}
|
|
||||||
const CollapsableContext = React.createContext<ICollapsableContext>(null!)
|
|
||||||
const ProviderChildrenMemo: React.FC<{}> = React.memo(({children}) => (
|
|
||||||
<>{children}</>
|
|
||||||
))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a context for managing collapsable items
|
|
||||||
* which are useable from {@link useSequenceEditorCollapsable}.
|
|
||||||
*/
|
|
||||||
export function ProvideCollapsable(
|
|
||||||
props: React.PropsWithChildren<{
|
|
||||||
sheetId: SheetId
|
|
||||||
layoutP: Pointer<SequenceEditorPanelLayout>
|
|
||||||
}>,
|
|
||||||
) {
|
|
||||||
const contextValue = usePrism((): ICollapsableContext => {
|
|
||||||
const studio = getStudio()
|
|
||||||
const sheetAddress = val(props.layoutP.sheet.address)
|
|
||||||
const collapsableItemsSetP =
|
|
||||||
getStudio().atomP.ahistoric.projects.stateByProjectId[
|
|
||||||
sheetAddress.projectId
|
|
||||||
].stateBySheetId[sheetAddress.sheetId].sequence
|
|
||||||
.sequenceEditorCollapsableItems
|
|
||||||
const setIsCollapsed = prism.memo(
|
|
||||||
'setIsCollapsed',
|
|
||||||
() => {
|
|
||||||
return function setIsCollapsed(
|
|
||||||
studioSheetItemKey: StudioSheetItemKey,
|
|
||||||
isCollapsed: boolean,
|
|
||||||
): void {
|
|
||||||
studio.transaction(({stateEditors}) => {
|
|
||||||
stateEditors.studio.ahistoric.projects.stateByProjectId.stateBySheetId.sequence.sequenceEditorCollapsableItems.set(
|
|
||||||
{...sheetAddress, studioSheetItemKey, isCollapsed},
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[sheetAddress],
|
|
||||||
)
|
|
||||||
return {
|
|
||||||
getCollapsable(itemId) {
|
|
||||||
const isCollapsedD = valueDerivation(
|
|
||||||
collapsableItemsSetP.byId[itemId].isCollapsed,
|
|
||||||
).map((value) => value ?? false)
|
|
||||||
|
|
||||||
return {
|
|
||||||
isCollapsed: isCollapsedD,
|
|
||||||
toggleCollapsed() {
|
|
||||||
setIsCollapsed(itemId, !isCollapsedD.getValue())
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}, [props.sheetId])
|
|
||||||
return (
|
|
||||||
<CollapsableContext.Provider value={contextValue}>
|
|
||||||
<ProviderChildrenMemo children={props.children} />
|
|
||||||
</CollapsableContext.Provider>
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -28,7 +28,6 @@ import {
|
||||||
TitleBar_Punctuation,
|
TitleBar_Punctuation,
|
||||||
} from '@theatre/studio/panels/BasePanel/common'
|
} from '@theatre/studio/panels/BasePanel/common'
|
||||||
import type {UIPanelId} from '@theatre/shared/utils/ids'
|
import type {UIPanelId} from '@theatre/shared/utils/ids'
|
||||||
import {ProvideCollapsable} from './DopeSheet/useSequenceEditorCollapsable'
|
|
||||||
|
|
||||||
const Container = styled(PanelWrapper)`
|
const Container = styled(PanelWrapper)`
|
||||||
z-index: ${panelZIndexes.sequenceEditorPanel};
|
z-index: ${panelZIndexes.sequenceEditorPanel};
|
||||||
|
@ -164,17 +163,15 @@ const Content: React.VFC<{}> = () => {
|
||||||
return (
|
return (
|
||||||
<Container ref={containerRef}>
|
<Container ref={containerRef}>
|
||||||
<LeftBackground style={{width: `${val(layoutP.leftDims.width)}px`}} />
|
<LeftBackground style={{width: `${val(layoutP.leftDims.width)}px`}} />
|
||||||
<ProvideCollapsable sheetId={sheet.address.sheetId} layoutP={layoutP}>
|
<FrameStampPositionProvider layoutP={layoutP}>
|
||||||
<FrameStampPositionProvider layoutP={layoutP}>
|
<Header layoutP={layoutP} />
|
||||||
<Header layoutP={layoutP} />
|
<DopeSheet key={key + '-dopeSheet'} layoutP={layoutP} />
|
||||||
<DopeSheet key={key + '-dopeSheet'} layoutP={layoutP} />
|
{graphEditorOpen && (
|
||||||
{graphEditorOpen && (
|
<GraphEditor key={key + '-graphEditor'} layoutP={layoutP} />
|
||||||
<GraphEditor key={key + '-graphEditor'} layoutP={layoutP} />
|
)}
|
||||||
)}
|
{graphEditorAvailable && <GraphEditorToggle layoutP={layoutP} />}
|
||||||
{graphEditorAvailable && <GraphEditorToggle layoutP={layoutP} />}
|
<RightOverlay layoutP={layoutP} />
|
||||||
<RightOverlay layoutP={layoutP} />
|
</FrameStampPositionProvider>
|
||||||
</FrameStampPositionProvider>
|
|
||||||
</ProvideCollapsable>
|
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}, [dims])
|
}, [dims])
|
||||||
|
|
|
@ -186,7 +186,11 @@ export function sequenceEditorPanelLayout(
|
||||||
.stateBySheetId[sheet.address.sheetId]
|
.stateBySheetId[sheet.address.sheetId]
|
||||||
|
|
||||||
return prism(() => {
|
return prism(() => {
|
||||||
const tree = subPrism('tree', () => calculateSequenceEditorTree(sheet), [])
|
const tree = subPrism(
|
||||||
|
'tree',
|
||||||
|
() => calculateSequenceEditorTree(sheet, studio),
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
|
||||||
const panelDims = val(panelDimsP)
|
const panelDims = val(panelDimsP)
|
||||||
const graphEditorState = val(
|
const graphEditorState = val(
|
||||||
|
|
|
@ -9,10 +9,12 @@ import type {IPropPathToTrackIdTree} from '@theatre/core/sheetObjects/SheetObjec
|
||||||
import type Sheet from '@theatre/core/sheets/Sheet'
|
import type Sheet from '@theatre/core/sheets/Sheet'
|
||||||
import type {PathToProp} from '@theatre/shared/utils/addresses'
|
import type {PathToProp} from '@theatre/shared/utils/addresses'
|
||||||
import type {SequenceTrackId} from '@theatre/shared/utils/ids'
|
import type {SequenceTrackId} from '@theatre/shared/utils/ids'
|
||||||
|
import {createStudioSheetItemKey} from '@theatre/shared/utils/ids'
|
||||||
import type {$FixMe, $IntentionalAny} from '@theatre/shared/utils/types'
|
import type {$FixMe, $IntentionalAny} from '@theatre/shared/utils/types'
|
||||||
import {prism, val} from '@theatre/dataverse'
|
import {prism, val, valueDerivation} from '@theatre/dataverse'
|
||||||
import logger from '@theatre/shared/logger'
|
import logger from '@theatre/shared/logger'
|
||||||
import {titleBarHeight} from '@theatre/studio/panels/BasePanel/common'
|
import {titleBarHeight} from '@theatre/studio/panels/BasePanel/common'
|
||||||
|
import type {Studio} from '@theatre/studio/Studio'
|
||||||
|
|
||||||
export type SequenceEditorTree_Row<Type> = {
|
export type SequenceEditorTree_Row<Type> = {
|
||||||
type: Type
|
type: Type
|
||||||
|
@ -32,6 +34,7 @@ export type SequenceEditorTree_Sheet = SequenceEditorTree_Row<'sheet'> & {
|
||||||
|
|
||||||
export type SequenceEditorTree_SheetObject =
|
export type SequenceEditorTree_SheetObject =
|
||||||
SequenceEditorTree_Row<'sheetObject'> & {
|
SequenceEditorTree_Row<'sheetObject'> & {
|
||||||
|
isCollapsed: boolean
|
||||||
sheetObject: SheetObject
|
sheetObject: SheetObject
|
||||||
children: Array<
|
children: Array<
|
||||||
SequenceEditorTree_PropWithChildren | SequenceEditorTree_PrimitiveProp
|
SequenceEditorTree_PropWithChildren | SequenceEditorTree_PrimitiveProp
|
||||||
|
@ -40,6 +43,7 @@ export type SequenceEditorTree_SheetObject =
|
||||||
|
|
||||||
export type SequenceEditorTree_PropWithChildren =
|
export type SequenceEditorTree_PropWithChildren =
|
||||||
SequenceEditorTree_Row<'propWithChildren'> & {
|
SequenceEditorTree_Row<'propWithChildren'> & {
|
||||||
|
isCollapsed: boolean
|
||||||
sheetObject: SheetObject
|
sheetObject: SheetObject
|
||||||
pathToProp: PathToProp
|
pathToProp: PathToProp
|
||||||
children: Array<
|
children: Array<
|
||||||
|
@ -62,13 +66,14 @@ export type SequenceEditorTree_AllRowTypes =
|
||||||
| SequenceEditorTree_PropWithChildren
|
| SequenceEditorTree_PropWithChildren
|
||||||
| SequenceEditorTree_PrimitiveProp
|
| SequenceEditorTree_PrimitiveProp
|
||||||
|
|
||||||
const heightOfAnyTitle = 28
|
const HEIGHT_OF_ANY_TITLE = 28
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must run inside prism()
|
* Must run inside prism()
|
||||||
*/
|
*/
|
||||||
export const calculateSequenceEditorTree = (
|
export const calculateSequenceEditorTree = (
|
||||||
sheet: Sheet,
|
sheet: Sheet,
|
||||||
|
studio: Studio,
|
||||||
): SequenceEditorTree => {
|
): SequenceEditorTree => {
|
||||||
prism.ensurePrism()
|
prism.ensurePrism()
|
||||||
let topSoFar = titleBarHeight
|
let topSoFar = titleBarHeight
|
||||||
|
@ -81,12 +86,15 @@ export const calculateSequenceEditorTree = (
|
||||||
top: topSoFar,
|
top: topSoFar,
|
||||||
depth: -1,
|
depth: -1,
|
||||||
n: nSoFar,
|
n: nSoFar,
|
||||||
nodeHeight: 0,
|
nodeHeight: 0, // always 0
|
||||||
heightIncludingChildren: -1, // will defined this later
|
heightIncludingChildren: -1, // will define this later
|
||||||
}
|
}
|
||||||
topSoFar += tree.nodeHeight
|
|
||||||
nSoFar += 1
|
nSoFar += 1
|
||||||
|
|
||||||
|
const collapsableP =
|
||||||
|
studio.atomP.ahistoric.projects.stateByProjectId[sheet.address.projectId]
|
||||||
|
.stateBySheetId[sheet.address.sheetId].sequence.collapsableItems
|
||||||
|
|
||||||
for (const sheetObject of Object.values(val(sheet.objectsP))) {
|
for (const sheetObject of Object.values(val(sheet.objectsP))) {
|
||||||
if (sheetObject) {
|
if (sheetObject) {
|
||||||
addObject(sheetObject, tree.children, tree.depth + 1)
|
addObject(sheetObject, tree.children, tree.depth + 1)
|
||||||
|
@ -105,29 +113,35 @@ export const calculateSequenceEditorTree = (
|
||||||
|
|
||||||
if (Object.keys(trackSetups).length === 0) return
|
if (Object.keys(trackSetups).length === 0) return
|
||||||
|
|
||||||
|
const isCollapsedP =
|
||||||
|
collapsableP.byId[createStudioSheetItemKey.forSheetObject(sheetObject)]
|
||||||
|
.isCollapsed
|
||||||
|
const isCollapsed = valueDerivation(isCollapsedP).getValue() ?? false
|
||||||
|
|
||||||
const row: SequenceEditorTree_SheetObject = {
|
const row: SequenceEditorTree_SheetObject = {
|
||||||
type: 'sheetObject',
|
type: 'sheetObject',
|
||||||
|
isCollapsed: isCollapsed,
|
||||||
top: topSoFar,
|
top: topSoFar,
|
||||||
children: [],
|
children: [],
|
||||||
depth: level,
|
depth: level,
|
||||||
n: nSoFar,
|
n: nSoFar,
|
||||||
sheetObject: sheetObject,
|
sheetObject: sheetObject,
|
||||||
nodeHeight: heightOfAnyTitle,
|
nodeHeight: HEIGHT_OF_ANY_TITLE,
|
||||||
heightIncludingChildren: -1,
|
heightIncludingChildren: -1,
|
||||||
}
|
}
|
||||||
arrayOfChildren.push(row)
|
arrayOfChildren.push(row)
|
||||||
nSoFar += 1
|
nSoFar += 1
|
||||||
topSoFar += heightOfAnyTitle
|
topSoFar += HEIGHT_OF_ANY_TITLE
|
||||||
|
if (!isCollapsed) {
|
||||||
addProps(
|
addProps(
|
||||||
sheetObject,
|
sheetObject,
|
||||||
trackSetups,
|
trackSetups,
|
||||||
[],
|
[],
|
||||||
sheetObject.template.config,
|
sheetObject.template.config,
|
||||||
row.children,
|
row.children,
|
||||||
level + 1,
|
level + 1,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
row.heightIncludingChildren = topSoFar - row.top
|
row.heightIncludingChildren = topSoFar - row.top
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,31 +215,39 @@ export const calculateSequenceEditorTree = (
|
||||||
>,
|
>,
|
||||||
level: number,
|
level: number,
|
||||||
) {
|
) {
|
||||||
|
const isCollapsedP =
|
||||||
|
collapsableP.byId[
|
||||||
|
createStudioSheetItemKey.forSheetObjectProp(sheetObject, pathToProp)
|
||||||
|
].isCollapsed
|
||||||
|
const isCollapsed = valueDerivation(isCollapsedP).getValue() ?? false
|
||||||
|
|
||||||
const row: SequenceEditorTree_PropWithChildren = {
|
const row: SequenceEditorTree_PropWithChildren = {
|
||||||
type: 'propWithChildren',
|
type: 'propWithChildren',
|
||||||
|
isCollapsed: isCollapsed,
|
||||||
pathToProp,
|
pathToProp,
|
||||||
sheetObject: sheetObject,
|
sheetObject: sheetObject,
|
||||||
top: topSoFar,
|
top: topSoFar,
|
||||||
children: [],
|
children: [],
|
||||||
nodeHeight: heightOfAnyTitle,
|
nodeHeight: HEIGHT_OF_ANY_TITLE,
|
||||||
heightIncludingChildren: -1,
|
heightIncludingChildren: -1,
|
||||||
depth: level,
|
depth: level,
|
||||||
trackMapping,
|
trackMapping,
|
||||||
n: nSoFar,
|
n: nSoFar,
|
||||||
}
|
}
|
||||||
topSoFar += heightOfAnyTitle
|
|
||||||
nSoFar += 1
|
|
||||||
arrayOfChildren.push(row)
|
arrayOfChildren.push(row)
|
||||||
|
topSoFar += HEIGHT_OF_ANY_TITLE
|
||||||
|
if (!isCollapsed) {
|
||||||
|
nSoFar += 1
|
||||||
|
|
||||||
addProps(
|
addProps(
|
||||||
sheetObject,
|
sheetObject,
|
||||||
trackMapping,
|
trackMapping,
|
||||||
pathToProp,
|
pathToProp,
|
||||||
conf,
|
conf,
|
||||||
row.children,
|
row.children,
|
||||||
level + 1,
|
level + 1,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
row.heightIncludingChildren = topSoFar - row.top
|
row.heightIncludingChildren = topSoFar - row.top
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,14 +268,14 @@ export const calculateSequenceEditorTree = (
|
||||||
sheetObject: sheetObject,
|
sheetObject: sheetObject,
|
||||||
pathToProp,
|
pathToProp,
|
||||||
top: topSoFar,
|
top: topSoFar,
|
||||||
nodeHeight: heightOfAnyTitle,
|
nodeHeight: HEIGHT_OF_ANY_TITLE,
|
||||||
heightIncludingChildren: heightOfAnyTitle,
|
heightIncludingChildren: HEIGHT_OF_ANY_TITLE,
|
||||||
trackId,
|
trackId,
|
||||||
n: nSoFar,
|
n: nSoFar,
|
||||||
}
|
}
|
||||||
arrayOfChildren.push(row)
|
arrayOfChildren.push(row)
|
||||||
nSoFar += 1
|
nSoFar += 1
|
||||||
topSoFar += heightOfAnyTitle
|
topSoFar += HEIGHT_OF_ANY_TITLE
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree
|
return tree
|
||||||
|
|
|
@ -490,10 +490,9 @@ namespace stateEditors {
|
||||||
stateEditors.studio.ahistoric.projects.stateByProjectId.stateBySheetId.sequence._ensure(
|
stateEditors.studio.ahistoric.projects.stateByProjectId.stateBySheetId.sequence._ensure(
|
||||||
p,
|
p,
|
||||||
)
|
)
|
||||||
let existing = seq.sequenceEditorCollapsableItems
|
let existing = seq.collapsableItems
|
||||||
if (!existing) {
|
if (!existing) {
|
||||||
existing = seq.sequenceEditorCollapsableItems =
|
existing = seq.collapsableItems = pointableSetUtil.create()
|
||||||
pointableSetUtil.create()
|
|
||||||
}
|
}
|
||||||
return existing
|
return existing
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ export type StudioAhistoricState = {
|
||||||
range: IRange
|
range: IRange
|
||||||
}
|
}
|
||||||
|
|
||||||
sequenceEditorCollapsableItems?: PointableSet<
|
collapsableItems?: PointableSet<
|
||||||
StudioSheetItemKey,
|
StudioSheetItemKey,
|
||||||
{
|
{
|
||||||
isCollapsed: boolean
|
isCollapsed: boolean
|
||||||
|
|
Loading…
Reference in a new issue