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.js.onMouseUpFunction
|
||||||
import kotlinx.html.style
|
import kotlinx.html.style
|
||||||
import kotlinx.html.svg
|
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.Position
|
||||||
import nl.astraeus.css.properties.TextAlign
|
import nl.astraeus.css.properties.TextAlign
|
||||||
|
import nl.astraeus.css.properties.prc
|
||||||
import nl.astraeus.css.properties.px
|
import nl.astraeus.css.properties.px
|
||||||
import nl.astraeus.css.properties.rem
|
import nl.astraeus.css.properties.rem
|
||||||
import nl.astraeus.css.style.cls
|
import nl.astraeus.css.style.cls
|
||||||
@@ -28,13 +34,26 @@ import org.w3c.dom.events.MouseEvent
|
|||||||
*/
|
*/
|
||||||
class KeyboardComponent(
|
class KeyboardComponent(
|
||||||
val title: String = "Keyboard",
|
val title: String = "Keyboard",
|
||||||
val octave: Int = 4,
|
initialOctave: Int = 4,
|
||||||
val keyboardWidth: Int = 210,
|
val keyboardWidth: Int = 210,
|
||||||
val keyboardHeight: Int = keyboardWidth / 2,
|
val keyboardHeight: Int = keyboardWidth / 2,
|
||||||
val onNoteDown: (Int) -> Unit = {},
|
val onNoteDown: (Int) -> Unit = {},
|
||||||
val onNoteUp: (Int) -> Unit = {}
|
val onNoteUp: (Int) -> Unit = {}
|
||||||
) : Komponent() {
|
) : 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
|
// Set to track which notes are currently pressed
|
||||||
private val pressedNotes = mutableSetOf<Int>()
|
private val pressedNotes = mutableSetOf<Int>()
|
||||||
|
|
||||||
@@ -87,14 +106,43 @@ class KeyboardComponent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div(KeyboardTitleCls.name) {
|
div(KeyboardControlsCls.name) {
|
||||||
// Show title of the keyboard
|
// Decrease octave button
|
||||||
+title
|
div(OctaveButtonCls.name) {
|
||||||
}
|
style = "width: ${whiteKeyWidth}px"
|
||||||
|
+"<"
|
||||||
|
onMouseDownFunction = { event ->
|
||||||
|
if (event is MouseEvent) {
|
||||||
|
octave--
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
div(KeyboardOctaveCls.name) {
|
// Title and octave display container
|
||||||
// Show current octave the piano is being played at
|
div(KeyboardInfoCls.name) {
|
||||||
+"Octave: $octave"
|
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) {
|
div(KeyboardKeysCls.name) {
|
||||||
@@ -207,9 +255,12 @@ class KeyboardComponent(
|
|||||||
|
|
||||||
companion object : CssId("keyboard") {
|
companion object : CssId("keyboard") {
|
||||||
object KeyboardCls : CssName()
|
object KeyboardCls : CssName()
|
||||||
|
object KeyboardControlsCls : CssName()
|
||||||
|
object KeyboardInfoCls : CssName()
|
||||||
object KeyboardTitleCls : CssName()
|
object KeyboardTitleCls : CssName()
|
||||||
object KeyboardOctaveCls : CssName()
|
object KeyboardOctaveCls : CssName()
|
||||||
object KeyboardKeysCls : CssName()
|
object KeyboardKeysCls : CssName()
|
||||||
|
object OctaveButtonCls : CssName()
|
||||||
object WhiteKeyCls : CssName()
|
object WhiteKeyCls : CssName()
|
||||||
object BlackKeyCls : CssName()
|
object BlackKeyCls : CssName()
|
||||||
|
|
||||||
@@ -219,31 +270,57 @@ class KeyboardComponent(
|
|||||||
position(Position.relative)
|
position(Position.relative)
|
||||||
margin(5.px)
|
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)) {
|
select(cls(KeyboardTitleCls)) {
|
||||||
position(Position.absolute)
|
|
||||||
width(100.px)
|
|
||||||
textAlign(TextAlign.center)
|
textAlign(TextAlign.center)
|
||||||
fontSize(1.2.rem)
|
fontSize(1.2.rem)
|
||||||
color(Css.currentStyle.mainFontColor)
|
color(Css.currentStyle.mainFontColor)
|
||||||
top(5.px)
|
|
||||||
left(0.px)
|
|
||||||
right(0.px)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
select(cls(KeyboardOctaveCls)) {
|
select(cls(KeyboardOctaveCls)) {
|
||||||
position(Position.absolute)
|
|
||||||
width(100.px)
|
|
||||||
textAlign(TextAlign.center)
|
textAlign(TextAlign.center)
|
||||||
fontSize(1.0.rem)
|
fontSize(1.0.rem)
|
||||||
color(Css.currentStyle.mainFontColor)
|
color(Css.currentStyle.mainFontColor)
|
||||||
top(30.px)
|
marginTop(5.px)
|
||||||
left(0.px)
|
}
|
||||||
right(0.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)) {
|
select(cls(KeyboardKeysCls)) {
|
||||||
position(Position.absolute)
|
position(Position.relative)
|
||||||
top(60.px)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user