package nl.astraeus.vst.chip.view import daw.style.Css import daw.style.Css.defineCss import daw.style.Css.noTextSelect import daw.style.CssId import daw.style.CssName import daw.style.hover import kotlinx.browser.window import kotlinx.html.* import kotlinx.html.js.onChangeFunction import kotlinx.html.js.onClickFunction import kotlinx.html.js.onInputFunction import nl.astraeus.css.properties.* import nl.astraeus.css.style.cls import nl.astraeus.komp.HtmlBuilder import nl.astraeus.komp.Komponent import nl.astraeus.vst.chip.audio.VstChipWorklet import nl.astraeus.vst.chip.midi.Midi import org.khronos.webgl.Uint8Array import org.w3c.dom.HTMLInputElement import org.w3c.dom.HTMLSelectElement object MainView : Komponent() { private var messages: MutableList = ArrayList() private var started = false init { MainViewCss } fun addMessage(message: String) { messages.add(message) while (messages.size > 10) { messages.removeAt(0) } requestUpdate() } override fun HtmlBuilder.render() { div(MainViewCss.MainDivCss.name) { if (!started) { div(MainViewCss.StartSplashCss.name) { div(MainViewCss.StartBoxCss.name) { div(MainViewCss.StartButtonCss.name) { +"START" onClickFunction = { started = true VstChipWorklet.create { requestUpdate() } } } } } } h1 { +"VST Chip" } div { span { +"Midi input: " select { option { +"None" value = "none" } for (mi in Midi.inputs) { option { +mi.name value = mi.id } } onChangeFunction = { event -> val target = event.target as HTMLSelectElement if (target.value == "none") { Midi.setInput(null) } else { val selected = Midi.inputs.find { it.id == target.value } if (selected != null) { Midi.setInput(selected) } else if (target.value == "midi-broadcast") { // } } } } } span { +"channel:" input { type = InputType.number value = Midi.inputChannel.toString() onInputFunction = { event -> val target = event.target as HTMLInputElement Midi.inputChannel = target.value.toInt() println("onInput channel: ${Midi.inputChannel}") VstChipWorklet.postMessage("set_channel\n${Midi.inputChannel}") } } } } div { span { +"Midi output: " select { option { +"None" value = "none" } for (mi in Midi.outputs) { option { +mi.name value = mi.id } } onChangeFunction = { event -> val target = event.target as HTMLSelectElement if (target.value == "none") { Midi.setOutput(null) } else { val selected = Midi.outputs.find { it.id == target.value } if (selected != null) { Midi.setOutput(selected) } } } } } span { +"channel:" input { type = InputType.number value = Midi.outputChannel.toString() onInputFunction = { event -> val target = event.target as HTMLInputElement Midi.outputChannel = target.value.toInt() } } } } div(MainViewCss.ButtonCss.name) { +"Send note on to output" onClickFunction = { val data = Uint8Array( arrayOf( 0x90.toByte(), 0x3c.toByte(), 0x70.toByte() ) ) Midi.send(data, window.performance.now() + 1000) Midi.send(data, window.performance.now() + 2000) } } div(MainViewCss.ButtonCss.name) { +"Send note off to output" onClickFunction = { val data = Uint8Array( arrayOf( 0x90.toByte(), 0x3c.toByte(), 0x0.toByte(), ) ) Midi.send(data) } } } } object MainViewCss : CssId("main") { object MainDivCss : CssName() object ActiveCss : CssName() object ButtonCss : CssName() object NoteBarCss : CssName() object StartSplashCss : CssName() object StartBoxCss : CssName() object StartButtonCss : CssName() init { defineCss { select("*") { select("*:before") { select("*:after") { boxSizing(BoxSizing.borderBox) } } } select("html", "body") { margin(0.px) padding(0.px) height(100.prc) } select("html", "body") { backgroundColor(Css.currentStyle.mainBackgroundColor) color(Css.currentStyle.mainFontColor) fontFamily("JetbrainsMono, monospace") fontSize(14.px) fontWeight(FontWeight.bold) //transition() noTextSelect() } select(cls(ButtonCss)) { margin(1.rem) padding(1.rem) backgroundColor(Css.currentStyle.buttonBackgroundColor) borderColor(Css.currentStyle.buttonBorderColor) borderWidth(Css.currentStyle.buttonBorderWidth) color(Css.currentStyle.mainFontColor) hover { backgroundColor(Css.currentStyle.buttonBackgroundColor.hover()) } } select(cls(ActiveCss)) { //backgroundColor(Css.currentStyle.selectedBackgroundColor) } select(cls(NoteBarCss)) { minHeight(4.rem) } select(cls(MainDivCss)) { margin(1.rem) } select("select") { plain("appearance", "none") border("0") outline("0") width(20.rem) padding(0.5.rem, 2.rem, 0.5.rem, 0.5.rem) backgroundImage("url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Caret_down_font_awesome_whitevariation.svg')") background("right 0.8em center/1.4em") backgroundColor(Css.currentStyle.inputBackgroundColor) //color(Css.currentStyle.entryFontColor) borderRadius(0.25.em) } select(cls(StartSplashCss)) { position(Position.fixed) left(0.px) top(0.px) width(100.vw) height(100.vh) zIndex(100) backgroundColor(hsla(32, 0, 50, 0.6)) select(cls(StartBoxCss)) { position(Position.relative) left(25.vw) top(25.vh) width(50.vw) height(50.vh) backgroundColor(hsla(0, 0, 50, 0.25)) select(cls(StartButtonCss)) { position(Position.absolute) left(50.prc) top(50.prc) transform(Transform("translate(-50%, -50%)")) padding(1.rem) backgroundColor(Css.currentStyle.buttonBackgroundColor) cursor("pointer") } } } } } } }