From 48e0691eec3f0a5496258ce0bc52336a8ba01774 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 15 Mar 2024 01:40:21 +0100 Subject: [PATCH] add pianoroll widget --- packages/codemirror/widget.mjs | 19 ++++++++++++------- packages/draw/draw.mjs | 4 ++-- packages/draw/pianoroll.mjs | 3 ++- packages/widgets/Claviature.jsx | 24 +++++++++++------------- packages/widgets/Pianoroll.jsx | 30 ++++++++++++++++++++++++++++++ packages/widgets/index.mjs | 1 + packages/widgets/package.json | 1 + pnpm-lock.yaml | 3 +++ 8 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 packages/widgets/Pianoroll.jsx diff --git a/packages/codemirror/widget.mjs b/packages/codemirror/widget.mjs index 3171d0df..c0bd9a24 100644 --- a/packages/codemirror/widget.mjs +++ b/packages/codemirror/widget.mjs @@ -14,13 +14,18 @@ export const updateWidgets = (view, widgets) => { }; function getWidgets(widgetConfigs) { - return widgetConfigs.map(({ to, type }) => { - return Decoration.widget({ - widget: new BlockWidget(to, type), - side: 0, - block: true, - }).range(to); - }); + return ( + widgetConfigs + // codemirror throws an error if we don't sort + .sort((a, b) => a.to - b.to) + .map(({ to, type }) => { + return Decoration.widget({ + widget: new BlockWidget(to, type), + side: 0, + block: true, + }).range(to); + }) + ); } const widgetField = StateField.define( diff --git a/packages/draw/draw.mjs b/packages/draw/draw.mjs index 2ea531cf..63245baf 100644 --- a/packages/draw/draw.mjs +++ b/packages/draw/draw.mjs @@ -29,14 +29,14 @@ export const getDrawContext = (id = 'test-canvas', options) => { return canvas.getContext(contextType); }; -Pattern.prototype.draw = function (callback, { from, to, onQuery } = {}) { +Pattern.prototype.draw = function (callback, { from, to, onQuery, ctx } = {}) { if (typeof window === 'undefined') { return this; } if (window.strudelAnimation) { cancelAnimationFrame(window.strudelAnimation); } - const ctx = getDrawContext(); + ctx = ctx || getDrawContext(); let cycle, events = []; const animate = (time) => { diff --git a/packages/draw/pianoroll.mjs b/packages/draw/pianoroll.mjs index 74b1480e..b032ef1a 100644 --- a/packages/draw/pianoroll.mjs +++ b/packages/draw/pianoroll.mjs @@ -30,7 +30,7 @@ const getValue = (e) => { }; Pattern.prototype.pianoroll = function (options = {}) { - let { cycles = 4, playhead = 0.5, overscan = 1, hideNegative = false } = options; + let { cycles = 4, playhead = 0.5, overscan = 1, hideNegative = false, ctx } = options; let from = -cycles * playhead; let to = cycles * (1 - playhead); @@ -49,6 +49,7 @@ Pattern.prototype.pianoroll = function (options = {}) { { from: from - overscan, to: to + overscan, + ctx, }, ); return this; diff --git a/packages/widgets/Claviature.jsx b/packages/widgets/Claviature.jsx index e4ebfec6..33777be4 100644 --- a/packages/widgets/Claviature.jsx +++ b/packages/widgets/Claviature.jsx @@ -17,19 +17,17 @@ customElement('strudel-claviature', { options: JSON.stringify(defaultOptions) }, return c; }; return ( -
- - - {(el) => { - return ( - - {el.value} - - ); - }} - - -
+ + + {(el) => { + return ( + + {el.value} + + ); + }} + + ); }); diff --git a/packages/widgets/Pianoroll.jsx b/packages/widgets/Pianoroll.jsx new file mode 100644 index 00000000..bf7c145c --- /dev/null +++ b/packages/widgets/Pianoroll.jsx @@ -0,0 +1,30 @@ +import { Pattern } from '@strudel/core'; +import { registerWidget } from '@strudel/transpiler'; +import { customElement } from 'solid-element'; + +customElement('strudel-pianoroll', { options: JSON.stringify('{}') }, (props, { element }) => { + return ; +}); + +registerWidget('roll', 'strudel-pianoroll'); + +Pattern.prototype.roll = function (id, options = { fold: 1 }) { + // TODO: remove setTimeout... + setTimeout(() => { + let el = document.getElementById(id); + if (!el) { + console.log('widget not found...'); + return this; + } + const { width = 400, height = 100 } = options; + const canvas = el?.shadowRoot.firstChild; + const pixelRatio = window.devicePixelRatio; + canvas.width = width * pixelRatio; + canvas.height = height * pixelRatio; + canvas.style.width = width + 'px'; + canvas.style.height = height + 'px'; + const ctx = canvas.getContext('2d'); + this.pianoroll({ ...options, ctx }); + }); + return this; +}; diff --git a/packages/widgets/index.mjs b/packages/widgets/index.mjs index 281c6ab8..80d01ab5 100644 --- a/packages/widgets/index.mjs +++ b/packages/widgets/index.mjs @@ -1 +1,2 @@ export * from './Claviature.jsx'; +export * from './Pianoroll.jsx'; diff --git a/packages/widgets/package.json b/packages/widgets/package.json index 213ae526..c77c2712 100644 --- a/packages/widgets/package.json +++ b/packages/widgets/package.json @@ -29,6 +29,7 @@ "dependencies": { "@strudel/core": "workspace:*", "@strudel/transpiler": "workspace:*", + "@strudel/draw": "workspace:*", "claviature": "^0.1.0", "solid-element": "^1.8.0", "solid-js": "^1.8.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ceaf3d9..ee159ab2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -493,6 +493,9 @@ importers: '@strudel/core': specifier: workspace:* version: link:../core + '@strudel/draw': + specifier: workspace:* + version: link:../draw '@strudel/transpiler': specifier: workspace:* version: link:../transpiler