diff --git a/markdown/dev/reference/api/en.md b/markdown/dev/reference/api/en.md index 22e71c3ee43..f9fb71d4d66 100644 --- a/markdown/dev/reference/api/en.md +++ b/markdown/dev/reference/api/en.md @@ -74,6 +74,7 @@ The following named exports are **utility methods**: | `lineIntersectsCircle` | See the [lineIntersectsCircle](/reference/api/utils/lineintersectscircle) documentation | | `lineIntersectsCurve` | See the [lineIntersectsCurve](/reference/api/utils/lineintersectscurve) documentation | | `linesIntersect` | See the [linesIntersect](/reference/api/utils/linesintersect) documentation | +| `mergeOptions` | See the [mergeOptions](/reference/api/utils/mergeoptions) documentation | | `pctBasedOn` | See the [pctBasedOn](/reference/api/utils/pctbasedon) documentation | | `pointOnBeam` | See the [pointOnBeam](/reference/api/utils/pointonbeam) documentation | | `pointOnCurve` | See the [pointOnCurve](/reference/api/utils/pointoncurve) documentation | diff --git a/markdown/dev/reference/api/part/config/options/pct/toabs/en.md b/markdown/dev/reference/api/part/config/options/pct/toabs/en.md index 3b20d5df34a..f32d3dbf4ff 100644 --- a/markdown/dev/reference/api/part/config/options/pct/toabs/en.md +++ b/markdown/dev/reference/api/part/config/options/pct/toabs/en.md @@ -17,16 +17,23 @@ The `toAbs` property should hold a function with the following signature: ```js -function toAbs(percentage, settings) { +function toAbs(percentage, settings, mergeOptions) { // return value in millimeter here } ``` The first parameter is the percentage value provided by the user (for example `0.5` for `50%`). + The second parameter holds the pattern's [settings](/reference/settings) object which holds -- among other things -- the measurements provided by the user. +The third parameter should be the return value of +[utils.mergeOptions()](/reference/api/utils/mergeoptions), which provides an +object with all option values populated. Although this parameter is not +required for simple values based on measurements, it is often required when the +result depends on several options. + ## Example In our example above, let's say that the `chestEase` option is diff --git a/markdown/dev/reference/api/utils/mergeoptions/en.md b/markdown/dev/reference/api/utils/mergeoptions/en.md new file mode 100644 index 00000000000..e38a054f3a5 --- /dev/null +++ b/markdown/dev/reference/api/utils/mergeoptions/en.md @@ -0,0 +1,27 @@ +--- +title: utils.mergeOptions() +--- + +The `utils.mergeOptions()` function merges the user-provided options with the +options from the pattern configuration. + +## Signature + +```js +float deg2rad(object settings, object optionsConfig) +``` + +## Notes + +Typically the only options that are passed as part of settings to the pattern +are those that differ from the defaults. This means that if you want to check +an option outside a draft method, you need to check whether the option is set, +and if it's not get the default value from the pattern config. Furthermore, +where the default is stored and whether or not it should be further transformed +depends on the option type. + +This method exists to facilitate this. You pass it the user-provided settings, +and the pattern config options key, and it will return an object where all +options are populated with the user-provided values, or their defaults if the +user did not provide any input. + diff --git a/packages/core/src/index.mjs b/packages/core/src/index.mjs index 8735fe5411b..85ab05ed4b7 100644 --- a/packages/core/src/index.mjs +++ b/packages/core/src/index.mjs @@ -26,6 +26,7 @@ import { lineIntersectsCircle, lineIntersectsCurve, linesIntersect, + mergeOptions, pctBasedOn, pointOnBeam, pointOnCurve, @@ -70,6 +71,7 @@ export { lineIntersectsCircle, lineIntersectsCurve, linesIntersect, + mergeOptions, pctBasedOn, pointOnBeam, pointOnCurve, diff --git a/packages/core/src/pattern/pattern-drafter.mjs b/packages/core/src/pattern/pattern-drafter.mjs index e82c75d3f99..c75669f6036 100644 --- a/packages/core/src/pattern/pattern-drafter.mjs +++ b/packages/core/src/pattern/pattern-drafter.mjs @@ -1,6 +1,6 @@ import { PatternDraftQueue } from './pattern-draft-queue.mjs' import { Part } from '../part.mjs' -import { __macroName } from '../utils.mjs' +import { __macroName, mergeOptions } from '../utils.mjs' /** * A class to handle drafting a pattern @@ -210,7 +210,11 @@ PatternDrafter.prototype.__loadAbsoluteOptionsSet = function (set) { */ PatternDrafter.prototype.__snappedPercentageOption = function (optionName, set) { const conf = this.pattern.config.options[optionName] - const abs = conf.toAbs(this.pattern.settings[set].options[optionName], this.pattern.settings[set]) + const abs = conf.toAbs( + this.pattern.settings[set].options[optionName], + this.pattern.settings[set], + mergeOptions(this.pattern.settings[set], this.pattern.config.options) + ) // Handle units-specific config - Side-step immutability for the snap conf let snapConf = conf.snap if (!Array.isArray(snapConf) && snapConf.metric && snapConf.imperial) diff --git a/packages/core/src/utils.mjs b/packages/core/src/utils.mjs index 7fbc23f4e5e..e8f19c5c036 100644 --- a/packages/core/src/utils.mjs +++ b/packages/core/src/utils.mjs @@ -441,6 +441,29 @@ export function lineIntersectsCurve(start, end, from, cp1, cp2, to) { else return intersections } +/** + * Helper method to merge passed in options with default options from the pattern config + * + * @param {object} settings - The settings passed to the pattern + * @param {object} optionsConfig - The pattern's options config + * @return {object} result - An object with the merged options and their values + */ +export function mergeOptions(settings, optionsConfig) { + const merged = typeof settings.options === 'undefined' ? {} : { ...settings.option } + for (const [key, option] of Object.entries(optionsConfig)) { + if (typeof option === 'object') { + if (typeof option.pct !== 'undefined') merged[key] = option.pct / 100 + else if (typeof option.mm !== 'undefined') merged[key] = option.mm + else if (typeof option.deg !== 'undefined') merged[key] = option.deg + else if (typeof option.count !== 'undefined') merged[key] = option.count + else if (typeof option.bool !== 'undefined') merged[key] = option.bool + else if (typeof option.dflt !== 'undefined') merged[key] = option.dflt + } else merged[key] = option + } + + return merged +} + /** * Helper method to calculate abolute option value based on a measurement * diff --git a/sites/shared/components/workbench/menus/design-options/index.mjs b/sites/shared/components/workbench/menus/design-options/index.mjs index 770f4a3f517..6829d5707dd 100644 --- a/sites/shared/components/workbench/menus/design-options/index.mjs +++ b/sites/shared/components/workbench/menus/design-options/index.mjs @@ -90,7 +90,7 @@ export const DesignOptions = ({ name: 'design-options:designOptions', language, ns: menuNs, - passProps: { settings }, + passProps: { settings, patternConfig }, updateFunc: (name, value) => update.settings(['options', ...name], value), }} /> diff --git a/sites/shared/components/workbench/menus/design-options/values.mjs b/sites/shared/components/workbench/menus/design-options/values.mjs index dd935ea3867..c1f2f1909b1 100644 --- a/sites/shared/components/workbench/menus/design-options/values.mjs +++ b/sites/shared/components/workbench/menus/design-options/values.mjs @@ -1,14 +1,19 @@ import { formatMm, formatPercentage } from 'shared/utils.mjs' import { ListValue, HighlightedValue, PlainValue, BoolValue } from '../shared/values' +import { mergeOptions } from '@freesewing/core' /** Displays the current percentatge value, and the absolute value if configured */ -export const PctOptionValue = ({ config, current, settings, changed }) => { +export const PctOptionValue = ({ config, current, settings, changed, patternConfig }) => { const val = changed ? current : config.pct / 100 return ( {formatPercentage(val)} - {config.toAbs && settings.measurements ? ` | ${formatMm(config.toAbs(val, settings))}` : null} + {config.toAbs && settings.measurements + ? ` | ${formatMm( + config.toAbs(val, settings, mergeOptions(settings, patternConfig.options)) + )}` + : null} ) }