diff --git a/ExistentialGraphs.studio b/ExistentialGraphs.studio index 3e21e157d6e1bb244e6602ded928d3f7a7aef5e1..22e6c4f559aa9466a1cb2156b0132ffa8bf9774d 100644 GIT binary patch delta 9864 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 DHG*b= delta 9672 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

ZCd}m%F5pV+4B0gpBbO6J;%Mp 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 F2LM1j*&hG^ diff --git a/package.json b/package.json index 8866228..49f5078 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "react": "^16.13.0", "react-dom": "^16.13.0", "react-mathjax": "^1.0.1", - "react-scripts": "3.4.0" + "react-scripts": "3.4.0", + "react-svg": "^11.0.18" }, "scripts": { "start": "react-scripts start", diff --git a/public/assets/step-first.svg b/public/assets/step-first.svg new file mode 100644 index 0000000..76c0159 --- /dev/null +++ b/public/assets/step-first.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/assets/step-last.svg b/public/assets/step-last.svg new file mode 100644 index 0000000..cb3d932 --- /dev/null +++ b/public/assets/step-last.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/assets/step-next.svg b/public/assets/step-next.svg new file mode 100644 index 0000000..dce34ed --- /dev/null +++ b/public/assets/step-next.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/assets/step-prev.svg b/public/assets/step-prev.svg new file mode 100644 index 0000000..89a04d8 --- /dev/null +++ b/public/assets/step-prev.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/canvas/Canvas.js b/src/canvas/Canvas.js index 4ec08ee..5d5657d 100644 --- a/src/canvas/Canvas.js +++ b/src/canvas/Canvas.js @@ -2,43 +2,59 @@ import React from 'react'; import { convertToArray } from '../converters'; import Toolbox from './Toolbox'; import StepMenu from './StepMenu'; +import DraggableText from './DraggableText'; import './Canvas.scss'; import Panzoom from 'panzoom'; const nanoid = require('nanoid').nanoid; -let prevLevel = 0 -let currentX = 0 -let currentY = 0 +// some defaults: +// blocks are automatically 22px high + +const TEXT_H = 22; function initXY(step, level) { - prevLevel = 0 - currentX = 0 - currentY = -50 - return initXYRecurse(step, level) -} + let data = {} + let prevLevel = 0 + let currentX = 0 + let currentY = 0 + let maxX = 0 + let maxY = 0 -function initXYRecurse(step, level) { - console.log(nanoid) - for (let s in step) { - if (step[s] instanceof Array) { - prevLevel = level - step[s] = initXYRecurse(step[s], level + 1) - } else { - step[s] = { var: step[s], id: nanoid(), x: currentX + Math.abs(prevLevel - level) * 25, y: currentY } - prevLevel = level - currentX += 50 + function initXYRecurse(step, level) { + for (let s in step) { + if (step[s] instanceof Array) { + prevLevel = level + step[s] = initXYRecurse(step[s], level + 1) + } else { + let X = currentX + Math.abs(prevLevel - level) * 25; + let Y = currentY; + let id = nanoid() + data[id] = { + var: step[s], + x: X, + y: Y + } + step[s] = id + maxY = Y > maxY ? Y : maxY; + maxX = X > maxX ? X : maxX; + prevLevel = level + currentX += 50 + } } + return step } - return step + return { stepZero: { data: initXYRecurse(step, level), h: maxY + TEXT_H, w: maxX }, data: data } } - class Canvas extends React.Component { constructor(props) { super(props); this.canvas = React.createRef(); + this.canvasContainer = React.createRef(); + this.renderStep = this.renderStep.bind(this); - this.renderRecurse = this.renderRecurse.bind(this); + this.changePos = this.changePos.bind(this); + this.getSVGCoords = this.getSVGCoords.bind(this); let { premises, conclusion, steps } = this.props.proof; this.state = { @@ -47,58 +63,126 @@ class Canvas extends React.Component { conclusion: conclusion }, steps: steps, + data: {}, currentStep: 0, + moveListeners: [], }; } - renderStep(stepIndex) { - console.log(stepIndex) - return this.renderRecurse(this.state.steps[stepIndex]) + changePos(id, x, y) { + let { data } = this.state; + Object.assign(data[id], { x: x, y: y }) + this.setState(data) } - renderRecurse(step) { - console.log(step) - let jsx = []; - for (let s in step) { - if (step[s] instanceof Array) { - jsx.push(this.renderRecurse(step[s])); - } else { - jsx.push({step[s].var}); + renderStep(stepIndex) { + let step = this.state.steps[stepIndex] + if (step) { + let svg = [] + + const renderRecurse = (step) => { + let jsx = []; + for (let s in step) { + if (step[s] instanceof Array) { + jsx.push({renderRecurse(step[s])}); + } else { + let el = this.state.data[step[s]] + jsx.push( + + {el.var} + + ); + } + } + return jsx; } + renderRecurse.bind(this); + svg.push(renderRecurse(step.data)) + return svg } - return jsx; } + + componentDidMount() { - const panzoom = Panzoom(this.canvas.current, { - maxScale: 5, - ignoreChildrensEvents: true, - refreshRate: 60 - }) + this.panzoom = Panzoom(this.canvas.current, { + maxZoom: 6, + minZoom: 0.5 + }); + // this.canvasContainer.current.addEventListener('wheel', this.panzoom.zoomWithWheel); + const vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); + const vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); // if there are no existing steps, init first step let { steps } = this.state; if (steps.length === 0) { let { premises, conclusion } = this.state.proof; - this.setState({ currentStep: 0 }); - steps.push(initXY(convertToArray(premises.join('')), 0)) + let { stepZero, data } = initXY(convertToArray(premises.join('')), 0); + steps.push(stepZero); + console.log(data) + this.setState({ steps: steps, currentStep: 0, data: data }); } - console.log(this.state) + console.log(steps) + let step = this.state.steps[this.state.currentStep]; + + this.panzoom.moveTo(vw/2 - step.w, vh/2 - step.h); + this.panzoom.zoomTo(vw/2 - step.w, vh/2 - step.h, 2); } componentWillUnmount() { window.removeEventListener('resize', this); } + addMoveListener(callback) { + let { moveListeners } = this.state; + moveListeners.push(callback); + this.setState({ moveListeners: moveListeners }); + } + + callMoveListener(evt) { + if (this.state.moveListeners.length > 0) { + for (let listener in this.state.moveListeners) { + this.state.moveListeners[listener](evt) + } + } + } + + getSVGCoords(domX, domY) { + var pt = this.canvasContainer.current.createSVGPoint(); + + pt.x = domX; + pt.y = domY; + + return pt.matrixTransform(this.canvas.current.getScreenCTM().inverse()); + } + render() { + let zoomWithWheel = () => {} + if (this.panzoom) + zoomWithWheel = this.panzoom.zoomWithWheel return (

- + {this.renderStep(this.state.currentStep)} - + this.setState({ currentStep: s })} + />
); } diff --git a/src/canvas/Canvas.scss b/src/canvas/Canvas.scss index 6824cae..126536a 100644 --- a/src/canvas/Canvas.scss +++ b/src/canvas/Canvas.scss @@ -9,6 +9,16 @@ display: absolute; } +.noselect { + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently + supported by Chrome, Opera and Firefox */ +} + .toolbox { position: absolute; display: inline-block; @@ -54,9 +64,18 @@ bottom: 53px; box-sizing: border-box; height: 73px; + line-height: 73px; width: 278px; border-radius: 36.5px; background-color: #EAEAEA; border: 1px solid #E6E6E6; box-shadow: 0 0 8px 0 rgba(0,0,0,0.28); + text-align: center; + div { + display: inline-block; + margin-left: 22px; + &:first-child { + margin-left: 0; + } + } } \ No newline at end of file diff --git a/src/canvas/DraggableText.js b/src/canvas/DraggableText.js new file mode 100644 index 0000000..f323094 --- /dev/null +++ b/src/canvas/DraggableText.js @@ -0,0 +1,54 @@ +import React from 'react'; + +class DraggableText extends React.Component { + constructor(props) { + super(props); + this.text = React.createRef() + this.getCoords = this.props.getCoords + this.state = { + x: props.x, + y: props.y, + dragging: false + }; + + this.props.addMoveListener(this.onMouseMove.bind(this)) + } + + componentDidMount() { + this.text.current.style.cursor = "pointer"; + } + + handleDragStart(evt) { + this.props.panzoom.pause() + this.setState({ dragging: true }); + } + + handleDragEnd(evt) { + this.props.panzoom.resume() + this.setState({ dragging: false }); + } + + onMouseMove(evt) { + if (this.state.dragging) { + let { x, y } = this.getCoords(evt.clientX, evt.clientY) + this.setState({ x: x, y: y }) + } + } + + render() { + return ( + + {this.props.children} + + ); + } +} + +export default DraggableText; \ No newline at end of file diff --git a/src/canvas/StepMenu.js b/src/canvas/StepMenu.js index 48ba01a..73ef366 100644 --- a/src/canvas/StepMenu.js +++ b/src/canvas/StepMenu.js @@ -1,4 +1,5 @@ import React from 'react'; +import { ReactSVG } from 'react-svg'; class StepMenu extends React.Component { constructor(props) { @@ -14,7 +15,10 @@ class StepMenu extends React.Component { return (
- test + + + +
Step {this.props.currentStep} of {this.props.stepInfo.length} diff --git a/src/intro/IntroWindow.js b/src/intro/IntroWindow.js index 25739c3..2557f73 100644 --- a/src/intro/IntroWindow.js +++ b/src/intro/IntroWindow.js @@ -1,5 +1,6 @@ import React from 'react'; import CreateNew from './CreateNew'; +import { ReactSVG } from 'react-svg'; import './intro.scss'; const IntroContent = () => ( @@ -59,10 +60,8 @@ class IntroWindow extends React.Component { {createShown && (
diff --git a/src/intro/intro.scss b/src/intro/intro.scss index 063bf13..b327c91 100644 --- a/src/intro/intro.scss +++ b/src/intro/intro.scss @@ -26,6 +26,7 @@ padding: 6px; padding-right: 20px; .svg { + display: inline-block; padding-right: 10px; } .back { diff --git a/src/verifySentence.js b/src/verifySentence.js index a818ddf..5f98383 100644 --- a/src/verifySentence.js +++ b/src/verifySentence.js @@ -24,7 +24,6 @@ let atomicRegex = new RegExp(`^${uReg}*[A-Za-z]+$`) let parenthesisRegex = new RegExp(`^${uReg}*\\((.*)\\)$`) function verifyRecursive(sentence) { - console.log(sentence) let res if (sentence.match(atomicRegex)) return true; else if ((res = binaryRegex.exec(sentence)) !== null) { diff --git a/step-first.svg b/step-first.svg new file mode 100644 index 0000000..76c0159 --- /dev/null +++ b/step-first.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/step-last.svg b/step-last.svg new file mode 100644 index 0000000..cb3d932 --- /dev/null +++ b/step-last.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/step-next.svg b/step-next.svg new file mode 100644 index 0000000..dce34ed --- /dev/null +++ b/step-next.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/step-prev.svg b/step-prev.svg new file mode 100644 index 0000000..89a04d8 --- /dev/null +++ b/step-prev.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/yarn.lock b/yarn.lock index daaa558..44e03fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -863,6 +863,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.9.2": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.4.0", "@babel/template@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8" @@ -1232,6 +1239,13 @@ "@svgr/plugin-svgo" "^4.3.1" loader-utils "^1.2.3" +"@tanem/svg-injector@^8.0.47": + version "8.0.48" + resolved "https://registry.yarnpkg.com/@tanem/svg-injector/-/svg-injector-8.0.48.tgz#c316eb3b78d08452713fde21869418564a4e3a39" + integrity sha512-+jFyiUxopc03Jf6B3rHLC3oMnJCT/oK+htMBpWXOiWAyQv4vv03ukYdF5PfkxKte6+TiwMlASPNrOupbBXjX0g== + dependencies: + "@babel/runtime" "^7.9.2" + "@testing-library/dom@^6.15.0": version "6.15.0" resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-6.15.0.tgz#042abea7b4685b70d9a919100da9024507dc20bb" @@ -8787,6 +8801,15 @@ react-scripts@3.4.0: optionalDependencies: fsevents "2.1.2" +react-svg@^11.0.18: + version "11.0.18" + resolved "https://registry.yarnpkg.com/react-svg/-/react-svg-11.0.18.tgz#d8f5cdc4644f02a6dfda864db6816559907c12e6" + integrity sha512-2JgC7NWr37TDC3BHV9JiQ8NwPO6CSzW5UY5vuxzinKGVAGrzRAJlwy/bag5XKCXZNaoMPAnhNpPz/U406svvZg== + dependencies: + "@babel/runtime" "^7.9.2" + "@tanem/svg-injector" "^8.0.47" + prop-types "^15.7.2" + react@^16.13.0: version "16.13.0" resolved "https://registry.yarnpkg.com/react/-/react-16.13.0.tgz#d046eabcdf64e457bbeed1e792e235e1b9934cf7"