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">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="" />
|
||||
<compositeConfiguration>
|
||||
<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">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/test-app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
|
||||
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="1.9.23" />
|
||||
<option name="version" value="2.1.0" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -40,12 +40,12 @@ kotlin {
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation("nl.astraeus:kotlin-css-generator:1.0.10")
|
||||
api("nl.astraeus:kotlin-css-generator:1.0.10")
|
||||
}
|
||||
}
|
||||
val jsMain by getting {
|
||||
dependencies {
|
||||
implementation("nl.astraeus:kotlin-komponent:1.2.4")
|
||||
api("nl.astraeus:kotlin-komponent:1.2.4")
|
||||
}
|
||||
}
|
||||
val jsTest by getting {
|
||||
@@ -55,7 +55,7 @@ kotlin {
|
||||
}
|
||||
val jvmMain by getting {
|
||||
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-websockets-jsr:2.3.14.Final")
|
||||
@@ -65,7 +65,7 @@ kotlin {
|
||||
implementation("com.zaxxer:HikariCP:4.0.3")
|
||||
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 {
|
||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
|
||||
}
|
||||
|
||||
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