Move stuff in base

This commit is contained in:
2024-08-09 19:54:36 +02:00
parent 8d529b0a45
commit 40ba59e7bd
27 changed files with 1595 additions and 36 deletions

View File

@@ -1,11 +1,17 @@
package nl.astraeus.vst.ui.components
import kotlinx.html.classes
import kotlinx.html.js.onMouseWheelFunction
import kotlinx.html.js.onWheelFunction
import kotlinx.html.org.w3c.dom.events.Event
import kotlinx.html.span
import kotlinx.html.style
import kotlinx.html.svg
import nl.astraeus.css.properties.*
import nl.astraeus.css.properties.Color
import nl.astraeus.css.properties.Position
import nl.astraeus.css.properties.TextAlign
import nl.astraeus.css.properties.em
import nl.astraeus.css.properties.prc
import nl.astraeus.css.properties.px
import nl.astraeus.css.style.cls
import nl.astraeus.komp.HtmlBuilder
import nl.astraeus.komp.Komponent
@@ -14,9 +20,9 @@ import nl.astraeus.vst.ui.css.Css
import nl.astraeus.vst.ui.css.Css.defineCss
import nl.astraeus.vst.ui.css.CssId
import nl.astraeus.vst.ui.css.CssName
import nl.astraeus.vst.util.arc
import nl.astraeus.vst.util.height
import nl.astraeus.vst.util.width
import nl.astraeus.vst.ui.util.arc
import nl.astraeus.vst.ui.util.height
import nl.astraeus.vst.ui.util.width
import org.w3c.dom.events.MouseEvent
import org.w3c.dom.events.WheelEvent
import kotlin.math.PI
@@ -77,10 +83,12 @@ open class BaseKnobComponent(
width(width)
height(height)
val actToVal = actualToValue(actualValue)
console.log("actualValue", actualValue, "actToVal", actToVal)
val middle = (
((ANGLE_RANGE_DEG.toFloat() *
(actualValue - actualMinimumValue)) /
(actualMaximumValue - actualMinimumValue)
(actToVal - minValue)) /
(maxValue - minValue)
+ START_ANGLE_DEG.toFloat()).toInt()
)
@@ -143,28 +151,7 @@ open class BaseKnobComponent(
+renderedValue
}
onMouseWheelFunction = {
if (it is WheelEvent) {
val delta = if (it.deltaY > 0) {
1.0
} else {
-1.0
} //it.deltaY / 250.0
var newValue = actualValue - delta * step
newValue = min(newValue, actualMaximumValue)
newValue = max(newValue, actualMinimumValue)
actualValue = newValue
callback(actualToValue(newValue))
requestUpdate()
it.preventDefault()
}
}
onWheelFunction = ::wheelFunction
/* onMouseDownFunction = {
if (it is MouseEvent) {
@@ -193,6 +180,31 @@ open class BaseKnobComponent(
}
}
private fun wheelFunction(event: Event) {
console.log("onMouseWheelFunction", event)
if (event is WheelEvent) {
val delta = if (event.deltaY > 0) {
1.0
} else {
-1.0
} //it.deltaY / 250.0
var newValue = actualValue - delta * step
newValue = min(newValue, actualMaximumValue)
newValue = max(newValue, actualMinimumValue)
actualValue = newValue
callback(actualToValue(newValue))
requestUpdate()
event.preventDefault()
event.stopPropagation()
}
}
private fun setValueByMouseDelta(
it: MouseEvent,
minValue: Double = 0.0,

View File

@@ -18,7 +18,7 @@ class ExpKnobComponent(
step: Double = 0.1,
width: Int = 50,
height: Int = 60,
renderer: (Double) -> String = { nv -> formatDouble(nv, 2) },
renderer: (Double) -> String = { nv -> formatDouble(nv, 3) },
callback: (Double) -> Unit = {}
) : BaseKnobComponent(
value,

View File

@@ -0,0 +1,29 @@
package nl.astraeus.vst.ui.components
import kotlinx.html.div
import nl.astraeus.komp.HtmlBuilder
import nl.astraeus.komp.Komponent
import nl.astraeus.vst.ui.css.Css.defineCss
import nl.astraeus.vst.ui.css.CssId
import nl.astraeus.vst.ui.css.CssName
class KeyboardInputComponent : Komponent() {
override fun HtmlBuilder.render() {
div {
+"Keyboard component"
}
}
companion object : CssId("keyboard-input") {
object KeyboardInputCss : CssName
init {
defineCss {
select(KeyboardInputCss.cls()) {
}
}
}
}
}

View File

@@ -0,0 +1,158 @@
package nl.astraeus.vst.ui.util
import kotlinx.html.SVG
import kotlinx.html.unsafe
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
fun SVG.width(width: Int) {
this.attributes["width"] = "$width"
}
fun SVG.height(height: Int) {
this.attributes["height"] = "$height"
}
fun SVG.svgStyle(
name: String,
vararg props: Pair<String, String>
) {
val result = StringBuilder()
result.append("<style>\n")
result.append(name)
result.append(" {\n")
for (prop in props) {
result.append(" ")
result.append(prop.first)
result.append(": ")
result.append(prop.second)
result.append(";\n")
}
result.append("}\n")
result.append("</style>\n")
unsafe {
+ "$result"
}
}
fun SVG.rect(
x: Int,
y: Int,
width: Int,
height: Int,
rx: Int,
cls: String
) {
this.unsafe {
+ """
<rect class="$cls" x="$x" y="$y" width="$width" height="$height" rx="$rx" />
""".trimIndent()
}
}
fun SVG.circle(
x: Int,
y: Int,
radius: Int,
cls: String
) {
this.unsafe {
+ """
<circle class="$cls" cx="$x" cy="$y" r="$radius" />
""".trimIndent()
}
}
fun SVG.control(
pnt: Pair<Int, Int>,
cls: String
) {
circle(pnt.first, pnt.second, 4, cls)
}
private val Pair<Int, Int>.crds: String
get() = "${this.first},${this.second}"
// https://svg-path-visualizer.netlify.app/bezier-curve/
fun SVG.curve(
start: Pair<Int, Int>,
control1: Pair<Int, Int>,
control2: Pair<Int, Int>,
end: Pair<Int, Int>,
smoothEnd: Pair<Int, Int>? = null,
vararg smooth: Pair<Int,Int>,
cls: String
) {
val smoothStr = StringBuilder()
for (crd in smooth) {
smoothStr.append("S ")
smoothStr.append(crd.crds)
smoothStr.append(" ")
}
val smoothEndStr = if (smoothEnd != null) {
smoothEnd.crds
} else {
""
}
this.unsafe {
+ """
<path class="$cls" d="M ${start.crds} C ${control1.crds} ${control2.crds} ${end.crds} $smoothStr $smoothEndStr " />
""".trimIndent()
}
this.control(start, cls = cls)
this.control(control1, cls = cls)
this.control(control2, cls = cls)
this.control(end, cls = cls)
for (sm in smooth) {
this.control(sm, cls = cls)
}
if (smoothEnd != null) {
this.control(smoothEnd, cls = cls)
}
}
/*
+"""<path d="${describeArc(middleX, middleY, radius, START_ANGLE_DEG, middle)}"
fill="none" stroke="${volumeColor.value}" stroke-width="10" />"""
*/
fun SVG.arc(
x: Int,
y: Int,
radius: Int,
startAngle: Int,
endAngle: Int,
cls: String
) {
val start = polarToCartesian(x, y, radius, endAngle)
val end = polarToCartesian(x, y, radius, startAngle)
val largeArcFlag = if (endAngle - startAngle <= 180) {
"0"
} else {
"1"
}
unsafe {
+"""<path class="$cls"
d="M ${start.first} ${start.second}
A $radius $radius 0 $largeArcFlag 0 ${end.first} ${end.second}" />"""
}
}
private fun polarToCartesian(
centerX: Int,
centerY: Int,
radius: Int,
angleInDegrees: Int
): Pair<Double, Double> {
val angleInRadians = (angleInDegrees - 90).toDouble() * PI / 180.0
return Pair(
centerX + (radius * cos(angleInRadians)),
centerY + (radius * sin(angleInRadians))
)
}

