diff --git a/src/jsMain/kotlin/nl/astraeus/vst/ui/components/KeyboardComponent.kt b/src/jsMain/kotlin/nl/astraeus/vst/ui/components/KeyboardComponent.kt index 5800313..09095a7 100644 --- a/src/jsMain/kotlin/nl/astraeus/vst/ui/components/KeyboardComponent.kt +++ b/src/jsMain/kotlin/nl/astraeus/vst/ui/components/KeyboardComponent.kt @@ -6,8 +6,14 @@ import kotlinx.html.js.onMouseLeaveFunction import kotlinx.html.js.onMouseUpFunction import kotlinx.html.style import kotlinx.html.svg +import nl.astraeus.css.properties.AlignItems +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.TextAlign +import nl.astraeus.css.properties.prc import nl.astraeus.css.properties.px import nl.astraeus.css.properties.rem import nl.astraeus.css.style.cls @@ -28,13 +34,26 @@ import org.w3c.dom.events.MouseEvent */ class KeyboardComponent( val title: String = "Keyboard", - val octave: Int = 4, + initialOctave: Int = 4, val keyboardWidth: Int = 210, val keyboardHeight: Int = keyboardWidth / 2, val onNoteDown: (Int) -> Unit = {}, val onNoteUp: (Int) -> Unit = {} ) : Komponent() { + // Current octave with range validation + private var _octave: Int = initialOctave + var octave: Int + get() = _octave + set(value) { + _octave = when { + value < 0 -> 0 + value > 8 -> 8 + else -> value + } + requestUpdate() + } + // Set to track which notes are currently pressed private val pressedNotes = mutableSetOf() @@ -87,14 +106,43 @@ class KeyboardComponent( } } - div(KeyboardTitleCls.name) { - // Show title of the keyboard - +title - } + div(KeyboardControlsCls.name) { + // Decrease octave button + div(OctaveButtonCls.name) { + style = "width: ${whiteKeyWidth}px" + +"<" + onMouseDownFunction = { event -> + if (event is MouseEvent) { + octave-- + event.preventDefault() + } + } + } - div(KeyboardOctaveCls.name) { - // Show current octave the piano is being played at - +"Octave: $octave" + // Title and octave display container + div(KeyboardInfoCls.name) { + div(KeyboardTitleCls.name) { + // Show title of the keyboard + +title + } + + div(KeyboardOctaveCls.name) { + // Show current octave the piano is being played at + +"Octave: $octave" + } + } + + // Increase octave button + div(OctaveButtonCls.name) { + style = "width: ${whiteKeyWidth}px" + +">" + onMouseDownFunction = { event -> + if (event is MouseEvent) { + octave++ + event.preventDefault() + } + } + } } div(KeyboardKeysCls.name) { @@ -207,9 +255,12 @@ class KeyboardComponent( companion object : CssId("keyboard") { object KeyboardCls : CssName() + object KeyboardControlsCls : CssName() + object KeyboardInfoCls : CssName() object KeyboardTitleCls : CssName() object KeyboardOctaveCls : CssName() object KeyboardKeysCls : CssName() + object OctaveButtonCls : CssName() object WhiteKeyCls : CssName() object BlackKeyCls : CssName() @@ -219,31 +270,57 @@ class KeyboardComponent( position(Position.relative) margin(5.px) + select(cls(KeyboardControlsCls)) { + position(Position.relative) + display(Display.flex) + flexDirection(FlexDirection.row) + justifyContent(JustifyContent.spaceBetween) + alignItems(AlignItems.center) + width(100.prc) + height(50.px) + marginBottom(10.px) + } + + select(cls(KeyboardInfoCls)) { + display(Display.flex) + flexDirection(FlexDirection.column) + alignItems(AlignItems.center) + justifyContent(JustifyContent.center) + flex("1") + } + select(cls(KeyboardTitleCls)) { - position(Position.absolute) - width(100.px) textAlign(TextAlign.center) fontSize(1.2.rem) color(Css.currentStyle.mainFontColor) - top(5.px) - left(0.px) - right(0.px) } select(cls(KeyboardOctaveCls)) { - position(Position.absolute) - width(100.px) textAlign(TextAlign.center) fontSize(1.0.rem) color(Css.currentStyle.mainFontColor) - top(30.px) - left(0.px) - right(0.px) + marginTop(5.px) + } + + select(cls(OctaveButtonCls)) { + height(50.px) + plain("background-color", Css.currentStyle.buttonBackgroundColor.toString()) + color(Css.currentStyle.mainFontColor) + border("1px solid ${Css.currentStyle.buttonBorderColor}") + textAlign(TextAlign.center) + lineHeight(50.px) + fontSize(1.5.rem) + fontWeight(FontWeight.bold) + cursor("pointer") + plain("-webkit-touch-callout", "none") + plain("-webkit-user-select", "none") + plain("-moz-user-select", "none") + plain("-ms-user-select", "none") + plain("user-select", "none") } select(cls(KeyboardKeysCls)) { - position(Position.absolute) - top(60.px) + position(Position.relative) } }