diff --git a/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/ContentMode.kt b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/ContentMode.kt new file mode 100644 index 0000000..52f11d9 --- /dev/null +++ b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/ContentMode.kt @@ -0,0 +1,40 @@ +package cn.rdlevel.rdkt.core.data.action + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Represents how the content will be rescaled in [SetBackgroundColorEvent][cn.rdlevel.rdkt.core.events.SetBackgroundColorEvent]. + */ +@Serializable +public enum class ContentMode { + /** + * Rescale the content to fill the space. + */ + @SerialName("ScaleToFill") + SCALE_TO_FILL, + + /** + * Rescale the content to fit the space while maintaining its aspect ratio. + */ + @SerialName("AspectFit") + ASPECT_FIT, + + /** + * Rescale the content to fill the space while maintaining its aspect ratio. + */ + @SerialName("AspectFill") + ASPECT_FILL, + + /** + * Center the content in the space. + */ + @SerialName("Center") + CENTER, + + /** + * Tile the content in the space. + */ + @SerialName("Tiled") + TILED, +} \ No newline at end of file diff --git a/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/RescaleFilter.kt b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/RescaleFilter.kt new file mode 100644 index 0000000..98f30a3 --- /dev/null +++ b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/RescaleFilter.kt @@ -0,0 +1,22 @@ +package cn.rdlevel.rdkt.core.data.action + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Represent how to render the image when the image is rescaled. + */ +@Serializable +public enum class RescaleFilter { + /** + * The color of the rescaled pixel will be the nearest neighbor's. + */ + @SerialName("NearestNeighbor") + NEAREST_NEIGHBOR, + + /** + * The color of the rescaled pixel will be a weighted average of the nearest neighbors. + */ + @SerialName("Bilinear") + BILINEAR, +} \ No newline at end of file diff --git a/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/TilingConfig.kt b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/TilingConfig.kt new file mode 100644 index 0000000..5a80e41 --- /dev/null +++ b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/TilingConfig.kt @@ -0,0 +1,36 @@ +package cn.rdlevel.rdkt.core.data.action + +import cn.rdlevel.rdkt.core.data.Easing +import cn.rdlevel.rdkt.core.data.Vector2 +import cn.rdlevel.rdkt.core.data.vectorOf +import kotlinx.serialization.Serializable + +/** + * Represents how the content should be tiled. + * + * @property tilingType The type of tiling to apply. + * @property scrollX The X component of the scroll speed of the tiling in px. + * @property scrollY The Y component of the scroll speed of the tiling in px. + * @property duration The duration of the tiling animation change in beats. + * @property interval The interval between pulses in beats when [tilingType] is [TilingType.PULSE]. + * @property ease The easing function for the tiling animation change. + */ +@Serializable +public data class TilingConfig( + var tilingType: TilingType = TilingType.SCROLL, + var scrollX: Double = 0.0, + var scrollY: Double = 0.0, + var duration: Double = 0.0, + var interval: Double = 1.0, + var ease: Easing = Easing.LINEAR, +) { + /** + * The scroll speed of the tiling in px. + */ + var scroll: Vector2 + get() = vectorOf(scrollX, scrollY) + set(value) { + scrollX = value.x + scrollY = value.y + } +} \ No newline at end of file diff --git a/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/TilingType.kt b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/TilingType.kt new file mode 100644 index 0000000..b1be596 --- /dev/null +++ b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/data/action/TilingType.kt @@ -0,0 +1,22 @@ +package cn.rdlevel.rdkt.core.data.action + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * Represents the tiling type of tiled content. + */ +@Serializable +public enum class TilingType { + /** + * The content will be scrolling. + */ + @SerialName("Scroll") + SCROLL, + + /** + * The content will be pulsing repeatedly. + */ + @SerialName("Pulse") + PULSE, +} \ No newline at end of file diff --git a/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/events/SetBackgroundColorEvent.kt b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/events/SetBackgroundColorEvent.kt new file mode 100644 index 0000000..3508812 --- /dev/null +++ b/core/src/commonMain/kotlin/cn/rdlevel/rdkt/core/events/SetBackgroundColorEvent.kt @@ -0,0 +1,74 @@ +@file:OptIn(RDKTInternalAPI::class, ExperimentalSerializationApi::class) + +package cn.rdlevel.rdkt.core.events + + +import cn.rdlevel.rdkt.core.annotations.RDKTInternalAPI +import cn.rdlevel.rdkt.core.data.* +import cn.rdlevel.rdkt.core.data.action.ContentMode +import cn.rdlevel.rdkt.core.data.action.RescaleFilter +import cn.rdlevel.rdkt.core.data.action.TilingConfig +import cn.rdlevel.rdkt.core.serialization.Flatten +import cn.rdlevel.rdkt.core.serialization.flatten +import kotlinx.serialization.* +import kotlinx.serialization.json.JsonClassDiscriminator + +/** + * Sets the background of rooms. + * @property type The type of the background. + * @property filter How should the pixels' color of the background be when rescaled. + */ +@ConsistentCopyVisibility +@Serializable(SetBackgroundColorEvent.Serializer::class) +@KeepGeneratedSerializer +@SerialName("SetBackgroundColor") +public data class SetBackgroundColorEvent private constructor( + @Flatten + private var type: Type, + var filter: RescaleFilter = RescaleFilter.NEAREST_NEIGHBOR, + override val rooms: RoomsOrTopLayer = roomsOf(ROOM1), +) : ActionEvent(), RoomsOrTopLayerSpecificEvent { + /** + * Represents the type and the settings of the background. + */ + @Serializable + @JsonClassDiscriminator("backgroundType") + public sealed class Type { + /** + * The color of the background. + */ + public abstract var color: ColorWithAlpha + + /** + * Represents a pure color background. + */ + @SerialName("Color") + @Serializable + public data class Color(override var color: ColorWithAlpha = WHITE) : Type() + + /** + * Represents a background with images. + * + * @property image The images to be used. When there's none, it clears the image background. When there are multiple, they will be played in a loop. + * @property color The color filter to be applied on images. + * @property fps The speed of the image loop in frames per second when there are multiple images. + * @property contentMode The content mode of the images. + * @property tilingConfig The tiling configuration of the images when [contentMode] is [ContentMode.TILED]. + */ + @SerialName("Image") + @Serializable(Image.Serializer::class) + @KeepGeneratedSerializer + public data class Image( + var image: List = listOf(), + override var color: ColorWithAlpha = WHITE, + var fps: Double = 30.0, + var contentMode: ContentMode = ContentMode.SCALE_TO_FILL, + @Flatten + var tilingConfig: TilingConfig = TilingConfig() + ) : Type() { + public object Serializer : KSerializer by generatedSerializer().flatten() + } + } + + public object Serializer : KSerializer by generatedSerializer().flatten() +} \ No newline at end of file