View File

@@ -0,0 +1,98 @@
package nl.astraeus.vst.ui.view
import kotlinx.html.div
import kotlinx.html.js.onClickFunction
import kotlinx.html.org.w3c.dom.events.Event
import nl.astraeus.css.properties.Display
import nl.astraeus.css.properties.FlexDirection
import nl.astraeus.css.properties.Position
import nl.astraeus.css.properties.Transform
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.ui.css.Css
import nl.astraeus.vst.ui.css.Css.defineCss
import nl.astraeus.vst.ui.css.CssId
import nl.astraeus.vst.ui.css.CssName
class BaseVstView(
val title: String,
val vstView: Komponent,
val audioStart: (e: Event) -> Unit
) : Komponent() {
var started = false
override fun HtmlBuilder.render() {
div(BaseVstCss.name) {
if (!started) {
div(BaseVstCss.StartSplashCss.name) {
div(BaseVstCss.StartBoxCss.name) {
div(BaseVstCss.StartButtonCss.name) {
+"START"
onClickFunction = { event ->
audioStart(event)
started = true
requestUpdate()
}
}
}
}
}
include(vstView)
}
}
object BaseVstCss : CssId("base-vst-view") {
object BaseVstCss : CssName
object StartSplashCss : CssName
object StartBoxCss : CssName
object StartButtonCss : CssName
init {
defineCss {
select(BaseVstCss.cls()) {
display(Display.flex)
flexDirection(FlexDirection.column)
}
select(cls(StartSplashCss)) {
position(Position.fixed)
left(0.px)
top(0.px)
width(100.vw)
height(100.vh)
zIndex(100)
backgroundColor(hsla(32, 0, 5, 0.65))
select(cls(StartBoxCss)) {
position(Position.relative)
left(25.vw)
top(25.vh)
width(50.vw)
height(50.vh)
backgroundColor(hsla(239, 50, 10, 1.0))
borderColor(Css.currentStyle.mainFontColor)
borderWidth(2.px)
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")
}
}
}
}
}
}
}