feat(components): Added pan and zoom to Workbench. Closes #368
This commit is contained in:
parent
b53615aea0
commit
054b7565e6
9 changed files with 397 additions and 91 deletions
|
@ -44,6 +44,7 @@
|
|||
"@material-ui/core": "^4.0.1",
|
||||
"@material-ui/icons": "^4.0.1",
|
||||
"@material-ui/lab": "^v4.0.0-alpha.14",
|
||||
"react-svg-pan-zoom": "^3.8.0",
|
||||
"prismjs": "1.16.0",
|
||||
"file-saver": "^2.0.2"
|
||||
},
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import babel from "rollup-plugin-babel";
|
||||
import resolve from "rollup-plugin-node-resolve";
|
||||
import json from "rollup-plugin-json";
|
||||
import minify from "rollup-plugin-babel-minify";
|
||||
import peerDepsExternal from "rollup-plugin-peer-deps-external";
|
||||
import { name, version, description, author, license } from "./package.json";
|
||||
import components from "./src/index.js";
|
||||
import babel from 'rollup-plugin-babel'
|
||||
import resolve from 'rollup-plugin-node-resolve'
|
||||
import json from 'rollup-plugin-json'
|
||||
import minify from 'rollup-plugin-babel-minify'
|
||||
import peerDepsExternal from 'rollup-plugin-peer-deps-external'
|
||||
import { name, version, description, author, license } from './package.json'
|
||||
import components from './src/index.js'
|
||||
|
||||
const createConfig = (component, module) => {
|
||||
return {
|
||||
input: `./src/${component + "/"}index.js`,
|
||||
input: `./src/${component + '/'}index.js`,
|
||||
output: {
|
||||
file: `./${component}/index` + (module ? ".mjs" : ".js"),
|
||||
format: module ? "es" : "cjs",
|
||||
file: `./${component}/index` + (module ? '.mjs' : '.js'),
|
||||
format: module ? 'es' : 'cjs',
|
||||
sourcemap: true
|
||||
},
|
||||
plugins: [
|
||||
|
@ -19,8 +19,8 @@ const createConfig = (component, module) => {
|
|||
resolve({ modulesOnly: true }),
|
||||
json(),
|
||||
babel({
|
||||
exclude: "node_modules/**",
|
||||
plugins: ["@babel/plugin-proposal-object-rest-spread"]
|
||||
exclude: 'node_modules/**',
|
||||
plugins: ['@babel/plugin-proposal-object-rest-spread']
|
||||
}),
|
||||
minify({
|
||||
comments: false,
|
||||
|
@ -28,13 +28,16 @@ const createConfig = (component, module) => {
|
|||
banner: `/**\n * ${name}/${component} | v${version}\n * ${description}\n * (c) ${new Date().getFullYear()} ${author}\n * @license ${license}\n */`
|
||||
})
|
||||
]
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const config = [];
|
||||
const config = []
|
||||
// When developing, you can use this to only rebuild the components you're working on
|
||||
let dev = false
|
||||
let only = ['Workbench']
|
||||
for (let component of components) {
|
||||
config.push(createConfig(component, false));
|
||||
if (!dev || only.indexOf(component) !== -1) config.push(createConfig(component, false))
|
||||
// Webpack doesn't handle .mjs very well
|
||||
//config.push(createConfig(component, true));
|
||||
}
|
||||
export default config;
|
||||
export default config
|
||||
|
|
|
@ -7,7 +7,7 @@ const Svg = (props) => {
|
|||
'xmlns:svg': 'http://www.w3.org/2000/svg',
|
||||
xmlnsXlink: 'http://www.w3.org/1999/xlink',
|
||||
xmlLang: props.language,
|
||||
viewBox: `0 0 ${props.width} ${props.height}`,
|
||||
viewBox: props.viewBox || `0 0 ${props.width} ${props.height}`,
|
||||
className: props.className,
|
||||
style: props.style
|
||||
}
|
||||
|
@ -33,7 +33,8 @@ Svg.defaultProps = {
|
|||
design: false,
|
||||
language: 'en',
|
||||
className: 'freesewing draft',
|
||||
style: {}
|
||||
style: {},
|
||||
viewBox: false
|
||||
}
|
||||
|
||||
export default Svg
|
||||
|
|
|
@ -13,6 +13,8 @@ const Draft = (props) => (
|
|||
id={props.settings.idPrefix + 'svg'}
|
||||
design={props.design}
|
||||
style={props.style}
|
||||
viewBox={props.viewBox}
|
||||
className={props.className || 'freesewing draft'}
|
||||
>
|
||||
<Defs
|
||||
units={props.settings.units}
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
import React, { useState } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import Draft from '../../Draft'
|
||||
import Zoombox from '../Zoombox'
|
||||
import Design from '../Design'
|
||||
import DraftConfigurator from '../../DraftConfigurator'
|
||||
import { FormattedMessage } from 'react-intl'
|
||||
import Prism from 'prismjs'
|
||||
import fileSaver from 'file-saver'
|
||||
import theme from '@freesewing/plugin-theme'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import DesignIcon from '@material-ui/icons/Fingerprint'
|
||||
import DumpIcon from '@material-ui/icons/LocalSee'
|
||||
import ClearIcon from '@material-ui/icons/HighlightOff'
|
||||
import AdvancedIcon from '@material-ui/icons/Policy'
|
||||
import PaperlessIcon from '@material-ui/icons/Nature'
|
||||
import CompleteIcon from '@material-ui/icons/Style'
|
||||
import UnhideIcon from '@material-ui/icons/ChevronLeft'
|
||||
import HideIcon from '@material-ui/icons/ChevronRight'
|
||||
|
||||
const DraftPattern = props => {
|
||||
const DraftPattern = (props) => {
|
||||
const [design, setDesign] = useState(true)
|
||||
const [focus, setFocus] = useState(null)
|
||||
const [viewBox, setViewBox] = useState(false)
|
||||
const [hideAside, setHideAside] = useState(false)
|
||||
|
||||
const raiseEvent = (type, data) => {
|
||||
if (type === 'clearFocusAll') {
|
||||
|
@ -31,7 +43,7 @@ const DraftPattern = props => {
|
|||
setFocus(f)
|
||||
}
|
||||
|
||||
const svgToFile = svg => {
|
||||
const svgToFile = (svg) => {
|
||||
const blob = new Blob([svg], {
|
||||
type: 'image/svg+xml;charset=utf-8'
|
||||
})
|
||||
|
@ -54,6 +66,27 @@ const DraftPattern = props => {
|
|||
const styles = {
|
||||
paragraph: {
|
||||
padding: '0 1rem'
|
||||
},
|
||||
aside: {
|
||||
maxWidth: '350px',
|
||||
background: 'transparent',
|
||||
border: 0,
|
||||
fontSize: '90%',
|
||||
boxShadow: '0 0 1px #cccc',
|
||||
display: hideAside ? 'none' : 'block'
|
||||
},
|
||||
icon: {
|
||||
margin: '0 0.25rem'
|
||||
},
|
||||
unhide: {
|
||||
position: 'absolute',
|
||||
top: '76px',
|
||||
right: 0,
|
||||
background: props.theme === 'dark' ? '#f8f9fa' : '#212529',
|
||||
borderTopLeftRadius: '50%',
|
||||
borderBottomLeftRadius: '50%',
|
||||
width: '26px',
|
||||
height: '30px'
|
||||
}
|
||||
}
|
||||
let pattern = new props.Pattern(props.gist.settings)
|
||||
|
@ -73,57 +106,116 @@ const DraftPattern = props => {
|
|||
Prism.languages.javascript,
|
||||
'javascript'
|
||||
)
|
||||
let iconProps = {
|
||||
size: 'small',
|
||||
style: styles.icon,
|
||||
color: 'inherit'
|
||||
}
|
||||
const color = (check) => (check ? '#40c057' : '#fa5252')
|
||||
|
||||
return (
|
||||
<div className="fs-sa">
|
||||
<section>
|
||||
<h2>
|
||||
<FormattedMessage id="app.pattern" />
|
||||
</h2>
|
||||
<Draft {...patternProps} design={design} focus={focus} raiseEvent={raiseEvent} />
|
||||
<h2>gist</h2>
|
||||
<div className="gatsby-highlight">
|
||||
<pre className="language-json" dangerouslySetInnerHTML={{ __html: gist }} />
|
||||
<Draft
|
||||
{...patternProps}
|
||||
design={design}
|
||||
focus={focus}
|
||||
raiseEvent={raiseEvent}
|
||||
viewBox={viewBox}
|
||||
className="freesewing draft shadow"
|
||||
/>
|
||||
{hideAside && (
|
||||
<div style={styles.unhide}>
|
||||
<IconButton
|
||||
onClick={() => setHideAside(false)}
|
||||
title="Show sidebar"
|
||||
{...iconProps}
|
||||
style={{ margin: 0 }}
|
||||
>
|
||||
<span style={{ color: props.theme === 'dark' ? '#212529' : '#f8f9fa' }}>
|
||||
<UnhideIcon />
|
||||
</span>
|
||||
</IconButton>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<aside>
|
||||
<aside style={styles.aside}>
|
||||
<div className="sticky">
|
||||
{design ? (
|
||||
<React.Fragment>
|
||||
<p style={styles.paragraph}>
|
||||
<FormattedMessage id="cfp.designModeIsOn" />
|
||||
(
|
||||
<a href="#logo" onClick={() => setDesign(false)}>
|
||||
<FormattedMessage id="cfp.turnOff" />
|
||||
</a>
|
||||
)
|
||||
{focusCount > 0 ? (
|
||||
<React.Fragment>
|
||||
 (
|
||||
<a href="#logo" onClick={() => raiseEvent('clearFocusAll', null)}>
|
||||
<FormattedMessage id="app.reset" />
|
||||
</a>
|
||||
)
|
||||
</React.Fragment>
|
||||
) : null}
|
||||
</p>
|
||||
<div style={{ padding: '5px' }}>
|
||||
<Zoombox patternProps={patternProps} setViewBox={setViewBox} />
|
||||
</div>
|
||||
<div style={{ margin: '1rem auto 0', textAlign: 'center' }}>
|
||||
<IconButton
|
||||
onClick={() => setDesign(!design)}
|
||||
title="Toggle design mode"
|
||||
{...iconProps}
|
||||
>
|
||||
<span style={{ color: color(design) }}>
|
||||
<DesignIcon />
|
||||
</span>
|
||||
</IconButton>
|
||||
{design && (
|
||||
<IconButton
|
||||
onClick={() => raiseEvent('clearFocusAll', null)}
|
||||
title="Clear design mode"
|
||||
{...iconProps}
|
||||
>
|
||||
<ClearIcon color="primary" />
|
||||
</IconButton>
|
||||
)}
|
||||
<IconButton
|
||||
onClick={() => console.log(pattern)}
|
||||
title="console.log(pattern)"
|
||||
{...iconProps}
|
||||
>
|
||||
<DumpIcon color="primary" />
|
||||
</IconButton>
|
||||
|
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
props.updateGist(!props.gist.settings.advanced, 'settings', 'advanced')
|
||||
}
|
||||
title="Toggle advanced settings"
|
||||
{...iconProps}
|
||||
>
|
||||
<span style={{ color: color(props.gist.settings.advanced) }}>
|
||||
<AdvancedIcon />
|
||||
</span>
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
props.updateGist(!props.gist.settings.paperless, 'settings', 'paperless')
|
||||
}
|
||||
title="Toggle paperless"
|
||||
{...iconProps}
|
||||
>
|
||||
<span style={{ color: color(props.gist.settings.paperless) }}>
|
||||
<PaperlessIcon />
|
||||
</span>
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
props.updateGist(!props.gist.settings.complete, 'settings', 'complete')
|
||||
}
|
||||
title="Toggle complete"
|
||||
{...iconProps}
|
||||
>
|
||||
<span style={{ color: color(props.gist.settings.complete) }}>
|
||||
<CompleteIcon />
|
||||
</span>
|
||||
</IconButton>
|
||||
<IconButton onClick={() => setHideAside(true)} title="Hide sidebar" {...iconProps}>
|
||||
<HideIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
{design && (
|
||||
<Design
|
||||
focus={focus}
|
||||
design={design}
|
||||
raiseEvent={raiseEvent}
|
||||
parts={patternProps.parts}
|
||||
/>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<p style={styles.paragraph}>
|
||||
<FormattedMessage id="cfp.designModeIsOff" />
|
||||
(
|
||||
<a href="#logo" onClick={() => setDesign(true)}>
|
||||
<FormattedMessage id="cfp.turnOn" />
|
||||
</a>
|
||||
)
|
||||
</p>
|
||||
)}
|
||||
<DraftConfigurator
|
||||
noDocs
|
||||
|
|
20
packages/components/src/Workbench/Json/index.js
Normal file
20
packages/components/src/Workbench/Json/index.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import React, { useState } from 'react'
|
||||
import Prism from 'prismjs'
|
||||
|
||||
const PatternJson = (props) => {
|
||||
let gist = Prism.highlight(
|
||||
JSON.stringify(props.gist, null, 2),
|
||||
Prism.languages.javascript,
|
||||
'javascript'
|
||||
)
|
||||
|
||||
return (
|
||||
<div style={{ padding: '1rem' }}>
|
||||
<div className="gatsby-highlight">
|
||||
<pre className="language-json" dangerouslySetInnerHTML={{ __html: gist }} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PatternJson
|
|
@ -1,27 +1,30 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import SampleConfigurator from "../../SampleConfigurator";
|
||||
import svgattrPlugin from "@freesewing/plugin-svgattr";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import SampleConfigurator from '../../SampleConfigurator'
|
||||
import svgattrPlugin from '@freesewing/plugin-svgattr'
|
||||
import { FormattedMessage } from 'react-intl'
|
||||
|
||||
const SamplePattern = props => {
|
||||
const SamplePattern = (props) => {
|
||||
let pattern = new props.Pattern(props.gist.settings).use(svgattrPlugin, {
|
||||
class: "freesewing draft"
|
||||
});
|
||||
class: 'freesewing draft'
|
||||
})
|
||||
try {
|
||||
pattern.sample();
|
||||
pattern.sample()
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
console.log(err)
|
||||
}
|
||||
return (
|
||||
<div className="fs-sa">
|
||||
<section>
|
||||
<h2>
|
||||
<FormattedMessage id="app.pattern" />
|
||||
</h2>
|
||||
<div dangerouslySetInnerHTML={{ __html: pattern.render() }} />
|
||||
<h2>gist</h2>
|
||||
<pre>{JSON.stringify(props.gist, null, 2)}</pre>
|
||||
<div style={{ padding: '1rem' }}>
|
||||
<div className="gatsby-highlight">
|
||||
<pre
|
||||
className="language-json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(props.gist, null, 2) }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<aside>
|
||||
|
@ -37,8 +40,8 @@ const SamplePattern = props => {
|
|||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
SamplePattern.propTypes = {
|
||||
gist: PropTypes.object.isRequired,
|
||||
|
@ -46,12 +49,12 @@ SamplePattern.propTypes = {
|
|||
config: PropTypes.object.isRequired,
|
||||
raiseEvent: PropTypes.func.isRequired,
|
||||
Pattern: PropTypes.func.isRequired,
|
||||
units: PropTypes.oneOf(["metric", "imperial"])
|
||||
};
|
||||
units: PropTypes.oneOf(['metric', 'imperial'])
|
||||
}
|
||||
|
||||
SamplePattern.defaultProps = {
|
||||
units: "metric",
|
||||
units: 'metric',
|
||||
pointInfo: null
|
||||
};
|
||||
}
|
||||
|
||||
export default SamplePattern;
|
||||
export default SamplePattern
|
||||
|
|
158
packages/components/src/Workbench/Zoombox/index.js
Normal file
158
packages/components/src/Workbench/Zoombox/index.js
Normal file
|
@ -0,0 +1,158 @@
|
|||
import React, { useState, useRef, useEffect } from 'react'
|
||||
import Draft from '../../Draft'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import ZoomIcon from '@material-ui/icons/Cancel'
|
||||
|
||||
const Zoombox = (props) => {
|
||||
const [from, setFrom] = useState(false)
|
||||
const [to, setTo] = useState(false)
|
||||
const [dragging, setDragging] = useState(false)
|
||||
const [factor, setFactor] = useState(1)
|
||||
const [box, setBox] = useState(false)
|
||||
const [panning, setPanning] = useState(false)
|
||||
const [falseAlarm, setFalseAlarm] = useState(false)
|
||||
const [panFrom, setPanFrom] = useState(false)
|
||||
const ref = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
let box = ref.current.getBoundingClientRect()
|
||||
setBox(box)
|
||||
setFactor(props.patternProps.width / box.width)
|
||||
}, [])
|
||||
|
||||
const resetZoom = (evt) => {
|
||||
evt.stopPropagation()
|
||||
evt.preventDefault()
|
||||
setFrom(false)
|
||||
setTo(false)
|
||||
setDragging(false)
|
||||
props.setViewBox(false)
|
||||
}
|
||||
const startPan = (evt) => {
|
||||
if (!dragging && !panning) {
|
||||
evt.stopPropagation()
|
||||
evt.preventDefault()
|
||||
setPanning(true)
|
||||
setPanFrom([evt.clientX, evt.clientY])
|
||||
}
|
||||
}
|
||||
const endPan = (evt) => {
|
||||
if (!dragging && panning) {
|
||||
evt.stopPropagation()
|
||||
evt.preventDefault()
|
||||
setPanning(false)
|
||||
setPanFrom(false)
|
||||
updateViewBox(evt)
|
||||
//props.setViewBox(`${from[0] * factor} ${from[1] * factor} ${to[0] * factor} ${to[1] * factor}`)
|
||||
}
|
||||
}
|
||||
const handlePan = (evt) => {
|
||||
if (!dragging && panning) {
|
||||
evt.stopPropagation()
|
||||
evt.preventDefault()
|
||||
let x, y
|
||||
if (from[0] + (evt.clientX - panFrom[0]) <= -5) {
|
||||
// Bump into left
|
||||
} else if (from[1] + (evt.clientY - panFrom[1]) <= -5) {
|
||||
// Bump into top
|
||||
} else if (to[0] + (evt.clientX - panFrom[0]) >= box.width - 11) {
|
||||
// Bump into right
|
||||
} else if (to[1] + (evt.clientY - panFrom[1]) >= box.height - 11) {
|
||||
// Bump into bottom
|
||||
} else {
|
||||
setPanFrom([evt.clientX, evt.clientY])
|
||||
setFrom([from[0] + (evt.clientX - panFrom[0]), from[1] + (evt.clientY - panFrom[1])])
|
||||
setTo([to[0] + (evt.clientX - panFrom[0]), to[1] + (evt.clientY - panFrom[1])])
|
||||
}
|
||||
}
|
||||
}
|
||||
const handleMouseDown = (evt) => {
|
||||
evt.stopPropagation()
|
||||
evt.preventDefault()
|
||||
setFrom([evt.clientX - box.x, evt.clientY - box.y])
|
||||
setTo([evt.clientX - box.x, evt.clientY - box.y])
|
||||
setDragging(1)
|
||||
setPanning(false)
|
||||
}
|
||||
const handleMouseUp = (evt) => {
|
||||
if (dragging == 2) {
|
||||
updateViewBox(evt)
|
||||
if (falseAlarm) setFalseAlarm(false)
|
||||
} else setFalseAlarm(true)
|
||||
setDragging(false)
|
||||
setPanning(false)
|
||||
evt.stopPropagation()
|
||||
evt.preventDefault()
|
||||
}
|
||||
const handleMouseMove = (evt) => {
|
||||
if (dragging) {
|
||||
evt.stopPropagation()
|
||||
evt.preventDefault()
|
||||
if (dragging === 1) setDragging(2)
|
||||
if (falseAlarm) setFalseAlarm(false)
|
||||
setTo([evt.clientX - box.x, evt.clientY - box.y])
|
||||
}
|
||||
}
|
||||
const handleMouseOver = (evt) => {
|
||||
evt.stopPropagation()
|
||||
evt.preventDefault()
|
||||
setFactor(props.patternProps.width / box.width)
|
||||
}
|
||||
const updateViewBox = (evt) => {
|
||||
props.setViewBox(
|
||||
from[0] * factor +
|
||||
' ' +
|
||||
from[1] * factor +
|
||||
' ' +
|
||||
(evt.clientX - box.x - from[0]) * factor +
|
||||
' ' +
|
||||
(evt.clientY - box.y - from[1]) * factor
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseOver={handleMouseOver}
|
||||
onMouseMove={handleMouseMove}
|
||||
className="zoombox"
|
||||
ref={ref}
|
||||
>
|
||||
<Draft {...props.patternProps} />
|
||||
<div className="mask" />
|
||||
{box && from && to && dragging !== 1 && !falseAlarm && (
|
||||
<div
|
||||
className={'box' + (dragging ? ' active' : ' inactive')}
|
||||
style={{
|
||||
// Remove 16px because of the close icon
|
||||
width: to[0] - from[0] - 16 + 'px',
|
||||
height: to[1] - from[1] - 16 + 'px',
|
||||
left: from[0] + 'px',
|
||||
top: from[1] + 'px'
|
||||
}}
|
||||
onMouseDown={startPan}
|
||||
onMouseUp={endPan}
|
||||
onMouseMove={handlePan}
|
||||
>
|
||||
{!dragging && (
|
||||
<IconButton
|
||||
size="small"
|
||||
color="primary"
|
||||
className="close"
|
||||
onMouseDown={resetZoom}
|
||||
onMouseUp={resetZoom}
|
||||
>
|
||||
<ZoomIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<pre>{false && JSON.stringify({ from, to, panFrom }, null, 2)}</pre>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Zoombox
|
|
@ -11,12 +11,13 @@ import LanguageIcon from '@material-ui/icons/Translate'
|
|||
import DarkModeIcon from '@material-ui/icons/Brightness3'
|
||||
import LanguageChooser from './LanguageChooser'
|
||||
import DraftPattern from './DraftPattern'
|
||||
import Json from './Json'
|
||||
import SamplePattern from './SamplePattern'
|
||||
import Welcome from './Welcome'
|
||||
import Footer from '../Footer'
|
||||
import Measurements from './Measurements'
|
||||
|
||||
const Workbench = props => {
|
||||
const Workbench = (props) => {
|
||||
const [display, setDisplay] = useState(null)
|
||||
const [pattern, setPattern] = useState(false)
|
||||
const [theme, setTheme] = useState('light')
|
||||
|
@ -39,12 +40,12 @@ const Workbench = props => {
|
|||
}, [props.language])
|
||||
|
||||
const getDisplay = () => storage.get(props.config.name + '-display')
|
||||
const saveDisplay = d => {
|
||||
const saveDisplay = (d) => {
|
||||
setDisplay(d)
|
||||
storage.set(props.config.name + '-display', d)
|
||||
}
|
||||
const getMeasurements = () => storage.get(props.config.name + '-measurements')
|
||||
const saveMeasurements = data => {
|
||||
const saveMeasurements = (data) => {
|
||||
storage.set(props.config.name + '-measurements', data)
|
||||
props.updateGist(data, 'settings', 'measurements')
|
||||
}
|
||||
|
@ -54,7 +55,7 @@ const Workbench = props => {
|
|||
setMeasurements(updatedMeasurements)
|
||||
saveMeasurements(updatedMeasurements)
|
||||
}
|
||||
const preloadMeasurements = model => {
|
||||
const preloadMeasurements = (model) => {
|
||||
let updatedMeasurements = {
|
||||
...measurements,
|
||||
...model
|
||||
|
@ -97,6 +98,12 @@ const Workbench = props => {
|
|||
onClick: () => saveDisplay('measurements'),
|
||||
text: 'app.measurements',
|
||||
active: display === 'measurements' ? true : false
|
||||
},
|
||||
json: {
|
||||
type: 'button',
|
||||
onClick: () => saveDisplay('json'),
|
||||
text: 'JSON',
|
||||
active: display === 'json' ? true : false
|
||||
}
|
||||
},
|
||||
right: {
|
||||
|
@ -148,6 +155,7 @@ const Workbench = props => {
|
|||
units={props.units}
|
||||
svgExport={svgExport}
|
||||
setSvgExport={setSvgExport}
|
||||
theme={theme}
|
||||
/>
|
||||
)
|
||||
break
|
||||
|
@ -177,6 +185,24 @@ const Workbench = props => {
|
|||
/>
|
||||
)
|
||||
break
|
||||
case 'json':
|
||||
main = <Json gist={props.gist} />
|
||||
break
|
||||
case 'inspect':
|
||||
main = (
|
||||
<InspectPattern
|
||||
freesewing={props.freesewing}
|
||||
Pattern={props.Pattern}
|
||||
config={props.config}
|
||||
gist={props.gist}
|
||||
updateGist={props.updateGist}
|
||||
raiseEvent={raiseEvent}
|
||||
units={props.units}
|
||||
svgExport={svgExport}
|
||||
setSvgExport={setSvgExport}
|
||||
/>
|
||||
)
|
||||
break
|
||||
default:
|
||||
main = <Welcome language={props.language} setDisplay={saveDisplay} />
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue