From 20e06b8fb98d8a1f8e4731b5cc4be29e817a00e7 Mon Sep 17 00:00:00 2001 From: rnentjes Date: Sun, 22 Dec 2024 17:02:32 +0100 Subject: [PATCH] v. 1.1.3 Implement mouse coordinate-based knob value adjustment. Added `setValueByMouseCoords` to calculate knob values derived from mouse coordinates using angles. Replaced obsolete mouse delta logic with the new approach for better precision and interaction. Upgraded dependencies and project configurations, including the Kotlin version, for enhanced compatibility and stability. --- build.gradle.kts | 7 +- .../vst/ui/components/BaseKnobComponent.kt | 78 ++++++++++++++----- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 71f63cf..002cee5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,7 @@ +@file:OptIn(ExperimentalKotlinGradlePluginApi::class) + +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi + plugins { kotlin("multiplatform") version "2.1.0" `maven-publish` @@ -33,7 +37,7 @@ kotlin { val commonMain by getting { dependencies { implementation("nl.astraeus:kotlin-css-generator:1.0.10") - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0") } } val jsMain by getting { @@ -49,7 +53,6 @@ kotlin { val jvmMain by getting { dependencies { //base - implementation("io.undertow:undertow-core:2.3.14.Final") implementation("io.undertow:undertow-websockets-jsr:2.3.14.Final") implementation("org.jboss.xnio:xnio-nio:3.8.16.Final") diff --git a/src/jsMain/kotlin/nl/astraeus/vst/ui/components/BaseKnobComponent.kt b/src/jsMain/kotlin/nl/astraeus/vst/ui/components/BaseKnobComponent.kt index e60f82a..c01b6a1 100644 --- a/src/jsMain/kotlin/nl/astraeus/vst/ui/components/BaseKnobComponent.kt +++ b/src/jsMain/kotlin/nl/astraeus/vst/ui/components/BaseKnobComponent.kt @@ -1,6 +1,8 @@ package nl.astraeus.vst.ui.components import kotlinx.html.classes +import kotlinx.html.js.onMouseDownFunction +import kotlinx.html.js.onMouseUpFunction import kotlinx.html.js.onWheelFunction import kotlinx.html.org.w3c.dom.events.Event import kotlinx.html.span @@ -26,6 +28,7 @@ import nl.astraeus.vst.ui.util.width import org.w3c.dom.events.MouseEvent import org.w3c.dom.events.WheelEvent import kotlin.math.PI +import kotlin.math.atan2 import kotlin.math.max import kotlin.math.min @@ -86,10 +89,10 @@ open class BaseKnobComponent( val actToVal = actualToValue(actualValue) console.log("actualValue", actualValue, "actToVal", actToVal) val middle = ( - ((ANGLE_RANGE_DEG.toFloat() * - (actToVal - minValue)) / - (maxValue - minValue) - + START_ANGLE_DEG.toFloat()).toInt() + ((ANGLE_RANGE_DEG.toFloat() * + (actToVal - minValue)) / + (maxValue - minValue) + + START_ANGLE_DEG.toFloat()).toInt() ) val middleX = getMiddleX() @@ -153,30 +156,20 @@ open class BaseKnobComponent( onWheelFunction = ::wheelFunction -/* onMouseDownFunction = { + onMouseDownFunction = { if (it is MouseEvent) { activated = true - mouseX = it.clientX.toDouble() - mouseY = it.clientY.toDouble() - startValue = actualValue - - mainView.globalMouseListener = { me -> - if (activated && me.buttons == 1.toShort()) { - setValueByMouseDelta(me, actualMinimumValue, actualMaximumValue, callback) - } - } - - requestUpdate() + setValueByMouseCoords(it, minValue, maxValue, callback) } } onMouseUpFunction = { if (it is MouseEvent) { activated = false - mainView.globalMouseListener = null requestUpdate() } - }*/ + } + } } @@ -205,6 +198,53 @@ open class BaseKnobComponent( } } + private fun setValueByMouseCoords( + it: MouseEvent, + minValue: Double = 0.0, + maxValue: Double = 5.0, + callback: (value: Double) -> Unit + ) { + val deltaX = it.offsetX - getMiddleX() + val deltaY = it.offsetY - getMiddleY() + + var angle = atan2(deltaX, deltaY) + + angle = if (angle < 0) { + -angle + } else { + PI * 2.0 - angle + } + + angle += PI / 2.0 + + if (angle > PI * 2.0) { + angle -= PI * 2.0 + } + + var newValue = minValue + + when { + angle > START_ANGLE -> newValue = + minValue + ((maxValue - minValue) / ANGLE_RANGE * (angle - START_ANGLE)).toFloat() + + angle < END_ANGLE -> { + val calcAngle = angle + PI * 2.0 + newValue = + minValue + ((maxValue - minValue) / ANGLE_RANGE * (calcAngle - START_ANGLE)).toFloat() + } + + angle < PI / 2.0 -> newValue = maxValue + } + + actualValue = newValue + + callback(newValue.toDouble()) + + requestUpdate() + + it.preventDefault() + } + private fun setValueByMouseDelta( it: MouseEvent, minValue: Double = 0.0, @@ -213,7 +253,7 @@ open class BaseKnobComponent( ) { val deltaX = it.clientX.toDouble() - mouseX val deltaY = it.clientY.toDouble() - mouseY - var length = - deltaX + deltaY + var length = -deltaX + deltaY if (it.offsetX < mouseX || it.offsetY < mouseY) { length = -length