From b36cee93f7e86b003e65b438caee14bdd24b976c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 30 Sep 2023 21:22:49 +0200 Subject: [PATCH] add slider function to scope --- packages/codemirror/index.mjs | 1 + packages/codemirror/slider.mjs | 25 +++++++++++++++++++++++-- packages/transpiler/transpiler.mjs | 10 ++++++---- website/src/repl/Repl.jsx | 1 + 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/packages/codemirror/index.mjs b/packages/codemirror/index.mjs index bf7ce971..c847c32c 100644 --- a/packages/codemirror/index.mjs +++ b/packages/codemirror/index.mjs @@ -1,3 +1,4 @@ export * from './codemirror.mjs'; export * from './highlight.mjs'; export * from './flash.mjs'; +export * from './slider.mjs'; diff --git a/packages/codemirror/slider.mjs b/packages/codemirror/slider.mjs index 2e75959b..7695cee6 100644 --- a/packages/codemirror/slider.mjs +++ b/packages/codemirror/slider.mjs @@ -13,7 +13,12 @@ export class SliderWidget extends WidgetType { } eq(other) { - const isSame = other.value.toFixed(4) == this.value.toFixed(4) && other.min == this.min && other.max == this.max; + const isSame = + other.value.toFixed(4) == this.value.toFixed(4) && + other.min == this.min && + other.max == this.max && + other.from === this.from && + other.to === this.to; return isSame; } @@ -152,6 +157,22 @@ function updateSliderValue(view, e) { let change = { from: draggedSlider.from, to: draggedSlider.to, insert }; draggedSlider.to = draggedSlider.from + insert.length; view.dispatch({ changes: change }); - window.postMessage({ type: 'cm-slider', value: next, loc: draggedSlider.from }); + const id = 'slider_' + draggedSlider.from; // matches id generated in transpiler + window.postMessage({ type: 'cm-slider', value: next, id }); return true; } + +export let sliderValues = {}; + +export let slider = (id, value, min, max) => { + sliderValues[id] = value; // sync state at eval time (code -> state) + return ref(() => sliderValues[id]); // use state at query time +}; +if (typeof window !== 'undefined') { + window.addEventListener('message', (e) => { + if (e.data.type === 'cm-slider') { + // update state when slider is moved + sliderValues[e.data.id] = e.data.value; + } + }); +} diff --git a/packages/transpiler/transpiler.mjs b/packages/transpiler/transpiler.mjs index 9ff558cb..28f7fdfa 100644 --- a/packages/transpiler/transpiler.mjs +++ b/packages/transpiler/transpiler.mjs @@ -98,18 +98,20 @@ function miniWithLocation(value, node) { }; } +// these functions are connected to @strudel/codemirror -> slider.mjs +// maybe someday there will be pluggable transpiler functions, then move this there function isWidgetFunction(node) { return node.type === 'CallExpression' && node.callee.name === 'slider'; } function widgetWithLocation(node) { - const loc = node.arguments[0].start; + const id = 'slider_' + node.arguments[0].start; // use loc of first arg for id // add loc as identifier to first argument - // the slider function is assumed to be slider(loc, value, min?, max?) + // the slider function is assumed to be slider(id, value, min?, max?) node.arguments.unshift({ type: 'Literal', - value: loc, - raw: loc + '', + value: id, + raw: id, }); return node; } diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index 4002eba8..9d80cc53 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -39,6 +39,7 @@ let modules = [ import('@strudel.cycles/mini'), import('@strudel.cycles/xen'), import('@strudel.cycles/webaudio'), + import('@strudel/codemirror'), import('@strudel.cycles/serial'), import('@strudel.cycles/soundfonts'),