Update lower-right corner units menu to read and edit inline settings annotations if present (#5212)
* WIP show annotation length unit setting in LowerRightControls if present * Add logic for changing settings annotation if it's present * Add E2E test * Cleanup lints, fmt, tsc, logs * Change to use settings from Rust helper function - Fix thrown error to use the cause field - Fix function names to not use "get" * Remove unneeded constants * Post-merge fixups * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores) * Add back `ImportStatement` to make tsc happy (thanks @jtran!) * fmt --------- Co-authored-by: Jonathan Tran <jonnytran@gmail.com> Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -896,4 +896,53 @@ test.describe('Testing settings', () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
test(`Change inline units setting`, async ({
|
||||||
|
page,
|
||||||
|
homePage,
|
||||||
|
context,
|
||||||
|
editor,
|
||||||
|
}) => {
|
||||||
|
const initialInlineUnits = 'yd'
|
||||||
|
const editedInlineUnits = { short: 'mm', long: 'Millimeters' }
|
||||||
|
const inlineSettingsString = (s: string) =>
|
||||||
|
`@settings(defaultLengthUnit = ${s})`
|
||||||
|
const unitsIndicator = page.getByRole('button', {
|
||||||
|
name: 'Current units are:',
|
||||||
|
})
|
||||||
|
const unitsChangeButton = (name: string) =>
|
||||||
|
page.getByRole('button', { name, exact: true })
|
||||||
|
|
||||||
|
await context.folderSetupFn(async (dir) => {
|
||||||
|
const bracketDir = join(dir, 'project-000')
|
||||||
|
await fsp.mkdir(bracketDir, { recursive: true })
|
||||||
|
await fsp.copyFile(
|
||||||
|
executorInputPath('cube.kcl'),
|
||||||
|
join(bracketDir, 'main.kcl')
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step(`Initial units from settings`, async () => {
|
||||||
|
await homePage.openProject('project-000')
|
||||||
|
await expect(unitsIndicator).toHaveText('Current units are: in')
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step(`Manually write inline settings`, async () => {
|
||||||
|
await editor.openPane()
|
||||||
|
await editor.replaceCode(
|
||||||
|
`fn cube`,
|
||||||
|
`${inlineSettingsString(initialInlineUnits)}
|
||||||
|
fn cube`
|
||||||
|
)
|
||||||
|
await expect(unitsIndicator).toContainText(initialInlineUnits)
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step(`Change units setting via lower-right control`, async () => {
|
||||||
|
await unitsIndicator.click()
|
||||||
|
await unitsChangeButton(editedInlineUnits.long).click()
|
||||||
|
await expect(
|
||||||
|
page.getByText(`Updated per-file units to ${editedInlineUnits.short}`)
|
||||||
|
).toBeVisible()
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,9 +1,31 @@
|
|||||||
import { Popover } from '@headlessui/react'
|
import { Popover } from '@headlessui/react'
|
||||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||||
|
import { changeKclSettings, unitLengthToUnitLen } from 'lang/wasm'
|
||||||
import { baseUnitLabels, baseUnitsUnion } from 'lib/settings/settingsTypes'
|
import { baseUnitLabels, baseUnitsUnion } from 'lib/settings/settingsTypes'
|
||||||
|
import { codeManager, kclManager } from 'lib/singletons'
|
||||||
|
import { err, reportRejection } from 'lib/trap'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import toast from 'react-hot-toast'
|
||||||
|
|
||||||
export function UnitsMenu() {
|
export function UnitsMenu() {
|
||||||
const { settings } = useSettingsAuthContext()
|
const { settings } = useSettingsAuthContext()
|
||||||
|
const [hasPerFileLengthUnit, setHasPerFileLengthUnit] = useState(
|
||||||
|
Boolean(kclManager.fileSettings.defaultLengthUnit)
|
||||||
|
)
|
||||||
|
const [lengthSetting, setLengthSetting] = useState(
|
||||||
|
kclManager.fileSettings.defaultLengthUnit ||
|
||||||
|
settings.context.modeling.defaultUnit.current
|
||||||
|
)
|
||||||
|
useEffect(() => {
|
||||||
|
setHasPerFileLengthUnit(Boolean(kclManager.fileSettings.defaultLengthUnit))
|
||||||
|
setLengthSetting(
|
||||||
|
kclManager.fileSettings.defaultLengthUnit ||
|
||||||
|
settings.context.modeling.defaultUnit.current
|
||||||
|
)
|
||||||
|
}, [
|
||||||
|
kclManager.fileSettings.defaultLengthUnit,
|
||||||
|
settings.context.modeling.defaultUnit.current,
|
||||||
|
])
|
||||||
return (
|
return (
|
||||||
<Popover className="relative pointer-events-auto">
|
<Popover className="relative pointer-events-auto">
|
||||||
{({ close }) => (
|
{({ close }) => (
|
||||||
@ -18,7 +40,7 @@ export function UnitsMenu() {
|
|||||||
<div className="absolute w-[1px] h-[1em] bg-primary right-0 top-1/2 -translate-y-1/2"></div>
|
<div className="absolute w-[1px] h-[1em] bg-primary right-0 top-1/2 -translate-y-1/2"></div>
|
||||||
</div>
|
</div>
|
||||||
<span className="sr-only">Current units are: </span>
|
<span className="sr-only">Current units are: </span>
|
||||||
{settings.context.modeling.defaultUnit.current}
|
{lengthSetting}
|
||||||
</Popover.Button>
|
</Popover.Button>
|
||||||
<Popover.Panel
|
<Popover.Panel
|
||||||
className={`absolute bottom-full right-0 mb-2 w-48 bg-chalkboard-10 dark:bg-chalkboard-90
|
className={`absolute bottom-full right-0 mb-2 w-48 bg-chalkboard-10 dark:bg-chalkboard-90
|
||||||
@ -31,6 +53,27 @@ export function UnitsMenu() {
|
|||||||
<button
|
<button
|
||||||
className="flex items-center gap-2 m-0 py-1.5 px-2 cursor-pointer hover:bg-chalkboard-20 dark:hover:bg-chalkboard-80 border-none text-left"
|
className="flex items-center gap-2 m-0 py-1.5 px-2 cursor-pointer hover:bg-chalkboard-20 dark:hover:bg-chalkboard-80 border-none text-left"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
if (hasPerFileLengthUnit) {
|
||||||
|
const newCode = changeKclSettings(codeManager.code, {
|
||||||
|
defaultLengthUnits: unitLengthToUnitLen(unit),
|
||||||
|
defaultAngleUnits: { type: 'Degrees' },
|
||||||
|
})
|
||||||
|
if (err(newCode)) {
|
||||||
|
toast.error(
|
||||||
|
`Failed to set per-file units: ${newCode.message}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
codeManager.updateCodeStateEditor(newCode)
|
||||||
|
Promise.all([
|
||||||
|
codeManager.writeToFile(),
|
||||||
|
kclManager.executeCode(),
|
||||||
|
])
|
||||||
|
.then(() => {
|
||||||
|
toast.success(`Updated per-file units to ${unit}`)
|
||||||
|
})
|
||||||
|
.catch(reportRejection)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
settings.send({
|
settings.send({
|
||||||
type: 'set.modeling.defaultUnit',
|
type: 'set.modeling.defaultUnit',
|
||||||
data: {
|
data: {
|
||||||
@ -38,11 +81,12 @@ export function UnitsMenu() {
|
|||||||
value: unit,
|
value: unit,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
close()
|
close()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="flex-1">{baseUnitLabels[unit]}</span>
|
<span className="flex-1">{baseUnitLabels[unit]}</span>
|
||||||
{unit === settings.context.modeling.defaultUnit.current && (
|
{unit === lengthSetting && (
|
||||||
<span className="text-chalkboard-60">current</span>
|
<span className="text-chalkboard-60">current</span>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
@ -25,7 +25,7 @@ import {
|
|||||||
SourceRange,
|
SourceRange,
|
||||||
topLevelRange,
|
topLevelRange,
|
||||||
} from 'lang/wasm'
|
} from 'lang/wasm'
|
||||||
import { getNodeFromPath } from './queryAst'
|
import { getNodeFromPath, getSettingsAnnotation } from './queryAst'
|
||||||
import { codeManager, editorManager, sceneInfra } from 'lib/singletons'
|
import { codeManager, editorManager, sceneInfra } from 'lib/singletons'
|
||||||
import { Diagnostic } from '@codemirror/lint'
|
import { Diagnostic } from '@codemirror/lint'
|
||||||
import { markOnce } from 'lib/performance'
|
import { markOnce } from 'lib/performance'
|
||||||
@ -35,6 +35,7 @@ import {
|
|||||||
ModelingCmdReq_type,
|
ModelingCmdReq_type,
|
||||||
} from '@kittycad/lib/dist/types/src/models'
|
} from '@kittycad/lib/dist/types/src/models'
|
||||||
import { Operation } from 'wasm-lib/kcl/bindings/Operation'
|
import { Operation } from 'wasm-lib/kcl/bindings/Operation'
|
||||||
|
import { KclSettingsAnnotation } from 'lib/settings/settingsTypes'
|
||||||
|
|
||||||
interface ExecuteArgs {
|
interface ExecuteArgs {
|
||||||
ast?: Node<Program>
|
ast?: Node<Program>
|
||||||
@ -70,6 +71,7 @@ export class KclManager {
|
|||||||
private _wasmInitFailed = true
|
private _wasmInitFailed = true
|
||||||
private _hasErrors = false
|
private _hasErrors = false
|
||||||
private _switchedFiles = false
|
private _switchedFiles = false
|
||||||
|
private _fileSettings: KclSettingsAnnotation = {}
|
||||||
|
|
||||||
engineCommandManager: EngineCommandManager
|
engineCommandManager: EngineCommandManager
|
||||||
|
|
||||||
@ -368,6 +370,13 @@ export class KclManager {
|
|||||||
await this.disableSketchMode()
|
await this.disableSketchMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let fileSettings = getSettingsAnnotation(ast)
|
||||||
|
if (err(fileSettings)) {
|
||||||
|
console.error(fileSettings)
|
||||||
|
fileSettings = {}
|
||||||
|
}
|
||||||
|
this.fileSettings = fileSettings
|
||||||
|
|
||||||
this.logs = logs
|
this.logs = logs
|
||||||
this.errors = errors
|
this.errors = errors
|
||||||
// Do not add the errors since the program was interrupted and the error is not a real KCL error
|
// Do not add the errors since the program was interrupted and the error is not a real KCL error
|
||||||
@ -699,6 +708,14 @@ export class KclManager {
|
|||||||
_isAstEmpty(ast: Node<Program>) {
|
_isAstEmpty(ast: Node<Program>) {
|
||||||
return ast.start === 0 && ast.end === 0 && ast.body.length === 0
|
return ast.start === 0 && ast.end === 0 && ast.body.length === 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get fileSettings() {
|
||||||
|
return this._fileSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
set fileSettings(settings: KclSettingsAnnotation) {
|
||||||
|
this._fileSettings = settings
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultSelectionFilter: EntityType_type[] = [
|
const defaultSelectionFilter: EntityType_type[] = [
|
||||||
|
@ -23,6 +23,9 @@ import {
|
|||||||
VariableDeclaration,
|
VariableDeclaration,
|
||||||
VariableDeclarator,
|
VariableDeclarator,
|
||||||
recast,
|
recast,
|
||||||
|
kclSettings,
|
||||||
|
unitLenToUnitLength,
|
||||||
|
unitAngToUnitAngle,
|
||||||
} from './wasm'
|
} from './wasm'
|
||||||
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
||||||
import { createIdentifier, splitPathAtLastIndex } from './modifyAst'
|
import { createIdentifier, splitPathAtLastIndex } from './modifyAst'
|
||||||
@ -38,6 +41,7 @@ import { ImportStatement } from 'wasm-lib/kcl/bindings/ImportStatement'
|
|||||||
import { Node } from 'wasm-lib/kcl/bindings/Node'
|
import { Node } from 'wasm-lib/kcl/bindings/Node'
|
||||||
import { findKwArg } from './util'
|
import { findKwArg } from './util'
|
||||||
import { codeRefFromRange } from './std/artifactGraph'
|
import { codeRefFromRange } from './std/artifactGraph'
|
||||||
|
import { KclSettingsAnnotation } from 'lib/settings/settingsTypes'
|
||||||
|
|
||||||
export const LABELED_ARG_FIELD = 'LabeledArg -> Arg'
|
export const LABELED_ARG_FIELD = 'LabeledArg -> Arg'
|
||||||
export const ARG_INDEX_FIELD = 'arg index'
|
export const ARG_INDEX_FIELD = 'arg index'
|
||||||
@ -866,3 +870,24 @@ export function getObjExprProperty(
|
|||||||
if (index === -1) return null
|
if (index === -1) return null
|
||||||
return { expr: node.properties[index].value, index }
|
return { expr: node.properties[index].value, index }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given KCL, returns the settings annotation object if it exists.
|
||||||
|
*/
|
||||||
|
export function getSettingsAnnotation(
|
||||||
|
kcl: string | Node<Program>
|
||||||
|
): KclSettingsAnnotation | Error {
|
||||||
|
const metaSettings = kclSettings(kcl)
|
||||||
|
if (err(metaSettings)) return metaSettings
|
||||||
|
|
||||||
|
const settings: KclSettingsAnnotation = {}
|
||||||
|
// No settings in the KCL.
|
||||||
|
if (!metaSettings) return settings
|
||||||
|
|
||||||
|
settings.defaultLengthUnit = unitLenToUnitLength(
|
||||||
|
metaSettings.defaultLengthUnits
|
||||||
|
)
|
||||||
|
settings.defaultAngleUnit = unitAngToUnitAngle(metaSettings.defaultAngleUnits)
|
||||||
|
|
||||||
|
return settings
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
default_project_settings,
|
default_project_settings,
|
||||||
base64_decode,
|
base64_decode,
|
||||||
clear_scene_and_bust_cache,
|
clear_scene_and_bust_cache,
|
||||||
|
kcl_settings,
|
||||||
change_kcl_settings,
|
change_kcl_settings,
|
||||||
reloadModule,
|
reloadModule,
|
||||||
} from 'lib/wasm_lib_wrapper'
|
} from 'lib/wasm_lib_wrapper'
|
||||||
@ -58,6 +59,9 @@ import { Artifact } from './std/artifactGraph'
|
|||||||
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
import { getNodePathFromSourceRange } from 'lang/queryAstNodePathUtils'
|
||||||
import { NumericSuffix } from 'wasm-lib/kcl/bindings/NumericSuffix'
|
import { NumericSuffix } from 'wasm-lib/kcl/bindings/NumericSuffix'
|
||||||
import { MetaSettings } from 'wasm-lib/kcl/bindings/MetaSettings'
|
import { MetaSettings } from 'wasm-lib/kcl/bindings/MetaSettings'
|
||||||
|
import { UnitAngle, UnitLength } from 'wasm-lib/kcl/bindings/ModelingCmd'
|
||||||
|
import { UnitLen } from 'wasm-lib/kcl/bindings/UnitLen'
|
||||||
|
import { UnitAngle as UnitAng } from 'wasm-lib/kcl/bindings/UnitAngle'
|
||||||
|
|
||||||
export type { Artifact } from 'wasm-lib/kcl/bindings/Artifact'
|
export type { Artifact } from 'wasm-lib/kcl/bindings/Artifact'
|
||||||
export type { ArtifactCommand } from 'wasm-lib/kcl/bindings/Artifact'
|
export type { ArtifactCommand } from 'wasm-lib/kcl/bindings/Artifact'
|
||||||
@ -857,8 +861,35 @@ export function base64Decode(base64: string): ArrayBuffer | Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change the meta settings for the kcl file.
|
/**
|
||||||
/// Returns the new kcl string with the updated settings.
|
* Get the meta settings for the KCL. If no settings were set in the file,
|
||||||
|
* returns null.
|
||||||
|
*/
|
||||||
|
export function kclSettings(
|
||||||
|
kcl: string | Node<Program>
|
||||||
|
): MetaSettings | null | Error {
|
||||||
|
let program: Node<Program>
|
||||||
|
if (typeof kcl === 'string') {
|
||||||
|
const parseResult = parse(kcl)
|
||||||
|
if (err(parseResult)) return parseResult
|
||||||
|
if (!resultIsOk(parseResult)) {
|
||||||
|
return new Error(`parse result had errors`, { cause: parseResult })
|
||||||
|
}
|
||||||
|
program = parseResult.program
|
||||||
|
} else {
|
||||||
|
program = kcl
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return kcl_settings(JSON.stringify(program))
|
||||||
|
} catch (e) {
|
||||||
|
return new Error('Caught error getting kcl settings', { cause: e })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the meta settings for the kcl file.
|
||||||
|
* @returns the new kcl string with the updated settings.
|
||||||
|
*/
|
||||||
export function changeKclSettings(
|
export function changeKclSettings(
|
||||||
kcl: string,
|
kcl: string,
|
||||||
settings: MetaSettings
|
settings: MetaSettings
|
||||||
@ -866,7 +897,59 @@ export function changeKclSettings(
|
|||||||
try {
|
try {
|
||||||
return change_kcl_settings(kcl, JSON.stringify(settings))
|
return change_kcl_settings(kcl, JSON.stringify(settings))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Caught error changing kcl settings: ' + e)
|
console.error('Caught error changing kcl settings', e)
|
||||||
return new Error('Caught error changing kcl settings: ' + e)
|
return new Error('Caught error changing kcl settings', { cause: e })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a `UnitLength_type` to a `UnitLen`
|
||||||
|
*/
|
||||||
|
export function unitLengthToUnitLen(input: UnitLength): UnitLen {
|
||||||
|
switch (input) {
|
||||||
|
case 'm':
|
||||||
|
return { type: 'M' }
|
||||||
|
case 'cm':
|
||||||
|
return { type: 'Cm' }
|
||||||
|
case 'yd':
|
||||||
|
return { type: 'Yards' }
|
||||||
|
case 'ft':
|
||||||
|
return { type: 'Feet' }
|
||||||
|
case 'in':
|
||||||
|
return { type: 'Inches' }
|
||||||
|
default:
|
||||||
|
return { type: 'Mm' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert `UnitLen` to `UnitLength_type`.
|
||||||
|
*/
|
||||||
|
export function unitLenToUnitLength(input: UnitLen): UnitLength {
|
||||||
|
switch (input.type) {
|
||||||
|
case 'M':
|
||||||
|
return 'm'
|
||||||
|
case 'Cm':
|
||||||
|
return 'cm'
|
||||||
|
case 'Yards':
|
||||||
|
return 'yd'
|
||||||
|
case 'Feet':
|
||||||
|
return 'ft'
|
||||||
|
case 'Inches':
|
||||||
|
return 'in'
|
||||||
|
default:
|
||||||
|
return 'mm'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert `UnitAngle` to `UnitAngle_type`.
|
||||||
|
*/
|
||||||
|
export function unitAngToUnitAngle(input: UnitAng): UnitAngle {
|
||||||
|
switch (input.type) {
|
||||||
|
case 'Radians':
|
||||||
|
return 'radians'
|
||||||
|
default:
|
||||||
|
return 'degrees'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,10 @@ import { AtLeast, PathValue, Paths } from 'lib/types'
|
|||||||
import { CommandArgumentConfig } from 'lib/commandTypes'
|
import { CommandArgumentConfig } from 'lib/commandTypes'
|
||||||
import { Themes } from 'lib/theme'
|
import { Themes } from 'lib/theme'
|
||||||
import { CameraProjectionType } from 'wasm-lib/kcl/bindings/CameraProjectionType'
|
import { CameraProjectionType } from 'wasm-lib/kcl/bindings/CameraProjectionType'
|
||||||
|
import {
|
||||||
|
UnitAngle_type,
|
||||||
|
UnitLength_type,
|
||||||
|
} from '@kittycad/lib/dist/types/src/models'
|
||||||
import { CameraOrbitType } from 'wasm-lib/kcl/bindings/CameraOrbitType'
|
import { CameraOrbitType } from 'wasm-lib/kcl/bindings/CameraOrbitType'
|
||||||
|
|
||||||
export interface SettingsViaQueryString {
|
export interface SettingsViaQueryString {
|
||||||
@ -138,3 +142,12 @@ type RecursiveSettingsPayloads<T> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type SaveSettingsPayload = RecursiveSettingsPayloads<typeof settings>
|
export type SaveSettingsPayload = RecursiveSettingsPayloads<typeof settings>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation names for default units are defined on rust side in
|
||||||
|
* src/wasm-lib/kcl/src/execution/annotations.rs
|
||||||
|
*/
|
||||||
|
export interface KclSettingsAnnotation {
|
||||||
|
defaultLengthUnit?: UnitLength_type
|
||||||
|
defaultAngleUnit?: UnitAngle_type
|
||||||
|
}
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
default_project_settings as DefaultProjectSettings,
|
default_project_settings as DefaultProjectSettings,
|
||||||
base64_decode as Base64Decode,
|
base64_decode as Base64Decode,
|
||||||
clear_scene_and_bust_cache as ClearSceneAndBustCache,
|
clear_scene_and_bust_cache as ClearSceneAndBustCache,
|
||||||
|
kcl_settings as KclSettings,
|
||||||
change_kcl_settings as ChangeKclSettings,
|
change_kcl_settings as ChangeKclSettings,
|
||||||
} from '../wasm-lib/pkg/wasm_lib'
|
} from '../wasm-lib/pkg/wasm_lib'
|
||||||
|
|
||||||
@ -111,6 +112,9 @@ export const clear_scene_and_bust_cache: typeof ClearSceneAndBustCache = (
|
|||||||
) => {
|
) => {
|
||||||
return getModule().clear_scene_and_bust_cache(...args)
|
return getModule().clear_scene_and_bust_cache(...args)
|
||||||
}
|
}
|
||||||
|
export const kcl_settings: typeof KclSettings = (...args) => {
|
||||||
|
return getModule().kcl_settings(...args)
|
||||||
|
}
|
||||||
export const change_kcl_settings: typeof ChangeKclSettings = (...args) => {
|
export const change_kcl_settings: typeof ChangeKclSettings = (...args) => {
|
||||||
return getModule().change_kcl_settings(...args)
|
return getModule().change_kcl_settings(...args)
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ impl Program {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the meta settings for the kcl file from the annotations.
|
/// Get the meta settings for the kcl file from the annotations.
|
||||||
pub fn get_meta_settings(&self) -> Result<Option<crate::MetaSettings>, KclError> {
|
pub fn meta_settings(&self) -> Result<Option<crate::MetaSettings>, KclError> {
|
||||||
self.ast.get_meta_settings()
|
self.ast.get_meta_settings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,6 +539,18 @@ pub fn calculate_circle_from_3_points(ax: f64, ay: f64, bx: f64, by: f64, cx: f6
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Takes a parsed KCL program and returns the Meta settings. If it's not
|
||||||
|
/// found, null is returned.
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn kcl_settings(program_json: &str) -> Result<JsValue, String> {
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
let program: Program = serde_json::from_str(program_json).map_err(|e| e.to_string())?;
|
||||||
|
let settings = program.meta_settings().map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
JsValue::from_serde(&settings).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
/// Takes a kcl string and Meta settings and changes the meta settings in the kcl string.
|
/// Takes a kcl string and Meta settings and changes the meta settings in the kcl string.
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn change_kcl_settings(code: &str, settings_str: &str) -> Result<String, String> {
|
pub fn change_kcl_settings(code: &str, settings_str: &str) -> Result<String, String> {
|
||||||
|
Reference in New Issue
Block a user