-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4a77854
commit e75aa7b
Showing
14 changed files
with
1,438 additions
and
0 deletions.
There are no files selected for viewing
80 changes: 80 additions & 0 deletions
80
docs/data/tree-view/rich-tree-view/customization/ThreeDCanvas.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import React from 'react'; | ||
import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; | ||
import CustomTreeItem from './three-d/CustomTreeItem'; | ||
import CustomTreeItemContextMenu from './three-d/ContextMenu'; | ||
import Scene from './three-d/Scene'; | ||
import sceneObjects from './three-d/SceneObjects'; | ||
import ThemeProvider from '@mui/material/styles/ThemeProvider'; | ||
import { createTheme } from '@mui/material/styles'; | ||
|
||
const darkTheme = createTheme({ | ||
palette: { | ||
mode: 'dark', | ||
primary: { | ||
main: '#5ecaff', | ||
}, | ||
background: { | ||
default: '#f5f5f5', // Replace with your desired background color | ||
}, | ||
}, | ||
}); | ||
|
||
export default function Demo() { | ||
const [objectsToRender, setObjectsToRender] = React.useState(sceneObjects); | ||
const [expandedNodes, setExpandedNodes] = React.useState([ | ||
'lights', | ||
'chassi', | ||
'wheels', | ||
'car', | ||
]); | ||
|
||
const handleExpandedNodesChange = (event, nodeIds) => { | ||
setExpandedNodes(nodeIds); | ||
}; | ||
|
||
const toggleVisibility = (nodeId, items = objectsToRender) => { | ||
items.forEach((item) => { | ||
if (item.id === nodeId) { | ||
item.visibility = !item.visibility; | ||
} | ||
if (item.children && item.children.length > 0) { | ||
// do it recursively | ||
toggleVisibility(nodeId, item.children); | ||
} | ||
}); | ||
setObjectsToRender([...items]); | ||
}; | ||
return ( | ||
<ThemeProvider theme={darkTheme}> | ||
<div | ||
style={{ | ||
minHeight: 200, | ||
flexGrow: 1, | ||
display: 'flex', | ||
flexDirection: 'row', | ||
background: 'black', | ||
alignContent: 'center', | ||
maxWidth: '800px', | ||
borderRadius: '30px', | ||
overflow: 'hidden', | ||
margin: '10px auto', | ||
}} | ||
> | ||
<RichTreeView | ||
items={sceneObjects} | ||
expandedItems={expandedNodes} | ||
onExpandedItemsChange={handleExpandedNodesChange} | ||
sx={{ minWidth: '50%', paddingTop: '60px', paddingLeft: '20px' }} | ||
slots={{ item: CustomTreeItem }} | ||
slotProps={{ | ||
item: { | ||
toggleVisibility: toggleVisibility, | ||
sceneObjects: objectsToRender, //temporarily solution | ||
}, | ||
}} | ||
/> | ||
<Scene objects={objectsToRender} /> | ||
</div> | ||
</ThemeProvider> | ||
); | ||
} |
83 changes: 83 additions & 0 deletions
83
docs/data/tree-view/rich-tree-view/customization/ThreeDCanvas.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React from 'react'; | ||
import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; | ||
import CustomTreeItem from './three-d/CustomTreeItem'; | ||
import CustomTreeItemContextMenu from './three-d/ContextMenu'; | ||
import Scene from './three-d/Scene'; | ||
import sceneObjects from './three-d/SceneObjects'; | ||
import ThemeProvider from '@mui/material/styles/ThemeProvider'; | ||
import { createTheme } from '@mui/material/styles'; | ||
|
||
const darkTheme = createTheme({ | ||
palette: { | ||
mode: 'dark', | ||
primary: { | ||
main: '#5ecaff', | ||
}, | ||
background: { | ||
default: '#f5f5f5', // Replace with your desired background color | ||
}, | ||
}, | ||
}); | ||
|
||
export default function Demo() { | ||
const [objectsToRender, setObjectsToRender] = React.useState(sceneObjects); | ||
const [expandedNodes, setExpandedNodes] = React.useState<string[]>([ | ||
'lights', | ||
'chassi', | ||
'wheels', | ||
'car', | ||
]); | ||
|
||
const handleExpandedNodesChange = ( | ||
event: React.SyntheticEvent, | ||
nodeIds: string[] | ||
) => { | ||
setExpandedNodes(nodeIds); | ||
}; | ||
|
||
const toggleVisibility = (nodeId, items = objectsToRender) => { | ||
items.forEach((item) => { | ||
if (item.id === nodeId) { | ||
item.visibility = !item.visibility; | ||
} | ||
if (item.children && item.children.length > 0) { | ||
// do it recursively | ||
toggleVisibility(nodeId, item.children); | ||
} | ||
}); | ||
setObjectsToRender([...items]); | ||
}; | ||
return ( | ||
<ThemeProvider theme={darkTheme}> | ||
<div | ||
style={{ | ||
minHeight: 200, | ||
flexGrow: 1, | ||
display: 'flex', | ||
flexDirection: 'row', | ||
background: 'black', | ||
alignContent: 'center', | ||
maxWidth: '800px', | ||
borderRadius: '30px', | ||
overflow: 'hidden', | ||
margin: '10px auto', | ||
}} | ||
> | ||
<RichTreeView | ||
items={sceneObjects} | ||
expandedItems={expandedNodes} | ||
onExpandedItemsChange={handleExpandedNodesChange} | ||
sx={{ minWidth: '50%', paddingTop: '60px', paddingLeft: '20px' }} | ||
slots={{ item: CustomTreeItem }} | ||
slotProps={{ | ||
item: { | ||
toggleVisibility: toggleVisibility, | ||
sceneObjects: objectsToRender, //temporarily solution | ||
}, | ||
}} | ||
/> | ||
<Scene objects={objectsToRender} /> | ||
</div> | ||
</ThemeProvider> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
docs/data/tree-view/rich-tree-view/customization/three-d/ContextMenu.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from 'react'; | ||
import Menu from '@mui/material/Menu'; | ||
import MenuItem from '@mui/material/MenuItem'; | ||
|
||
export default function CustomTreeItemContextMenu(props) { | ||
const { positionSeed, onClose, onClick, menuItems } = props; | ||
|
||
const open = Boolean(positionSeed); | ||
|
||
const { x, y } = positionSeed ? positionSeed : { x: null, y: null }; | ||
return ( | ||
<Menu | ||
open={open} | ||
onClose={onClose} | ||
anchorReference="anchorPosition" | ||
anchorPosition={positionSeed !== null ? { top: y, left: x } : undefined} | ||
> | ||
{menuItems.map((item, index) => ( | ||
<MenuItem | ||
key={index} | ||
onClick={() => { | ||
onClick(item); | ||
}} | ||
> | ||
{item} | ||
</MenuItem> | ||
))} | ||
</Menu> | ||
); | ||
} |
38 changes: 38 additions & 0 deletions
38
docs/data/tree-view/rich-tree-view/customization/three-d/ContextMenu.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
|
||
import React from 'react'; | ||
import Menu from '@mui/material/Menu'; | ||
import MenuItem from '@mui/material/MenuItem'; | ||
|
||
interface ContextMenuProps { | ||
positionSeed: { x: number; y: number } | null; | ||
onClose: () => void; | ||
onClick: (menuItem: string) => void; | ||
menuItems: string[]; //you may want to have another type for | ||
} | ||
|
||
export default function CustomTreeItemContextMenu(props: ContextMenuProps) { | ||
const { positionSeed, onClose, onClick, menuItems } = props; | ||
|
||
const open = Boolean(positionSeed); | ||
|
||
const { x, y } = positionSeed ? positionSeed : { x: null, y: null }; | ||
return ( | ||
<Menu | ||
open={open} | ||
onClose={onClose} | ||
anchorReference="anchorPosition" | ||
anchorPosition={positionSeed !== null ? { top: y, left: x } : undefined} | ||
> | ||
{menuItems.map((item, index) => ( | ||
<MenuItem | ||
key={index} | ||
onClick={() => { | ||
onClick(item); | ||
}} | ||
> | ||
{item} | ||
</MenuItem> | ||
))} | ||
</Menu> | ||
); | ||
} |
148 changes: 148 additions & 0 deletions
148
docs/data/tree-view/rich-tree-view/customization/three-d/CustomTreeItem.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
import React from 'react'; | ||
import { styled } from '@mui/material/styles'; | ||
import Box from '@mui/material/Box'; | ||
import VisibilityIcon from '@mui/icons-material/Visibility'; | ||
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'; | ||
import ViewInArOutlinedIcon from '@mui/icons-material/ViewInArOutlined'; | ||
import LightbulbOutlinedIcon from '@mui/icons-material/LightbulbOutlined'; | ||
import FolderOutlinedIcon from '@mui/icons-material/FolderOutlined'; | ||
import { unstable_useTreeItem2 as useTreeItem2 } from '@mui/x-tree-view/useTreeItem2'; | ||
import { | ||
TreeItem2Content, | ||
TreeItem2IconContainer, | ||
TreeItem2Label, | ||
TreeItem2Root, | ||
TreeItem2GroupTransition, | ||
} from '@mui/x-tree-view/TreeItem2'; | ||
import { TreeItem2Icon } from '@mui/x-tree-view/TreeItem2Icon'; | ||
import { TreeItem2Provider } from '@mui/x-tree-view/TreeItem2Provider'; | ||
import { useTreeItem2Utils } from '@mui/x-tree-view/hooks'; | ||
|
||
import { findItemById } from './SceneObjects'; //temporarily solution | ||
import CustomTreeItemContextMenu from './ContextMenu'; | ||
|
||
const CustomTreeItemContent = styled(TreeItem2Content)(({ theme }) => ({ | ||
padding: theme.spacing(0.5, 1), | ||
})); | ||
|
||
const CustomTreeItem = React.forwardRef(function CustomTreeItem(props, ref) { | ||
const { id, itemId, label, children, sceneObjects, toggleVisibility, ...other } = | ||
props; | ||
|
||
const { | ||
getRootProps, | ||
getContentProps, | ||
getIconContainerProps, | ||
getLabelProps, | ||
getGroupTransitionProps, | ||
status, | ||
} = useTreeItem2({ id, itemId, children, label, rootRef: ref }); | ||
|
||
const originalItem = findItemById(sceneObjects, itemId); | ||
const { visibility, type } = originalItem; | ||
|
||
const [mousePosition, setMousePosition] = React.useState(null); | ||
|
||
const handleContextMenu = (event) => { | ||
event.preventDefault(); | ||
setMousePosition({ | ||
x: event.clientX - 2, | ||
y: event.clientY - 4, | ||
}); | ||
}; | ||
|
||
const handleContextMenuClose = () => { | ||
setMousePosition(null); // Closes the context menu | ||
}; | ||
|
||
const handleContextMenuItemClick = (action) => { | ||
console.log(action); | ||
handleContextMenuClose(); | ||
}; | ||
|
||
const handleEyeClick = () => { | ||
toggleVisibility(itemId); | ||
}; | ||
|
||
const { interactions } = useTreeItem2Utils({ | ||
itemId: props.itemId, | ||
children: props.children, | ||
}); | ||
|
||
const handleContentClick = (event) => { | ||
event.defaultMuiPrevented = true; | ||
interactions.handleSelection(event); | ||
}; | ||
|
||
const handleIconContainerClick = (event) => { | ||
interactions.handleExpansion(event); | ||
}; | ||
|
||
const ItemIcon = () => { | ||
switch (type) { | ||
case 'mesh': | ||
return <ViewInArOutlinedIcon style={{ color: 'darkolivegreen' }} />; | ||
case 'light': | ||
return <LightbulbOutlinedIcon style={{ color: 'yellow' }} />; | ||
case 'collection': | ||
return <FolderOutlinedIcon style={{ color: 'gray' }} />; | ||
default: | ||
return null; | ||
} | ||
}; | ||
|
||
return ( | ||
<TreeItem2Provider itemId={itemId}> | ||
<TreeItem2Root {...getRootProps(other)}> | ||
<CustomTreeItemContent | ||
{...getContentProps()} | ||
onContextMenu={handleContextMenu} | ||
> | ||
<TreeItem2IconContainer | ||
{...getIconContainerProps()} | ||
onClick={handleIconContainerClick} | ||
> | ||
<TreeItem2Icon status={status} /> | ||
</TreeItem2IconContainer> | ||
<Box | ||
sx={{ flexGrow: 1, display: 'flex', gap: 1 }} | ||
onClick={handleContentClick} | ||
> | ||
{visibility ? ( | ||
<VisibilityIcon | ||
sx={(theme) => ({ | ||
color: theme.palette.primary.main, | ||
width: 24, | ||
height: 24, | ||
})} | ||
onClick={handleEyeClick} | ||
/> | ||
) : ( | ||
<VisibilityOffIcon | ||
sx={{ width: 24, height: 24, color: '#555' }} | ||
onClick={handleEyeClick} | ||
/> | ||
)} | ||
|
||
<ItemIcon /> | ||
<TreeItem2Label | ||
{...getLabelProps()} | ||
sx={(theme) => ({ | ||
color: visibility ? theme.palette.text.primary : '#888', | ||
})} | ||
/> | ||
</Box> | ||
</CustomTreeItemContent> | ||
{children && <TreeItem2GroupTransition {...getGroupTransitionProps()} />} | ||
</TreeItem2Root> | ||
<CustomTreeItemContextMenu | ||
positionSeed={mousePosition} | ||
onClose={handleContextMenuClose} | ||
onClick={handleContextMenuItemClick} | ||
menuItems={['Action 1', 'Action 2', 'Action 3']} | ||
/> | ||
</TreeItem2Provider> | ||
); | ||
}); | ||
|
||
export default CustomTreeItem; |
Oops, something went wrong.