Add octave controls to KeyboardComponent
Introduced buttons to dynamically adjust the octave within the range of 0 to 8. Added new CSS classes for layout and styling of octave controls, updated component logic with range validation, and reorganized the title and octave display for improved UI.
This commit is contained in:
@@ -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<Int>()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user