wip: Working on development environment
This commit is contained in:
parent
6dbc108d29
commit
e4756087d8
10 changed files with 533 additions and 535 deletions
|
@ -1,221 +1,113 @@
|
||||||
import React from "react";
|
import React from 'react'
|
||||||
|
import IconButton from '@material-ui/core/IconButton'
|
||||||
|
import IsolateIcon from '@material-ui/icons/Search'
|
||||||
|
import CameraIcon from '@material-ui/icons/CameraAlt'
|
||||||
|
|
||||||
const Design = props => {
|
const Design = (props) => {
|
||||||
// Methods
|
// Methods
|
||||||
const renderAttributes = attr => {
|
const renderAttributes = (attr) => {
|
||||||
let list = [];
|
let list = []
|
||||||
for (let a in attr.list)
|
for (let a in attr.list)
|
||||||
list.push(
|
list.push(
|
||||||
<li key={a}>
|
<li key={a}>
|
||||||
<b>{a}</b>: {renderAttributeValue(attr.list[a])}
|
<b>{a}</b>: {renderAttributeValue(attr.list[a])}
|
||||||
</li>
|
</li>
|
||||||
);
|
)
|
||||||
|
|
||||||
return <ul className="links">{list}</ul>;
|
return <ul>{list}</ul>
|
||||||
};
|
}
|
||||||
|
|
||||||
const renderAttributeValue = val => {
|
const renderAttributeValue = (val) => {
|
||||||
if (Array.isArray(val)) {
|
if (Array.isArray(val)) {
|
||||||
if (val.length === 1) return val.pop();
|
if (val.length === 1) return val.pop()
|
||||||
let list = [];
|
let list = []
|
||||||
for (let v of val) list.push(<li key={v}>{v}</li>);
|
for (let v of val) list.push(<li key={v}>{v}</li>)
|
||||||
return <ul>{list}</ul>;
|
return <ul>{list}</ul>
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val
|
||||||
};
|
}
|
||||||
|
|
||||||
const idPathPoint = (part, a) => {
|
const idPathPoint = (part, a) => {
|
||||||
for (let p in props.parts[part].points) {
|
for (let p in props.parts[part].points) {
|
||||||
let b = props.parts[part].points[p];
|
let b = props.parts[part].points[p]
|
||||||
if (a.x === b.x && a.y === b.y) return p;
|
if (a.x === b.x && a.y === b.y) return p
|
||||||
}
|
}
|
||||||
return false;
|
return false
|
||||||
};
|
}
|
||||||
|
|
||||||
const renderPathOps = (path, part) => {
|
if (!props.design || props.focus === null || Object.keys(props.focus).length < 1) return null
|
||||||
let list = [];
|
let info = []
|
||||||
for (let i in path.ops) list.push(renderPathOp(path.ops[i], i, part));
|
|
||||||
|
|
||||||
return <ul className="links">{list}</ul>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderPathOp = (op, key, part) => {
|
|
||||||
let list = [];
|
|
||||||
let focus = {
|
|
||||||
part,
|
|
||||||
coords: {
|
|
||||||
x: null,
|
|
||||||
y: null
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (op.type === "move" || op.type === "line") {
|
|
||||||
focus.coords.x = op.to.x;
|
|
||||||
focus.coords.y = op.to.y;
|
|
||||||
let text = <span>(op.to.x,op.to.y)</span>;
|
|
||||||
let click = () => props.raiseEvent("coords", focus);
|
|
||||||
let pname = idPathPoint(part, op.to);
|
|
||||||
if (pname) {
|
|
||||||
text = pname;
|
|
||||||
click = () =>
|
|
||||||
props.raiseEvent("point", {
|
|
||||||
point: props.parts[part].points[pname],
|
|
||||||
name: pname,
|
|
||||||
part: part
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<li key={key}>
|
|
||||||
<b>{op.type}</b>
|
|
||||||
»
|
|
||||||
<a href="#logo" role="button" onClick={click}>
|
|
||||||
{text}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
} else if (op.type === "curve") {
|
|
||||||
let texts = {};
|
|
||||||
let clicks = {};
|
|
||||||
let types = ["to", "cp1", "cp2"];
|
|
||||||
for (let t of types) {
|
|
||||||
let pname = idPathPoint(part, op[t]);
|
|
||||||
if (pname) {
|
|
||||||
texts[t] = pname;
|
|
||||||
clicks[t] = () =>
|
|
||||||
props.raiseEvent("point", {
|
|
||||||
point: props.parts[part].points[pname],
|
|
||||||
name: pname,
|
|
||||||
part
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
texts[t] = (
|
|
||||||
<span>
|
|
||||||
({op[t].x},{op[t].y})
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
clicks[t] = () =>
|
|
||||||
props.raiseEvent("coords", {
|
|
||||||
...focus,
|
|
||||||
coords: {
|
|
||||||
x: op[t].x,
|
|
||||||
y: op[t].y
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<li key={key}>
|
|
||||||
<b>{op.type}</b>
|
|
||||||
{types.map(t => (
|
|
||||||
<React.Fragment key={t}>
|
|
||||||
<span> » </span>
|
|
||||||
<a href="#logo" role="button" onClick={clicks[t]}>
|
|
||||||
{texts[t]}
|
|
||||||
</a>
|
|
||||||
</React.Fragment>
|
|
||||||
))}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
} else if (op.type === "close")
|
|
||||||
return (
|
|
||||||
<li key={key}>
|
|
||||||
<b>close</b>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
const styles = {
|
|
||||||
container: {
|
|
||||||
padding: "0 1rem"
|
|
||||||
},
|
|
||||||
h5: {
|
|
||||||
margin: "0.5rem 0"
|
|
||||||
},
|
|
||||||
h6: {
|
|
||||||
margin: "0.25rem 0 0 0.5rem"
|
|
||||||
},
|
|
||||||
ul: {
|
|
||||||
marginTop: "0.25rem"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (
|
|
||||||
!props.design ||
|
|
||||||
props.focus === null ||
|
|
||||||
Object.keys(props.focus).length < 1
|
|
||||||
)
|
|
||||||
return null;
|
|
||||||
let info = [];
|
|
||||||
for (let part of Object.keys(props.focus)) {
|
for (let part of Object.keys(props.focus)) {
|
||||||
info.push(
|
let points = []
|
||||||
<h5 key={"part-" + part} style={styles.h5}>
|
let paths = []
|
||||||
parts.<b>{part}</b>(
|
|
||||||
<a href="#logo" onClick={() => props.raiseEvent("part", part)}>
|
|
||||||
Isolate
|
|
||||||
</a>
|
|
||||||
)
|
|
||||||
</h5>
|
|
||||||
);
|
|
||||||
for (let i in props.focus[part].paths) {
|
for (let i in props.focus[part].paths) {
|
||||||
let name = props.focus[part].paths[i];
|
let name = props.focus[part].paths[i]
|
||||||
let path = props.parts[part].paths[name];
|
let path = props.parts[part].paths[name]
|
||||||
info.push(
|
paths.push(
|
||||||
<h6
|
<li key={'patitle-' + name} className={'path c' + (i % 4)}>
|
||||||
key={"patitle-" + name}
|
|
||||||
style={styles.h6}
|
|
||||||
className={"path c" + (i % 4)}
|
|
||||||
>
|
|
||||||
path.<b>{name}</b>
|
path.<b>{name}</b>
|
||||||
</h6>
|
<IconButton
|
||||||
);
|
size="small"
|
||||||
info.push(
|
onClick={() => console.log(`parts.${part}.paths.${name}:`, path)}
|
||||||
<ul className="links" key={"ops-" + name} style={styles.ul}>
|
>
|
||||||
<li>
|
<CameraIcon />
|
||||||
<b>attributes</b>: {renderAttributes(path.attributes)}
|
</IconButton>
|
||||||
</li>
|
{path.attributes.length > 0 && (
|
||||||
<li>
|
<ul key={'ops-' + name}>
|
||||||
<b>ops</b>: {renderPathOps(path, part)}
|
<li>
|
||||||
</li>
|
<b>attributes</b>: {renderAttributes(path.attributes)}
|
||||||
</ul>
|
</li>
|
||||||
);
|
</ul>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
for (let i in props.focus[part].points) {
|
for (let i in props.focus[part].points) {
|
||||||
let name = props.focus[part].points[i];
|
let name = props.focus[part].points[i]
|
||||||
let point = props.parts[part].points[name];
|
let point = props.parts[part].points[name]
|
||||||
info.push(
|
points.push(
|
||||||
<h6
|
<li key={'potitle-' + name} className={'point c' + (i % 4)}>
|
||||||
key={"potitle-" + name}
|
|
||||||
style={styles.h6}
|
|
||||||
className={"point c" + (i % 4)}
|
|
||||||
>
|
|
||||||
point.<b>{name}</b>
|
point.<b>{name}</b>
|
||||||
</h6>
|
<IconButton
|
||||||
);
|
size="small"
|
||||||
info.push(
|
onClick={() => console.log(`parts.${part}.points.${name}:`, point)}
|
||||||
<ul className="links" key={"pdata-" + name} style={styles.ul}>
|
>
|
||||||
<li>
|
<CameraIcon />
|
||||||
<b>x</b>: {point.x}
|
</IconButton>
|
||||||
</li>
|
<ul key={'pdata-' + name}>
|
||||||
<li>
|
<li>
|
||||||
<b>y</b>: {point.y}
|
<b>x</b>: {point.x}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<b>attributes</b>: {renderAttributes(point.attributes)}
|
<b>y</b>: {point.y}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
{point.attributes.length > 0 && (
|
||||||
);
|
<li>
|
||||||
|
<b>attributes</b>: {renderAttributes(point.attributes)}
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
info.push(
|
||||||
|
<li key={'part-' + part}>
|
||||||
|
parts.<b>{part}</b>
|
||||||
|
<IconButton onClick={() => props.raiseEvent('part', part)}>
|
||||||
|
<IsolateIcon />
|
||||||
|
</IconButton>
|
||||||
|
{points.length > 0 && <ul>{points}</ul>}
|
||||||
|
{paths.length > 0 && <ul>{paths}</ul>}
|
||||||
|
</li>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={styles.container} className="design">
|
<div className="design">
|
||||||
{info}
|
<ul>{info}</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
export default Design;
|
export default Design
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import React from 'react'
|
||||||
|
import DebugIcon from '@material-ui/icons/PlayCircleOutline'
|
||||||
|
import InfoIcon from '@material-ui/icons/Info'
|
||||||
|
import WarningIcon from '@material-ui/icons/ErrorOutline'
|
||||||
|
import ErrorIcon from '@material-ui/icons/HighlightOff'
|
||||||
|
import Markdown from 'react-markdown'
|
||||||
|
|
||||||
|
const Event = ({ type, event }) => {
|
||||||
|
const formatError = (err) => (
|
||||||
|
<details>
|
||||||
|
<summary>
|
||||||
|
<Markdown
|
||||||
|
source={`
|
||||||
|
\`\`\`js
|
||||||
|
${err.name}: ${err.message}
|
||||||
|
\`\`\`
|
||||||
|
`}
|
||||||
|
className="react-markdown dense"
|
||||||
|
/>
|
||||||
|
</summary>
|
||||||
|
<Markdown
|
||||||
|
source={`Error in \`${err.fileName}\` line \`${err.lineNumber}:${err.columnNumber}\``}
|
||||||
|
className="react-markdown"
|
||||||
|
/>
|
||||||
|
<Markdown
|
||||||
|
source={`
|
||||||
|
\`\`\`js
|
||||||
|
${err.stack}
|
||||||
|
\`\`\`
|
||||||
|
`}
|
||||||
|
className="react-markdown"
|
||||||
|
/>
|
||||||
|
</details>
|
||||||
|
)
|
||||||
|
|
||||||
|
const formatObject = (obj) => (
|
||||||
|
<Markdown
|
||||||
|
source={`
|
||||||
|
\`\`\`json
|
||||||
|
${JSON.stringify(obj, null, 2)}
|
||||||
|
\`\`\`
|
||||||
|
`}
|
||||||
|
className="react-markdown"
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
const formatEvent = (e, data = false) => {
|
||||||
|
if (!data) data = []
|
||||||
|
if (typeof e === 'object') {
|
||||||
|
if (e instanceof Error === true) data.push(formatError(e))
|
||||||
|
else if (Array.isArray(e)) {
|
||||||
|
for (const subevent of e) data.concat(formatEvent(subevent, data))
|
||||||
|
} else data.push(formatObject(e))
|
||||||
|
} else data.push(<Markdown source={e} className="react-markdown" />)
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`draft-event ${type}`}>
|
||||||
|
<div className={`icon ${type}`}>
|
||||||
|
{type === 'debug' && <DebugIcon fontSize="small" />}
|
||||||
|
{type === 'info' && <InfoIcon fontSize="small" />}
|
||||||
|
{type === 'warning' && <WarningIcon fontSize="small" />}
|
||||||
|
{type === 'error' && <ErrorIcon fontSize="small" />}
|
||||||
|
</div>
|
||||||
|
{formatEvent(event)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Event
|
|
@ -0,0 +1,16 @@
|
||||||
|
import React from 'react'
|
||||||
|
import Event from './event'
|
||||||
|
|
||||||
|
const DraftEvents = ({ events }) => (
|
||||||
|
<div className="draft-events">
|
||||||
|
{['error', 'warning', 'debug'].map((type) => (
|
||||||
|
<div className={`events-${type}`} key={type}>
|
||||||
|
{events[type].map((event, index) => (
|
||||||
|
<Event event={event} type={type} key={index} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default DraftEvents
|
134
packages/components/src/Workbench/DraftConfig/index.js
Normal file
134
packages/components/src/Workbench/DraftConfig/index.js
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
import Draft from '../../Draft'
|
||||||
|
import Zoombox from '../Zoombox'
|
||||||
|
import Design from '../Design'
|
||||||
|
import DraftConfigurator from '../../DraftConfigurator'
|
||||||
|
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 HideIcon from '@material-ui/icons/ChevronLeft'
|
||||||
|
import Events from './Events'
|
||||||
|
|
||||||
|
const DraftPattern = (props) => {
|
||||||
|
const styles = {
|
||||||
|
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 focusCount = 0
|
||||||
|
if (props.focus !== null) {
|
||||||
|
for (let p of Object.keys(props.focus)) {
|
||||||
|
for (let i in props.focus[p].points) focusCount++
|
||||||
|
for (let i in props.focus[p].paths) focusCount++
|
||||||
|
for (let i in props.focus[p].coords) focusCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let iconProps = {
|
||||||
|
size: 'small',
|
||||||
|
style: styles.icon,
|
||||||
|
color: 'inherit'
|
||||||
|
}
|
||||||
|
const color = (check) => (check ? '#40c057' : '#fa5252')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div style={{ margin: '1rem auto 0', textAlign: 'center' }}>
|
||||||
|
<IconButton onClick={() => props.setHideAside(true)} title="Hide sidebar" {...iconProps}>
|
||||||
|
<HideIcon />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => props.setDesign(!props.design)}
|
||||||
|
title="Toggle design mode"
|
||||||
|
{...iconProps}
|
||||||
|
>
|
||||||
|
<span style={{ color: color(props.design) }}>
|
||||||
|
<DesignIcon />
|
||||||
|
</span>
|
||||||
|
</IconButton>
|
||||||
|
{props.design && (
|
||||||
|
<IconButton
|
||||||
|
onClick={() => props.raiseEvent('clearFocusAll', null)}
|
||||||
|
title="Clear design mode"
|
||||||
|
{...iconProps}
|
||||||
|
>
|
||||||
|
<ClearIcon color="primary" />
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
|
<IconButton
|
||||||
|
onClick={() => console.log(props.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>
|
||||||
|
</div>
|
||||||
|
{props.design && (
|
||||||
|
<Design
|
||||||
|
focus={props.focus}
|
||||||
|
design={props.design}
|
||||||
|
raiseEvent={props.raiseEvent}
|
||||||
|
parts={props.patternProps.parts}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<DraftConfigurator
|
||||||
|
noDocs
|
||||||
|
config={props.config}
|
||||||
|
data={props.gist}
|
||||||
|
updatePatternData={props.updateGist}
|
||||||
|
raiseEvent={props.raiseEvent}
|
||||||
|
freesewing={props.freesewing}
|
||||||
|
units={props.units || 'metric'}
|
||||||
|
/>
|
||||||
|
<div style={{ padding: '5px', marginTop: '1rem' }}>
|
||||||
|
<Zoombox patternProps={props.patternProps} setViewBox={props.setViewBox} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DraftPattern
|
|
@ -2,45 +2,11 @@ import React, { useState } from 'react'
|
||||||
import Draft from '../../Draft'
|
import Draft from '../../Draft'
|
||||||
import Zoombox from '../Zoombox'
|
import Zoombox from '../Zoombox'
|
||||||
import Design from '../Design'
|
import Design from '../Design'
|
||||||
import DraftConfigurator from '../../DraftConfigurator'
|
|
||||||
import fileSaver from 'file-saver'
|
import fileSaver from 'file-saver'
|
||||||
import theme from '@freesewing/plugin-theme'
|
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'
|
|
||||||
import Events from './Events'
|
import Events from './Events'
|
||||||
|
|
||||||
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') {
|
|
||||||
props.updateGist(false, 'settings', 'only')
|
|
||||||
return setFocus(null)
|
|
||||||
}
|
|
||||||
let f = {}
|
|
||||||
if (focus !== null) f = { ...focus }
|
|
||||||
if (typeof f[data.part] === 'undefined') f[data.part] = { paths: [], points: [], coords: [] }
|
|
||||||
if (type === 'point') f[data.part].points.push(data.name)
|
|
||||||
else if (type === 'path') f[data.part].paths.push(data.name)
|
|
||||||
else if (type === 'coords') f[data.part].coords.push(data.coords)
|
|
||||||
else if (type === 'clearFocus') {
|
|
||||||
let i = focus[data.part][data.type].indexOf(data.name)
|
|
||||||
f[data.part][data.type].splice(i, 1)
|
|
||||||
} else if (type === 'part') props.updateGist(data, 'settings', 'only')
|
|
||||||
|
|
||||||
setFocus(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
const svgToFile = (svg) => {
|
const svgToFile = (svg) => {
|
||||||
const blob = new Blob([svg], {
|
const blob = new Blob([svg], {
|
||||||
type: 'image/svg+xml;charset=utf-8'
|
type: 'image/svg+xml;charset=utf-8'
|
||||||
|
@ -61,35 +27,6 @@ const DraftPattern = (props) => {
|
||||||
props.setSvgExport(false)
|
props.setSvgExport(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
pattern.draft()
|
|
||||||
let patternProps = pattern.getRenderProps()
|
|
||||||
let focusCount = 0
|
let focusCount = 0
|
||||||
if (focus !== null) {
|
if (focus !== null) {
|
||||||
for (let p of Object.keys(focus)) {
|
for (let p of Object.keys(focus)) {
|
||||||
|
@ -99,130 +36,18 @@ const DraftPattern = (props) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let iconProps = {
|
|
||||||
size: 'small',
|
|
||||||
style: styles.icon,
|
|
||||||
color: 'inherit'
|
|
||||||
}
|
|
||||||
const color = (check) => (check ? '#40c057' : '#fa5252')
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fs-sa">
|
<section>
|
||||||
<section>
|
<Draft
|
||||||
<Draft
|
{...props.patternProps}
|
||||||
{...patternProps}
|
design={props.design}
|
||||||
design={design}
|
focus={props.focus}
|
||||||
focus={focus}
|
raiseEvent={props.raiseEvent}
|
||||||
raiseEvent={raiseEvent}
|
viewBox={props.viewBox}
|
||||||
viewBox={viewBox}
|
className="freesewing draft shadow"
|
||||||
className="freesewing draft shadow"
|
/>
|
||||||
/>
|
<Events events={props.patternProps.events} />
|
||||||
<Events events={patternProps.events} />
|
</section>
|
||||||
{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 style={styles.aside}>
|
|
||||||
<div className="sticky">
|
|
||||||
<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}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<DraftConfigurator
|
|
||||||
noDocs
|
|
||||||
config={props.config}
|
|
||||||
data={props.gist}
|
|
||||||
updatePatternData={props.updateGist}
|
|
||||||
raiseEvent={props.raiseEvent}
|
|
||||||
freesewing={props.freesewing}
|
|
||||||
units={props.units || 'metric'}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import { languages } from "@freesewing/i18n";
|
|
||||||
|
|
||||||
const LanguageChooser = props => {
|
|
||||||
const styles = {
|
|
||||||
container: {
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
|
||||||
width: "100%"
|
|
||||||
},
|
|
||||||
chooser: {
|
|
||||||
width: "100%",
|
|
||||||
textAlign: "center",
|
|
||||||
alignSelf: "center"
|
|
||||||
},
|
|
||||||
button: {
|
|
||||||
margin: "1rem"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeLanguage = lang => {
|
|
||||||
props.setLanguage(lang);
|
|
||||||
props.setDisplay("pattern");
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={styles.container}>
|
|
||||||
<div style={styles.chooser}>
|
|
||||||
{Object.keys(languages).map(lang => {
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
style={styles.button}
|
|
||||||
key={lang}
|
|
||||||
color="primary"
|
|
||||||
size="large"
|
|
||||||
variant="contained"
|
|
||||||
onClick={() => changeLanguage(lang)}
|
|
||||||
>
|
|
||||||
{languages[lang]}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default LanguageChooser;
|
|
|
@ -8,12 +8,27 @@ import { dark, light } from '@freesewing/mui-theme'
|
||||||
import withLanguage from '../withLanguage'
|
import withLanguage from '../withLanguage'
|
||||||
import LanguageIcon from '@material-ui/icons/Translate'
|
import LanguageIcon from '@material-ui/icons/Translate'
|
||||||
import DarkModeIcon from '@material-ui/icons/Brightness3'
|
import DarkModeIcon from '@material-ui/icons/Brightness3'
|
||||||
import LanguageChooser from './LanguageChooser'
|
|
||||||
import DraftPattern from './DraftPattern'
|
import DraftPattern from './DraftPattern'
|
||||||
|
import DraftConfig from './DraftConfig'
|
||||||
import Json from './Json'
|
import Json from './Json'
|
||||||
import SamplePattern from './SamplePattern'
|
import SamplePattern from './SamplePattern'
|
||||||
import Welcome from './Welcome'
|
import Welcome from './Welcome'
|
||||||
import Measurements from './Measurements'
|
import Measurements from './Measurements'
|
||||||
|
import DraftIcon from '@material-ui/icons/Gesture'
|
||||||
|
import TestIcon from '@material-ui/icons/DoneAll'
|
||||||
|
import MeasurementsIcon from '@material-ui/icons/Height'
|
||||||
|
import ExportIcon from '@material-ui/icons/ScreenShare'
|
||||||
|
import { FormattedMessage } from 'react-intl'
|
||||||
|
import { languages } from '@freesewing/i18n'
|
||||||
|
import Button from '@material-ui/core/Button'
|
||||||
|
import UnhideIcon from '@material-ui/icons/ChevronRight'
|
||||||
|
|
||||||
|
const icons = {
|
||||||
|
draft: <DraftIcon />,
|
||||||
|
test: <TestIcon />,
|
||||||
|
measurements: <MeasurementsIcon />,
|
||||||
|
xport: <ExportIcon />
|
||||||
|
}
|
||||||
|
|
||||||
const Workbench = ({
|
const Workbench = ({
|
||||||
updateGist,
|
updateGist,
|
||||||
|
@ -22,7 +37,6 @@ const Workbench = ({
|
||||||
language = 'en',
|
language = 'en',
|
||||||
gist,
|
gist,
|
||||||
importGist,
|
importGist,
|
||||||
config,
|
|
||||||
freesewing,
|
freesewing,
|
||||||
Pattern,
|
Pattern,
|
||||||
units = 'metric',
|
units = 'metric',
|
||||||
|
@ -34,6 +48,38 @@ const Workbench = ({
|
||||||
const [theme, setTheme] = useState('light')
|
const [theme, setTheme] = useState('light')
|
||||||
const [measurements, setMeasurements] = useState(null)
|
const [measurements, setMeasurements] = useState(null)
|
||||||
const [svgExport, setSvgExport] = useState(false)
|
const [svgExport, setSvgExport] = useState(false)
|
||||||
|
const [viewBox, setViewBox] = useState(false)
|
||||||
|
const [hideAside, setHideAside] = useState(false)
|
||||||
|
const [design, setDesign] = useState(true)
|
||||||
|
const [focus, setFocus] = useState(null)
|
||||||
|
|
||||||
|
const raiseEvent = (type, data) => {
|
||||||
|
if (type === 'clearFocusAll') {
|
||||||
|
updateGist(false, 'settings', 'only')
|
||||||
|
return setFocus(null)
|
||||||
|
}
|
||||||
|
let f = {}
|
||||||
|
if (focus !== null) f = { ...focus }
|
||||||
|
if (typeof f[data.part] === 'undefined') f[data.part] = { paths: [], points: [], coords: [] }
|
||||||
|
if (type === 'point') f[data.part].points.push(data.name)
|
||||||
|
else if (type === 'path') f[data.part].paths.push(data.name)
|
||||||
|
else if (type === 'coords') f[data.part].coords.push(data.coords)
|
||||||
|
else if (type === 'clearFocus') {
|
||||||
|
let i = focus[data.part][data.type].indexOf(data.name)
|
||||||
|
f[data.part][data.type].splice(i, 1)
|
||||||
|
} else if (type === 'part') updateGist(data, 'settings', 'only')
|
||||||
|
|
||||||
|
setFocus(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get config from pattern object
|
||||||
|
const config = Pattern.config
|
||||||
|
const links = {
|
||||||
|
draft: <FormattedMessage id="cfp.draftThing" values={{ thing: config.name }} />,
|
||||||
|
test: <FormattedMessage id="cfp.testThing" values={{ thing: config.name }} />,
|
||||||
|
measurements: <FormattedMessage id="app.measurements" />,
|
||||||
|
xport: <FormattedMessage id="app.export" />
|
||||||
|
}
|
||||||
|
|
||||||
// Enable debug in Workbench
|
// Enable debug in Workbench
|
||||||
defaultGist.settings.debug = true
|
defaultGist.settings.debug = true
|
||||||
|
@ -42,19 +88,15 @@ const Workbench = ({
|
||||||
let m = getMeasurements()
|
let m = getMeasurements()
|
||||||
setMeasurements(m)
|
setMeasurements(m)
|
||||||
updateGist(m, 'settings', 'measurements')
|
updateGist(m, 'settings', 'measurements')
|
||||||
setDisplay(getDisplay())
|
|
||||||
setLanguage(userLanguage)
|
setLanguage(userLanguage)
|
||||||
if (translations) addTranslations(translations)
|
if (translations) addTranslations(translations)
|
||||||
|
console.log('useEffect 1')
|
||||||
}, [])
|
}, [])
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (language !== gist.settings.locale) updateGist(language, 'settings', 'locale')
|
if (language !== gist.settings.locale) updateGist(language, 'settings', 'locale')
|
||||||
|
console.log('useEffect 2')
|
||||||
}, [language])
|
}, [language])
|
||||||
|
|
||||||
const getDisplay = () => storage.get(config.name + '-display')
|
|
||||||
const saveDisplay = (d) => {
|
|
||||||
setDisplay(d)
|
|
||||||
storage.set(config.name + '-display', d)
|
|
||||||
}
|
|
||||||
const getMeasurements = () => storage.get(config.name + '-measurements')
|
const getMeasurements = () => storage.get(config.name + '-measurements')
|
||||||
const saveMeasurements = (data) => {
|
const saveMeasurements = (data) => {
|
||||||
storage.set(config.name + '-measurements', data)
|
storage.set(config.name + '-measurements', data)
|
||||||
|
@ -88,33 +130,33 @@ const Workbench = ({
|
||||||
if (theme === 'light') setTheme('dark')
|
if (theme === 'light') setTheme('dark')
|
||||||
else setTheme('light')
|
else setTheme('light')
|
||||||
}
|
}
|
||||||
const raiseEvent = (type = null, data = null) => {}
|
//const raiseEvent = (type = null, data = null) => {}
|
||||||
|
|
||||||
|
const MainMenu = () => (
|
||||||
|
<ul className="aside-main-menu">
|
||||||
|
{Object.keys(icons).map((link) => {
|
||||||
|
return (
|
||||||
|
<li key={link}>
|
||||||
|
<a
|
||||||
|
href={`#test`}
|
||||||
|
onClick={() => setDisplay(link)}
|
||||||
|
className={link === display ? 'active' : ''}
|
||||||
|
>
|
||||||
|
{icons[link]}
|
||||||
|
<span className="text">{links[link]}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
|
|
||||||
const navs = {
|
const navs = {
|
||||||
left: {
|
left: {
|
||||||
draft: {
|
discord: {
|
||||||
type: 'button',
|
type: 'link',
|
||||||
onClick: () => saveDisplay('draft'),
|
href: 'https://chat.freesewing.org/',
|
||||||
text: 'cfp.draftYourPattern',
|
text: 'cfp.draftYourPattern'
|
||||||
active: display === 'draft' ? true : false
|
|
||||||
},
|
|
||||||
sample: {
|
|
||||||
type: 'button',
|
|
||||||
onClick: () => saveDisplay('sample'),
|
|
||||||
text: 'cfp.testYourPattern',
|
|
||||||
active: display === 'sample' ? true : false
|
|
||||||
},
|
|
||||||
measurements: {
|
|
||||||
type: 'button',
|
|
||||||
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: {
|
right: {
|
||||||
|
@ -125,7 +167,7 @@ const Workbench = ({
|
||||||
},
|
},
|
||||||
language: {
|
language: {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
onClick: () => saveDisplay('languages'),
|
onClick: () => setDisplay('languages'),
|
||||||
text: <LanguageIcon className="nav-icon" />,
|
text: <LanguageIcon className="nav-icon" />,
|
||||||
title: 'Languages',
|
title: 'Languages',
|
||||||
active: display === 'languages' ? true : false
|
active: display === 'languages' ? true : false
|
||||||
|
@ -138,27 +180,71 @@ const Workbench = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (display === 'draft' && !measurementsMissing())
|
|
||||||
navs.left.svgExport = {
|
const languageButtons = () => (
|
||||||
type: 'button',
|
<p>
|
||||||
onClick: () => setSvgExport(true),
|
{Object.keys(languages).map((lang) => {
|
||||||
text: 'app.export',
|
return (
|
||||||
active: false
|
<Button
|
||||||
|
key={lang}
|
||||||
|
color="primary"
|
||||||
|
size="large"
|
||||||
|
variant="outlined"
|
||||||
|
onClick={() => setLanguage(lang)}
|
||||||
|
style={{ margin: '0 0.5rem 0.5rem 0' }}
|
||||||
|
disabled={lang === language ? true : false}
|
||||||
|
>
|
||||||
|
{languages[lang]}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
|
||||||
|
const styles = {
|
||||||
|
unhide: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
top: 0
|
||||||
}
|
}
|
||||||
// FIXME:
|
}
|
||||||
navs.mleft = navs.left
|
|
||||||
navs.mright = navs.right
|
|
||||||
let main = null
|
let main = null
|
||||||
|
let context = null
|
||||||
switch (display) {
|
switch (display) {
|
||||||
case 'languages':
|
case 'languages':
|
||||||
main = <LanguageChooser setLanguage={setLanguage} setDisplay={saveDisplay} />
|
main = (
|
||||||
|
<>
|
||||||
|
<h1>
|
||||||
|
<FormattedMessage id="account.languageTitle" />
|
||||||
|
</h1>
|
||||||
|
{languageButtons()}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
context = (
|
||||||
|
<ul>
|
||||||
|
{Object.keys(languages).map((lang) => {
|
||||||
|
return (
|
||||||
|
<li key={lang}>
|
||||||
|
<a href="#" onClick={() => setLanguage(lang)}>
|
||||||
|
{languages[lang]}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
break
|
break
|
||||||
case 'draft':
|
case 'draft':
|
||||||
if (measurementsMissing()) saveDisplay('measurements')
|
if (measurementsMissing()) setDisplay('measurements')
|
||||||
|
let pattern = new Pattern(gist.settings)
|
||||||
|
pattern.draft()
|
||||||
|
let patternProps = pattern.getRenderProps()
|
||||||
main = (
|
main = (
|
||||||
<DraftPattern
|
<DraftPattern
|
||||||
freesewing={freesewing}
|
freesewing={freesewing}
|
||||||
Pattern={Pattern}
|
Pattern={Pattern}
|
||||||
|
patternProps={patternProps}
|
||||||
config={config}
|
config={config}
|
||||||
gist={gist}
|
gist={gist}
|
||||||
updateGist={updateGist}
|
updateGist={updateGist}
|
||||||
|
@ -167,11 +253,37 @@ const Workbench = ({
|
||||||
svgExport={svgExport}
|
svgExport={svgExport}
|
||||||
setSvgExport={setSvgExport}
|
setSvgExport={setSvgExport}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
|
viewBox={viewBox}
|
||||||
|
focus={focus}
|
||||||
|
design={design}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
context = (
|
||||||
|
<DraftConfig
|
||||||
|
freesewing={freesewing}
|
||||||
|
Pattern={Pattern}
|
||||||
|
patternProps={patternProps}
|
||||||
|
config={config}
|
||||||
|
gist={gist}
|
||||||
|
updateGist={updateGist}
|
||||||
|
raiseEvent={raiseEvent}
|
||||||
|
units={units}
|
||||||
|
svgExport={svgExport}
|
||||||
|
setSvgExport={setSvgExport}
|
||||||
|
theme={theme}
|
||||||
|
viewBox={viewBox}
|
||||||
|
setViewBox={setViewBox}
|
||||||
|
setHideAside={setHideAside}
|
||||||
|
focus={focus}
|
||||||
|
setFocus={setFocus}
|
||||||
|
design={design}
|
||||||
|
setDesign={setDesign}
|
||||||
|
pattern={pattern}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
case 'sample':
|
case 'sample':
|
||||||
if (measurementsMissing()) saveDisplay('measurements')
|
if (measurementsMissing()) setDisplay('measurements')
|
||||||
main = (
|
main = (
|
||||||
<SamplePattern
|
<SamplePattern
|
||||||
freesewing={freesewing}
|
freesewing={freesewing}
|
||||||
|
@ -199,23 +311,13 @@ const Workbench = ({
|
||||||
case 'json':
|
case 'json':
|
||||||
main = <Json gist={gist} />
|
main = <Json gist={gist} />
|
||||||
break
|
break
|
||||||
case 'inspect':
|
|
||||||
main = (
|
|
||||||
<InspectPattern
|
|
||||||
freesewing={freesewing}
|
|
||||||
Pattern={Pattern}
|
|
||||||
config={config}
|
|
||||||
gist={gist}
|
|
||||||
updateGist={updateGist}
|
|
||||||
raiseEvent={raiseEvent}
|
|
||||||
units={units}
|
|
||||||
svgExport={svgExport}
|
|
||||||
setSvgExport={setSvgExport}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
break
|
|
||||||
default:
|
default:
|
||||||
main = <Welcome language={language} setDisplay={saveDisplay} />
|
main = (
|
||||||
|
<>
|
||||||
|
<Welcome language={language} setDisplay={setDisplay} />
|
||||||
|
<div style={{ margin: 'auto', textAlign: 'center' }}>{languageButtons()}</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const themes = { dark, light }
|
const themes = { dark, light }
|
||||||
|
@ -227,8 +329,22 @@ const Workbench = ({
|
||||||
theme === 'light' ? 'workbench theme-wrapper light' : 'workbench theme-wrapper dark'
|
theme === 'light' ? 'workbench theme-wrapper light' : 'workbench theme-wrapper dark'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{display !== 'welcome' ? <Navbar navs={navs} home={() => saveDisplay('welcome')} /> : null}
|
<Navbar navs={navs} home={() => setDisplay('welcome')} />
|
||||||
{main}
|
<div className="fs-sa" style={{ position: 'relative' }}>
|
||||||
|
{hideAside ? (
|
||||||
|
<a href="#" style={styles.unhide} onClick={() => setHideAside(false)}>
|
||||||
|
<UnhideIcon />
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<aside>
|
||||||
|
<div className="sticky">
|
||||||
|
<MainMenu />
|
||||||
|
<div className="aside-context">{context}</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
)}
|
||||||
|
<section>{main}</section>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MuiThemeProvider>
|
</MuiThemeProvider>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
ul.config {
|
ul.config {
|
||||||
@include title-font;
|
@include button-font;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
ul.config.l1 { overflow-x: hidden;}
|
ul.config.l1 {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
ul.config.l2,
|
ul.config.l2,
|
||||||
ul.config.l3,
|
ul.config.l3,
|
||||||
ul.config.l4 {
|
ul.config.l4 {
|
||||||
|
@ -10,7 +12,9 @@ ul.config.l4 {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.config li { list-style-type: none; }
|
ul.config li {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* level 1 */
|
/* level 1 */
|
||||||
ul.config.l1 > li > span {
|
ul.config.l1 > li > span {
|
||||||
|
@ -65,15 +69,18 @@ div.expanded div.MuiSlider-container {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: initial;
|
overflow: initial;
|
||||||
}
|
}
|
||||||
ul.config p { @include body-font;}
|
ul.config p {
|
||||||
|
@include body-font;
|
||||||
|
}
|
||||||
|
|
||||||
/* level 4 */
|
/* level 4 */
|
||||||
ul.config.l3 li span.subheading {
|
ul.config.l3 li span.subheading {
|
||||||
padding-left: 2rem;
|
padding-left: 2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
ul.config.l4 > li > div { padding-left: 2.5rem; }
|
ul.config.l4 > li > div {
|
||||||
|
padding-left: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
span.dflt,
|
span.dflt,
|
||||||
span.p-dflt,
|
span.p-dflt,
|
||||||
|
@ -126,4 +133,3 @@ button.mini-icon-btn {
|
||||||
.theme-wrapper.dark button.mini-icon-btn.pattern:enabled {
|
.theme-wrapper.dark button.mini-icon-btn.pattern:enabled {
|
||||||
color: $oc-green-6;
|
color: $oc-green-6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,17 +101,31 @@ div.design {
|
||||||
font-size: 115%;
|
font-size: 115%;
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
h6.point.c0 {
|
.path,
|
||||||
border-bottom: 1px solid $oc-red-6;
|
.point {
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
padding-left: 5px;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
font-size: 80%;
|
||||||
}
|
}
|
||||||
h6.point.c1 {
|
.path {
|
||||||
border-bottom: 1px solid $oc-green-6;
|
border-left: 3px dashed transparent;
|
||||||
}
|
}
|
||||||
h6.point.c2 {
|
.path.c0,
|
||||||
border-bottom: 1px solid $oc-blue-6;
|
.point.c0 {
|
||||||
|
border-color: $oc-red-6;
|
||||||
}
|
}
|
||||||
h6.point.c3 {
|
.path.c1,
|
||||||
border-bottom: 1px solid $oc-grape-6;
|
.point.c1 {
|
||||||
|
border-color: $oc-green-6;
|
||||||
|
}
|
||||||
|
.path.c2,
|
||||||
|
.point.c2 {
|
||||||
|
border-color: $oc-blue-6;
|
||||||
|
}
|
||||||
|
.path.c3,
|
||||||
|
.point.c3 {
|
||||||
|
border-color: $oc-grape-6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,21 +146,6 @@ div.design {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-wrapper.light div.design {
|
|
||||||
h6.path.c0 {
|
|
||||||
background-color: rgba($oc-red-6, 0.3);
|
|
||||||
}
|
|
||||||
h6.path.c1 {
|
|
||||||
background-color: rgba($oc-green-6, 0.3);
|
|
||||||
}
|
|
||||||
h6.path.c2 {
|
|
||||||
background-color: rgba($oc-blue-6, 0.3);
|
|
||||||
}
|
|
||||||
h6.path.c3 {
|
|
||||||
background-color: rgba($oc-grape-6, 0.3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-wrapper.dark svg.freesewing.draft {
|
.theme-wrapper.dark svg.freesewing.draft {
|
||||||
g.design.point {
|
g.design.point {
|
||||||
circle {
|
circle {
|
||||||
|
@ -166,18 +165,3 @@ div.design {
|
||||||
stroke-opacity: 0.5;
|
stroke-opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-wrapper.dark div.design {
|
|
||||||
h6.path.c0 {
|
|
||||||
background-color: rgba($oc-red-6, 0.5);
|
|
||||||
}
|
|
||||||
h6.path.c1 {
|
|
||||||
background-color: rgba($oc-green-6, 0.5);
|
|
||||||
}
|
|
||||||
h6.path.c2 {
|
|
||||||
background-color: rgba($oc-blue-6, 0.5);
|
|
||||||
}
|
|
||||||
h6.path.c3 {
|
|
||||||
background-color: rgba($oc-grape-6, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ devDocsAvailableAt: Developer documentation is available at
|
||||||
talkToUs: For questions, feedback or suggestions, come talk to us in our chat room
|
talkToUs: For questions, feedback or suggestions, come talk to us in our chat room
|
||||||
draftYourPattern: Draft your pattern
|
draftYourPattern: Draft your pattern
|
||||||
testYourPattern: Test your pattern
|
testYourPattern: Test your pattern
|
||||||
|
draftThing: 'Draft {thing}'
|
||||||
|
testThing: 'Test {thing}'
|
||||||
renderInBrowser: Click below to render your pattern in the browser.
|
renderInBrowser: Click below to render your pattern in the browser.
|
||||||
weWillReRender: When you make changes, we will re-render for you.
|
weWillReRender: When you make changes, we will re-render for you.
|
||||||
youCan: You can
|
youCan: You can
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue