diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/direct-edit/useDiagramDirectEdit.tsx b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/direct-edit/useDiagramDirectEdit.tsx index 9f43e3fb6b..df76ca8d6b 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/direct-edit/useDiagramDirectEdit.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/direct-edit/useDiagramDirectEdit.tsx @@ -41,7 +41,7 @@ export const useDiagramDirectEdit = (): UseDiagramDirectEditValue => { if (key !== 'F2' && isTextField) { return; } - + event.preventDefault(); const validFirstInputChar = !event.metaKey && !event.ctrlKey && key.length === 1 && directEditActivationValidCharacters.test(key); diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/Palette.tsx b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/Palette.tsx index 6ac7064da2..09b7bd5c32 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/Palette.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/Palette.tsx @@ -11,16 +11,17 @@ * Obeo - initial API and implementation *******************************************************************************/ +import CloseIcon from '@mui/icons-material/Close'; import DragIndicatorIcon from '@mui/icons-material/DragIndicator'; import Box from '@mui/material/Box'; import Divider from '@mui/material/Divider'; +import IconButton from '@mui/material/IconButton'; import Paper from '@mui/material/Paper'; import { Edge, Node, useStoreApi, useViewport, XYPosition } from '@xyflow/react'; import React, { useCallback, useEffect, useState } from 'react'; import Draggable, { DraggableData } from 'react-draggable'; import { makeStyles } from 'tss-react/mui'; import { EdgeData, NodeData } from '../DiagramRenderer.types'; -import { useGroupPalette } from './group-tool/useGroupPalette'; import { GQLPalette, GQLPaletteDivider, @@ -48,14 +49,13 @@ const usePaletteStyle = makeStyles()((theme, props) => ({ zIndex: 5, position: 'fixed', width: props.paletteWidth, - height: props.paletteHeight, }, paletteHeader: { cursor: 'move', width: '100%', display: 'flex', flexDirection: 'row', - justifyContent: 'flex-start', + justifyContent: 'space-between', alignItems: 'center', backgroundColor: `${theme.palette.secondary.main}08`, }, @@ -77,7 +77,6 @@ const computeDraggableBounds = (bounds?: DOMRect): XYPosition => { }; const paletteWidth = 200; -const paletteHeight = 275; const getPaletteToolCount = (palette: GQLPalette): number => { return ( @@ -93,7 +92,8 @@ const computePaletteLocation = ( paletteX: number, paletteY: number, viewportWidth: number, - viewportHeight: number + viewportHeight: number, + paletteHeight: number ): XYPosition => { return { x: paletteX + paletteWidth < viewportWidth ? paletteX : viewportWidth - paletteWidth, @@ -126,9 +126,16 @@ export const Palette = ({ y = (paletteY - viewportY) / viewportZoom; } const { handleToolClick, palette } = usePalette({ x, y, diagramElementId, onDirectEditClick, targetObjectId }); + const paletteHeight = palette ? palette.paletteEntries.length * 30 + 50 : 50; useEffect(() => { - const paletteLocation: XYPosition = computePaletteLocation(paletteX, paletteY, viewportWidth, viewportHeight); + const paletteLocation: XYPosition = computePaletteLocation( + paletteX, + paletteY, + viewportWidth, + viewportHeight, + paletteHeight + ); setState((prevState) => ({ ...prevState, controlledPosition: paletteLocation })); }, [paletteX, paletteY, viewportWidth, viewportHeight]); @@ -138,36 +145,32 @@ export const Palette = ({ const { hideDiagramPalette } = useDiagramPalette(); const { hideDiagramElementPalette } = useDiagramElementPalette(); - const { hideGroupPalette } = useGroupPalette(); + const store = useStoreApi, Edge>(); const closeAllPalettes = useCallback(() => { hideDiagramPalette(); hideDiagramElementPalette(); - hideGroupPalette(); - }, [hideDiagramPalette, hideDiagramElementPalette, hideGroupPalette]); - const store = useStoreApi, Edge>(); + //Set the focus from the palette to the node/edge + const selectedNode = store.getState().nodes.filter((node) => node.selected); + const selectedEdges = store.getState().edges.filter((edge) => edge.selected); + if (selectedNode.length + selectedEdges.length === 1) { + const selectedElement = selectedNode[0] || selectedEdges[0]; + if (selectedElement) { + let domElement = document.querySelector(`[data-id='${selectedElement.id}']`); + if (domElement) { + (domElement as HTMLElement).focus(); + } + } + } + }, [hideDiagramPalette, hideDiagramElementPalette]); const onKeyDown = useCallback((event: React.KeyboardEvent) => { const { key } = event; if (key === 'Escape') { // Stop propagating the event in order to keep the node/edge selected event.stopPropagation(); - closeAllPalettes(); - - //Set the focus from the palette to the node/edge - const selectedNode = store.getState().nodes.filter((node) => node.selected); - const selectedEdges = store.getState().edges.filter((edge) => edge.selected); - if (selectedNode.length + selectedEdges.length === 1) { - const selectedElement = selectedNode[0] || selectedEdges[0]; - if (selectedElement) { - let domElement = document.querySelector(`[data-id='${selectedElement.id}']`); - if (domElement) { - (domElement as HTMLElement).focus(); - } - } - } } }, []); @@ -209,6 +212,9 @@ export const Palette = ({ tabIndex={0}> + + + | Edge): diagramEle return !!diagramElement.data && 'bendingPoints' in diagramElement.data && !!diagramElement.data.bendingPoints; }; -const useStyle = makeStyles()(() => ({ +const useStyle = makeStyles()((theme) => ({ quickAccessTools: { display: 'flex', flexWrap: 'nowrap', @@ -44,6 +43,9 @@ const useStyle = makeStyles()(() => ({ alignItems: 'center', overflowX: 'auto', }, + quickAccessToolContainer: { + width: theme.spacing(3.5), + }, })); export const PaletteQuickAccessToolBar = ({ @@ -54,15 +56,10 @@ export const PaletteQuickAccessToolBar = ({ y, }: PaletteQuickAccessToolBarProps) => { const { classes } = useStyle(); - + const quickAccessToolComponents: JSX.Element[] = []; const { nodeLookup, edgeLookup } = useStoreApi, Edge>().getState(); const diagramElement = nodeLookup.get(diagramElementId) || edgeLookup.get(diagramElementId); - const quickAccessToolComponents: JSX.Element[] = []; - quickAccessTools.forEach((tool) => - quickAccessToolComponents.push() - ); - if (diagramElement) { if (isPinnable(diagramElement)) { quickAccessToolComponents.push( @@ -109,16 +106,18 @@ export const PaletteQuickAccessToolBar = ({ /> ) ); - } - if (quickAccessToolComponents.length > 0) { - return ( - <> - {quickAccessToolComponents} - - + quickAccessTools.forEach((tool) => + quickAccessToolComponents.push() ); - } else { - return null; } + return ( + + {quickAccessToolComponents.map((quickAcessTool, index) => ( +
+ {quickAcessTool} +
+ ))} +
+ ); }; diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/tool-list/PaletteToolSectionList.tsx b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/tool-list/PaletteToolSectionList.tsx index 7caf25d95f..9dd912db9c 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/tool-list/PaletteToolSectionList.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/tool-list/PaletteToolSectionList.tsx @@ -16,6 +16,7 @@ import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import Tooltip from '@mui/material/Tooltip'; import { makeStyles } from 'tss-react/mui'; +import { isSingleClickOnDiagramElementTool } from '../Palette'; import { ToolListItem } from '../tool-list-item/ToolListItem'; import { PaletteToolSectionListProps } from './PaletteToolSectionList.types'; @@ -69,7 +70,7 @@ export const PaletteToolSectionList = ({ toolSection, onToolClick, onBackToMainL - {toolSection.tools.map((tool) => ( + {toolSection.tools.filter(isSingleClickOnDiagramElementTool).map((tool) => ( ))} diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/usePalette.tsx b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/usePalette.tsx index e364eb5522..6feb5ec797 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/usePalette.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/palette/usePalette.tsx @@ -324,6 +324,7 @@ export const usePalette = ({ const { setLastToolInvoked } = useDiagramPalette(); const handleToolClick = (tool: GQLTool) => { + closeAllPalettes(); closeAllPalettes(); switch (tool.id) { case 'edit': diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.tsx b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.tsx index 8c3e555115..fec01609ce 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/panel/DiagramPanel.tsx @@ -29,23 +29,26 @@ import IconButton from '@mui/material/IconButton'; import Paper from '@mui/material/Paper'; import Tooltip from '@mui/material/Tooltip'; import { Edge, Node, Panel, useNodesInitialized, useReactFlow } from '@xyflow/react'; -import { memo, useContext, useEffect, useState } from 'react'; +import { memo, useCallback, useContext, useEffect, useState } from 'react'; import { DiagramContext } from '../../contexts/DiagramContext'; import { DiagramContextValue } from '../../contexts/DiagramContext.types'; import { HelperLinesIcon } from '../../icons/HelperLinesIcon'; import { HelperLinesIconOff } from '../../icons/HelperLinesIconOff'; +import { SmartEdgeIcon } from '../../icons/SmartEdgeIcon'; +import { SmoothStepEdgeIcon } from '../../icons/SmoothStepEdgeIcon'; import { UnpinIcon } from '../../icons/UnpinIcon'; import { EdgeData, NodeData } from '../DiagramRenderer.types'; import { useFadeDiagramElements } from '../fade/useFadeDiagramElements'; import { useFullscreen } from '../fullscreen/useFullscreen'; import { useHideDiagramElements } from '../hide/useHideDiagramElements'; import { useArrangeAll } from '../layout/useArrangeAll'; +import { useGroupPalette } from '../palette/group-tool/useGroupPalette'; +import { useDiagramElementPalette } from '../palette/useDiagramElementPalette'; +import { useDiagramPalette } from '../palette/useDiagramPalette'; import { usePinDiagramElements } from '../pin/usePinDiagramElements'; import { DiagramPanelActionProps, DiagramPanelProps, DiagramPanelState } from './DiagramPanel.types'; import { diagramPanelActionExtensionPoint } from './DiagramPanelExtensionPoints'; import { useExportToImage } from './useExportToImage'; -import { SmartEdgeIcon } from '../../icons/SmartEdgeIcon'; -import { SmoothStepEdgeIcon } from '../../icons/SmoothStepEdgeIcon'; export const DiagramPanel = memo( ({ @@ -103,6 +106,16 @@ export const DiagramPanel = memo( const onUnhideAll = () => hideDiagramElements([...getAllElementsIds()], false); const onUnpinAll = () => pinDiagramElements([...getAllElementsIds()], false); + const { hideDiagramPalette } = useDiagramPalette(); + const { hideDiagramElementPalette } = useDiagramElementPalette(); + const { hideGroupPalette } = useGroupPalette(); + + const closeAllPalettes = useCallback(() => { + hideDiagramPalette(); + hideDiagramElementPalette(); + hideGroupPalette(); + }, [hideDiagramPalette, hideDiagramElementPalette, hideGroupPalette]); + const { exportToImage } = useExportToImage(); const { editingContextId, diagramId } = useContext(DiagramContext); @@ -276,7 +289,9 @@ export const DiagramPanel = memo( {diagramPanelActionComponents.map(({ Component: DiagramPanelActionComponent }, index) => ( - +
+ +
))}