mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-25 20:40:36 +03:00
F: Add space mode to ossFlow
This commit is contained in:
parent
a618a2bc42
commit
e6a5b49b7a
|
@ -3,12 +3,15 @@ import {
|
|||
IconAnimation,
|
||||
IconAnimationOff,
|
||||
IconChild,
|
||||
IconConceptBlock,
|
||||
IconConnect,
|
||||
IconConsolidation,
|
||||
IconCoordinates,
|
||||
IconDestroy,
|
||||
IconEdit2,
|
||||
IconExecute,
|
||||
IconFitImage,
|
||||
IconFixLayout,
|
||||
IconGrid,
|
||||
IconLineStraight,
|
||||
IconLineWave,
|
||||
|
@ -16,7 +19,8 @@ import {
|
|||
IconNewRSForm,
|
||||
IconReset,
|
||||
IconRSForm,
|
||||
IconSave
|
||||
IconSave,
|
||||
IconSettings
|
||||
} from '@/components/icons';
|
||||
|
||||
import { LinkTopic } from '../../components/link-topic';
|
||||
|
@ -29,9 +33,19 @@ export function HelpOssGraph() {
|
|||
<div className='flex flex-col sm:flex-row'>
|
||||
<div className='sm:w-56'>
|
||||
<h1>Настройка графа</h1>
|
||||
<li>
|
||||
<IconReset className='inline-icon' /> Сбросить изменения
|
||||
</li>
|
||||
<li>
|
||||
<IconFitImage className='inline-icon' /> Вписать в экран
|
||||
</li>
|
||||
<li>
|
||||
<IconFixLayout className='inline-icon' /> Исправить расположения
|
||||
</li>
|
||||
<li>
|
||||
<IconSettings className='inline-icon' /> Диалог настроек
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<IconGrid className='inline-icon' /> Отображение сетки
|
||||
</li>
|
||||
|
@ -43,6 +57,9 @@ export function HelpOssGraph() {
|
|||
<IconAnimation className='inline-icon' />
|
||||
<IconAnimationOff className='inline-icon' /> Анимация
|
||||
</li>
|
||||
<li>
|
||||
<IconCoordinates className='inline-icon' /> Отображение координат
|
||||
</li>
|
||||
<li>черта сверху - Загрузка</li>
|
||||
<li>
|
||||
черта слева - КС <LinkTopic text='внешняя' topic={HelpTopic.CC_OSS} />
|
||||
|
@ -63,11 +80,14 @@ export function HelpOssGraph() {
|
|||
<kbd>Двойной клик</kbd> – переход к связанной <LinkTopic text='КС' topic={HelpTopic.CC_SYSTEM} />
|
||||
</li>
|
||||
<li>
|
||||
<IconEdit2 className='inline-icon' /> Редактирование операции
|
||||
<IconConceptBlock className='inline-icon icon-green' /> Новый блок
|
||||
</li>
|
||||
<li>
|
||||
<IconNewItem className='inline-icon icon-green' /> Новая операция
|
||||
</li>
|
||||
<li>
|
||||
<IconEdit2 className='inline-icon' /> Редактирование узла
|
||||
</li>
|
||||
<li>
|
||||
<IconDestroy className='inline-icon icon-red' /> <kbd>Delete</kbd> – удалить выбранные
|
||||
</li>
|
||||
|
@ -80,10 +100,13 @@ export function HelpOssGraph() {
|
|||
<div className='sm:w-56'>
|
||||
<h1>Общие</h1>
|
||||
<li>
|
||||
<IconReset className='inline-icon' /> Сбросить изменения
|
||||
<IconSave className='inline-icon' /> Сохранить положения
|
||||
</li>
|
||||
<li>
|
||||
<IconSave className='inline-icon' /> Сохранить положения
|
||||
<kbd>Space</kbd> – перемещение экрана
|
||||
</li>
|
||||
<li>
|
||||
<kbd>Shift</kbd> – перемещение выделенных элементов в границах родителя
|
||||
</li>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -97,8 +97,6 @@ export class LayoutManager {
|
|||
: Math.max(bottom, block.y + block.height + MIN_DISTANCE);
|
||||
}
|
||||
|
||||
console.log('left, top, right, bottom', left, top, right, bottom);
|
||||
|
||||
for (const operation of operation_nodes) {
|
||||
left = !left ? operation.x - MIN_DISTANCE : Math.min(left, operation.x - MIN_DISTANCE);
|
||||
top = !top ? operation.y - MIN_DISTANCE : Math.min(top, operation.y - MIN_DISTANCE);
|
||||
|
|
|
@ -28,7 +28,7 @@ export function BlockNode(node: BlockInternalNode) {
|
|||
return (
|
||||
<>
|
||||
<NodeResizeControl minWidth={BLOCK_NODE_MIN_WIDTH} minHeight={BLOCK_NODE_MIN_HEIGHT}>
|
||||
<IconResize size={8} className='absolute bottom-[2px] right-[2px]' />
|
||||
<IconResize size={8} className='absolute bottom-[2px] right-[2px] cc-graph-interactive' />
|
||||
</NodeResizeControl>
|
||||
{showCoordinates ? (
|
||||
<div
|
||||
|
@ -49,10 +49,10 @@ export function BlockNode(node: BlockInternalNode) {
|
|||
isChild && 'border-accent-orange'
|
||||
)}
|
||||
>
|
||||
<div className='absolute top-0 left-0 w-full h-2 pointer-events-auto cursor-pointer' />
|
||||
<div className='absolute top-0 right-0 h-full w-2 pointer-events-auto cursor-pointer' />
|
||||
<div className='absolute bottom-0 right-0 w-full h-2 pointer-events-auto cursor-pointer' />
|
||||
<div className='absolute bottom-0 left-0 h-full w-2 pointer-events-auto cursor-pointer' />
|
||||
<div className='absolute top-0 left-0 w-full h-2 cc-graph-interactive cursor-pointer' />
|
||||
<div className='absolute top-0 right-0 h-full w-2 cc-graph-interactive cursor-pointer' />
|
||||
<div className='absolute bottom-0 right-0 w-full h-2 cc-graph-interactive cursor-pointer' />
|
||||
<div className='absolute bottom-0 left-0 h-full w-2 cc-graph-interactive cursor-pointer' />
|
||||
|
||||
<div
|
||||
className={clsx(
|
||||
|
@ -60,7 +60,7 @@ export function BlockNode(node: BlockInternalNode) {
|
|||
'px-2',
|
||||
'bg-background rounded-lg',
|
||||
'text-[18px]/[20px] line-clamp-2 text-center text-ellipsis',
|
||||
'pointer-events-auto cursor-pointer'
|
||||
'cc-graph-interactive cursor-pointer'
|
||||
)}
|
||||
data-tooltip-id={globalIDs.operation_tooltip}
|
||||
data-tooltip-hidden={node.dragging}
|
||||
|
|
|
@ -46,6 +46,7 @@ export function OssFlow() {
|
|||
const { deleteBlock } = useDeleteBlock();
|
||||
|
||||
const [mouseCoords, setMouseCoords] = useState<Position2D>({ x: 0, y: 0 });
|
||||
const [spacePressed, setSpacePressed] = useState(false);
|
||||
|
||||
const showCreateOperation = useDialogsStore(state => state.showCreateOperation);
|
||||
const showCreateBlock = useDialogsStore(state => state.showCreateBlock);
|
||||
|
@ -128,6 +129,12 @@ export function OssFlow() {
|
|||
}
|
||||
|
||||
function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
|
||||
if (event.code === 'Space') {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
setSpacePressed(true);
|
||||
return;
|
||||
}
|
||||
if (isProcessing) {
|
||||
return;
|
||||
}
|
||||
|
@ -164,6 +171,12 @@ export function OssFlow() {
|
|||
}
|
||||
}
|
||||
|
||||
function handleKeyUp(event: React.KeyboardEvent<HTMLDivElement>) {
|
||||
if (event.code === 'Space') {
|
||||
setSpacePressed(false);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMouseMove(event: React.MouseEvent<HTMLDivElement>) {
|
||||
const targetPosition = screenToFlowPosition({ x: event.clientX, y: event.clientY });
|
||||
setMouseCoords(targetPosition);
|
||||
|
@ -174,6 +187,7 @@ export function OssFlow() {
|
|||
tabIndex={-1}
|
||||
className='relative'
|
||||
onKeyDown={handleKeyDown}
|
||||
onKeyUp={handleKeyUp}
|
||||
onMouseMove={showCoordinates ? handleMouseMove : undefined}
|
||||
>
|
||||
{showCoordinates ? <CoordinateDisplay mouseCoords={mouseCoords} className='absolute top-1 right-2' /> : null}
|
||||
|
@ -188,14 +202,18 @@ export function OssFlow() {
|
|||
<ContextMenu isOpen={isContextMenuOpen} onHide={hideContextMenu} {...menuProps} />
|
||||
|
||||
<div
|
||||
className={clsx('relative w-[100vw] cc-mask-sides', !containMovement && 'cursor-relocate')}
|
||||
className={clsx(
|
||||
'relative w-[100vw] cc-mask-sides',
|
||||
spacePressed ? 'space-mode' : '',
|
||||
!containMovement && 'cursor-relocate'
|
||||
)}
|
||||
style={{ height: mainHeight, fontFamily: 'Rubik' }}
|
||||
>
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onNodesChange={spacePressed ? undefined : onNodesChange}
|
||||
onEdgesChange={spacePressed ? undefined : onEdgesChange}
|
||||
edgesFocusable={false}
|
||||
nodesFocusable={false}
|
||||
fitView
|
||||
|
@ -206,15 +224,16 @@ export function OssFlow() {
|
|||
snapToGrid={true}
|
||||
snapGrid={[GRID_SIZE, GRID_SIZE]}
|
||||
onClick={hideContextMenu}
|
||||
onNodeDoubleClick={handleNodeDoubleClick}
|
||||
onNodeDoubleClick={spacePressed ? undefined : handleNodeDoubleClick}
|
||||
onNodeContextMenu={handleContextMenu}
|
||||
onContextMenu={event => {
|
||||
event.preventDefault();
|
||||
hideContextMenu();
|
||||
}}
|
||||
onNodeDragStart={handleDragStart}
|
||||
onNodeDrag={handleDrag}
|
||||
onNodeDragStop={handleDragStop}
|
||||
nodesDraggable={!spacePressed}
|
||||
onNodeDragStart={spacePressed ? undefined : handleDragStart}
|
||||
onNodeDrag={spacePressed ? undefined : handleDrag}
|
||||
onNodeDragStop={spacePressed ? undefined : handleDragStop}
|
||||
>
|
||||
{showGrid ? <Background gap={GRID_SIZE} /> : null}
|
||||
</ReactFlow>
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
/* stylelint-disable selector-class-pattern */
|
||||
|
||||
.react-flow__handle {
|
||||
pointer-events: auto;
|
||||
|
||||
z-index: var(--z-index-navigation);
|
||||
cursor: default !important;
|
||||
border-radius: 9999px;
|
||||
|
@ -16,6 +18,10 @@
|
|||
.selected & {
|
||||
border-color: var(--color-muted-foreground);
|
||||
}
|
||||
|
||||
.space-mode & {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.react-flow__resize-control.handle {
|
||||
|
@ -31,14 +37,26 @@
|
|||
&:hover {
|
||||
color: var(--color-foreground);
|
||||
}
|
||||
|
||||
.space-mode & {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.react-flow__pane {
|
||||
cursor: default;
|
||||
cursor: inherit;
|
||||
|
||||
.space-mode & {
|
||||
cursor: grab;
|
||||
|
||||
&.dragging {
|
||||
cursor: grabbing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.react-flow__edge {
|
||||
cursor: default;
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
.react-flow__attribution {
|
||||
|
@ -52,8 +70,13 @@
|
|||
}
|
||||
|
||||
[class*='react-flow__node-'] {
|
||||
.space-mode & {
|
||||
box-shadow: none;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
&:hover:not(.selected) {
|
||||
box-shadow: 0 0 0 2px var(--color-selected) !important;
|
||||
box-shadow: 0 0 0 2px var(--color-selected);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,8 +161,6 @@
|
|||
|
||||
.react-flow__node-input,
|
||||
.react-flow__node-synthesis {
|
||||
cursor: pointer;
|
||||
|
||||
border-radius: 5px;
|
||||
border-width: 0;
|
||||
|
||||
|
|
|
@ -205,3 +205,11 @@
|
|||
--tw-duration: var(--duration-move);
|
||||
transition-duration: var(--duration-move);
|
||||
}
|
||||
|
||||
@utility cc-graph-interactive {
|
||||
pointer-events: auto;
|
||||
|
||||
.space-mode & {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user