From 632bc3fee7ffabef299cf7567a2bb0a92001d908 Mon Sep 17 00:00:00 2001 From: trian-gles <69212477+trian-gles@users.noreply.github.com> Date: Wed, 3 Jul 2024 12:41:37 +0200 Subject: [PATCH] working UI --- example.maxpat | 234 + lfogui.html | 84 + lfogui.js | 166 + react-dom.js | 29924 +++++++++++++++++++++++++++++++++++++++++++++++ react.js | 3343 ++++++ 5 files changed, 33751 insertions(+) create mode 100644 example.maxpat create mode 100644 lfogui.html create mode 100644 lfogui.js create mode 100644 react-dom.js create mode 100644 react.js diff --git a/example.maxpat b/example.maxpat new file mode 100644 index 0000000..2593b7a --- /dev/null +++ b/example.maxpat @@ -0,0 +1,234 @@ +{ + "patcher" : { + "fileversion" : 1, + "appversion" : { + "major" : 8, + "minor" : 6, + "revision" : 2, + "architecture" : "x64", + "modernui" : 1 + } +, + "classnamespace" : "box", + "rect" : [ 134.0, 134.0, 922.0, 715.0 ], + "bglocked" : 0, + "openinpresentation" : 0, + "default_fontsize" : 12.0, + "default_fontface" : 0, + "default_fontname" : "Arial", + "gridonopen" : 1, + "gridsize" : [ 15.0, 15.0 ], + "gridsnaponopen" : 1, + "objectsnaponopen" : 1, + "statusbarvisible" : 2, + "toolbarvisible" : 1, + "lefttoolbarpinned" : 0, + "toptoolbarpinned" : 0, + "righttoolbarpinned" : 0, + "bottomtoolbarpinned" : 0, + "toolbars_unpinned_last_save" : 0, + "tallnewobj" : 0, + "boxanimatetime" : 200, + "enablehscroll" : 1, + "enablevscroll" : 1, + "devicewidth" : 0.0, + "description" : "", + "digest" : "", + "tags" : "", + "style" : "", + "subpatcher_template" : "", + "assistshowspatchername" : 0, + "boxes" : [ { + "box" : { + "id" : "obj-6", + "linecount" : 2, + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 488.0, 6.0, 150.0, 34.0 ], + "text" : "required due to the asynchronous operation" + } + + } +, { + "box" : { + "id" : "obj-3", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 493.0, 42.0, 55.0, 22.0 ], + "text" : "del 1000" + } + + } +, { + "box" : { + "id" : "obj-45", + "maxclass" : "comment", + "numinlets" : 1, + "numoutlets" : 0, + "patching_rect" : [ 681.0, 43.0, 150.0, 20.0 ], + "text" : "Storage for the matrix" + } + + } +, { + "box" : { + "id" : "obj-20", + "maxclass" : "newobj", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "bang" ], + "patching_rect" : [ 217.0, 6.0, 58.0, 22.0 ], + "text" : "loadbang" + } + + } +, { + "box" : { + "id" : "obj-14", + "maxclass" : "message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 575.0, 69.0, 39.0, 22.0 ], + "text" : "dump" + } + + } +, { + "box" : { + "data" : { + "foo" : { + "lfos" : [ "0.2", "1", "3" ], + "matrix" : [ [ "90", "10", "48" ], [ "5", "3", "251" ], [ "-61", "8", "98" ] ], + "paramNames" : [ "carrierFreq", "modFreq", "modDepth" ] + } + + } +, + "id" : "obj-4", + "maxclass" : "newobj", + "numinlets" : 2, + "numoutlets" : 5, + "outlettype" : [ "dictionary", "", "", "", "" ], + "patching_rect" : [ 681.0, 69.0, 159.0, 22.0 ], + "saved_object_attributes" : { + "embed" : 1, + "legacy" : 0, + "parameter_enable" : 0, + "parameter_mappable" : 0 + } +, + "text" : "dict localStorage @embed 1" + } + + } +, { + "box" : { + "id" : "obj-13", + "maxclass" : "message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 493.0, 69.0, 51.0, 22.0 ], + "text" : "load foo" + } + + } +, { + "box" : { + "id" : "obj-12", + "maxclass" : "message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 426.0, 69.0, 54.0, 22.0 ], + "text" : "save foo" + } + + } +, { + "box" : { + "id" : "obj-18", + "maxclass" : "message", + "numinlets" : 2, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 217.0, 69.0, 106.0, 22.0 ], + "text" : "readfile lfogui.html" + } + + } +, { + "box" : { + "id" : "obj-2", + "maxclass" : "jweb", + "numinlets" : 1, + "numoutlets" : 1, + "outlettype" : [ "" ], + "patching_rect" : [ 443.0, 124.0, 428.0, 246.0 ], + "rendermode" : 0, + "url" : "file://lfogui.html" + } + + } + ], + "lines" : [ { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "source" : [ "obj-12", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "source" : [ "obj-13", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "source" : [ "obj-14", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-2", 0 ], + "source" : [ "obj-18", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-18", 0 ], + "order" : 1, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-3", 0 ], + "order" : 0, + "source" : [ "obj-20", 0 ] + } + + } +, { + "patchline" : { + "destination" : [ "obj-13", 0 ], + "source" : [ "obj-3", 0 ] + } + + } + ], + "dependency_cache" : [ ], + "autosave" : 0 + } + +} diff --git a/lfogui.html b/lfogui.html new file mode 100644 index 0000000..1e11878 --- /dev/null +++ b/lfogui.html @@ -0,0 +1,84 @@ + + + + + +
+ + + + + + + + + + + + + diff --git a/lfogui.js b/lfogui.js new file mode 100644 index 0000000..0ec67df --- /dev/null +++ b/lfogui.js @@ -0,0 +1,166 @@ +// const { createElement } = require("./react"); + +const log = console.log; +// const log = window.max.outlet; + +const e = React.createElement; + +let lfos = []; +const MAXLFOS = 20; + +const SHAPETYPES = ["Sine", "SawUp", "SawDown", "Tri", "Square"]; +const PARAMOPTIONS = ["attenuation", "melody_scope"]; + + + +function DropDown(props) { + return e('select', {type: "number", onChange: props.onChange, value: props.value}, + ...props.options.map((item) => Option(item))); +} + +function ListItem(child){ + return e('li', null, child) +} + +function NumberBox(props){ + return e('input', {type: "number", onChange: props.onChange, value: props.value}, null); +} + +function Option(str){ + return e("option", null, str); +} + +function ControlType(){ + return e('select', {className: 'control-type'}, Option("LFO")); +} + +function LfoShape(){ + return e('select', {className: 'lfo-shape'}, Option("Sine"), Option("SawUp"), Option("SawDown"), Option("Tri"), Option("Square")); +} + +function ParamName(){ + return e('select', {className: 'param-name'}, Option("djParam"), Option("melody_scope")); +} + +function LfoRow(props){ + let content = e('ul', {className: 'lfo-item'}, + ListItem(ControlType()), + ListItem(DropDown({onChange: props.setShape, value:props.shape, options: SHAPETYPES})), + ListItem(DropDown({onChange: props.setDjParam, value: props.djParam, options: PARAMOPTIONS})), + ListItem(e(NumberBox, {onChange:props.setFreq, value:props.freq}, null)), + ListItem(e(NumberBox, {onChange:props.setAmp, value:props.amp}, null)), + ListItem(e(NumberBox, {onChange:props.setPhase, value:props.phase}, null)), + ListItem(e(Button, {text:'+', onClick: props.addLfo}, null)), + ListItem(e(Button, {text:'-', onClick: props.removeLfo}, null)) + ); + if (props.visible){ + return content + } + ; + + +} + +function Button(props){ + return e('button', {onClick: props.onClick}, props.text); +} + +function MasterLfoHandler(){ + + let initVisArr = Array(MAXLFOS).fill(false); + initVisArr[0] = true; + const [visibleArr, setVisibleArr] = React.useState(initVisArr); + + const [shapeArr, setShapeArr] = React.useState(Array(MAXLFOS).fill('Sine')); + const [djParamArr, setDjParamArr] = React.useState(Array(MAXLFOS).fill('djParam')); + + const [freqArr, setFreqArr] = React.useState(Array(MAXLFOS).fill('1')); + const [ampArr, setAmpArr] = React.useState(Array(MAXLFOS).fill('1')); + const [phaseArr, setPhaseArr] = React.useState(Array(MAXLFOS).fill('0')); + + const allArrays = [visibleArr, shapeArr, djParamArr, freqArr, ampArr, phaseArr]; + const allSetters = [setVisibleArr, setShapeArr, setDjParamArr, setFreqArr, setAmpArr, setPhaseArr]; + const blankVals = [true, 'Sine', '1', '1', '0']; + + + createParamChanger = (arr, setArr, index) => { + return (event) => { + let newArr = arr.slice(); + newArr[index] = event.target.value; + setArr(newArr); + log(`${index} ${event.target.value}`); + } + } + + + + + log("Rendering") + let contents = [] + for (var i = 0; i