Fx
This commit is contained in:
@@ -6,38 +6,39 @@ import daw.style.Css.noTextSelect
|
||||
import daw.style.CssId
|
||||
import daw.style.CssName
|
||||
import daw.style.hover
|
||||
import kotlinx.html.FlowContent
|
||||
import kotlinx.html.P
|
||||
import kotlinx.html.a
|
||||
import kotlinx.html.br
|
||||
import kotlinx.html.classes
|
||||
import kotlinx.browser.window
|
||||
import kotlinx.html.InputType
|
||||
import kotlinx.html.div
|
||||
import kotlinx.html.h1
|
||||
import kotlinx.html.hr
|
||||
import kotlinx.html.input
|
||||
import kotlinx.html.js.onChangeFunction
|
||||
import kotlinx.html.js.onClickFunction
|
||||
import kotlinx.html.js.onMouseDownFunction
|
||||
import kotlinx.html.js.onMouseUpFunction
|
||||
import kotlinx.html.option
|
||||
import kotlinx.html.select
|
||||
import kotlinx.html.span
|
||||
import nl.astraeus.css.properties.BoxSizing
|
||||
import nl.astraeus.css.properties.FontWeight
|
||||
import nl.astraeus.css.properties.Position
|
||||
import nl.astraeus.css.properties.Transform
|
||||
import nl.astraeus.css.properties.em
|
||||
import nl.astraeus.css.properties.hsla
|
||||
import nl.astraeus.css.properties.prc
|
||||
import nl.astraeus.css.properties.px
|
||||
import nl.astraeus.css.properties.rem
|
||||
import nl.astraeus.css.properties.vh
|
||||
import nl.astraeus.css.properties.vw
|
||||
import nl.astraeus.css.style.cls
|
||||
import nl.astraeus.komp.HtmlBuilder
|
||||
import nl.astraeus.komp.Komponent
|
||||
import nl.astraeus.vst.Note
|
||||
import nl.astraeus.vst.chip.audio.VstChipWorklet
|
||||
import nl.astraeus.vst.chip.channel.Broadcaster
|
||||
import nl.astraeus.vst.chip.midi.Midi
|
||||
import org.khronos.webgl.Int32Array
|
||||
import org.khronos.webgl.Uint8Array
|
||||
import org.w3c.dom.HTMLSelectElement
|
||||
import org.w3c.performance.Performance
|
||||
|
||||
object MainView : Komponent() {
|
||||
private var messages: MutableList<String> = ArrayList()
|
||||
private var started = false
|
||||
|
||||
init {
|
||||
MainViewCss
|
||||
@@ -52,94 +53,153 @@ object MainView : Komponent() {
|
||||
}
|
||||
|
||||
override fun HtmlBuilder.render() {
|
||||
div {
|
||||
h1 {
|
||||
+"VST Chip"
|
||||
}
|
||||
div {
|
||||
+"Hello, World!"
|
||||
}
|
||||
div {
|
||||
if (VstChipWorklet.created) {
|
||||
+"Worklet created"
|
||||
} else {
|
||||
a {
|
||||
href = "#"
|
||||
+"Create worklet"
|
||||
onClickFunction = {
|
||||
VstChipWorklet.create {
|
||||
requestUpdate()
|
||||
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 {
|
||||
+ "Midi input: "
|
||||
select {
|
||||
for (mi in Midi.inputs) {
|
||||
span {
|
||||
+"Midi input: "
|
||||
select {
|
||||
option {
|
||||
+mi.name
|
||||
value = mi.id
|
||||
+"None"
|
||||
value = ""
|
||||
}
|
||||
option {
|
||||
+"Midi over Broadcast"
|
||||
value = "midi-broadcast"
|
||||
}
|
||||
for (mi in Midi.inputs) {
|
||||
option {
|
||||
+mi.name
|
||||
value = mi.id
|
||||
}
|
||||
}
|
||||
|
||||
onChangeFunction = { event ->
|
||||
val target = event.target as HTMLSelectElement
|
||||
if (target.value == "") {
|
||||
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") {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onChangeFunction = { event ->
|
||||
val target = event.target as HTMLSelectElement
|
||||
val selected = Midi.inputs.find { it.id == target.value }
|
||||
if (selected != null) {
|
||||
Midi.setInput(selected)
|
||||
}
|
||||
span {
|
||||
+"channel:"
|
||||
input {
|
||||
type = InputType.number
|
||||
value = Midi.inputChannel.toString()
|
||||
onChangeFunction = { event ->
|
||||
val target = event.target as HTMLSelectElement
|
||||
Midi.inputChannel = target.value.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
div {
|
||||
span {
|
||||
+"Midi output: "
|
||||
select {
|
||||
option {
|
||||
+"None"
|
||||
value = ""
|
||||
}
|
||||
option {
|
||||
+"Midi over Broadcast"
|
||||
value = "midi-broadcast"
|
||||
}
|
||||
for (mi in Midi.outputs) {
|
||||
option {
|
||||
+mi.name
|
||||
value = mi.id
|
||||
}
|
||||
}
|
||||
|
||||
br {}
|
||||
|
||||
hr {}
|
||||
|
||||
repeat(9) {
|
||||
div(classes = MainViewCss.NoteBarCss.name) {
|
||||
for (index in it*12+12..it*12+23) {
|
||||
notePlayer(Note.entries[index])
|
||||
onChangeFunction = { event ->
|
||||
val target = event.target as HTMLSelectElement
|
||||
if (target.value == "") {
|
||||
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()
|
||||
onChangeFunction = { event ->
|
||||
val target = event.target as HTMLSelectElement
|
||||
Midi.outputChannel = target.value.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr {}
|
||||
|
||||
for (message in messages) {
|
||||
div {
|
||||
+message
|
||||
div {
|
||||
+"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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FlowContent.notePlayer(note: Note) {
|
||||
span {
|
||||
a(classes = MainViewCss.ButtonCss.name) {
|
||||
href = "#"
|
||||
+note.sharp
|
||||
onMouseDownFunction = {
|
||||
VstChipWorklet.postMessage(Int32Array(arrayOf(0x90, note.ordinal, 32)))
|
||||
div {
|
||||
+"Send note off to output"
|
||||
onClickFunction = {
|
||||
val data = Uint8Array(
|
||||
arrayOf(
|
||||
0x90.toByte(),
|
||||
0x3c.toByte(),
|
||||
0x0.toByte(),
|
||||
)
|
||||
)
|
||||
Midi.send(data)
|
||||
}
|
||||
onMouseUpFunction = {
|
||||
VstChipWorklet.postMessage(Int32Array(arrayOf(0x90, note.ordinal, 0)))
|
||||
}
|
||||
/*
|
||||
onMouseOutFunction = {
|
||||
VstChipWorklet.postMessage(Int32Array(arrayOf(0x90, note.ordinal, 0)))
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -155,9 +215,6 @@ object MainView : Komponent() {
|
||||
padding(0.px)
|
||||
height(100.prc)
|
||||
|
||||
color(Css.currentStyle.mainFontColor)
|
||||
backgroundColor(Css.currentStyle.mainBackgroundColor)
|
||||
|
||||
fontFamily("JetbrainsMono, monospace")
|
||||
fontSize(14.px)
|
||||
fontWeight(FontWeight.bold)
|
||||
@@ -180,6 +237,49 @@ object MainView : Komponent() {
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user