[{"data":1,"prerenderedAt":39},["ShallowReactive",2],{"project-omx-panel-modgui":3},{"page":4,"others":17},{"slug":5,"src":6,"title":7,"source":8,"toc":9,"html":16},"modgui","docs\u002Fmodgui.md","The MOD GUI generator","https:\u002F\u002Fgithub.com\u002FFreeMixer\u002Fomx-panel\u002Fblob\u002Fedaf4f48de7e57496ead1b949f754b7e111867e3\u002Fdocs\u002Fmodgui.md",[10,13],{"id":11,"title":12},"the-look","The look",{"id":14,"title":15},"the-test","The test","\u003Ch1 id=\"the-mod-gui-generator\">The MOD GUI generator\u003C\u002Fh1>\n\u003Cp>\u003Ccode>tools\u002Fmodgui-gen.mjs\u003C\u002Fcode> writes a MOD GUI (MOD Devices' modgui, the format MOD and Zynthian draw) for one plugin,\nfrom its \u003Cstrong>descriptor\u003C\u002Fstrong> (omx-contract \u003Ccode>docs\u002Fdescriptors.md\u003C\u002Fcode>) and, when the plugin declares one, its \u003Cstrong>panel\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>omx-panel modgui --descriptor &lt;file&gt; | --installed &lt;package&gt;\u002F&lt;name&gt;\n                 [--panel &lt;file&gt;] --out &lt;bundle.lv2&gt; [--stem &lt;name&gt;] [--source &lt;text&gt;] [--easy-first] [--check | --emit-stdout]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cul>\n\u003Cli>\u003Ccode>--descriptor\u003C\u002Fcode> names a descriptor file; \u003Ccode>--installed omx-plugins\u002Fomx-delay\u003C\u002Fcode> reads the one a package installed into\nomx-contract's contract directory (\u003Ccode>&lt;contractdir&gt;\u002F3\u002F&lt;package&gt;\u002Fplugins\u002F&lt;name&gt;.json\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>\u003Ccode>--panel\u003C\u002Fcode> names a JSON file holding the declared panel: \u003Ccode>family\u003C\u002Fcode>, \u003Ccode>sections\u003C\u002Fcode> (each \u003Ccode>key\u003C\u002Fcode>, \u003Ccode>label\u003C\u002Fcode>, \u003Ccode>controls\u003C\u002Fcode> by\nsymbol) and, optionally, \u003Ccode>widgets\u003C\u002Fcode> (symbol to \u003Ccode>knob\u003C\u002Fcode>, \u003Ccode>fader\u003C\u002Fcode>, \u003Ccode>switch\u003C\u002Fcode> or \u003Ccode>selector\u003C\u002Fcode>, the list in\n\u003Ccode>schema\u002Fpanel.schema.json\u003C\u002Fcode>) and \u003Ccode>easy\u003C\u002Fcode> (the controls of the Easy face). With none, the sections are the descriptor's groups, laid out by\n\u003Ccode>tools\u002Fpanel-description.mjs\u003C\u002Fcode>, and the family the one their meanings make.\u003C\u002Fli>\n\u003Cli>\u003Ccode>--out\u003C\u002Fcode> is the LV2 bundle the files go into: \u003Ccode>modgui.ttl\u003C\u002Fcode> and \u003Ccode>modgui\u002F\u003C\u002Fcode>. \u003Ccode>--stem\u003C\u002Fcode> names the files\n(\u003Ccode>icon-&lt;stem&gt;.html\u003C\u002Fcode>, \u003Ccode>stylesheet-&lt;stem&gt;.css\u003C\u002Fcode>, \u003Ccode>screenshot-&lt;stem&gt;.png\u003C\u002Fcode>, \u003Ccode>thumbnail-&lt;stem&gt;.png\u003C\u002Fcode>); it defaults to\nthe bundle's name without \u003Ccode>.lv2\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Ccode>--source\u003C\u002Fcode> is the text the files' banner names as what they were made from; it defaults to the descriptor and\nthe panel files.\u003C\u002Fli>\n\u003Cli>\u003Ccode>--check\u003C\u002Fcode> writes nothing and refuses a stale, missing or extra file byte for byte; \u003Ccode>--emit-stdout\u003C\u002Fcode> prints every\ntext file and one digest line per image.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Every control's symbol, travel, default and label is the descriptor's. A toggle is a switch; a choice, or an\ninteger travel of at most 16 steps, a selector over its values; every other travel a knob. The template lays out\nevery section and every control; \u003Ccode>modgui.ttl\u003C\u002Fcode> lists the input controls of the first section as \u003Ccode>modgui:port\u003C\u002Fcode>. With \u003Ccode>--easy-first\u003C\u002Fcode> the Easy controls (\u003Ca href=\"\u002Fprojects\u002Fomx-panel\u002Fpanel-layout\">panel-layout.md\u003C\u002Fa>) are that first section, so a pedal's listed ports are them; a plugin's package turns it on when it regenerates its committed files, and \u003Ccode>omx-modgui-sync\u003C\u002Fcode> always does.\u003C\u002Fp>\n\u003Cp>A readout (a \u003Ccode>readonly\u003C\u002Fcode> control: a gain reduction, a level) has no travel to turn and no default. It is drawn as a\ndisplay: a frame in its cell carrying its symbol and its range, never a knob, a fader, a switch or a selector, and\nnever looked up as a control input. MOD's template binds input control ports by role (\u003Ccode>input-control-port\u003C\u002Fcode>) and\nhas no role for an output control port, so the frame carries none; it is not a \u003Ccode>modgui:port\u003C\u002Fcode> either. Showing the\nreading live needs the bundle's own \u003Ccode>modgui:javascript\u003C\u002Fcode>, which this generator does not write. A declared panel\nthat names a widget for a readout is refused.\u003C\u002Fp>\n\u003Cp>The images (the screenshot, the thumbnail, the knob film and the fader's when a control is one) are rasterised by\n\u003Ccode>tools\u002Fraster.mjs\u003C\u002Fcode> from the template's own layout, each control at its default. The screenshot and the thumbnail\ncarry the plugin title, the section labels (one band per section, so per group of a grouped descriptor), and each\ncontrol's name and its default with unit; the thumbnail is the screenshot at half size. The text is set from the font\nfile the look names (\u003Ccode>--font-file\u003C\u002Fcode>, \u003Ccode>tools\u002Ffonts\u002FInter-Regular.ttf\u003C\u002Fcode>, SIL OFL 1.1, licence beside it), whose\noutlines \u003Ccode>tools\u002Ffont.mjs\u003C\u002Fcode> reads and \u003Ccode>tools\u002Fraster.mjs\u003C\u002Fcode> fills at the shapes' own sampling: no host font is consulted.\nA fixed-code deflate and no zlib, so their bytes depend only on the descriptor, the panel and the look.\u003C\u002Fp>\n\u003Ch2 id=\"the-look\">The look\u003C\u002Fh2>\n\u003Cp>\u003Ccode>tools\u002Flook\u002Ftokens.css\u003C\u002Fcode> is the omx look's token cascade, the one source of the colours and the font a renderer\nwears. \u003Ccode>tools\u002Flook.mjs\u003C\u002Fcode> resolves it at the look it names into \u003Ccode>tools\u002Flook.json\u003C\u002Fcode>, every colour a plain \u003Ccode>#rrggbb\u003C\u002Fcode>;\n\u003Ccode>omx-panel look --check\u003C\u002Fcode> refuses a \u003Ccode>look.json\u003C\u002Fcode> that is not what the cascade resolves to.\u003C\u002Fp>\n\u003Ch2 id=\"the-test\">The test\u003C\u002Fh2>\n\u003Cp>\u003Ccode>tools\u002Fmodgui-test.sh &lt;bundle.lv2&gt; &lt;descriptor&gt; [&lt;panel&gt;]\u003C\u002Fcode> holds a written MOD GUI to its descriptor on values:\nthe files are the generation byte for byte; every control is drawn in the template with its symbol, travel and\ndefault (a readout with its symbol and range, as a display with no port role), and nothing undeclared is; every choice is a selector with each of its values; \u003Ccode>sord_validate\u003C\u002Fcode> accepts\nthe bundle against the LV2 specifications, \u003Ccode>tools\u002Fmodgui-terms.ttl\u003C\u002Fcode> (the closed modgui vocabulary) and\nomx-contract's resource-hint terms, and refuses a property outside that vocabulary; and a descriptor with its\nfirst control's default moved makes \u003Ccode>--check\u003C\u002Fcode> fail on the template.\u003C\u002Fp>\n",[18,21,24,27,30,33,36],{"slug":19,"title":20},"","omx-panel",{"slug":22,"title":23},"compare","Compare A\u002FB\u002FC\u002FD and undo",{"slug":25,"title":26},"group-inference","Port-group inference for LV2 plugins",{"slug":28,"title":29},"lv2-complement","The LV2 complement: a replacing bundle with the inferred port groups",{"slug":31,"title":32},"panel-layout","Panel layout from a descriptor",{"slug":34,"title":35},"skin-package","The skin package",{"slug":37,"title":38},"worked-example","Worked example: a third-party LV2 and CLAP plugin to a generated panel, adapted to Zynthian",1793954996633]