import React, { useState, useMemo, useLayoutEffect, useRef } from 'react' import {ToolbarBlock} from './ToolbarElements' const NAME_CATEGORIES = { logical: 'Логические', arithmetic: 'Арифметические', timers: 'Таймеры', counters: 'Счётчики', comparisons: 'Сравнения', other: 'Другие', data: 'Данные', customized: 'Пользовательские' }; const BLOCK_CATEGORIES = { logical: [ { type: 'and', label: 'AND', inputs: ['BOOL', 'BOOL'], outputs: ['BOOL'] }, { type: 'or', label: 'OR', inputs: ['BOOL', 'BOOL'], outputs: ['BOOL'] }, { type: 'not', label: 'NOT', inputs: ['BOOL'], outputs: ['BOOL'] }, { type: 'xor', label: 'XOR', inputs: ['BOOL', 'BOOL'], outputs: ['BOOL'] }], arithmetic: [ { type: 'add', label: 'ADD', inputs: ['$/INT/DINT/REAL', '$/INT/DINT/REAL'], outputs: ['$/INT/DINT/REAL'] }, { type: 'sub', label: 'SUB', inputs: ['$/INT/DINT/REAL', '$/INT/DINT/REAL'], outputs: ['$/INT/DINT/REAL'] }, { type: 'mul', label: 'MUL', inputs: ['$/INT/DINT/REAL', '$/INT/DINT/REAL'], outputs: ['$/INT/DINT/REAL'] }, { type: 'div', label: 'DIV', inputs: ['$/INT/DINT/REAL', '$/INT/DINT/REAL'], outputs: ['$/INT/DINT/REAL'] }], timers: [ { type: 'ton', label: 'TON', inputs: ['BOOL', 'TIME'], outputs: ['BOOL', 'TIME'] }, { type: 'tof', label: 'TOF', inputs: ['BOOL', 'TIME'], outputs: ['BOOL', 'TIME'] }, { type: 'tp', label: 'TP', inputs: ['BOOL', 'TIME'], outputs: ['BOOL', 'TIME'] }], counters: [ { type: 'ctu', label: 'CTU', inputs: ['BOOL', 'BOOL', '$/INT/DINT'], outputs: ['BOOL', '$/INT/DINT'] }, { type: 'ctd', label: 'CTD', inputs: ['BOOL', 'BOOL', '$/INT/DINT'], outputs: ['BOOL', '$/INT/DINT'] }, { type: 'ctud', label: 'CTUD', inputs: ['BOOL', 'BOOL', 'BOOL', 'BOOL', '$/INT/DINT'], outputs: ['BOOL', 'BOOL', '$/INT/DINT'] }], comparisons: [ { type: 'gt', label: '>', inputs: ['$/INT/DINT/REAL/TIME', '$/INT/DINT/REAL/TIME'], outputs: ['BOOL'] }, { type: 'lt', label: '<', inputs: ['$/INT/DINT/REAL/TIME', '$/INT/DINT/REAL/TIME'], outputs: ['BOOL'] }, { type: 'eq', label: '=', inputs: ['$/BOOl/INT/DINT/REAL/TIME/STRING', '$/BOOl/INT/DINT/REAL/TIME/STRING'], outputs: ['BOOL'] }], other: [ { type: 'sr', label: 'SR', inputs: ['BOOL', 'BOOL'], outputs: ['BOOL'] }, { type: 'rs', label: 'RS', inputs: ['BOOL', 'BOOL'], outputs: ['BOOL'] }, { type: 'move', label: 'MOVE', inputs: ['$/BOOl/INT/DINT/REAL/TIME/STRING'], outputs: ['$/BOOl/INT/DINT/REAL/TIME/STRING'] }], data: [ { type: 'input', label: 'input', inputs: [], outputs: ['BOOl/INT/DINT/REAL/TIME/STRING'] }, { type: 'output', label: 'output', inputs: ['BOOl/INT/DINT/REAL/TIME/STRING'], outputs: [] }, { type: 'const', label: 'const', inputs: [], outputs: ['BOOl/INT/DINT/REAL/TIME/STRING'] }, { type: 'switch_type', label: '*_TO_**', inputs: ['BOOl/INT/DINT/REAL/TIME/STRING'], outputs: ['BOOl/INT/DINT/REAL/TIME/STRING'] } ] // customized: [] } const LINES_TYPES = [ { type: 'bool', stroke: '#000', dasharray: '0' }, { type: 'a', stroke: '#000', dasharray: '4 4' }, // Пунктир { type: 'b', stroke: '#D8000A', dasharray: '0' }, // Красная { type: 'c', stroke: '#000', dasharray: '1 3' }, // Точечная { type: 'd', stroke: '#008000', dasharray: '0' }, // Зеленая { type: 'e', stroke: '#1717D8', dasharray: '0' } // Синяя ]; const BLOCK_SCALE = 1 function Toolbar() { const [activeTab, setActiveTab] = useState('logical') const containerRef = useRef(null) const [caseWidth, setCaseWidth] = useState(0) const tabs = useMemo(() => Object.keys(BLOCK_CATEGORIES), []) const activeBlocks = BLOCK_CATEGORIES[activeTab] || [] useLayoutEffect(() => { if (!containerRef.current) return function updateSize() { const rect = containerRef.current.getBoundingClientRect() setCaseWidth(rect.width / 2) } updateSize() const observer = new ResizeObserver(() => updateSize()) observer.observe(containerRef.current) return () => observer.disconnect() }, []) function onDragStart(event, block) { const offsetX = event.nativeEvent.offsetX * BLOCK_SCALE const offsetY = event.nativeEvent.offsetY * BLOCK_SCALE event.dataTransfer.setData('application/reactflow', JSON.stringify({ type: block.type, label: block.label, inputs: block.inputs, outputs: block.outputs, offsetX, offsetY })) event.dataTransfer.effectAllowed = 'move' } return(

Блоки

{ /*Вкладки*/ }
{tabs.map((tab) => ( ))}
{ /*Блоки*/ }
{activeBlocks.map((block) => ( ))}
) } export default Toolbar