diff --git a/packages/freesewing.shared/components/icons/page-size.js b/packages/freesewing.shared/components/icons/page-size.js
new file mode 100644
index 00000000000..9ee81d00cd2
--- /dev/null
+++ b/packages/freesewing.shared/components/icons/page-size.js
@@ -0,0 +1,7 @@
+const PageSizeIcon = props => (
+
+)
+
+export default PageSizeIcon
diff --git a/packages/freesewing.shared/components/icons/page.js b/packages/freesewing.shared/components/icons/page.js
new file mode 100644
index 00000000000..0b994cb4ed1
--- /dev/null
+++ b/packages/freesewing.shared/components/icons/page.js
@@ -0,0 +1,7 @@
+const PageIcon = props => (
+
+)
+
+export default PageIcon
diff --git a/packages/freesewing.shared/components/workbench/layout/cut/index.js b/packages/freesewing.shared/components/workbench/layout/cut/index.js
new file mode 100644
index 00000000000..64b94163194
--- /dev/null
+++ b/packages/freesewing.shared/components/workbench/layout/cut/index.js
@@ -0,0 +1,21 @@
+import { useTranslation } from 'next-i18next'
+import Settings from './settings'
+
+const CutLayout = props => {
+ const { t } = useTranslation(['workbench'])
+
+ return (
+
+
+ {
+ t('layoutThing', { thing: props.pattern.config.name })
+ + ': '
+ + t('forCutting')
+ }
+
+
+
+ )
+}
+
+export default CutLayout
diff --git a/packages/freesewing.shared/components/workbench/layout/cut/settings.js b/packages/freesewing.shared/components/workbench/layout/cut/settings.js
new file mode 100644
index 00000000000..d71f192bb34
--- /dev/null
+++ b/packages/freesewing.shared/components/workbench/layout/cut/settings.js
@@ -0,0 +1,10 @@
+const CutLayoutSettings = props => {
+
+ return (
+
+
Fixme: Cut layout settings here
+
+ )
+}
+
+export default CutLayoutSettings
diff --git a/packages/freesewing.shared/components/workbench/layout/draft.js b/packages/freesewing.shared/components/workbench/layout/draft.js
new file mode 100644
index 00000000000..dd0434c6857
--- /dev/null
+++ b/packages/freesewing.shared/components/workbench/layout/draft.js
@@ -0,0 +1,33 @@
+import Svg from '../draft/svg'
+import Defs from '../draft/defs'
+import Part from '../draft/part'
+
+const Draft = props => {
+ const { patternProps, gist, app, updateGist, unsetGist, bgProps={} } = props
+
+ return (
+
+
+
+ )
+}
+
+export default Draft
+
diff --git a/packages/freesewing.shared/components/workbench/layout/print/index.js b/packages/freesewing.shared/components/workbench/layout/print/index.js
new file mode 100644
index 00000000000..b56e172035c
--- /dev/null
+++ b/packages/freesewing.shared/components/workbench/layout/print/index.js
@@ -0,0 +1,49 @@
+import { useTranslation } from 'next-i18next'
+import Settings from './settings'
+import Draft from '../draft'
+import pluginBuilder from './plugin'
+
+const addPages = (gist) => {
+ const pages = []
+}
+
+
+const PrintLayout = props => {
+ const { t } = useTranslation(['workbench'])
+
+ const draft = new props.pattern(props.gist).use(pluginBuilder(
+ props.gist?._state?.layout?.forPrinting?.page?.size,
+ props.gist?._state?.layout?.forPrinting?.page?.orientation,
+ ))
+ let patternProps
+ try {
+ draft.draft()
+ patternProps = draft.getRenderProps()
+ } catch(err) {
+ console.log(err)
+ }
+ const bgProps = { fill: "url(#page)" }
+
+ return (
+
+
+ {
+ t('layoutThing', { thing: props.pattern.config.name })
+ + ': '
+ + t('forPrinting')
+ }
+
+
+
+
+
+
+ )
+}
+
+export default PrintLayout
diff --git a/packages/freesewing.shared/components/workbench/layout/print/orientation-picker.js b/packages/freesewing.shared/components/workbench/layout/print/orientation-picker.js
new file mode 100644
index 00000000000..ef8b01aaf69
--- /dev/null
+++ b/packages/freesewing.shared/components/workbench/layout/print/orientation-picker.js
@@ -0,0 +1,29 @@
+import PageIcon from 'shared/components/icons/page'
+import { useTranslation } from 'next-i18next'
+
+const PageOrientationPicker = ({ gist, updateGist }) => {
+ const { t } = useTranslation(['workbench'])
+
+ return (
+
+ )
+}
+
+export default PageOrientationPicker
diff --git a/packages/freesewing.shared/components/workbench/layout/print/pagesize-picker.js b/packages/freesewing.shared/components/workbench/layout/print/pagesize-picker.js
new file mode 100644
index 00000000000..69ba5bb2c9b
--- /dev/null
+++ b/packages/freesewing.shared/components/workbench/layout/print/pagesize-picker.js
@@ -0,0 +1,78 @@
+import PageSizeIcon from 'shared/components/icons/page-size'
+import { useTranslation } from 'next-i18next'
+import Popout from 'shared/components/popout'
+
+
+const sizes = ['a4', 'a3', 'a2', 'a1', 'a0', 'letter', 'tabloid']
+
+
+const PageSizePicker = ({ gist, updateGist }) => {
+ const { t } = useTranslation(['workbench'])
+ const setSize = size => {
+ updateGist(
+ ['_state', 'layout', 'forPrinting', 'page', 'size'],
+ size
+ )
+ if (!gist._state?.layout?.forPrinting?.page?.orientation) {
+ updateGist(
+ ['_state', 'layout', 'forPrinting', 'page', 'orientation'],
+ 'portrait'
+ )
+ }
+ }
+
+ if (
+ !gist._state?.layout?.forPrinting?.page?.size ||
+ sizes.indexOf(gist._state.layout.forPrinting.page.size) === -1
+ ) return (
+
+ {t('startBySelectingAThing', { thing: t('pageSize')})}
+
+ {sizes.map(size => (
+
+ ))}
+
+
+ )
+
+ return (
+
+
+
+
{t(`pageSize`)}:
+
{gist._state.layout.forPrinting.page.size}
+
+
+ {sizes.map(size => (
+ -
+
+
+ ))}
+
+
+ )
+}
+
+export default PageSizePicker
diff --git a/packages/freesewing.shared/components/workbench/layout/print/plugin.js b/packages/freesewing.shared/components/workbench/layout/print/plugin.js
new file mode 100644
index 00000000000..f95af82525c
--- /dev/null
+++ b/packages/freesewing.shared/components/workbench/layout/print/plugin.js
@@ -0,0 +1,76 @@
+
+const name = 'Pages Plugin'
+const version = '1.0.0'
+const sizes = {
+ a4: [ 210, 297 ],
+ a3: [ 297, 420 ],
+ a2: [ 420, 594 ],
+ a1: [ 594, 841 ],
+ a0: [ 841, 1188 ],
+ letter: [ 215.9, 279.4 ],
+ tabloid: [ 279.4, 431.8 ],
+}
+
+const drawPage = (x, y, size, orientation) => {
+//
+}
+
+const pagesPlugin = (size='a4', orientation='portrait') => ({
+ name,
+ version,
+ hooks: {
+ postLayout: function(pattern) {
+ // Add part
+ pattern.parts.pages = pattern.Part('pages')
+ // Keep part out of layout
+ pattern.parts.pages.layout = false
+ // Add pages
+ const { macro } = pattern.parts.pages.shorthand()
+ const { height, width } = pattern
+ macro('addPages', { size, orientation, height, width })
+ }
+ },
+ macros: {
+ addPages: function(so) {
+ const ls = so.orientation === 'landscape'
+ const w = sizes[so.size][ls ? 1 : 0]
+ const h = sizes[so.size][ls ? 0 : 1]
+ const cols = Math.ceil(so.width / w)
+ const rows = Math.ceil(so.height / h)
+ const { points, Point, paths, Path } = this.shorthand()
+ let x = 0
+ let y = 0
+ let count = 0
+ for (let row=0;row {
+ const settingsProps = {
+ gist: props.gist,
+ updateGist: props.updateGist
+ }
+
+ return (
+
+
+
+
{JSON.stringify(props.gist._state, null ,2)}
+
+ )
+}
+
+export default PrintLayoutSettings
diff --git a/packages/freesewing.shared/components/workbench/menu/view.js b/packages/freesewing.shared/components/workbench/menu/view.js
index fe141067bd8..1f79077d153 100644
--- a/packages/freesewing.shared/components/workbench/menu/view.js
+++ b/packages/freesewing.shared/components/workbench/menu/view.js
@@ -20,8 +20,21 @@ const View = props => {
title: t('testPattern', { pattern: props.pattern.config.name }),
onClick: () => props.updateGist(['_state', 'view'], 'test')
},
+ {
+ name: 'printingLayout',
+ title: t('layoutThing', { thing: props.pattern.config.name })
+ + ': ' + t('forPrinting'),
+ onClick: () => props.updateGist(['_state', 'view'], 'printingLayout')
+ },
+ {
+ name: 'cuttingLayout',
+ title: t('layoutThing', { thing: props.pattern.config.name })
+ + ': ' + t('forCutting'),
+ onClick: () => props.updateGist(['_state', 'view'], 'cuttingLayout')
+ },
{
name: 'export',
+ title: t('exportThing', { thing: props.pattern.config.name }),
title: t('export'),
onClick: () => props.updateGist(['_state', 'view'], 'export')
},
@@ -40,6 +53,11 @@ const View = props => {
title: t('JSON'),
onClick: () => props.updateGist(['_state', 'view'], 'json')
},
+ {
+ name: 'edit',
+ title: t('editThing', { thing: 'YAML' }),
+ onClick: () => props.updateGist(['_state', 'view'], 'edit')
+ },
]
return (
diff --git a/packages/freesewing.shared/components/wrappers/workbench.js b/packages/freesewing.shared/components/wrappers/workbench.js
index 5b7be1c3d8f..9c2cb7a7414 100644
--- a/packages/freesewing.shared/components/wrappers/workbench.js
+++ b/packages/freesewing.shared/components/wrappers/workbench.js
@@ -16,11 +16,15 @@ import ExportDraft from 'shared/components/workbench/export.js'
import GistAsJson from 'shared/components/workbench/json.js'
import GistAsYaml from 'shared/components/workbench/yaml.js'
import DraftEvents from 'shared/components/workbench/events.js'
+import CutLayout from 'shared/components/workbench/layout/cut'
+import PrintLayout from 'shared/components/workbench/layout/print'
const views = {
measurements: Measurements,
draft: LabDraft,
test: LabSample,
+ printingLayout: PrintLayout,
+ cuttingLayout: CutLayout,
export: ExportDraft,
events: DraftEvents,
yaml: GistAsYaml,
diff --git a/packages/freesewing.shared/styles/svg-freesewing-draft.css b/packages/freesewing.shared/styles/svg-freesewing-draft.css
index 575c770e5c2..1181f246fb3 100644
--- a/packages/freesewing.shared/styles/svg-freesewing-draft.css
+++ b/packages/freesewing.shared/styles/svg-freesewing-draft.css
@@ -57,6 +57,11 @@ svg.freesewing.pattern {
.center { text-anchor: middle; }
.right { text-anchor: end; }
+ /* muted page numbers */
+ .muted {
+ opacity: 0.1;
+ }
+
/* Developer view */
g.develop.point {
circle.center {