Add test-app module with initial UI and backend setup
Introduced a new `test-app` module with a basic Kotlin/JS UI and a Kotlin/JVM backend. Updated dependencies to use `api` where applicable and made configuration changes to support composite builds.
This commit is contained in:
15
.idea/gradle.xml
generated
15
.idea/gradle.xml
generated
@@ -4,11 +4,22 @@
|
|||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<compositeConfiguration>
|
||||||
<option name="gradleHome" value="" />
|
<compositeBuild compositeDefinitionSource="SCRIPT">
|
||||||
|
<builds>
|
||||||
|
<build path="$PROJECT_DIR$" name="vst-ui-base">
|
||||||
|
<projects>
|
||||||
|
<project path="$PROJECT_DIR$" />
|
||||||
|
</projects>
|
||||||
|
</build>
|
||||||
|
</builds>
|
||||||
|
</compositeBuild>
|
||||||
|
</compositeConfiguration>
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$/test-app" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/test-app" />
|
||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
</GradleProjectSettings>
|
</GradleProjectSettings>
|
||||||
|
|||||||
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="1.9.23" />
|
<option name="version" value="2.1.0" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -40,12 +40,12 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("nl.astraeus:kotlin-css-generator:1.0.10")
|
api("nl.astraeus:kotlin-css-generator:1.0.10")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val jsMain by getting {
|
val jsMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("nl.astraeus:kotlin-komponent:1.2.4")
|
api("nl.astraeus:kotlin-komponent:1.2.4")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val jsTest by getting {
|
val jsTest by getting {
|
||||||
@@ -55,7 +55,7 @@ kotlin {
|
|||||||
}
|
}
|
||||||
val jvmMain by getting {
|
val jvmMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0")
|
api("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0")
|
||||||
|
|
||||||
implementation("io.undertow:undertow-core:2.3.14.Final")
|
implementation("io.undertow:undertow-core:2.3.14.Final")
|
||||||
implementation("io.undertow:undertow-websockets-jsr:2.3.14.Final")
|
implementation("io.undertow:undertow-websockets-jsr:2.3.14.Final")
|
||||||
@@ -65,7 +65,7 @@ kotlin {
|
|||||||
implementation("com.zaxxer:HikariCP:4.0.3")
|
implementation("com.zaxxer:HikariCP:4.0.3")
|
||||||
implementation("nl.astraeus:simple-jdbc-stats:1.6.1")
|
implementation("nl.astraeus:simple-jdbc-stats:1.6.1")
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-html-jvm:0.11.0")
|
api("org.jetbrains.kotlinx:kotlinx-html-jvm:0.11.0")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject.name = "vst-ui-base"
|
rootProject.name = "vst-ui-base"
|
||||||
|
|
||||||
|
//include("test-app")
|
||||||
|
|||||||
5
test-app/settings.gradle.kts
Normal file
5
test-app/settings.gradle.kts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
plugins {
|
||||||
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
includeBuild("..")
|
||||||
19
test-app/src/jsMain/kotlin/nl/astraeus/vst/ui/Test.kt
Normal file
19
test-app/src/jsMain/kotlin/nl/astraeus/vst/ui/Test.kt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package nl.astraeus.vst.ui
|
||||||
|
|
||||||
|
import kotlinx.browser.document
|
||||||
|
import nl.astraeus.komp.Komponent
|
||||||
|
import nl.astraeus.komp.UnsafeMode
|
||||||
|
import nl.astraeus.vst.ui.css.CssSettings
|
||||||
|
import nl.astraeus.vst.ui.view.MainView
|
||||||
|
|
||||||
|
val mainView: MainView by lazy {
|
||||||
|
MainView()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
CssSettings.shortId = false
|
||||||
|
CssSettings.preFix = "vst"
|
||||||
|
|
||||||
|
Komponent.unsafeMode = UnsafeMode.UNSAFE_SVG_ONLY
|
||||||
|
Komponent.create(document.body!!, mainView)
|
||||||
|
}
|
||||||
312
test-app/src/jsMain/kotlin/nl/astraeus/vst/ui/view/MainView.kt
Normal file
312
test-app/src/jsMain/kotlin/nl/astraeus/vst/ui/view/MainView.kt
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
@file:OptIn(ExperimentalJsExport::class)
|
||||||
|
|
||||||
|
package nl.astraeus.vst.ui.view
|
||||||
|
|
||||||
|
import kotlinx.html.div
|
||||||
|
import kotlinx.html.h1
|
||||||
|
import kotlinx.html.js.onClickFunction
|
||||||
|
import kotlinx.html.option
|
||||||
|
import kotlinx.html.select
|
||||||
|
import kotlinx.html.span
|
||||||
|
import nl.astraeus.css.properties.AlignItems
|
||||||
|
import nl.astraeus.css.properties.BoxSizing
|
||||||
|
import nl.astraeus.css.properties.Display
|
||||||
|
import nl.astraeus.css.properties.FlexDirection
|
||||||
|
import nl.astraeus.css.properties.FontWeight
|
||||||
|
import nl.astraeus.css.properties.JustifyContent
|
||||||
|
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.Style
|
||||||
|
import nl.astraeus.css.style.cls
|
||||||
|
import nl.astraeus.komp.HtmlBuilder
|
||||||
|
import nl.astraeus.komp.Komponent
|
||||||
|
import nl.astraeus.vst.ui.components.ExpKnobComponent
|
||||||
|
import nl.astraeus.vst.ui.components.KnobComponent
|
||||||
|
import nl.astraeus.vst.ui.css.Css
|
||||||
|
import nl.astraeus.vst.ui.css.Css.defineCss
|
||||||
|
import nl.astraeus.vst.ui.css.Css.noTextSelect
|
||||||
|
import nl.astraeus.vst.ui.css.CssName
|
||||||
|
import nl.astraeus.vst.ui.css.hover
|
||||||
|
|
||||||
|
class MainView : Komponent() {
|
||||||
|
private var messages: MutableList<String> = ArrayList()
|
||||||
|
var started = true
|
||||||
|
|
||||||
|
fun addMessage(message: String) {
|
||||||
|
messages.add(message)
|
||||||
|
while (messages.size > 10) {
|
||||||
|
messages.removeAt(0)
|
||||||
|
}
|
||||||
|
requestUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun renderUpdate() {
|
||||||
|
println("Rendering MainView")
|
||||||
|
super.renderUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun HtmlBuilder.render() {
|
||||||
|
div(MainDivCss.name) {
|
||||||
|
if (!started) {
|
||||||
|
div(StartSplashCss.name) {
|
||||||
|
div(StartBoxCss.name) {
|
||||||
|
div(StartButtonCss.name) {
|
||||||
|
+"START"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClickFunction = {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
+"VST UI-base Test"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
span {
|
||||||
|
+"Midi input: "
|
||||||
|
select {
|
||||||
|
option {
|
||||||
|
+"None"
|
||||||
|
value = "none"
|
||||||
|
}
|
||||||
|
/* for (mi in Midi.inputs) {
|
||||||
|
option {
|
||||||
|
+mi.name
|
||||||
|
value = mi.id
|
||||||
|
selected = mi.id == Midi.currentInput?.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeFunction = { event ->
|
||||||
|
val target = event.target as HTMLSelectElement
|
||||||
|
if (target.value == "none") {
|
||||||
|
Midi.setInput(null)
|
||||||
|
} else {
|
||||||
|
Midi.setInput(target.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
+"channel:"
|
||||||
|
/*
|
||||||
|
input {
|
||||||
|
type = InputType.number
|
||||||
|
value = VstChipWorklet.midiChannel.toString()
|
||||||
|
onInputFunction = { event ->
|
||||||
|
val target = event.target as HTMLInputElement
|
||||||
|
kotlin.io.println("onInput channel: $target")
|
||||||
|
VstChipWorklet.midiChannel = target.value.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
div {
|
||||||
|
span(ButtonBarCss.name) {
|
||||||
|
+"SAVE"
|
||||||
|
onClickFunction = {
|
||||||
|
val patch = VstChipWorklet.save().copy(
|
||||||
|
midiId = Midi.currentInput?.id ?: "",
|
||||||
|
midiName = Midi.currentInput?.name ?: ""
|
||||||
|
)
|
||||||
|
|
||||||
|
WebsocketClient.send("SAVE\n${JSON.stringify(patch)}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
span(ButtonBarCss.name) {
|
||||||
|
+"STOP"
|
||||||
|
onClickFunction = {
|
||||||
|
VstChipWorklet.postDirectlyToWorklet(
|
||||||
|
TimedMidiMessage(getCurrentTime(), (0xb0 + midiChannel).toByte(), 123, 0)
|
||||||
|
.data.buffer.data
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
div(ControlsCss.name) {
|
||||||
|
include(
|
||||||
|
ExpKnobComponent(
|
||||||
|
value = 0.0,
|
||||||
|
label = "Volume",
|
||||||
|
minValue = 0.0,
|
||||||
|
maxValue = 1.0,
|
||||||
|
step = 5.0 / 127.0,
|
||||||
|
width = 100,
|
||||||
|
height = 120,
|
||||||
|
) { value ->
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
include(
|
||||||
|
KnobComponent(
|
||||||
|
value = 0.5,
|
||||||
|
label = "Duty cycle",
|
||||||
|
minValue = 0.0,
|
||||||
|
maxValue = 1.0,
|
||||||
|
step = 2.0 / 127.0,
|
||||||
|
width = 100,
|
||||||
|
height = 120,
|
||||||
|
) { value ->
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
include(
|
||||||
|
KnobComponent(
|
||||||
|
value = 0.5,
|
||||||
|
label = "Duty cycle",
|
||||||
|
minValue = 0.0,
|
||||||
|
maxValue = 1.0,
|
||||||
|
step = 2.0 / 127.0,
|
||||||
|
width = 500,
|
||||||
|
height = 600,
|
||||||
|
) { value ->
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object MainViewCss : CssName() {
|
||||||
|
object MainDivCss : CssName()
|
||||||
|
object ActiveCss : CssName()
|
||||||
|
object ButtonCss : CssName()
|
||||||
|
object ButtonBarCss : CssName()
|
||||||
|
object SelectedCss : CssName()
|
||||||
|
object NoteBarCss : CssName()
|
||||||
|
object StartSplashCss : CssName()
|
||||||
|
object StartBoxCss : CssName()
|
||||||
|
object StartButtonCss : CssName()
|
||||||
|
object ControlsCss : 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("input", "textarea") {
|
||||||
|
backgroundColor(Css.currentStyle.inputBackgroundColor)
|
||||||
|
color(Css.currentStyle.mainFontColor)
|
||||||
|
border("none")
|
||||||
|
}
|
||||||
|
select(cls(ButtonCss)) {
|
||||||
|
margin(1.rem)
|
||||||
|
commonButton()
|
||||||
|
}
|
||||||
|
select(cls(ButtonBarCss)) {
|
||||||
|
margin(1.rem, 0.px)
|
||||||
|
commonButton()
|
||||||
|
}
|
||||||
|
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.mainFontColor)
|
||||||
|
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, 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select(ControlsCss.cls()) {
|
||||||
|
display(Display.flex)
|
||||||
|
flexDirection(FlexDirection.row)
|
||||||
|
justifyContent(JustifyContent.flexStart)
|
||||||
|
alignItems(AlignItems.center)
|
||||||
|
margin(1.rem)
|
||||||
|
padding(1.rem)
|
||||||
|
backgroundColor(Css.currentStyle.mainBackgroundColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Style.commonButton() {
|
||||||
|
display(Display.inlineBlock)
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
and(SelectedCss.cls()) {
|
||||||
|
backgroundColor(Css.currentStyle.buttonBackgroundColor.hover().hover().hover())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
21
test-app/src/jvmMain/kotlin/nl/astraeus/vst/ui/Test.kt
Normal file
21
test-app/src/jvmMain/kotlin/nl/astraeus/vst/ui/Test.kt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package nl.astraeus.vst.ui
|
||||||
|
|
||||||
|
import nl.astraeus.vst.base.Settings
|
||||||
|
import nl.astraeus.vst.base.db.Database
|
||||||
|
import nl.astraeus.vst.base.web.UndertowServer
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
Thread.setDefaultUncaughtExceptionHandler { _, e ->
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings.port = 9999
|
||||||
|
Settings.jdbcStatsPort = 7777
|
||||||
|
|
||||||
|
Database.start()
|
||||||
|
|
||||||
|
UndertowServer.start(
|
||||||
|
"Vst UI-base Test",
|
||||||
|
"/vst-ui-base-test.js"
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user